@georeferencing/react 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +400 -2
  3. package/dist/Georeferencer.d.ts +71 -0
  4. package/dist/Georeferencer.js +220 -0
  5. package/dist/components/accuracy.d.ts +15 -0
  6. package/dist/components/accuracy.js +39 -0
  7. package/dist/components/exports.d.ts +32 -0
  8. package/dist/components/exports.js +152 -0
  9. package/dist/components/fields.d.ts +17 -0
  10. package/dist/components/fields.js +35 -0
  11. package/dist/controls.d.ts +40 -0
  12. package/dist/controls.js +28 -0
  13. package/dist/hooks/useGeoreferencer.d.ts +6 -0
  14. package/dist/hooks/useGeoreferencer.js +8 -0
  15. package/dist/index.d.ts +20 -0
  16. package/dist/index.js +16 -0
  17. package/dist/licenses/APACHE-2.0.txt +202 -0
  18. package/dist/licenses/GDAL-NOTICE.txt +24 -0
  19. package/dist/licenses/inventory.json +1 -0
  20. package/dist/localization.d.ts +6 -0
  21. package/dist/localization.js +1 -0
  22. package/dist/panels/AlignmentPanel.d.ts +19 -0
  23. package/dist/panels/AlignmentPanel.js +27 -0
  24. package/dist/panels/FeaturePanel.d.ts +28 -0
  25. package/dist/panels/FeaturePanel.js +43 -0
  26. package/dist/panels/GcpPanel.d.ts +35 -0
  27. package/dist/panels/GcpPanel.js +81 -0
  28. package/dist/panels/ImagePanel.d.ts +30 -0
  29. package/dist/panels/ImagePanel.js +279 -0
  30. package/dist/panels/PreviewControls.d.ts +17 -0
  31. package/dist/panels/PreviewControls.js +37 -0
  32. package/dist/panels/ReferencePanel.d.ts +17 -0
  33. package/dist/panels/ReferencePanel.js +24 -0
  34. package/dist/styles.css +594 -0
  35. package/dist/utils/downloadBlob.d.ts +5 -0
  36. package/dist/utils/downloadBlob.js +11 -0
  37. package/package.json +57 -3
