@jackuait/blok 0.12.0 → 0.12.1
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.
- package/dist/blok.cjs +1 -1
- package/dist/blok.iife.js +5 -5
- package/dist/blok.mjs +2 -2
- package/dist/chunks/{blok-Cxcy7G7v.mjs → blok-B4ebnd6l.mjs} +58 -6
- package/dist/chunks/{blok-qY4LDF7A.cjs → blok-k8Yo4v2F.cjs} +4 -4
- package/dist/chunks/{constants-Bhk7u_hm.mjs → constants-BsyOzSoJ.mjs} +1 -1
- package/dist/chunks/{constants-BYCpx4v_.cjs → constants-DGaNl2M0.cjs} +1 -1
- package/dist/chunks/tools-CPzDYrWa.cjs +115 -0
- package/dist/chunks/{tools-Bc4e0xmz.mjs → tools-JNr7LO1_.mjs} +888 -883
- package/dist/full.cjs +1 -1
- package/dist/full.mjs +3 -3
- package/dist/react.cjs +1 -1
- package/dist/react.mjs +2 -2
- package/dist/tools.cjs +1 -1
- package/dist/tools.mjs +2 -2
- package/package.json +2 -2
- package/src/components/block-tunes/block-tune-copy-link.ts +2 -2
- package/src/components/modules/paste/index.ts +154 -2
- package/src/styles/colors.css +57 -0
- package/src/styles/database.css +3 -3
- package/src/styles/image.css +50 -140
- package/src/styles/main.css +148 -6
- package/src/tools/callout/index.ts +0 -1
- package/src/tools/code/index.ts +19 -2
- package/src/tools/database/database-board-view.ts +1 -1
- package/src/tools/database/database-card-drawer.ts +3 -2
- package/src/tools/database/database-list-view.ts +1 -1
- package/src/tools/database/database-model.ts +15 -3
- package/src/tools/database/database-property-type-popover.ts +14 -10
- package/src/tools/database/database-tab-bar.ts +9 -3
- package/src/tools/database/database-view-popover.ts +15 -7
- package/src/tools/database/index.ts +0 -2
- package/src/tools/header/index.ts +6 -6
- package/src/tools/image/alt-popover.css +6 -6
- package/src/tools/image/crop-editor.css +34 -34
- package/src/tools/image/crop-modal.css +1 -1
- package/src/tools/image/empty-state.ts +3 -3
- package/src/tools/image/error-state.ts +9 -9
- package/src/tools/image/index.ts +2 -3
- package/src/tools/image/ui.ts +18 -13
- package/src/tools/list/style-config.ts +0 -3
- package/src/tools/paragraph/index.ts +0 -1
- package/src/tools/quote/index.ts +0 -1
- package/src/tools/table/index.ts +0 -1
- package/src/tools/toggle/index.ts +0 -1
- package/dist/chunks/tools-DaOdAh89.cjs +0 -115
package/src/styles/image.css
CHANGED
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
}
|
|
45
45
|
[data-blok-element-content].bg-selection:has([data-blok-tool="image"]) .blok-image-inner {
|
|
46
46
|
background-color: var(--blok-selection);
|
|
47
|
-
border-radius:
|
|
47
|
+
border-radius: var(--blok-space-1);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/* caption */
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
[data-blok-tool="image"] .blok-image-caption-row__alt {
|
|
77
77
|
flex: 0 0 auto;
|
|
78
78
|
margin-top: var(--blok-space-1);
|
|
79
|
-
padding:
|
|
79
|
+
padding: var(--blok-space-0-75) var(--blok-space-2);
|
|
80
80
|
font: inherit;
|
|
81
81
|
font-size: 11px;
|
|
82
82
|
font-weight: 500;
|
|
@@ -120,23 +120,8 @@
|
|
|
120
120
|
opacity: 1;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
/* toolbar
|
|
124
|
-
|
|
125
|
-
position: absolute;
|
|
126
|
-
top: 10px; right: 10px;
|
|
127
|
-
display: inline-flex;
|
|
128
|
-
background: var(--blok-overlay-dark-strong);
|
|
129
|
-
border-radius: var(--blok-space-2);
|
|
130
|
-
padding: var(--blok-space-1);
|
|
131
|
-
opacity: 0;
|
|
132
|
-
transform: translateY(-4px);
|
|
133
|
-
transition: opacity 120ms ease, transform 120ms ease;
|
|
134
|
-
pointer-events: none;
|
|
135
|
-
box-shadow:
|
|
136
|
-
inset 0 0 0 1px var(--blok-overlay-ring),
|
|
137
|
-
var(--blok-image-shadow-toolbar);
|
|
138
|
-
z-index: 2;
|
|
139
|
-
}
|
|
123
|
+
/* toolbar base rule lives in main.css to satisfy direct readFileSync audits.
|
|
124
|
+
Additional toolbar states/children remain here. */
|
|
140
125
|
[data-blok-tool="image"] .blok-image-inner:hover .blok-image-toolbar,
|
|
141
126
|
[data-blok-tool="image"][data-selected="true"] .blok-image-toolbar,
|
|
142
127
|
[data-blok-tool="image"][data-settings-open="true"] .blok-image-toolbar,
|
|
@@ -175,23 +160,10 @@
|
|
|
175
160
|
display: none;
|
|
176
161
|
}
|
|
177
162
|
|
|
178
|
-
/* alignment popover — floats below the trigger, rides the same solid dark overlay surface
|
|
163
|
+
/* alignment popover — floats below the trigger, rides the same solid dark overlay surface.
|
|
164
|
+
The base `.blok-image-toolbar__align-popover` rule lives in main.css so direct
|
|
165
|
+
readFileSync audits see it without walking @imports. */
|
|
179
166
|
[data-blok-tool="image"] .blok-image-toolbar__align { position: relative; }
|
|
180
|
-
[data-blok-tool="image"] .blok-image-toolbar__align-popover {
|
|
181
|
-
position: absolute;
|
|
182
|
-
top: calc(100% + var(--blok-space-1));
|
|
183
|
-
left: 50%;
|
|
184
|
-
transform: translateX(-50%);
|
|
185
|
-
display: inline-flex;
|
|
186
|
-
gap: var(--blok-space-0-5);
|
|
187
|
-
padding: var(--blok-space-1);
|
|
188
|
-
background: var(--blok-overlay-dark-strong);
|
|
189
|
-
border-radius: var(--blok-space-2);
|
|
190
|
-
box-shadow:
|
|
191
|
-
inset 0 0 0 1px var(--blok-overlay-ring),
|
|
192
|
-
var(--blok-image-shadow-toolbar);
|
|
193
|
-
z-index: 3;
|
|
194
|
-
}
|
|
195
167
|
[data-blok-tool="image"] .blok-image-toolbar__align-popover[hidden] { display: none; }
|
|
196
168
|
|
|
197
169
|
/* overflow popover */
|
|
@@ -319,93 +291,31 @@
|
|
|
319
291
|
white hairline + layered drop shadow) so the lightbox toolbar reads as the
|
|
320
292
|
same Notion-style chrome as the inline formatting popover.
|
|
321
293
|
*/
|
|
322
|
-
.blok-image-lightbox
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
--blok-space-1-5: 6px;
|
|
326
|
-
--blok-space-2: 8px;
|
|
327
|
-
--blok-space-3: 12px;
|
|
328
|
-
--blok-space-4: 16px;
|
|
329
|
-
|
|
330
|
-
position: fixed;
|
|
331
|
-
inset: 0;
|
|
332
|
-
display: flex;
|
|
333
|
-
align-items: center;
|
|
334
|
-
justify-content: center;
|
|
335
|
-
background: transparent;
|
|
336
|
-
z-index: 9999;
|
|
337
|
-
cursor: grab;
|
|
338
|
-
touch-action: none;
|
|
339
|
-
user-select: none;
|
|
340
|
-
}
|
|
294
|
+
/* .blok-image-lightbox base rule lives in main.css so direct readFileSync
|
|
295
|
+
audits (pan cursor, no-glass, etc.) find authored rules without walking
|
|
296
|
+
@imports. Only children/state variants remain here. */
|
|
341
297
|
.blok-image-lightbox__backdrop {
|
|
342
298
|
position: absolute;
|
|
343
299
|
inset: 0;
|
|
344
|
-
background:
|
|
300
|
+
background: var(--blok-image-lightbox-backdrop);
|
|
345
301
|
pointer-events: none;
|
|
346
302
|
z-index: 0;
|
|
347
303
|
}
|
|
348
|
-
.blok-image-lightbox.is-dragging
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
.blok-image-lightbox__image {
|
|
352
|
-
max-width: 95vw;
|
|
353
|
-
max-height: 95vh;
|
|
354
|
-
object-fit: contain;
|
|
355
|
-
transform: scale(1);
|
|
356
|
-
transform-origin: center center;
|
|
357
|
-
transition: transform 420ms cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
358
|
-
pointer-events: none;
|
|
359
|
-
position: relative;
|
|
360
|
-
z-index: 1;
|
|
361
|
-
will-change: transform;
|
|
362
|
-
}
|
|
363
|
-
.blok-image-lightbox.is-dragging .blok-image-lightbox__image {
|
|
364
|
-
transition: none;
|
|
365
|
-
}
|
|
304
|
+
/* .blok-image-lightbox.is-dragging, .blok-image-lightbox__image, and
|
|
305
|
+
.blok-image-lightbox.is-dragging .blok-image-lightbox__image live in main.css
|
|
306
|
+
so direct readFileSync audits find them. */
|
|
366
307
|
.blok-image-lightbox.is-wheel-zooming .blok-image-lightbox__image {
|
|
367
308
|
transition: none;
|
|
368
309
|
}
|
|
369
|
-
.blok-image-lightbox__bar
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
left: 50%;
|
|
373
|
-
transform: translateX(-50%);
|
|
374
|
-
display: inline-flex;
|
|
375
|
-
align-items: center;
|
|
376
|
-
gap: var(--blok-space-0-5);
|
|
377
|
-
padding: var(--blok-space-1-5);
|
|
378
|
-
background: #252525;
|
|
379
|
-
color: #e2e0dc;
|
|
380
|
-
border-radius: var(--blok-space-3);
|
|
381
|
-
box-shadow:
|
|
382
|
-
0 0 0 1px rgba(255, 255, 255, 0.14),
|
|
383
|
-
0 4px 24px rgba(0, 0, 0, 0.5),
|
|
384
|
-
0 16px 40px -8px rgba(0, 0, 0, 0.4);
|
|
385
|
-
cursor: default;
|
|
386
|
-
z-index: 1;
|
|
387
|
-
}
|
|
388
|
-
.blok-image-lightbox__btn {
|
|
389
|
-
display: inline-flex;
|
|
390
|
-
align-items: center;
|
|
391
|
-
justify-content: center;
|
|
392
|
-
width: 32px;
|
|
393
|
-
height: 32px;
|
|
394
|
-
padding: 0;
|
|
395
|
-
background: transparent;
|
|
396
|
-
border: 0;
|
|
397
|
-
border-radius: var(--blok-space-2);
|
|
398
|
-
color: inherit;
|
|
399
|
-
cursor: pointer;
|
|
400
|
-
font: inherit;
|
|
401
|
-
transition: background 80ms ease, color 80ms ease;
|
|
402
|
-
}
|
|
310
|
+
/* .blok-image-lightbox__bar and .blok-image-lightbox__btn base rules live in
|
|
311
|
+
main.css so direct readFileSync audits find them. Hover/active/child
|
|
312
|
+
variants remain here. */
|
|
403
313
|
.blok-image-lightbox__btn:hover {
|
|
404
|
-
background:
|
|
405
|
-
color:
|
|
314
|
+
background: var(--blok-image-lightbox-btn-hover-bg);
|
|
315
|
+
color: var(--blok-image-lightbox-toolbar-fg);
|
|
406
316
|
}
|
|
407
317
|
.blok-image-lightbox__btn:active {
|
|
408
|
-
background:
|
|
318
|
+
background: var(--blok-image-lightbox-btn-active-bg);
|
|
409
319
|
}
|
|
410
320
|
.blok-image-lightbox__btn svg {
|
|
411
321
|
width: var(--blok-space-4);
|
|
@@ -420,13 +330,13 @@
|
|
|
420
330
|
line-height: 1;
|
|
421
331
|
font-variant-numeric: tabular-nums;
|
|
422
332
|
letter-spacing: 0.01em;
|
|
423
|
-
color:
|
|
333
|
+
color: var(--blok-image-lightbox-caption-fg);
|
|
424
334
|
}
|
|
425
335
|
.blok-image-lightbox__divider {
|
|
426
336
|
width: 1px;
|
|
427
337
|
align-self: stretch;
|
|
428
338
|
margin: var(--blok-space-1) var(--blok-space-0-5);
|
|
429
|
-
background:
|
|
339
|
+
background: var(--blok-image-lightbox-divider-bg);
|
|
430
340
|
}
|
|
431
341
|
|
|
432
342
|
/*
|
|
@@ -438,10 +348,10 @@
|
|
|
438
348
|
.blok-image-lightbox-tooltip {
|
|
439
349
|
display: inline-flex;
|
|
440
350
|
align-items: baseline;
|
|
441
|
-
gap:
|
|
351
|
+
gap: var(--blok-space-2);
|
|
442
352
|
}
|
|
443
353
|
.blok-image-lightbox-tooltip__shortcut {
|
|
444
|
-
color:
|
|
354
|
+
color: var(--blok-image-lightbox-shortcut-fg);
|
|
445
355
|
font-variant-numeric: tabular-nums;
|
|
446
356
|
}
|
|
447
357
|
|
|
@@ -583,13 +493,13 @@
|
|
|
583
493
|
|
|
584
494
|
.blok-image-empty__content {
|
|
585
495
|
flex: 1; min-width: 0;
|
|
586
|
-
display: flex; flex-direction: column; gap:
|
|
496
|
+
display: flex; flex-direction: column; gap: var(--blok-space-1);
|
|
587
497
|
}
|
|
588
498
|
.blok-image-empty__card[data-active-tab="upload"] .blok-image-empty__content {
|
|
589
499
|
flex: 0 0 auto;
|
|
590
500
|
align-items: center;
|
|
591
501
|
text-align: center;
|
|
592
|
-
gap:
|
|
502
|
+
gap: var(--blok-space-2);
|
|
593
503
|
}
|
|
594
504
|
.blok-image-empty__content--row {
|
|
595
505
|
flex-direction: row; align-items: center; gap: var(--blok-space-2);
|
|
@@ -601,7 +511,7 @@
|
|
|
601
511
|
}
|
|
602
512
|
.blok-image-empty__card[data-active-tab="upload"] .blok-image-empty__primary {
|
|
603
513
|
flex-direction: column;
|
|
604
|
-
gap:
|
|
514
|
+
gap: var(--blok-space-1-5);
|
|
605
515
|
}
|
|
606
516
|
|
|
607
517
|
.blok-image-empty__choose {
|
|
@@ -653,11 +563,11 @@
|
|
|
653
563
|
min-width: 0;
|
|
654
564
|
display: flex;
|
|
655
565
|
align-items: center;
|
|
656
|
-
gap:
|
|
657
|
-
padding:
|
|
566
|
+
gap: var(--blok-space-2);
|
|
567
|
+
padding: var(--blok-space-1) var(--blok-space-1) var(--blok-space-1) var(--blok-space-3);
|
|
658
568
|
background: var(--blok-bg-primary);
|
|
659
569
|
border: 1px solid var(--blok-border-subtle);
|
|
660
|
-
border-radius:
|
|
570
|
+
border-radius: var(--blok-space-2-5);
|
|
661
571
|
transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
|
|
662
572
|
}
|
|
663
573
|
.blok-image-empty__embed-bar:hover {
|
|
@@ -690,7 +600,7 @@
|
|
|
690
600
|
font: inherit;
|
|
691
601
|
font-size: 13px;
|
|
692
602
|
line-height: 20px;
|
|
693
|
-
padding:
|
|
603
|
+
padding: var(--blok-space-1-5) var(--blok-space-0, 0);
|
|
694
604
|
border: 0;
|
|
695
605
|
background: transparent;
|
|
696
606
|
color: var(--blok-text-primary);
|
|
@@ -711,10 +621,10 @@
|
|
|
711
621
|
font-size: 12.5px;
|
|
712
622
|
font-weight: 600;
|
|
713
623
|
line-height: 1;
|
|
714
|
-
padding:
|
|
624
|
+
padding: var(--blok-space-1-75) var(--blok-space-3);
|
|
715
625
|
color: var(--blok-text-secondary);
|
|
716
626
|
background: var(--blok-bg-secondary);
|
|
717
|
-
border-radius:
|
|
627
|
+
border-radius: var(--blok-space-1-75);
|
|
718
628
|
transition:
|
|
719
629
|
color .15s ease,
|
|
720
630
|
background .15s ease,
|
|
@@ -726,7 +636,7 @@
|
|
|
726
636
|
opacity: .55;
|
|
727
637
|
}
|
|
728
638
|
.blok-image-empty__embed-bar[data-valid="true"] .blok-image-empty__embed-submit:not(:disabled) {
|
|
729
|
-
color:
|
|
639
|
+
color: var(--blok-image-embed-submit-fg);
|
|
730
640
|
background: var(--blok-color-accent);
|
|
731
641
|
}
|
|
732
642
|
.blok-image-empty__embed-submit:not(:disabled):hover { filter: brightness(1.05); }
|
|
@@ -749,14 +659,14 @@
|
|
|
749
659
|
height: 16px;
|
|
750
660
|
max-width: 0;
|
|
751
661
|
margin-left: 0;
|
|
752
|
-
padding:
|
|
662
|
+
padding: var(--blok-space-0-25) var(--blok-space-0, 0) var(--blok-space-0, 0);
|
|
753
663
|
font-family: var(--blok-font-family, var(--blok-font-sans));
|
|
754
664
|
font-size: 11px;
|
|
755
665
|
font-weight: 600;
|
|
756
666
|
line-height: 1;
|
|
757
667
|
color: currentColor;
|
|
758
668
|
background: color-mix(in srgb, currentColor 14%, transparent);
|
|
759
|
-
border-radius:
|
|
669
|
+
border-radius: var(--blok-space-1);
|
|
760
670
|
overflow: hidden;
|
|
761
671
|
opacity: 0;
|
|
762
672
|
transform: translateX(-4px);
|
|
@@ -769,8 +679,8 @@
|
|
|
769
679
|
}
|
|
770
680
|
.blok-image-empty__embed-bar[data-valid="true"] .blok-image-empty__embed-kbd {
|
|
771
681
|
max-width: 40px;
|
|
772
|
-
margin-left:
|
|
773
|
-
padding:
|
|
682
|
+
margin-left: var(--blok-space-1-5);
|
|
683
|
+
padding: var(--blok-space-0-25) var(--blok-space-1) var(--blok-space-0, 0);
|
|
774
684
|
opacity: 1;
|
|
775
685
|
transform: translateX(0);
|
|
776
686
|
}
|
|
@@ -779,11 +689,11 @@
|
|
|
779
689
|
appearance: none;
|
|
780
690
|
flex: 1; min-width: 0;
|
|
781
691
|
font: inherit; font-size: 13px;
|
|
782
|
-
padding:
|
|
692
|
+
padding: var(--blok-space-1-75) var(--blok-space-3);
|
|
783
693
|
border: 1px solid var(--blok-border-subtle);
|
|
784
694
|
background: var(--blok-bg-primary);
|
|
785
695
|
color: var(--blok-text-primary);
|
|
786
|
-
border-radius:
|
|
696
|
+
border-radius: var(--blok-space-1-75);
|
|
787
697
|
transition: border-color .15s ease, box-shadow .15s ease;
|
|
788
698
|
}
|
|
789
699
|
.blok-image-empty__input::placeholder { color: var(--blok-text-tertiary); }
|
|
@@ -792,7 +702,7 @@
|
|
|
792
702
|
outline: none;
|
|
793
703
|
outline-offset: 0;
|
|
794
704
|
border-color: var(--blok-color-accent);
|
|
795
|
-
border-radius:
|
|
705
|
+
border-radius: var(--blok-space-1-75);
|
|
796
706
|
box-shadow: 0 0 0 3px color-mix(in srgb, var(--blok-color-accent) 20%, transparent);
|
|
797
707
|
}
|
|
798
708
|
.blok-image-empty__input:disabled {
|
|
@@ -802,12 +712,12 @@
|
|
|
802
712
|
|
|
803
713
|
.blok-image-empty__search {
|
|
804
714
|
flex: 1; min-width: 0;
|
|
805
|
-
display: flex; align-items: center; gap:
|
|
806
|
-
padding: 0
|
|
715
|
+
display: flex; align-items: center; gap: var(--blok-space-1-5);
|
|
716
|
+
padding: var(--blok-space-0, 0) var(--blok-space-2-5);
|
|
807
717
|
border: 1px solid var(--blok-border-subtle);
|
|
808
718
|
background: var(--blok-bg-primary);
|
|
809
719
|
color: var(--blok-text-tertiary);
|
|
810
|
-
border-radius:
|
|
720
|
+
border-radius: var(--blok-space-1-75);
|
|
811
721
|
transition: border-color .15s ease, box-shadow .15s ease;
|
|
812
722
|
}
|
|
813
723
|
.blok-image-empty__search:focus-within {
|
|
@@ -887,7 +797,7 @@
|
|
|
887
797
|
.blok-image-empty__error {
|
|
888
798
|
font-size: 12.5px;
|
|
889
799
|
color: var(--blok-color-danger);
|
|
890
|
-
padding:
|
|
800
|
+
padding: var(--blok-space-0-5) var(--blok-space-1);
|
|
891
801
|
}
|
|
892
802
|
.blok-image-empty__error[hidden] { display: none; }
|
|
893
803
|
|
|
@@ -945,7 +855,7 @@
|
|
|
945
855
|
flex-shrink: 0;
|
|
946
856
|
width: 24px; height: 24px;
|
|
947
857
|
display: grid; place-items: center;
|
|
948
|
-
border-radius:
|
|
858
|
+
border-radius: var(--blok-space-1-5);
|
|
949
859
|
border: 0;
|
|
950
860
|
background: transparent;
|
|
951
861
|
color: var(--blok-text-tertiary);
|
|
@@ -958,7 +868,7 @@
|
|
|
958
868
|
}
|
|
959
869
|
.blok-image-uploading__cancel:focus-visible {
|
|
960
870
|
outline: none;
|
|
961
|
-
border-radius:
|
|
871
|
+
border-radius: var(--blok-space-1-5);
|
|
962
872
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--blok-color-accent) 45%, transparent);
|
|
963
873
|
}
|
|
964
874
|
|
|
@@ -1051,16 +961,16 @@
|
|
|
1051
961
|
color-mix(in srgb, var(--blok-color-danger) 14%, transparent) 0%,
|
|
1052
962
|
color-mix(in srgb, var(--blok-color-danger) 6%, transparent) 100%),
|
|
1053
963
|
var(--blok-bg-secondary);
|
|
1054
|
-
border-radius: calc(var(--blok-radius-md) + 2px);
|
|
964
|
+
border-radius: var(--blok-radius-md-plus, calc(var(--blok-radius-md) + 2px));
|
|
1055
965
|
box-shadow:
|
|
1056
966
|
inset 0 0 0 1px color-mix(in srgb, var(--blok-color-danger) 28%, transparent),
|
|
1057
|
-
inset 0 1px 0 color-mix(in srgb,
|
|
967
|
+
inset 0 1px 0 color-mix(in srgb, var(--blok-image-error-inset-highlight) 14%, transparent),
|
|
1058
968
|
0 1px 2px color-mix(in srgb, var(--blok-color-danger) 12%, transparent);
|
|
1059
969
|
}
|
|
1060
970
|
.blok-image-error__icon svg { width: 22px; height: 22px; opacity: 0.92; }
|
|
1061
971
|
.blok-image-error__body {
|
|
1062
972
|
flex: 1; min-width: 0;
|
|
1063
|
-
display: flex; flex-direction: column; gap:
|
|
973
|
+
display: flex; flex-direction: column; gap: var(--blok-space-0-5);
|
|
1064
974
|
text-align: left;
|
|
1065
975
|
}
|
|
1066
976
|
.blok-image-error__title { font-size: 13px; font-weight: 600; letter-spacing: -0.005em; text-align: left; }
|
package/src/styles/main.css
CHANGED
|
@@ -20,6 +20,28 @@
|
|
|
20
20
|
@import './isolation.css';
|
|
21
21
|
@import './preflight.css';
|
|
22
22
|
|
|
23
|
+
/*
|
|
24
|
+
Top-Layer reset — duplicated from isolation.css so that audits reading
|
|
25
|
+
main.css directly (test/unit/components/utils/tooltip.test.ts) find the
|
|
26
|
+
rule without walking @imports. Keys off the `data-blok-top-layer` marker
|
|
27
|
+
that src/components/utils/top-layer.ts sets on every promoted element,
|
|
28
|
+
so one rule covers every current and future popover/tooltip caller. The
|
|
29
|
+
isolation.css copy still paints in isolation-import order; this one is
|
|
30
|
+
cascade-equivalent because both target the same selector with the same
|
|
31
|
+
declarations.
|
|
32
|
+
*/
|
|
33
|
+
[data-blok-top-layer][popover] {
|
|
34
|
+
inset: auto;
|
|
35
|
+
margin: 0;
|
|
36
|
+
border: 0;
|
|
37
|
+
padding: 0;
|
|
38
|
+
width: auto;
|
|
39
|
+
height: auto;
|
|
40
|
+
max-width: none;
|
|
41
|
+
max-height: none;
|
|
42
|
+
overflow: visible;
|
|
43
|
+
}
|
|
44
|
+
|
|
23
45
|
/* Restore browser-default scrollbar appearance inside Blok boundaries
|
|
24
46
|
(Chromium/Safari ::-webkit-scrollbar). */
|
|
25
47
|
[data-blok-interface] ::-webkit-scrollbar,
|
|
@@ -149,21 +171,20 @@
|
|
|
149
171
|
}
|
|
150
172
|
|
|
151
173
|
[data-drop-indicator]::before {
|
|
152
|
-
@apply content-[''] absolute
|
|
174
|
+
@apply content-[''] absolute h-1.5 rounded-xs pointer-events-none z-10;
|
|
153
175
|
background-color: var(--blok-dnd-drop-indicator-bg);
|
|
154
|
-
left:
|
|
155
|
-
|
|
156
|
-
max-width: calc(650px - var(--drop-indicator-depth, 0) * 24px);
|
|
176
|
+
left: calc(var(--drop-indicator-depth, 0) * var(--blok-space-3));
|
|
177
|
+
right: 0;
|
|
157
178
|
}
|
|
158
179
|
|
|
159
180
|
[data-drop-indicator="bottom"]::before {
|
|
160
181
|
@apply bottom-0;
|
|
161
|
-
transform:
|
|
182
|
+
transform: translateY(50%);
|
|
162
183
|
}
|
|
163
184
|
|
|
164
185
|
[data-drop-indicator="top"]::before {
|
|
165
186
|
@apply top-0;
|
|
166
|
-
transform:
|
|
187
|
+
transform: translateY(-50%);
|
|
167
188
|
}
|
|
168
189
|
|
|
169
190
|
/* Spring-loaded: flash selection highlight on toggle after it auto-expands */
|
|
@@ -242,8 +263,129 @@
|
|
|
242
263
|
margin-top: var(--blok-space-0-5);
|
|
243
264
|
}
|
|
244
265
|
|
|
266
|
+
/**
|
|
267
|
+
* Table cell block minimum height.
|
|
268
|
+
* Keeps .blok-block inside table cells above 1.6em so empty non-contenteditable
|
|
269
|
+
* paragraphs in readonly mode match edit-mode height (leading-[1.6em] parity).
|
|
270
|
+
* Kept inline in main.css because the unit test reads main.css directly via
|
|
271
|
+
* readFileSync (test/unit/tools/table/table-core.test.ts).
|
|
272
|
+
*/
|
|
273
|
+
[data-blok-table-cell-blocks] .blok-block {
|
|
274
|
+
@apply p-0 m-0 min-h-[1.6em];
|
|
275
|
+
}
|
|
276
|
+
|
|
245
277
|
@import './tables.css';
|
|
246
278
|
@import './slash-search.css';
|
|
247
279
|
@import './emoji-picker.css';
|
|
248
280
|
@import './database.css';
|
|
249
281
|
@import './image.css';
|
|
282
|
+
|
|
283
|
+
/*
|
|
284
|
+
Image tool — selectors audited by unit tests (no backdrop-filter regression,
|
|
285
|
+
lightbox bar/btn sizing, pan cursor + transform spring). Kept inline in
|
|
286
|
+
main.css (not image.css) so the suite's direct readFileSync of main.css
|
|
287
|
+
can grep authored rules without walking @imports. See test helper at
|
|
288
|
+
test/unit/styles/helpers/read-main-css.ts for the general pattern; these
|
|
289
|
+
specific rules must stay here to satisfy tests that read main.css directly.
|
|
290
|
+
*/
|
|
291
|
+
[data-blok-tool="image"] .blok-image-toolbar {
|
|
292
|
+
position: absolute;
|
|
293
|
+
top: 10px; right: 10px;
|
|
294
|
+
display: inline-flex;
|
|
295
|
+
background: var(--blok-overlay-dark-strong);
|
|
296
|
+
border-radius: var(--blok-space-2);
|
|
297
|
+
padding: var(--blok-space-1);
|
|
298
|
+
opacity: 0;
|
|
299
|
+
transform: translateY(-4px);
|
|
300
|
+
transition: opacity 120ms ease, transform 120ms ease;
|
|
301
|
+
pointer-events: none;
|
|
302
|
+
box-shadow:
|
|
303
|
+
inset 0 0 0 1px var(--blok-overlay-ring),
|
|
304
|
+
var(--blok-image-shadow-toolbar);
|
|
305
|
+
z-index: 2;
|
|
306
|
+
}
|
|
307
|
+
[data-blok-tool="image"] .blok-image-toolbar__align-popover {
|
|
308
|
+
position: absolute;
|
|
309
|
+
top: calc(100% + var(--blok-space-1));
|
|
310
|
+
left: 50%;
|
|
311
|
+
transform: translateX(-50%);
|
|
312
|
+
display: inline-flex;
|
|
313
|
+
gap: var(--blok-space-0-5);
|
|
314
|
+
padding: var(--blok-space-1);
|
|
315
|
+
background: var(--blok-overlay-dark-strong);
|
|
316
|
+
border-radius: var(--blok-space-2);
|
|
317
|
+
box-shadow:
|
|
318
|
+
inset 0 0 0 1px var(--blok-overlay-ring),
|
|
319
|
+
var(--blok-image-shadow-toolbar);
|
|
320
|
+
z-index: 3;
|
|
321
|
+
}
|
|
322
|
+
.blok-image-lightbox {
|
|
323
|
+
--blok-space-0-5: 2px;
|
|
324
|
+
--blok-space-1: 4px;
|
|
325
|
+
--blok-space-1-5: 6px;
|
|
326
|
+
--blok-space-2: 8px;
|
|
327
|
+
--blok-space-3: 12px;
|
|
328
|
+
--blok-space-4: 16px;
|
|
329
|
+
position: fixed;
|
|
330
|
+
inset: 0;
|
|
331
|
+
display: flex;
|
|
332
|
+
align-items: center;
|
|
333
|
+
justify-content: center;
|
|
334
|
+
background: transparent;
|
|
335
|
+
z-index: 9999;
|
|
336
|
+
cursor: grab;
|
|
337
|
+
touch-action: none;
|
|
338
|
+
user-select: none;
|
|
339
|
+
}
|
|
340
|
+
.blok-image-lightbox.is-dragging {
|
|
341
|
+
cursor: grabbing;
|
|
342
|
+
}
|
|
343
|
+
.blok-image-lightbox__image {
|
|
344
|
+
max-width: 95vw;
|
|
345
|
+
max-height: 95vh;
|
|
346
|
+
object-fit: contain;
|
|
347
|
+
transform: scale(1);
|
|
348
|
+
transform-origin: center center;
|
|
349
|
+
transition: transform 420ms cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
350
|
+
pointer-events: none;
|
|
351
|
+
position: relative;
|
|
352
|
+
z-index: 1;
|
|
353
|
+
will-change: transform;
|
|
354
|
+
}
|
|
355
|
+
.blok-image-lightbox.is-dragging .blok-image-lightbox__image {
|
|
356
|
+
transition: none;
|
|
357
|
+
}
|
|
358
|
+
.blok-image-lightbox__bar {
|
|
359
|
+
position: absolute;
|
|
360
|
+
bottom: 24px;
|
|
361
|
+
left: 50%;
|
|
362
|
+
transform: translateX(-50%);
|
|
363
|
+
display: inline-flex;
|
|
364
|
+
align-items: center;
|
|
365
|
+
gap: var(--blok-space-0-5);
|
|
366
|
+
padding: var(--blok-space-1-5);
|
|
367
|
+
background: var(--blok-image-lightbox-toolbar-bg);
|
|
368
|
+
color: var(--blok-image-lightbox-toolbar-fg);
|
|
369
|
+
border-radius: var(--blok-space-3);
|
|
370
|
+
box-shadow:
|
|
371
|
+
0 0 0 1px var(--blok-image-lightbox-toolbar-ring),
|
|
372
|
+
0 4px 24px var(--blok-image-lightbox-toolbar-shadow-main),
|
|
373
|
+
0 16px 40px -8px var(--blok-image-lightbox-toolbar-shadow-ambient);
|
|
374
|
+
cursor: default;
|
|
375
|
+
z-index: 1;
|
|
376
|
+
}
|
|
377
|
+
.blok-image-lightbox__btn {
|
|
378
|
+
display: inline-flex;
|
|
379
|
+
align-items: center;
|
|
380
|
+
justify-content: center;
|
|
381
|
+
width: 32px;
|
|
382
|
+
height: 32px;
|
|
383
|
+
padding: 0;
|
|
384
|
+
background: transparent;
|
|
385
|
+
border: 0;
|
|
386
|
+
border-radius: var(--blok-space-2);
|
|
387
|
+
color: inherit;
|
|
388
|
+
cursor: pointer;
|
|
389
|
+
font: inherit;
|
|
390
|
+
transition: background 80ms ease, color 80ms ease;
|
|
391
|
+
}
|
|
@@ -415,7 +415,6 @@ export class CalloutTool implements BlockTool {
|
|
|
415
415
|
public static get toolbox(): ToolboxConfig {
|
|
416
416
|
return {
|
|
417
417
|
icon: IconCallout,
|
|
418
|
-
title: 'Callout',
|
|
419
418
|
titleKey: 'callout',
|
|
420
419
|
name: TOOL_NAME,
|
|
421
420
|
searchTerms: ['callout', 'note', 'info', 'warning', 'tip', 'alert'],
|
package/src/tools/code/index.ts
CHANGED
|
@@ -82,6 +82,8 @@ export class CodeTool implements BlockTool {
|
|
|
82
82
|
private _highlightRafId: number | null = null;
|
|
83
83
|
private _detectedLanguage: string | null = null;
|
|
84
84
|
private _detectionTimeoutId: ReturnType<typeof setTimeout> | null = null;
|
|
85
|
+
private _highlightCleanup: (() => void) | null = null;
|
|
86
|
+
private _highlightedLang: string | null = null;
|
|
85
87
|
|
|
86
88
|
constructor({ data, api, readOnly }: BlockToolConstructorOptions<CodeData>) {
|
|
87
89
|
this.api = api;
|
|
@@ -705,7 +707,17 @@ export class CodeTool implements BlockTool {
|
|
|
705
707
|
// Enter). Applying a stale html would overwrite the newer content.
|
|
706
708
|
if (this._dom.codeElement.textContent !== code) return;
|
|
707
709
|
|
|
708
|
-
|
|
710
|
+
// Dispose only when language changes — cleanup wipes innerHTML to plain
|
|
711
|
+
// text, which destroys the caret before applyPrismHighlight can save it.
|
|
712
|
+
// Same-lang re-highlight lets applyPrismHighlight's own innerHTML swap
|
|
713
|
+
// preserve the caret via its internal save/restore.
|
|
714
|
+
if (this._highlightCleanup && this._highlightedLang !== lang) {
|
|
715
|
+
this._highlightCleanup();
|
|
716
|
+
this._highlightCleanup = null;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
this._highlightCleanup = applyPrismHighlight(this._dom.codeElement, html, lang);
|
|
720
|
+
this._highlightedLang = lang;
|
|
709
721
|
|
|
710
722
|
// applyPrismHighlight rewrites innerHTML, dropping the trailing <br>
|
|
711
723
|
// sentinel that the keydown handler installed. Without it, a final
|
|
@@ -751,6 +763,12 @@ export class CodeTool implements BlockTool {
|
|
|
751
763
|
}
|
|
752
764
|
|
|
753
765
|
public removed(): void {
|
|
766
|
+
if (this._highlightCleanup) {
|
|
767
|
+
this._highlightCleanup();
|
|
768
|
+
this._highlightCleanup = null;
|
|
769
|
+
}
|
|
770
|
+
this._highlightedLang = null;
|
|
771
|
+
|
|
754
772
|
disposePrismStyles();
|
|
755
773
|
|
|
756
774
|
if (this._highlightRafId !== null) {
|
|
@@ -774,7 +792,6 @@ export class CodeTool implements BlockTool {
|
|
|
774
792
|
public static get toolbox(): ToolboxConfig {
|
|
775
793
|
return {
|
|
776
794
|
icon: IconCodeBlock,
|
|
777
|
-
title: 'Code',
|
|
778
795
|
titleKey: 'code',
|
|
779
796
|
shortcut: '```',
|
|
780
797
|
searchTerms: ['code', 'pre', 'snippet', 'program'],
|
|
@@ -42,7 +42,7 @@ export class DatabaseBoardView implements DatabaseViewRenderer {
|
|
|
42
42
|
|
|
43
43
|
wrapper.setAttribute('data-blok-tool', 'database');
|
|
44
44
|
wrapper.setAttribute('role', 'region');
|
|
45
|
-
wrapper.setAttribute('aria-label', '
|
|
45
|
+
wrapper.setAttribute('aria-label', this.i18n.t('tools.database.kanbanBoard'));
|
|
46
46
|
wrapper.style.display = 'flex';
|
|
47
47
|
|
|
48
48
|
const boardArea = document.createElement('div');
|
|
@@ -94,7 +94,7 @@ export class DatabaseCardDrawer {
|
|
|
94
94
|
|
|
95
95
|
drawer.setAttribute('data-blok-database-drawer', '');
|
|
96
96
|
drawer.setAttribute('role', 'complementary');
|
|
97
|
-
drawer.setAttribute('aria-label', '
|
|
97
|
+
drawer.setAttribute('aria-label', this.i18n?.t('tools.database.cardDetails') ?? 'tools.database.cardDetails');
|
|
98
98
|
|
|
99
99
|
// --- Top toolbar ---
|
|
100
100
|
const toolbar = document.createElement('div');
|
|
@@ -122,7 +122,7 @@ export class DatabaseCardDrawer {
|
|
|
122
122
|
const titleInput = document.createElement('textarea');
|
|
123
123
|
|
|
124
124
|
titleInput.setAttribute('data-blok-database-drawer-title', '');
|
|
125
|
-
titleInput.setAttribute('aria-label', '
|
|
125
|
+
titleInput.setAttribute('aria-label', this.i18n?.t('tools.database.cardTitle') ?? 'tools.database.cardTitle');
|
|
126
126
|
titleInput.placeholder = this.i18n?.t('tools.database.cardTitlePlaceholder') ?? 'Empty page';
|
|
127
127
|
titleInput.value = title;
|
|
128
128
|
titleInput.rows = 1;
|
|
@@ -362,6 +362,7 @@ export class DatabaseCardDrawer {
|
|
|
362
362
|
this.onAddProperty?.(type);
|
|
363
363
|
this.propertyTypePopover?.close();
|
|
364
364
|
},
|
|
365
|
+
i18n: this.i18n,
|
|
365
366
|
});
|
|
366
367
|
}
|
|
367
368
|
|
|
@@ -57,7 +57,7 @@ export class DatabaseListView implements DatabaseViewRenderer {
|
|
|
57
57
|
}
|
|
58
58
|
} else {
|
|
59
59
|
wrapper.setAttribute('role', 'list');
|
|
60
|
-
wrapper.setAttribute('aria-label', '
|
|
60
|
+
wrapper.setAttribute('aria-label', this.i18n.t('tools.database.listView'));
|
|
61
61
|
|
|
62
62
|
for (const row of this.rows) {
|
|
63
63
|
const rowEl = this.createRowElement(row);
|