@softwarity/geojson-editor 1.0.9 → 1.0.11

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.
@@ -0,0 +1,453 @@
1
+ /* Base reset - protect against inherited styles */
2
+ :host *, :host *::before, :host *::after {
3
+ box-sizing: border-box;
4
+ font: normal normal 13px/1.5 'Courier New', Courier, monospace;
5
+ font-variant: normal;
6
+ letter-spacing: 0;
7
+ word-spacing: 0;
8
+ text-transform: none;
9
+ text-decoration: none;
10
+ text-indent: 0;
11
+ }
12
+
13
+ :host {
14
+ display: flex;
15
+ flex-direction: column;
16
+ position: relative;
17
+ width: 100%;
18
+ height: 400px;
19
+ border-radius: 4px;
20
+ overflow: hidden;
21
+ }
22
+
23
+ :host([readonly]) .editor-wrapper::after {
24
+ content: '';
25
+ position: absolute;
26
+ inset: 0;
27
+ pointer-events: none;
28
+ background: repeating-linear-gradient(-45deg, rgba(128,128,128,0.08), rgba(128,128,128,0.08) 3px, transparent 3px, transparent 12px);
29
+ z-index: 1;
30
+ }
31
+
32
+ :host([readonly]) .hidden-textarea { cursor: text; }
33
+
34
+ .editor-wrapper {
35
+ position: relative;
36
+ width: 100%;
37
+ flex: 1;
38
+ background: var(--bg-color, #fff);
39
+ display: flex;
40
+ overflow: hidden;
41
+ }
42
+
43
+ /* ========== Gutter ========== */
44
+ .gutter {
45
+ width: 50px;
46
+ background: var(--gutter-bg, #f0f0f0);
47
+ border-right: 1px solid var(--gutter-border, #e0e0e0);
48
+ overflow: hidden;
49
+ flex-shrink: 0;
50
+ position: relative;
51
+ }
52
+
53
+ .gutter-scroll {
54
+ position: absolute;
55
+ inset: 0;
56
+ overflow: hidden;
57
+ padding: 8px 0;
58
+ }
59
+
60
+ .gutter-scroll-content {
61
+ position: relative;
62
+ width: 100%;
63
+ }
64
+
65
+ .gutter-content {
66
+ position: absolute;
67
+ top: 0;
68
+ left: 0;
69
+ right: 0;
70
+ will-change: transform;
71
+ }
72
+
73
+ .gutter-line {
74
+ height: 19.5px; /* line-height * font-size = 1.5 * 13px */
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: flex-end;
78
+ padding-right: 4px;
79
+ }
80
+
81
+ .line-number {
82
+ font-size: 11px;
83
+ color: var(--gutter-text, #999);
84
+ user-select: none;
85
+ min-width: 20px;
86
+ text-align: right;
87
+ }
88
+
89
+ .collapse-column {
90
+ width: 16px;
91
+ display: flex;
92
+ align-items: center;
93
+ justify-content: center;
94
+ flex-shrink: 0;
95
+ }
96
+
97
+ /* ========== Gutter Controls ========== */
98
+ .color-indicator, .collapse-button, .boolean-checkbox {
99
+ width: 12px;
100
+ height: 12px;
101
+ border-radius: 2px;
102
+ cursor: pointer;
103
+ transition: transform 0.1s;
104
+ flex-shrink: 0;
105
+ }
106
+
107
+ .color-indicator {
108
+ border: 1px solid #555;
109
+ }
110
+ .color-indicator:hover {
111
+ transform: scale(1.2);
112
+ border-color: #fff;
113
+ }
114
+
115
+ .boolean-checkbox {
116
+ appearance: none;
117
+ -webkit-appearance: none;
118
+ background: transparent;
119
+ border: 1.5px solid var(--control-border, #c0c0c0);
120
+ border-radius: 2px;
121
+ margin: 0;
122
+ position: relative;
123
+ }
124
+ .boolean-checkbox:checked {
125
+ border-color: var(--control-color, #000080);
126
+ }
127
+ .boolean-checkbox:checked::after {
128
+ content: '✔';
129
+ color: var(--control-color, #000080);
130
+ font-size: 11px;
131
+ font-weight: bold;
132
+ position: absolute;
133
+ top: -3px;
134
+ right: -1px;
135
+ }
136
+ .boolean-checkbox:hover {
137
+ transform: scale(1.2);
138
+ border-color: var(--control-color, #000080);
139
+ }
140
+
141
+ .collapse-button {
142
+ background: transparent;
143
+ border: none;
144
+ color: var(--json-punct, #a9b7c6);
145
+ font-size: 10px;
146
+ display: flex;
147
+ align-items: center;
148
+ justify-content: center;
149
+ user-select: none;
150
+ opacity: 0;
151
+ transition: opacity 0.15s;
152
+ }
153
+ .collapse-button.collapsed {
154
+ opacity: 1;
155
+ }
156
+ .gutter:hover .collapse-button {
157
+ opacity: 1;
158
+ }
159
+ .collapse-button:hover {
160
+ transform: scale(1.2);
161
+ }
162
+
163
+ /* Touch devices: always show collapse buttons */
164
+ @media (hover: none), (pointer: coarse) {
165
+ .collapse-button {
166
+ opacity: 1;
167
+ }
168
+ }
169
+
170
+ .visibility-button {
171
+ width: 14px;
172
+ height: 14px;
173
+ background: transparent;
174
+ color: var(--control-color, #000080);
175
+ border: none;
176
+ cursor: pointer;
177
+ display: flex;
178
+ align-items: center;
179
+ justify-content: center;
180
+ transition: all 0.1s;
181
+ flex-shrink: 0;
182
+ opacity: 0.7;
183
+ padding: 0;
184
+ font-size: 11px;
185
+ }
186
+ .visibility-button:hover { opacity: 1; transform: scale(1.15); }
187
+ .visibility-button.hidden { opacity: 0.35; }
188
+
189
+ /* ========== Editor Content ========== */
190
+ .editor-content {
191
+ position: relative;
192
+ flex: 1;
193
+ overflow: hidden;
194
+ }
195
+
196
+ /* Hidden textarea for input capture (Monaco-style) */
197
+ .hidden-textarea {
198
+ position: absolute;
199
+ top: 0;
200
+ left: 0;
201
+ width: 100%;
202
+ height: 100%;
203
+ opacity: 0;
204
+ padding: 0;
205
+ margin: 0;
206
+ border: none;
207
+ outline: none;
208
+ resize: none;
209
+ overflow: hidden;
210
+ z-index: -1;
211
+ pointer-events: none;
212
+ caret-color: transparent;
213
+ }
214
+
215
+ /* Viewport container with scroll */
216
+ .viewport {
217
+ position: absolute;
218
+ inset: 0;
219
+ overflow: auto;
220
+ padding: 8px 12px;
221
+ overscroll-behavior: contain; /* Prevent scroll chaining to parent */
222
+ }
223
+
224
+ /* Scroll content - defines total scrollable height */
225
+ .scroll-content {
226
+ position: relative;
227
+ width: 100%;
228
+ }
229
+
230
+ /* Lines container - positioned via transform */
231
+ .lines-container {
232
+ position: absolute;
233
+ top: 0;
234
+ left: 0;
235
+ right: 0;
236
+ will-change: transform;
237
+ }
238
+
239
+ /* Single line */
240
+ .line {
241
+ height: 19.5px; /* line-height * font-size */
242
+ white-space: pre;
243
+ display: block;
244
+ position: relative;
245
+ }
246
+
247
+ /* Cursor - positioned absolutely to not affect text layout */
248
+ .cursor {
249
+ position: absolute;
250
+ width: 2px;
251
+ height: 1em;
252
+ background: var(--caret-color, #000);
253
+ top: 0.15em;
254
+ pointer-events: none;
255
+ animation: cursor-blink 1s step-end infinite;
256
+ }
257
+
258
+ @keyframes cursor-blink {
259
+ 0%, 100% { opacity: 1; }
260
+ 50% { opacity: 0; }
261
+ }
262
+
263
+ /* Selection highlight */
264
+ .selection {
265
+ position: absolute;
266
+ height: 100%;
267
+ top: 0;
268
+ background: var(--selection-color, rgba(51, 153, 255, 0.3));
269
+ pointer-events: none;
270
+ z-index: 0;
271
+ }
272
+
273
+ .line-hidden > span {
274
+ opacity: 0.35;
275
+ filter: grayscale(50%);
276
+ }
277
+
278
+ .line-collapsed {
279
+ display: none;
280
+ }
281
+
282
+ /* Placeholder */
283
+ .placeholder-layer {
284
+ position: absolute;
285
+ top: 8px;
286
+ left: 12px;
287
+ color: #6a6a6a;
288
+ pointer-events: none;
289
+ z-index: 0;
290
+ white-space: pre;
291
+ }
292
+
293
+ /* ========== Syntax Highlighting ========== */
294
+ .json-key { color: var(--json-key, #660e7a); }
295
+ .json-string { color: var(--json-string, #008000); }
296
+ .json-number { color: var(--json-number, #00f); }
297
+ .json-boolean, .json-null { color: var(--json-boolean, #000080); }
298
+ .json-punctuation { color: var(--json-punct, #000); }
299
+ .json-key-invalid { color: var(--json-key-invalid, #f00); }
300
+ .json-error { color: var(--json-error, #f00); }
301
+
302
+ .geojson-key { color: var(--geojson-key, #660e7a); font-weight: 600; }
303
+ .geojson-type { color: var(--geojson-type, #008000); font-weight: 600; }
304
+ .geojson-type-invalid { color: var(--geojson-type-invalid, #f00); font-weight: 600; }
305
+
306
+ /* Hidden marker - invisible but present for data */
307
+ .d-none { display: none; }
308
+
309
+ /* Collapsed node styling */
310
+ .collapsed-bracket-array,
311
+ .collapsed-bracket-object {
312
+ color: var(--json-punct, #000);
313
+ }
314
+ .collapsed-bracket-array::after,
315
+ .collapsed-bracket-object::after {
316
+ content: '…';
317
+ color: var(--json-punct, #888);
318
+ }
319
+ .collapsed-content { display: none; }
320
+
321
+ /* ========== Prefix/Suffix ========== */
322
+ .prefix-wrapper, .suffix-wrapper {
323
+ display: flex;
324
+ flex-shrink: 0;
325
+ background: var(--bg-color, #fff);
326
+ }
327
+
328
+ .prefix-gutter, .suffix-gutter {
329
+ width: 50px;
330
+ background: var(--gutter-bg, #f0f0f0);
331
+ border-right: 1px solid var(--gutter-border, #e0e0e0);
332
+ flex-shrink: 0;
333
+ }
334
+
335
+ .editor-prefix, .editor-suffix {
336
+ flex: 1;
337
+ padding: 4px 12px;
338
+ color: var(--text-color, #000);
339
+ background: var(--bg-color, #fff);
340
+ user-select: none;
341
+ white-space: pre-wrap;
342
+ word-wrap: break-word;
343
+ opacity: 0.6;
344
+ }
345
+
346
+ .prefix-wrapper { border-bottom: 1px solid rgba(255,255,255,0.1); }
347
+ .suffix-wrapper { border-top: 1px solid rgba(255,255,255,0.1); position: relative; }
348
+
349
+ .clear-btn {
350
+ position: absolute;
351
+ right: 0.5rem;
352
+ top: 50%;
353
+ transform: translateY(-50%);
354
+ background: transparent;
355
+ border: none;
356
+ color: var(--text-color, #000);
357
+ opacity: 0.3;
358
+ cursor: pointer;
359
+ font-size: 0.65rem;
360
+ width: 1rem;
361
+ height: 1rem;
362
+ padding: 0.15rem 0 0 0;
363
+ border-radius: 3px;
364
+ display: flex;
365
+ align-items: center;
366
+ justify-content: center;
367
+ transition: opacity 0.2s, background 0.2s;
368
+ }
369
+ .clear-btn:hover { opacity: 0.7; background: rgba(255,255,255,0.1); }
370
+ .clear-btn[hidden] { display: none; }
371
+
372
+ /* ========== Scrollbar ========== */
373
+ .viewport::-webkit-scrollbar { width: 10px; height: 10px; }
374
+ .viewport::-webkit-scrollbar-track { background: var(--control-bg, #e8e8e8); }
375
+ .viewport::-webkit-scrollbar-thumb { background: var(--control-border, #c0c0c0); border-radius: 5px; }
376
+ .viewport::-webkit-scrollbar-thumb:hover { background: var(--control-color, #000080); }
377
+ .viewport { scrollbar-width: thin; scrollbar-color: var(--control-border, #c0c0c0) var(--control-bg, #e8e8e8); }
378
+
379
+ /* ========== Selection highlight ========== */
380
+ .line .selected {
381
+ background: rgba(51, 153, 255, 0.3);
382
+ }
383
+
384
+ /* ========== Inline Controls (using ::before pseudo-elements) ========== */
385
+
386
+ /* Shared styles for inline control pseudo-elements */
387
+ .json-color,
388
+ .json-boolean {
389
+ position: relative;
390
+ }
391
+ .json-color::before,
392
+ .json-boolean::before {
393
+ content: '';
394
+ position: absolute;
395
+ left: -8px;
396
+ top: 50%;
397
+ transform: translateY(-50%);
398
+ margin-top: -1px;
399
+ width: 8px;
400
+ height: 8px;
401
+ border-radius: 2px;
402
+ cursor: pointer;
403
+ }
404
+ .json-color:hover::before,
405
+ .json-boolean:hover::before {
406
+ transform: translateY(-50%) scale(1.2);
407
+ border-color: var(--control-color, #000080);
408
+ }
409
+
410
+ /* Color swatch specific styles */
411
+ .json-color::before {
412
+ background-color: var(--swatch-color);
413
+ border: 1px solid var(--json-punct, #a9b7c6);
414
+ }
415
+
416
+ /* Boolean checkbox specific styles */
417
+ .json-boolean::before {
418
+ border: 1.5px solid var(--control-border, #c0c0c0);
419
+ background: transparent;
420
+ }
421
+ .json-bool-true::before {
422
+ content: '✔';
423
+ border-color: var(--control-color, #000080);
424
+ color: var(--control-color, #000080);
425
+ font-size: 8px;
426
+ display: flex;
427
+ align-items: center;
428
+ justify-content: center;
429
+ line-height: 8px;
430
+ }
431
+
432
+ /* Feature visibility using ::before on the line (placed in indentation space) */
433
+ .line.has-visibility {
434
+ position: relative;
435
+ }
436
+ .line.has-visibility::before {
437
+ content: '👁';
438
+ position: absolute;
439
+ left: 0;
440
+ top: 3px;
441
+ font-size: 10px;
442
+ color: var(--control-color, #000080);
443
+ opacity: 0.6;
444
+ cursor: pointer;
445
+ z-index: 1;
446
+ }
447
+ .line.has-visibility:hover::before {
448
+ opacity: 1;
449
+ transform: scale(1.15);
450
+ }
451
+ .line.has-visibility.feature-hidden::before {
452
+ opacity: 0.5;
453
+ }