@@ -0,0 +1,594 @@
1
+ .rg-editor {
2
+ --rg-accent: #12695b;
3
+ --rg-border: #d4ded9;
4
+ --rg-paper: #fffef9;
5
+ color: #20322f;
6
+ background: var(--rg-paper);
7
+ font:
8
+ 14px / 1.5 system-ui,
9
+ sans-serif;
10
+ padding: 24px;
11
+ border: 1px solid var(--rg-border);
12
+ }
13
+ .rg-editor *,
14
+ .rg-guard * {
15
+ box-sizing: border-box;
16
+ }
17
+ .rg-editor h1 {
18
+ font-size: 25px;
19
+ letter-spacing: -0.7px;
20
+ line-height: 1.2;
21
+ margin: 5px 0 18px;
22
+ font-weight: 550;
23
+ }
24
+ .rg-editor h2,
25
+ .rg-guard h2 {
26
+ font-size: 16px;
27
+ margin: 0 0 12px;
28
+ font-weight: 650;
29
+ }
30
+ .rg-editor p {
31
+ margin: 8px 0;
32
+ }
33
+ .rg-editor small,
34
+ .rg-editor caption,
35
+ .rg-hint {
36
+ color: #5b6c65;
37
+ font-size: 12px;
38
+ }
39
+ .rg-eyebrow {
40
+ font-size: 10px;
41
+ letter-spacing: 2px;
42
+ font-weight: 700;
43
+ color: var(--rg-accent);
44
+ }
45
+ .rg-editor-heading,
46
+ .rg-panel-heading {
47
+ display: flex;
48
+ justify-content: space-between;
49
+ align-items: baseline;
50
+ gap: 12px;
51
+ }
52
+ .rg-dirty {
53
+ font-size: 11px;
54
+ white-space: nowrap;
55
+ border-bottom: 2px solid #c48e45;
56
+ }
57
+ .rg-toolbar {
58
+ display: flex;
59
+ flex-wrap: wrap;
60
+ gap: 6px;
61
+ align-items: center;
62
+ margin: 10px 0;
63
+ }
64
+ .rg-file {
65
+ position: relative;
66
+ overflow: hidden;
67
+ display: inline-flex;
68
+ }
69
+ .rg-editor button:not(:where(.ol-viewport *)),
70
+ .rg-editor .rg-file,
71
+ .rg-guard button {
72
+ font: inherit;
73
+ font-size: 12px;
74
+ padding: 7px 11px;
75
+ border: 1px solid #b7c8bf;
76
+ border-radius: 3px;
77
+ background: #fffef9;
78
+ color: #20322f;
79
+ cursor: pointer;
80
+ }
81
+ .rg-editor button:not(:where(.ol-viewport *)):hover,
82
+ .rg-editor .rg-file:hover {
83
+ border-color: #12695b;
84
+ background: #eef4ee;
85
+ }
86
+ .rg-editor button:not(:where(.ol-viewport *)):disabled,
87
+ .rg-guard button:disabled {
88
+ opacity: 0.45;
89
+ cursor: not-allowed;
90
+ }
91
+ .rg-editor button:not(:where(.ol-viewport *))[aria-pressed="true"],
92
+ .rg-editor .rg-primary {
93
+ background: var(--rg-accent);
94
+ color: white;
95
+ border-color: var(--rg-accent);
96
+ }
97
+ .rg-editor :focus-visible,
98
+ .rg-guard :focus-visible {
99
+ outline: 3px solid #de9c38;
100
+ outline-offset: 2px;
101
+ }
102
+ .rg-file input[type="file"] {
103
+ position: absolute;
104
+ inset: 0;
105
+ opacity: 0;
106
+ cursor: pointer;
107
+ width: 100%;
108
+ }
109
+ .rg-file:focus-within {
110
+ outline: 3px solid #de9c38;
111
+ outline-offset: 2px;
112
+ }
113
+ .rg-editor input:not([type="checkbox"]):not([type="range"]):not([type="file"]),
114
+ .rg-editor select {
115
+ width: 100%;
116
+ border: 1px solid #c4d0c8;
117
+ border-radius: 3px;
118
+ padding: 6px;
119
+ font: inherit;
120
+ background: white;
121
+ color: #20322f;
122
+ }
123
+ .rg-editor input[type="range"] {
124
+ width: 100%;
125
+ accent-color: var(--rg-accent);
126
+ }
127
+ .rg-editor input[type="checkbox"] {
128
+ accent-color: var(--rg-accent);
129
+ }
130
+ .rg-editor label {
131
+ display: block;
132
+ font-size: 12px;
133
+ margin: 8px 0;
134
+ }
135
+ .rg-editor .rg-inline {
136
+ display: flex;
137
+ align-items: center;
138
+ gap: 8px;
139
+ }
140
+ .rg-workbench {
141
+ display: grid;
142
+ grid-template-columns: minmax(220px, 1fr) minmax(210px, 0.65fr);
143
+ gap: 22px;
144
+ padding-top: 16px;
145
+ border-top: 1px solid var(--rg-border);
146
+ }
147
+ .rg-image-view {
148
+ width: 100%;
149
+ height: 330px;
150
+ background: #e5e9e0;
151
+ border: 1px solid #cbd4c8;
152
+ touch-action: none;
153
+ cursor: crosshair;
154
+ }
155
+ .rg-image-meta {
156
+ font-size: 11px;
157
+ margin-bottom: 9px;
158
+ overflow-wrap: anywhere;
159
+ }
160
+ .rg-empty {
161
+ height: 330px;
162
+ display: flex;
163
+ flex-direction: column;
164
+ justify-content: center;
165
+ align-items: center;
166
+ text-align: center;
167
+ padding: 24px;
168
+ background: #f1f3eb;
169
+ border: 1px dashed #9dab9e;
170
+ }
171
+ .rg-cross {
172
+ font-size: 38px;
173
+ font-weight: 200;
174
+ color: #678476;
175
+ }
176
+ .rg-editor section + section {
177
+ margin-top: 20px;
178
+ padding-top: 18px;
179
+ border-top: 1px solid var(--rg-border);
180
+ }
181
+ .rg-fit-summary {
182
+ font-variant-numeric: tabular-nums;
183
+ }
184
+ .rg-table-scroll {
185
+ overflow-x: auto;
186
+ margin: 12px 0;
187
+ }
188
+ .rg-editor table {
189
+ border-collapse: collapse;
190
+ width: 100%;
191
+ font-size: 12px;
192
+ }
193
+ .rg-editor th,
194
+ .rg-editor td {
195
+ padding: 7px 4px;
196
+ text-align: left;
197
+ border-bottom: 1px solid #e1e7df;
198
+ white-space: nowrap;
199
+ }
200
+ .rg-editor td input[type="number"] {
201
+ min-width: 90px;
202
+ max-width: 130px;
203
+ font-variant-numeric: tabular-nums;
204
+ }
205
+ .rg-editor caption {
206
+ caption-side: bottom;
207
+ text-align: left;
208
+ padding-top: 7px;
209
+ }
210
+ .rg-editor details {
211
+ margin-top: 14px;
212
+ }
213
+ .rg-editor summary {
214
+ cursor: pointer;
215
+ font-size: 12px;
216
+ font-weight: 600;
217
+ padding: 8px 0;
218
+ }
219
+ .rg-coordinate-entry,
220
+ .rg-output-fields {
221
+ display: grid;
222
+ grid-template-columns: repeat(2, minmax(0, 1fr));
223
+ gap: 6px 14px;
224
+ }
225
+ .rg-feature {
226
+ display: flex;
227
+ justify-content: space-between;
228
+ gap: 8px;
229
+ align-items: center;
230
+ border-bottom: 1px solid var(--rg-border);
231
+ padding: 5px 0;
232
+ font-size: 12px;
233
+ flex-wrap: wrap;
234
+ }
235
+ .rg-feature > input {
236
+ flex-basis: 100%;
237
+ }
238
+ .rg-status {
239
+ margin-top: 20px;
240
+ padding: 12px;
241
+ background: #eef2e9;
242
+ border-left: 3px solid #7c917c;
243
+ font-size: 12px;
244
+ overflow-wrap: anywhere;
245
+ }
246
+ .rg-guard {
247
+ color: #20322f;
248
+ border: 1px solid #9dab9e;
249
+ border-radius: 5px;
250
+ max-width: 460px;
251
+ padding: 28px;
252
+ font:
253
+ 14px / 1.5 system-ui,
254
+ sans-serif;
255
+ }
256
+ .rg-guard::backdrop {
257
+ background: #10292170;
258
+ }
259
+ .rg-histogram {
260
+ max-height: 70px;
261
+ width: 100%;
262
+ color: #12695b;
263
+ }
264
+ .rg-editor progress {
265
+ width: 100%;
266
+ accent-color: var(--rg-accent);
267
+ }
268
+ @media (max-width: 750px) {
269
+ .rg-workbench {
270
+ grid-template-columns: 1fr;
271
+ }
272
+ .rg-editor {
273
+ padding: 16px;
274
+ }
275
+ .rg-editor-heading {
276
+ display: block;
277
+ }
278
+ }
279
+
280
+ /* Guided step-by-step layout; all selectors remain scoped to the editor. */
281
+ .rg-editor .rg-primary:hover:not(:disabled) {
282
+ background: #0e5a4e;
283
+ border-color: #0e5a4e;
284
+ color: white;
285
+ }
286
+ .rg-visually-hidden {
287
+ position: absolute;
288
+ width: 1px;
289
+ height: 1px;
290
+ overflow: hidden;
291
+ clip-path: inset(50%);
292
+ white-space: nowrap;
293
+ }
294
+ .rg-guided {
295
+ padding: 18px;
296
+ }
297
+ .rg-steps {
298
+ display: flex;
299
+ flex-wrap: wrap;
300
+ gap: 8px 22px;
301
+ list-style: none;
302
+ margin: 0;
303
+ padding: 0 0 14px;
304
+ border-bottom: 1px solid var(--rg-border);
305
+ font-size: 13px;
306
+ color: #5b6c65;
307
+ }
308
+ .rg-steps li,
309
+ .rg-editor .rg-step-button {
310
+ display: inline-flex;
311
+ align-items: center;
312
+ gap: 8px;
313
+ }
314
+ .rg-editor .rg-step-button {
315
+ padding: 0;
316
+ border: 0;
317
+ background: none;
318
+ color: inherit;
319
+ font-size: inherit;
320
+ }
321
+ .rg-editor .rg-step-button:hover .rg-step-label {
322
+ text-decoration: underline;
323
+ }
324
+ .rg-step-index {
325
+ display: inline-grid;
326
+ place-items: center;
327
+ width: 24px;
328
+ height: 24px;
329
+ border-radius: 50%;
330
+ border: 1.5px solid #9dab9e;
331
+ font-size: 12px;
332
+ font-weight: 700;
333
+ font-variant-numeric: tabular-nums;
334
+ }
335
+ .rg-steps [data-state="current"] {
336
+ color: var(--rg-accent);
337
+ font-weight: 700;
338
+ }
339
+ .rg-steps [data-state="current"] .rg-step-index {
340
+ border-color: var(--rg-accent);
341
+ background: #e3efe9;
342
+ }
343
+ .rg-steps [data-state="done"] {
344
+ color: #20322f;
345
+ }
346
+ .rg-steps [data-state="done"] .rg-step-index {
347
+ border-color: var(--rg-accent);
348
+ background: var(--rg-accent);
349
+ color: white;
350
+ }
351
+ .rg-matching-bar {
352
+ display: grid;
353
+ grid-template-columns: minmax(0, 1fr) auto;
354
+ align-items: center;
355
+ gap: 8px 24px;
356
+ padding: 14px 0 10px;
357
+ }
358
+ .rg-guided .rg-matching-bar {
359
+ position: sticky;
360
+ top: 0;
361
+ z-index: 5;
362
+ background: var(--rg-paper);
363
+ border-bottom: 1px solid var(--rg-border);
364
+ }
365
+ .rg-instruction strong {
366
+ font-size: 16px;
367
+ }
368
+ .rg-instruction p {
369
+ max-width: 640px;
370
+ margin: 4px 0 0;
371
+ font-size: 12px;
372
+ color: #5b6c65;
373
+ }
374
+ .rg-editor .rg-link {
375
+ padding: 0;
376
+ border: 0;
377
+ background: none;
378
+ color: var(--rg-accent);
379
+ font-size: inherit;
380
+ text-decoration: underline;
381
+ }
382
+ .rg-step-actions {
383
+ display: flex;
384
+ flex-wrap: wrap;
385
+ align-items: center;
386
+ justify-content: flex-end;
387
+ gap: 8px;
388
+ }
389
+ .rg-preview-controls {
390
+ display: flex;
391
+ align-items: center;
392
+ gap: 16px;
393
+ }
394
+ .rg-preview-controls label {
395
+ display: flex;
396
+ align-items: center;
397
+ gap: 8px;
398
+ margin: 0;
399
+ }
400
+ .rg-preview-controls > div {
401
+ text-align: right;
402
+ }
403
+ .rg-readiness {
404
+ display: block;
405
+ margin-top: 4px;
406
+ }
407
+ .rg-match-tools {
408
+ margin: 10px 0 12px;
409
+ }
410
+ .rg-tools-end {
411
+ display: flex;
412
+ align-items: center;
413
+ gap: 14px;
414
+ margin-left: auto;
415
+ }
416
+ .rg-editor .rg-inline-field {
417
+ display: flex;
418
+ align-items: center;
419
+ gap: 8px;
420
+ margin: 0;
421
+ white-space: nowrap;
422
+ }
423
+ .rg-editor .rg-inline-field select {
424
+ width: auto;
425
+ max-width: 225px;
426
+ }
427
+ .rg-guided .rg-dirty {
428
+ line-height: 1.6;
429
+ }
430
+ .rg-paired-views {
431
+ display: grid;
432
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
433
+ gap: 18px;
434
+ }
435
+ .rg-source-pane,
436
+ .rg-reference-pane {
437
+ min-width: 0;
438
+ border-top: 3px solid transparent;
439
+ padding-top: 10px;
440
+ }
441
+ .rg-paired-views [data-active="true"] {
442
+ border-top-color: var(--rg-accent);
443
+ }
444
+ .rg-guided .rg-image-view,
445
+ .rg-guided .rg-empty {
446
+ height: clamp(280px, 44vh, 480px);
447
+ }
448
+ .rg-guided .rg-image-panel .rg-panel-heading {
449
+ min-height: 39px;
450
+ align-items: center;
451
+ }
452
+ .rg-guided .rg-image-panel .rg-panel-heading h2 {
453
+ margin: 0;
454
+ }
455
+ .rg-guided .rg-image-panel .rg-panel-heading .rg-file {
456
+ margin: 0;
457
+ }
458
+ .rg-guided .rg-image-panel[data-empty] .rg-panel-heading .rg-file {
459
+ display: none;
460
+ }
461
+ .rg-guided .rg-image-meta {
462
+ margin-top: 4px;
463
+ }
464
+ .rg-empty-actions {
465
+ justify-content: center;
466
+ margin-top: 16px;
467
+ }
468
+ .rg-view-tabs {
469
+ display: none;
470
+ border: 0;
471
+ margin: 0;
472
+ padding: 0;
473
+ }
474
+ .rg-review-panels {
475
+ display: grid;
476
+ grid-template-columns: repeat(2, minmax(0, 1fr));
477
+ gap: 18px;
478
+ padding: 18px 0 0;
479
+ }
480
+ .rg-editor .rg-review-panels section + section {
481
+ margin-top: 0;
482
+ padding-top: 0;
483
+ border-top: none;
484
+ }
485
+ .rg-card {
486
+ min-width: 0;
487
+ padding: 16px;
488
+ border: 1px solid var(--rg-border);
489
+ border-radius: 6px;
490
+ background: white;
491
+ }
492
+ .rg-editor .rg-review-panels .rg-card {
493
+ padding: 16px;
494
+ }
495
+ .rg-editor .rg-card h3 {
496
+ margin: 16px 0 0;
497
+ font-size: 13px;
498
+ font-weight: 650;
499
+ }
500
+ .rg-accuracy {
501
+ margin-bottom: 12px;
502
+ padding: 10px 12px;
503
+ border-left: 4px solid #9dab9e;
504
+ background: #f4f6f1;
505
+ }
506
+ .rg-accuracy[data-quality="good"] {
507
+ border-left-color: #2f8a5b;
508
+ }
509
+ .rg-accuracy[data-quality="fair"] {
510
+ border-left-color: #c48e45;
511
+ }
512
+ .rg-accuracy[data-quality="poor"] {
513
+ border-left-color: #b4452d;
514
+ }
515
+ .rg-accuracy p {
516
+ margin: 4px 0;
517
+ font-size: 12px;
518
+ }
519
+ .rg-guided .rg-gcp-panel {
520
+ border-top: 1px solid var(--rg-border);
521
+ margin-top: 18px;
522
+ padding-top: 16px;
523
+ }
524
+ .rg-editor .rg-review-panels .rg-gcp-panel {
525
+ margin-top: 0;
526
+ padding-top: 0;
527
+ border-top: none;
528
+ }
529
+ .rg-editor .rg-point-list {
530
+ width: auto;
531
+ min-width: 280px;
532
+ }
533
+ .rg-advanced {
534
+ margin-top: 16px;
535
+ }
536
+ .rg-export-progress {
537
+ display: flex;
538
+ align-items: center;
539
+ gap: 12px;
540
+ margin: 10px 0;
541
+ }
542
+ .rg-status:empty {
543
+ margin: 0;
544
+ padding: 0;
545
+ border: 0;
546
+ }
547
+ @media (max-width: 720px) {
548
+ .rg-guided {
549
+ padding: 12px;
550
+ }
551
+ .rg-steps li:not([data-state="current"]) .rg-step-label {
552
+ display: none;
553
+ }
554
+ .rg-matching-bar {
555
+ grid-template-columns: minmax(0, 1fr);
556
+ }
557
+ .rg-step-actions,
558
+ .rg-preview-controls {
559
+ justify-content: flex-start;
560
+ }
561
+ .rg-preview-controls > div {
562
+ text-align: left;
563
+ }
564
+ .rg-tools-end {
565
+ margin-left: 0;
566
+ width: 100%;
567
+ flex-wrap: wrap;
568
+ }
569
+ .rg-paired-views {
570
+ grid-template-columns: minmax(0, 1fr);
571
+ }
572
+ .rg-paired-views[data-mobile-view="image"] .rg-reference-pane,
573
+ .rg-paired-views[data-mobile-view="map"] .rg-source-pane {
574
+ display: none;
575
+ }
576
+ .rg-view-tabs {
577
+ display: flex;
578
+ gap: 8px;
579
+ }
580
+ .rg-guided .rg-image-view,
581
+ .rg-guided .rg-empty {
582
+ height: 340px;
583
+ }
584
+ .rg-review-panels {
585
+ grid-template-columns: minmax(0, 1fr);
586
+ }
587
+ }
588
+ .rg-editor .rg-error {
589
+ padding: 8px 12px;
590
+ border-left: 3px solid #b4452d;
591
+ background: #fbefea;
592
+ color: #7a2614;
593
+ font-size: 12px;
594
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Start a browser download and revoke its temporary object URL after one second. Invoke
3
+ * from a client-side user action; this utility performs no upload.
4
+ */
5
+ export declare function downloadBlob(blob: Blob, name: string): void;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Start a browser download and revoke its temporary object URL after one second. Invoke
3
+ * from a client-side user action; this utility performs no upload.
4
+ */
5
+ export function downloadBlob(blob, name) {
6
+ const url = URL.createObjectURL(blob), a = document.createElement("a");
7
+ a.href = url;
8
+ a.download = name;
9
+ a.click();
10
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
11
+ }
package/package.json CHANGED
@@ -1,6 +1,60 @@
1
1
  {
2
+ "version": "0.2.0",
3
+ "license": "MIT",
4
+ "type": "module",
5
+ "engines": {
6
+ "node": ">=22.12.0"
7
+ },
8
+ "homepage": "https://github.com/tobilg/georeferencing#readme",
9
+ "bugs": {
10
+ "url": "https://github.com/tobilg/georeferencing/issues"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
2
15
  "name": "@georeferencing/react",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
16
+ "description": "React panels and editor for the headless georeferencing core and optional export plugins",
17
+ "sideEffects": [
18
+ "**/*.css"
19
+ ],
20
+ "files": [
21
+ "dist",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "main": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ },
32
+ "./styles.css": "./dist/styles.css"
33
+ },
34
+ "dependencies": {
35
+ "@georeferencing/core": "^0.2.0"
36
+ },
37
+ "peerDependencies": {
38
+ "react": ">=19.3.0 <20",
39
+ "react-dom": ">=19.3.0 <20",
40
+ "ol": ">=10.10.0 <11"
41
+ },
42
+ "devDependencies": {
43
+ "typescript": "5.9.3",
44
+ "react": "19.3.0",
45
+ "react-dom": "19.3.0",
46
+ "ol": "10.10.0",
47
+ "@types/react": "19.2.14",
48
+ "@types/react-dom": "19.2.3"
49
+ },
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/tobilg/georeferencing.git",
53
+ "directory": "packages/react"
54
+ },
55
+ "scripts": {
56
+ "build": "node ../../scripts/build-package.mjs react",
57
+ "dev": "node ../../scripts/build-package.mjs react --watch",
58
+ "typecheck": "tsc --noEmit --noUnusedLocals --noUnusedParameters"
59
+ }
6
60
  }