@threadlabs/looma 0.26.26 → 0.27.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.
- package/components/shared/editor.js +4 -5
- package/components/shared/overlay.js +231 -55
- package/components/ui-affordance-scope/ui-affordance-scope.js +4 -8
- package/components/ui-card/ui-card.html +3 -0
- package/components/ui-dialog/ui-dialog.html +7 -5
- package/components/ui-dialog/ui-dialog.js +67 -7
- package/components/ui-editor-mention-menu/ui-editor-mention-menu.html +6 -0
- package/components/ui-editor-mention-menu/ui-editor-mention-menu.js +5 -9
- package/components/ui-editor-slash-menu/ui-editor-slash-menu.html +6 -0
- package/components/ui-editor-slash-menu/ui-editor-slash-menu.js +5 -9
- package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.html +21 -4
- package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.js +50 -22
- package/components/ui-editor-table-overlay/ui-editor-table-overlay.js +4 -6
- package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +3 -11
- package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.js +33 -44
- package/components/ui-listbox/ui-listbox.html +22 -17
- package/components/ui-menu/ui-menu.js +5 -3
- package/components/ui-popover/ui-popover.js +3 -2
- package/components/ui-scroll-area/ui-scroll-area.html +16 -0
- package/components/ui-search-shell/ui-search-shell.html +1 -1
- package/components/ui-search-shell/ui-search-shell.js +3 -5
- package/components/ui-section/ui-section.html +3 -0
- package/components/ui-toast/ui-toast.html +2 -1
- package/components/ui-toast/ui-toast.js +18 -2
- package/components/ui-toast-region/ui-toast-region.js +11 -3
- package/dist/index.js +1 -1
- package/editor/chunks/extensions.js +2 -0
- package/editor/extensions/slash-command.d.ts +2 -0
- package/editor/mention-contract.d.ts +2 -0
- package/package.json +1 -1
- package/styles/ui-card.css +3 -0
- package/styles/ui-dialog.css +4 -2
- package/styles/ui-editor-mention-menu.css +7 -1
- package/styles/ui-editor-slash-menu.css +7 -1
- package/styles/ui-editor-table-context-menu.css +29 -5
- package/styles/ui-editor-table-toolbar.css +3 -11
- package/styles/ui-listbox.css +6 -0
- package/styles/ui-scroll-area.css +13 -0
- package/styles/ui-search-shell.css +1 -1
- package/styles/ui-section.css +3 -0
- package/vanilla/UiDialog.js +10 -6
- package/vanilla/UiListbox.js +10 -9
- package/vanilla/UiScrollArea.d.ts +1 -0
- package/vanilla/UiScrollArea.js +4 -4
- package/vue/UiCard.vue +3 -0
- package/vue/UiDialog.vue +12 -6
- package/vue/UiEditorMentionMenu.vue +6 -0
- package/vue/UiEditorSlashMenu.vue +6 -0
- package/vue/UiEditorTableContextMenu.vue +21 -4
- package/vue/UiEditorTableToolbar.vue +3 -11
- package/vue/UiListbox.vue +20 -15
- package/vue/UiScrollArea.d.ts +9 -0
- package/vue/UiScrollArea.vue +39 -1
- package/vue/UiSearchShell.vue +1 -1
- package/vue/UiSection.vue +3 -0
- package/vue/UiToast.vue +1 -1
- package/vue/chunks/UiCard.js +1 -1
- package/vue/chunks/UiDialog.js +25 -8
- package/vue/chunks/UiEditorMentionMenu.js +1 -1
- package/vue/chunks/UiEditorSlashMenu.js +1 -1
- package/vue/chunks/UiEditorTableContextMenu.js +1 -1
- package/vue/chunks/UiEditorTableToolbar.js +1 -1
- package/vue/chunks/UiListbox.js +12 -12
- package/vue/chunks/UiScrollArea.js +33 -2
- package/vue/chunks/UiSearchShell.js +1 -1
- package/vue/chunks/UiSection.js +1 -1
- package/vue/chunks/UiToast.js +2 -2
- package/vue/components.css +258 -213
- package/vue/editor/index.js +225 -40
|
@@ -6612,6 +6612,7 @@ function createLoomaMentionExtension(options = {}) {
|
|
|
6612
6612
|
selectedIndex,
|
|
6613
6613
|
query: props.query,
|
|
6614
6614
|
rect: props.clientRect?.() ?? null,
|
|
6615
|
+
getRect: () => props.clientRect?.() ?? null,
|
|
6615
6616
|
loading,
|
|
6616
6617
|
highlight: (index) => {
|
|
6617
6618
|
if (index >= 0 && index < props.items.length) {
|
|
@@ -10697,6 +10698,7 @@ var LoomaSlashCommand = Extension.create({
|
|
|
10697
10698
|
selectedIndex,
|
|
10698
10699
|
query: props.query,
|
|
10699
10700
|
rect: props.clientRect?.() ?? null,
|
|
10701
|
+
getRect: () => props.clientRect?.() ?? null,
|
|
10700
10702
|
select: (index) => {
|
|
10701
10703
|
if (revision !== generation || props !== currentProps || document !== this.editor.state.doc || !this.editor.isEditable || !isCurrent(props)) return;
|
|
10702
10704
|
const item = props.items[index];
|
|
@@ -39,6 +39,8 @@ export interface LoomaSlashMenuSnapshot {
|
|
|
39
39
|
selectedIndex: number;
|
|
40
40
|
query: string;
|
|
41
41
|
rect: DOMRect | null;
|
|
42
|
+
/** Re-measures the current virtual anchor after scrolling; valid for this snapshot only. */
|
|
43
|
+
getRect?: () => DOMRect | null;
|
|
42
44
|
select: ((index: number) => void) | null;
|
|
43
45
|
/** Keeps editor keyboard selection synchronized with a UI's hovered row. */
|
|
44
46
|
highlight?: ((index: number) => void) | null;
|
|
@@ -44,6 +44,8 @@ export interface LoomaMentionMenuSnapshot {
|
|
|
44
44
|
selectedIndex: number;
|
|
45
45
|
query: string;
|
|
46
46
|
rect: DOMRect | null;
|
|
47
|
+
/** Re-measures the current virtual anchor after scrolling; valid for this snapshot only. */
|
|
48
|
+
getRect?: () => DOMRect | null;
|
|
47
49
|
loading: boolean;
|
|
48
50
|
highlight: ((index: number) => void) | null;
|
|
49
51
|
select: ((index: number) => void) | null;
|
package/package.json
CHANGED
package/styles/ui-card.css
CHANGED
|
@@ -69,6 +69,9 @@
|
|
|
69
69
|
:scope[data-ui-card-state~="tone=danger"] {
|
|
70
70
|
border-color: color-mix(in srgb, var(--ui-danger) 45%, var(--ui-border-default));
|
|
71
71
|
border-inline-start: var(--ui-accent-line-width) solid var(--ui-danger);
|
|
72
|
+
/* An accent edge keeps the corners on its side straight. */
|
|
73
|
+
border-start-start-radius: 0;
|
|
74
|
+
border-end-start-radius: 0;
|
|
72
75
|
--_ui-card-surface: var(--ui-danger-soft);
|
|
73
76
|
}
|
|
74
77
|
|
package/styles/ui-dialog.css
CHANGED
|
@@ -110,7 +110,9 @@
|
|
|
110
110
|
align-items: center;
|
|
111
111
|
gap: var(--ui-space-3);
|
|
112
112
|
flex: none;
|
|
113
|
-
|
|
113
|
+
/* The title's ink sits inside its line box and the taller close target. Balance that
|
|
114
|
+
visible top inset against the action row's bottom inset, not just the boxes. */
|
|
115
|
+
padding: calc(var(--ui-space-3) + var(--ui-space-1) / 2) var(--ui-space-3) var(--ui-space-3) var(--ui-space-5);
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
/* :host-qualified so page heading rules that reach in cannot outrank the dialog chrome. */
|
|
@@ -211,7 +213,7 @@
|
|
|
211
213
|
overlay var(--_ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease) allow-discrete;
|
|
212
214
|
}
|
|
213
215
|
|
|
214
|
-
:scope[open]::backdrop {
|
|
216
|
+
:scope[open]:modal::backdrop {
|
|
215
217
|
background-color: var(--ui-overlay-backdrop);
|
|
216
218
|
animation: ui-dialog-backdrop-enter var(--_ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease);
|
|
217
219
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/* Generated by HTML Next 1.0.0-alpha.35. Do not edit. */
|
|
2
2
|
@scope ([data-component~="ui-editor-mention-menu"]) to ([data-component], [data-slotted]) {
|
|
3
|
-
:scope {
|
|
3
|
+
:scope[popover] {
|
|
4
|
+
position: fixed;
|
|
5
|
+
inset: auto;
|
|
6
|
+
margin: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
:scope {
|
|
4
10
|
user-select: none;
|
|
5
11
|
}
|
|
6
12
|
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/* Generated by HTML Next 1.0.0-alpha.35. Do not edit. */
|
|
2
2
|
@scope ([data-component~="ui-editor-slash-menu"]) to ([data-component], [data-slotted]) {
|
|
3
|
-
:scope {
|
|
3
|
+
:scope[popover] {
|
|
4
|
+
position: fixed;
|
|
5
|
+
inset: auto;
|
|
6
|
+
margin: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
:scope {
|
|
4
10
|
user-select: none;
|
|
5
11
|
}
|
|
6
12
|
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
/* Generated by HTML Next 1.0.0-alpha.35. Do not edit. */
|
|
2
2
|
@scope ([data-component~="ui-editor-table-context-menu"]) to ([data-component], [data-slotted]) {
|
|
3
|
-
:scope {
|
|
3
|
+
:scope[popover] {
|
|
4
|
+
position: fixed;
|
|
5
|
+
inset: auto;
|
|
6
|
+
margin: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
:scope {
|
|
4
10
|
/* The max-width is a promise about the menu's footprint, so it counts padding and border. */
|
|
5
11
|
box-sizing: border-box;
|
|
6
|
-
min-width: 14rem;
|
|
12
|
+
min-width: min(14rem, calc(100vw - 24px));
|
|
7
13
|
max-width: min(17rem, calc(100vw - 24px));
|
|
8
14
|
max-height: min(28rem, calc(100vh - 24px));
|
|
9
15
|
padding: var(--ui-space-2);
|
|
@@ -58,16 +64,22 @@
|
|
|
58
64
|
color: var(--ui-danger);
|
|
59
65
|
}
|
|
60
66
|
|
|
67
|
+
/* Swatches wrap like words: the row asks for the menu's full width, and a narrower menu fits fewer. */
|
|
61
68
|
.swatches {
|
|
62
|
-
display:
|
|
63
|
-
|
|
69
|
+
display: flex;
|
|
70
|
+
flex-wrap: wrap;
|
|
64
71
|
gap: 3px;
|
|
65
72
|
}
|
|
66
73
|
|
|
67
|
-
.
|
|
74
|
+
/* Three to a row at the menu's full width; 5rem keeps the longest label, "Default", whole. */
|
|
75
|
+
:scope .swatch-button {
|
|
68
76
|
display: inline-flex;
|
|
69
77
|
align-items: center;
|
|
70
78
|
gap: var(--ui-space-2);
|
|
79
|
+
flex: 1 0 5rem;
|
|
80
|
+
min-width: 5rem;
|
|
81
|
+
max-width: calc((100% - 6px) / 3);
|
|
82
|
+
padding-inline-end: var(--ui-space-1);
|
|
71
83
|
}
|
|
72
84
|
|
|
73
85
|
.swatch {
|
|
@@ -114,7 +126,19 @@
|
|
|
114
126
|
margin: var(--ui-space-1) 0;
|
|
115
127
|
}
|
|
116
128
|
|
|
129
|
+
/* Separators divide sections, so none sits above the first. */
|
|
130
|
+
.sep:first-child {
|
|
131
|
+
display: none;
|
|
132
|
+
}
|
|
133
|
+
|
|
117
134
|
:scope[hidden] {
|
|
118
135
|
display: none;
|
|
119
136
|
}
|
|
120
137
|
}
|
|
138
|
+
@scope ([data-component~="ui-editor-table-context-menu"]) to ([data-component]) {
|
|
139
|
+
/* Swatches wrap like words: the row asks for the menu's full width, and a narrower menu fits fewer. */
|
|
140
|
+
|
|
141
|
+
/* Three to a row at the menu's full width; 5rem keeps the longest label, "Default", whole. */
|
|
142
|
+
|
|
143
|
+
/* Separators divide sections, so none sits above the first. */
|
|
144
|
+
}
|
|
@@ -21,14 +21,6 @@
|
|
|
21
21
|
background: var(--ui-accent-soft, var(--ui-accent-subtle));
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
.looma-editor__mobile-toolbar-shell :scope .menu {
|
|
25
|
-
top: auto;
|
|
26
|
-
right: 0;
|
|
27
|
-
bottom: calc(100% + var(--ui-space-2));
|
|
28
|
-
max-height: min(50dvh, 22rem);
|
|
29
|
-
overflow-y: auto;
|
|
30
|
-
overscroll-behavior: contain;
|
|
31
|
-
}
|
|
32
24
|
:scope {
|
|
33
25
|
display: inline-flex;
|
|
34
26
|
align-items: center;
|
|
@@ -119,9 +111,9 @@
|
|
|
119
111
|
|
|
120
112
|
.menu {
|
|
121
113
|
box-sizing: border-box;
|
|
122
|
-
position:
|
|
123
|
-
|
|
124
|
-
|
|
114
|
+
position: fixed;
|
|
115
|
+
inset: auto;
|
|
116
|
+
margin: 0;
|
|
125
117
|
min-width: 12rem;
|
|
126
118
|
max-width: min(17rem, calc(100vw - 24px));
|
|
127
119
|
padding: var(--ui-space-1);
|
package/styles/ui-listbox.css
CHANGED
|
@@ -38,7 +38,10 @@
|
|
|
38
38
|
outline: none;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/* Its own box around the nested Scroll Area, which it shrinks into so the choices scroll. */
|
|
41
42
|
.choices {
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: column;
|
|
42
45
|
max-block-size: calc(max(2, var(--_rows, 5)) * var(--ui-control-size-md));
|
|
43
46
|
}
|
|
44
47
|
|
|
@@ -92,3 +95,6 @@
|
|
|
92
95
|
display: none;
|
|
93
96
|
}
|
|
94
97
|
}
|
|
98
|
+
@scope ([data-component~="ui-listbox"]) to ([data-component]) {
|
|
99
|
+
/* Its own box around the nested Scroll Area, which it shrinks into so the choices scroll. */
|
|
100
|
+
}
|
|
@@ -53,6 +53,19 @@
|
|
|
53
53
|
max-block-size: 30rem;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
:scope[data-ui-scroll-area-state~="padding=xs"] {
|
|
57
|
+
padding: var(--ui-space-2);
|
|
58
|
+
}
|
|
59
|
+
:scope[data-ui-scroll-area-state~="padding=sm"] {
|
|
60
|
+
padding: var(--ui-space-3);
|
|
61
|
+
}
|
|
62
|
+
:scope[data-ui-scroll-area-state~="padding=md"] {
|
|
63
|
+
padding: var(--ui-space-5);
|
|
64
|
+
}
|
|
65
|
+
:scope[data-ui-scroll-area-state~="padding=lg"] {
|
|
66
|
+
padding: var(--ui-space-6);
|
|
67
|
+
}
|
|
68
|
+
|
|
56
69
|
/* A component that sets its display still honours the hidden attribute on its root. */
|
|
57
70
|
:scope[hidden] {
|
|
58
71
|
display: none;
|
package/styles/ui-section.css
CHANGED
|
@@ -36,6 +36,9 @@
|
|
|
36
36
|
--_ui-selection-context-text: var(--ui-text-primary);
|
|
37
37
|
border-color: color-mix(in srgb, var(--ui-danger) 45%, var(--ui-border-default));
|
|
38
38
|
border-inline-start: var(--ui-accent-line-width) solid var(--ui-danger);
|
|
39
|
+
/* An accent edge keeps the corners on its side straight. */
|
|
40
|
+
border-start-start-radius: 0;
|
|
41
|
+
border-end-start-radius: 0;
|
|
39
42
|
background: var(--ui-danger-soft);
|
|
40
43
|
}
|
|
41
44
|
|
package/vanilla/UiDialog.js
CHANGED
|
@@ -62,7 +62,7 @@ export function createUiDialog(options = {}, html) {
|
|
|
62
62
|
if (c === -1) {
|
|
63
63
|
const x1 = true;
|
|
64
64
|
const s1 = toAttribute(x1, "trim");
|
|
65
|
-
if (s1 !== r.v1) writeAttribute(r.
|
|
65
|
+
if (s1 !== r.v1) writeAttribute(r.a5, "trim", r.v1 = s1);
|
|
66
66
|
}
|
|
67
67
|
if (c & 516) {
|
|
68
68
|
const x2 = hostState(["size","alert"], [v[9], v[2]]);
|
|
@@ -74,15 +74,15 @@ export function createUiDialog(options = {}, html) {
|
|
|
74
74
|
if (true) {
|
|
75
75
|
{
|
|
76
76
|
r.b0 = undefined;
|
|
77
|
-
clearRegion(r.
|
|
77
|
+
clearRegion(r.a2, r.e0);
|
|
78
78
|
if (t0) { r.b0 = m1(d); r.e0.before(r.b0.n); }
|
|
79
79
|
}
|
|
80
80
|
} else if (r.b0 !== undefined) p1(r.b0, c, d);
|
|
81
81
|
} else if (r.b0 !== undefined) p1(r.b0, c, d);
|
|
82
|
-
if (r.f1 === undefined) { r.f1 = 1; const at = fillSlot(r.
|
|
82
|
+
if (r.f1 === undefined) { r.f1 = 1; const at = fillSlot(r.a6, r.e1, "", J, false, undefined, d);
|
|
83
83
|
if (Array.isArray(at)) (r.z ??= []).push(() => { at[0].l.delete(at[1]); dispose(at[1]); }); else if (at !== undefined) { r.b1 = m2(d); at.before(r.b1.n); } }
|
|
84
84
|
else if (r.b1 !== undefined) p2(r.b1, c, d);
|
|
85
|
-
if (r.f2 === undefined) { r.f2 = 1; const at = fillSlot(r.
|
|
85
|
+
if (r.f2 === undefined) { r.f2 = 1; const at = fillSlot(r.a8, r.e2, "actions", J, false, undefined, d);
|
|
86
86
|
if (Array.isArray(at)) (r.z ??= []).push(() => { at[0].l.delete(at[1]); dispose(at[1]); }); else if (at !== undefined) { r.b2 = m3(d); at.before(r.b2.n); } }
|
|
87
87
|
else if (r.b2 !== undefined) p3(r.b2, c, d);
|
|
88
88
|
};
|
|
@@ -92,13 +92,17 @@ export function createUiDialog(options = {}, html) {
|
|
|
92
92
|
const t3 = t0.nextSibling;
|
|
93
93
|
const t4 = t3.firstChild;
|
|
94
94
|
const t5 = t4.firstChild;
|
|
95
|
-
const t6 = t3.nextSibling
|
|
96
|
-
const
|
|
95
|
+
const t6 = t3.nextSibling;
|
|
96
|
+
const t7 = t6.firstChild;
|
|
97
|
+
const R = { n: element, a5: t4, v0: undefined, v1: null, v2: undefined, a2: t1, e0: t1.nextSibling, b0: undefined, a6: t5, e1: t5.nextSibling, b1: undefined, f1: undefined, a8: t7, e2: t7.nextSibling, b2: undefined, f2: undefined };
|
|
97
98
|
const I = { B };
|
|
98
99
|
const J = project(I, children, slots);
|
|
99
100
|
I.R = new Set();
|
|
100
101
|
attachGeneratedController(element, S, v, (c, d) => { ((c, d) => p0(R, c, d))(c, d); for (const f of I.R) f(c, d); }, C, undefined, I);
|
|
101
102
|
manageProps(I);
|
|
103
|
+
I.r["header"] = t0;
|
|
102
104
|
I.r["close"] = t2;
|
|
105
|
+
I.r["body"] = t3;
|
|
106
|
+
I.r["footer"] = t6;
|
|
103
107
|
return element;
|
|
104
108
|
}
|
package/vanilla/UiListbox.js
CHANGED
|
@@ -3,7 +3,7 @@ import { attachGeneratedController, buildTemplate, checkReference, clearRegion,
|
|
|
3
3
|
import * as controller from "../components/ui-listbox/ui-listbox.js";
|
|
4
4
|
import "../styles/ui-listbox.css";
|
|
5
5
|
|
|
6
|
-
const T0 = ["",[],["
|
|
6
|
+
const T0 = ["",[],["div",["class","choices"],["ui-scroll-area",[],2]],["select",["class","fallback","aria-label","Choices"],4],1,["input",["class","validity","type","checkbox","aria-hidden","true","tabindex","-1"]]];
|
|
7
7
|
const T1 = ["div",["class","option","role","option","data-ui-choice-option",""],["span",[],0]];
|
|
8
8
|
const T2 = ["",[]];
|
|
9
9
|
const T3 = ["",[],2];
|
|
@@ -201,18 +201,19 @@ export function createUiListbox(options = {}, html) {
|
|
|
201
201
|
};
|
|
202
202
|
const t0 = element.firstChild;
|
|
203
203
|
const t1 = t0.firstChild;
|
|
204
|
-
const t2 =
|
|
205
|
-
const t3 =
|
|
206
|
-
const t4 =
|
|
207
|
-
const t5 =
|
|
208
|
-
const
|
|
204
|
+
const t2 = t1.firstChild;
|
|
205
|
+
const t3 = t0.nextSibling;
|
|
206
|
+
const t4 = t3.firstChild;
|
|
207
|
+
const t5 = t3.nextSibling;
|
|
208
|
+
const t6 = t5.nextSibling.nextSibling;
|
|
209
|
+
const R = { n: element, a3: t3, a6: t6, v0: undefined, v1: undefined, v2: undefined, v3: undefined, v4: undefined, v5: undefined, v6: null, v7: null, v8: null, v9: null, v10: null, v11: null, v12: null, v13: null, L0: new KeyedList(t2, t2.nextSibling, m1, p1, (o) => readMember(o, "index"), "choice"), a4: t4, e1: t4.nextSibling, b1: undefined, f1: undefined, a5: t5, e2: t5.nextSibling, b2: undefined };
|
|
209
210
|
const I = { B };
|
|
210
211
|
const J = project(I, children, slots);
|
|
211
212
|
I.R = new Set();
|
|
212
213
|
attachGeneratedController(element, S, v, (c, d) => { ((c, d) => p0(R, c, d))(c, d); for (const f of I.R) f(c, d); }, C, undefined, I);
|
|
213
214
|
manageProps(I);
|
|
214
|
-
I.r["choices"] =
|
|
215
|
-
I.r["options"] =
|
|
216
|
-
I.r["validity"] =
|
|
215
|
+
I.r["choices"] = t1;
|
|
216
|
+
I.r["options"] = t3;
|
|
217
|
+
I.r["validity"] = t6;
|
|
217
218
|
return element;
|
|
218
219
|
}
|
|
@@ -8,6 +8,7 @@ export interface UiScrollAreaElement extends HTMLDivElement {
|
|
|
8
8
|
export interface UiScrollAreaProps {
|
|
9
9
|
fill?: boolean | null;
|
|
10
10
|
orientation?: "vertical" | "horizontal" | null;
|
|
11
|
+
padding?: "none" | "xs" | "sm" | "md" | "lg" | null;
|
|
11
12
|
size?: "content" | "sm" | "md" | "lg" | null;
|
|
12
13
|
trim?: boolean | null;
|
|
13
14
|
attributes?: Readonly<Record<string, string | number | boolean | null | undefined>>;
|
package/vanilla/UiScrollArea.js
CHANGED
|
@@ -7,7 +7,7 @@ const T0 = ["",[],["div",["class","content"],4]];
|
|
|
7
7
|
const T1 = ["",[]];
|
|
8
8
|
let P0, P1;
|
|
9
9
|
const S = { n: [], t: [], f: import.meta.url, g: "ui-scroll-area" };
|
|
10
|
-
const D = { props: { "fill": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "orientation": { "required":false,"values":["vertical","horizontal"],"default":"vertical", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "size": { "required":false,"values":["content","sm","md","lg"],"default":"content", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "trim": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" } } };
|
|
10
|
+
const D = { props: { "fill": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" }, "orientation": { "required":false,"values":["vertical","horizontal"],"default":"vertical", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "padding": { "required":false,"values":["none","xs","sm","md","lg"],"default":"none", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "size": { "required":false,"values":["content","sm","md","lg"],"default":"content", c: checkFormat("keyword", keywordFormat), t: "keyword", j: 0, m: ["p",formatOf(keywordFormat),false] }, "trim": { "required":false,"default":false, c: checkBoolean, t: "boolean", j: 0, m: "b" } } };
|
|
11
11
|
const C = (host) => controller.default(host);
|
|
12
12
|
|
|
13
13
|
export function createUiScrollArea(options = {}, html) {
|
|
@@ -19,7 +19,7 @@ export function createUiScrollArea(options = {}, html) {
|
|
|
19
19
|
}
|
|
20
20
|
element.setAttribute("data-component", "ui-scroll-area");
|
|
21
21
|
element.append((P0 ??= buildTemplate(T0)).cloneNode(true));
|
|
22
|
-
const v = [null, null, null, null];
|
|
22
|
+
const v = [null, null, null, null, null];
|
|
23
23
|
const B = acceptProps(element, D, S.n, v, componentProps, [], html);
|
|
24
24
|
const m1 = (d) => {
|
|
25
25
|
const n = (P1 ??= buildTemplate(T1)).cloneNode(true);
|
|
@@ -30,8 +30,8 @@ export function createUiScrollArea(options = {}, html) {
|
|
|
30
30
|
const p1 = (r, c, d) => {
|
|
31
31
|
};
|
|
32
32
|
const p0 = (r, c, d) => {
|
|
33
|
-
if (c &
|
|
34
|
-
const x0 = hostState(["fill","orientation","size","trim"], [v[0], v[1], v[2], v[
|
|
33
|
+
if (c & 31) {
|
|
34
|
+
const x0 = hostState(["fill","orientation","size","padding","trim"], [v[0], v[1], v[3], v[2], v[4]]);
|
|
35
35
|
const s0 = x0;
|
|
36
36
|
if (s0 !== r.v0) writeAttribute(r.n, "data-ui-scroll-area-state", (r.v0 = s0) === "" ? null : s0);
|
|
37
37
|
}
|
package/vue/UiCard.vue
CHANGED
|
@@ -331,6 +331,9 @@ const hostState = computed(() =>
|
|
|
331
331
|
[data-component~="ui-card"][data-ui-card-state~="tone=danger"] {
|
|
332
332
|
border-color: color-mix(in srgb, var(--ui-danger) 45%, var(--ui-border-default));
|
|
333
333
|
border-inline-start: var(--ui-accent-line-width) solid var(--ui-danger);
|
|
334
|
+
/* An accent edge keeps the corners on its side straight. */
|
|
335
|
+
border-start-start-radius: 0;
|
|
336
|
+
border-end-start-radius: 0;
|
|
334
337
|
--_ui-card-surface: var(--ui-danger-soft);
|
|
335
338
|
}
|
|
336
339
|
|
package/vue/UiDialog.vue
CHANGED
|
@@ -228,7 +228,10 @@ const emit = defineEmits<{
|
|
|
228
228
|
}>()
|
|
229
229
|
|
|
230
230
|
const root = ref<HTMLElement | null>(null)
|
|
231
|
+
const headerElement = useTemplateRef<HTMLElement>('headerElement')
|
|
231
232
|
const closeElement = useTemplateRef<HTMLElement>('closeElement')
|
|
233
|
+
const bodyElement = useTemplateRef<HTMLElement>('bodyElement')
|
|
234
|
+
const footerElement = useTemplateRef<HTMLElement>('footerElement')
|
|
232
235
|
const internalOpen = ref(false)
|
|
233
236
|
const accessibleLabel = ref('Dialog')
|
|
234
237
|
let guardedPrevious: any
|
|
@@ -324,7 +327,7 @@ useComponentHost(() => import('../components/ui-dialog/ui-dialog.js'), {
|
|
|
324
327
|
propNames: ['alert', 'closedby', 'for', 'label', 'modal', 'modeless', 'open', 'size'],
|
|
325
328
|
propValidity: (name: string) =>
|
|
326
329
|
propValidityState({ contract: propValidityContract, values: { ...props } }, name),
|
|
327
|
-
refs: { close: closeElement },
|
|
330
|
+
refs: { header: headerElement, close: closeElement, body: bodyElement, footer: footerElement },
|
|
328
331
|
state: { internalOpen, accessibleLabel },
|
|
329
332
|
})
|
|
330
333
|
</script>
|
|
@@ -346,12 +349,12 @@ useComponentHost(() => import('../components/ui-dialog/ui-dialog.js'), {
|
|
|
346
349
|
:data-ui-dialog-state="hostState || undefined"
|
|
347
350
|
ref="root"
|
|
348
351
|
>
|
|
349
|
-
<header>
|
|
352
|
+
<header ref="headerElement">
|
|
350
353
|
<h2 v-if="checkedProps.label" class="title">{{ checkedProps.label }}</h2>
|
|
351
354
|
<button class="close" type="button" aria-label="Close" ref="closeElement"></button>
|
|
352
355
|
</header>
|
|
353
|
-
<div class="body"><UiScrollArea :trim="true"><slot /></UiScrollArea></div>
|
|
354
|
-
<footer><slot name="actions" /></footer>
|
|
356
|
+
<div class="body" ref="bodyElement"><UiScrollArea :trim="true"><slot /></UiScrollArea></div>
|
|
357
|
+
<footer ref="footerElement"><slot name="actions" /></footer>
|
|
355
358
|
</dialog>
|
|
356
359
|
</template>
|
|
357
360
|
|
|
@@ -459,7 +462,10 @@ header {
|
|
|
459
462
|
align-items: center;
|
|
460
463
|
gap: var(--ui-space-3);
|
|
461
464
|
flex: none;
|
|
462
|
-
|
|
465
|
+
/* The title's ink sits inside its line box and the taller close target. Balance that
|
|
466
|
+
visible top inset against the action row's bottom inset, not just the boxes. */
|
|
467
|
+
padding: calc(var(--ui-space-3) + var(--ui-space-1) / 2) var(--ui-space-3) var(--ui-space-3)
|
|
468
|
+
var(--ui-space-5);
|
|
463
469
|
}
|
|
464
470
|
|
|
465
471
|
/* :host-qualified so page heading rules that reach in cannot outrank the dialog chrome. */
|
|
@@ -569,7 +575,7 @@ footer:empty {
|
|
|
569
575
|
overlay var(--_ui-dialog-duration, var(--ui-motion-base)) var(--ui-motion-ease) allow-discrete;
|
|
570
576
|
}
|
|
571
577
|
|
|
572
|
-
[data-component~="ui-dialog"][open]::backdrop {
|
|
578
|
+
[data-component~="ui-dialog"][open]:modal::backdrop {
|
|
573
579
|
background-color: var(--ui-overlay-backdrop);
|
|
574
580
|
animation: ui-dialog-backdrop-enter var(--_ui-dialog-duration, var(--ui-motion-base))
|
|
575
581
|
var(--ui-motion-ease);
|
|
@@ -460,6 +460,12 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
|
|
|
460
460
|
</template>
|
|
461
461
|
|
|
462
462
|
<style scoped>
|
|
463
|
+
[data-component~="ui-editor-mention-menu"][popover] {
|
|
464
|
+
position: fixed;
|
|
465
|
+
inset: auto;
|
|
466
|
+
margin: 0;
|
|
467
|
+
}
|
|
468
|
+
|
|
463
469
|
[data-component~="ui-editor-mention-menu"] {
|
|
464
470
|
user-select: none;
|
|
465
471
|
}
|
|
@@ -394,6 +394,12 @@ useComponentHost(() => import('../components/ui-editor-slash-menu/ui-editor-slas
|
|
|
394
394
|
</template>
|
|
395
395
|
|
|
396
396
|
<style scoped>
|
|
397
|
+
[data-component~="ui-editor-slash-menu"][popover] {
|
|
398
|
+
position: fixed;
|
|
399
|
+
inset: auto;
|
|
400
|
+
margin: 0;
|
|
401
|
+
}
|
|
402
|
+
|
|
397
403
|
[data-component~="ui-editor-slash-menu"] {
|
|
398
404
|
user-select: none;
|
|
399
405
|
}
|
|
@@ -654,10 +654,16 @@ function uniqueKeys<T>(
|
|
|
654
654
|
</template>
|
|
655
655
|
|
|
656
656
|
<style scoped>
|
|
657
|
+
[data-component~="ui-editor-table-context-menu"][popover] {
|
|
658
|
+
position: fixed;
|
|
659
|
+
inset: auto;
|
|
660
|
+
margin: 0;
|
|
661
|
+
}
|
|
662
|
+
|
|
657
663
|
[data-component~="ui-editor-table-context-menu"] {
|
|
658
664
|
/* The max-width is a promise about the menu's footprint, so it counts padding and border. */
|
|
659
665
|
box-sizing: border-box;
|
|
660
|
-
min-width: 14rem;
|
|
666
|
+
min-width: min(14rem, calc(100vw - 24px));
|
|
661
667
|
max-width: min(17rem, calc(100vw - 24px));
|
|
662
668
|
max-height: min(28rem, calc(100vh - 24px));
|
|
663
669
|
padding: var(--ui-space-2);
|
|
@@ -712,16 +718,22 @@ function uniqueKeys<T>(
|
|
|
712
718
|
color: var(--ui-danger);
|
|
713
719
|
}
|
|
714
720
|
|
|
721
|
+
/* Swatches wrap like words: the row asks for the menu's full width, and a narrower menu fits fewer. */
|
|
715
722
|
.swatches {
|
|
716
|
-
display:
|
|
717
|
-
|
|
723
|
+
display: flex;
|
|
724
|
+
flex-wrap: wrap;
|
|
718
725
|
gap: 3px;
|
|
719
726
|
}
|
|
720
727
|
|
|
721
|
-
.
|
|
728
|
+
/* Three to a row at the menu's full width; 5rem keeps the longest label, "Default", whole. */
|
|
729
|
+
[data-component~="ui-editor-table-context-menu"] .swatch-button {
|
|
722
730
|
display: inline-flex;
|
|
723
731
|
align-items: center;
|
|
724
732
|
gap: var(--ui-space-2);
|
|
733
|
+
flex: 1 0 5rem;
|
|
734
|
+
min-width: 5rem;
|
|
735
|
+
max-width: calc((100% - 6px) / 3);
|
|
736
|
+
padding-inline-end: var(--ui-space-1);
|
|
725
737
|
}
|
|
726
738
|
|
|
727
739
|
.swatch {
|
|
@@ -768,6 +780,11 @@ function uniqueKeys<T>(
|
|
|
768
780
|
margin: var(--ui-space-1) 0;
|
|
769
781
|
}
|
|
770
782
|
|
|
783
|
+
/* Separators divide sections, so none sits above the first. */
|
|
784
|
+
.sep:first-child {
|
|
785
|
+
display: none;
|
|
786
|
+
}
|
|
787
|
+
|
|
771
788
|
[data-component~="ui-editor-table-context-menu"][hidden] {
|
|
772
789
|
display: none;
|
|
773
790
|
}
|
|
@@ -796,14 +796,6 @@ function uniqueKeys<T>(
|
|
|
796
796
|
background: var(--ui-accent-soft, var(--ui-accent-subtle));
|
|
797
797
|
}
|
|
798
798
|
|
|
799
|
-
.looma-editor__mobile-toolbar-shell [data-component~="ui-editor-table-toolbar"] .menu {
|
|
800
|
-
top: auto;
|
|
801
|
-
right: 0;
|
|
802
|
-
bottom: calc(100% + var(--ui-space-2));
|
|
803
|
-
max-height: min(50dvh, 22rem);
|
|
804
|
-
overflow-y: auto;
|
|
805
|
-
overscroll-behavior: contain;
|
|
806
|
-
}
|
|
807
799
|
[data-component~="ui-editor-table-toolbar"] {
|
|
808
800
|
display: inline-flex;
|
|
809
801
|
align-items: center;
|
|
@@ -894,9 +886,9 @@ function uniqueKeys<T>(
|
|
|
894
886
|
|
|
895
887
|
.menu {
|
|
896
888
|
box-sizing: border-box;
|
|
897
|
-
position:
|
|
898
|
-
|
|
899
|
-
|
|
889
|
+
position: fixed;
|
|
890
|
+
inset: auto;
|
|
891
|
+
margin: 0;
|
|
900
892
|
min-width: 12rem;
|
|
901
893
|
max-width: min(17rem, calc(100vw - 24px));
|
|
902
894
|
padding: var(--ui-space-1);
|
package/vue/UiListbox.vue
CHANGED
|
@@ -479,21 +479,23 @@ function uniqueKeys<T>(
|
|
|
479
479
|
:data-values="reflectedProp('values', 'values', checkedProps.values, undefined, false)"
|
|
480
480
|
ref="root"
|
|
481
481
|
>
|
|
482
|
-
<
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
482
|
+
<div class="choices">
|
|
483
|
+
<UiScrollArea ref="choicesElement"><KeyedBoundary><div
|
|
484
|
+
v-for="choice in uniqueKeys(choices, (choice, index, loop) => choice.index)"
|
|
485
|
+
:key="choice.index"
|
|
486
|
+
class="option"
|
|
487
|
+
role="option"
|
|
488
|
+
data-ui-choice-option=""
|
|
489
|
+
:data-multiple="checkedProps.multiple ? '' : undefined"
|
|
490
|
+
:id="concat(uid, '-option-', choice.index)"
|
|
491
|
+
:data-index="choice.index"
|
|
492
|
+
:aria-selected="choice.selected"
|
|
493
|
+
:aria-disabled="choice.disabled"
|
|
494
|
+
:class="{ active: choice.index === active }"
|
|
495
|
+
>
|
|
496
|
+
<span>{{ choice.label }}</span>
|
|
497
|
+
</div></KeyedBoundary></UiScrollArea>
|
|
498
|
+
</div>
|
|
497
499
|
<select
|
|
498
500
|
class="fallback"
|
|
499
501
|
aria-label="Choices"
|
|
@@ -566,7 +568,10 @@ function uniqueKeys<T>(
|
|
|
566
568
|
outline: none;
|
|
567
569
|
}
|
|
568
570
|
|
|
571
|
+
/* Its own box around the nested Scroll Area, which it shrinks into so the choices scroll. */
|
|
569
572
|
.choices {
|
|
573
|
+
display: flex;
|
|
574
|
+
flex-direction: column;
|
|
570
575
|
max-block-size: calc(max(2, var(--_rows, 5)) * var(--ui-control-size-md));
|
|
571
576
|
}
|
|
572
577
|
|
package/vue/UiScrollArea.d.ts
CHANGED
|
@@ -12,6 +12,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
12
12
|
type: PropType<"vertical" | "horizontal" | null>;
|
|
13
13
|
default: string;
|
|
14
14
|
};
|
|
15
|
+
padding: {
|
|
16
|
+
type: PropType<"none" | "xs" | "sm" | "md" | "lg" | null>;
|
|
17
|
+
default: string;
|
|
18
|
+
};
|
|
15
19
|
size: {
|
|
16
20
|
type: PropType<"content" | "sm" | "md" | "lg" | null>;
|
|
17
21
|
default: string;
|
|
@@ -29,6 +33,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
29
33
|
type: PropType<"vertical" | "horizontal" | null>;
|
|
30
34
|
default: string;
|
|
31
35
|
};
|
|
36
|
+
padding: {
|
|
37
|
+
type: PropType<"none" | "xs" | "sm" | "md" | "lg" | null>;
|
|
38
|
+
default: string;
|
|
39
|
+
};
|
|
32
40
|
size: {
|
|
33
41
|
type: PropType<"content" | "sm" | "md" | "lg" | null>;
|
|
34
42
|
default: string;
|
|
@@ -40,6 +48,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
40
48
|
}>> & Readonly<{}>, {
|
|
41
49
|
fill: boolean | null;
|
|
42
50
|
size: "sm" | "md" | "lg" | "content" | null;
|
|
51
|
+
padding: "none" | "xs" | "sm" | "md" | "lg" | null;
|
|
43
52
|
trim: boolean | null;
|
|
44
53
|
orientation: "vertical" | "horizontal" | null;
|
|
45
54
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|