@threadlabs/looma 0.25.4 → 0.25.5
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/ui-card/ui-card.html +27 -2
- package/components/ui-cluster/ui-cluster.html +30 -0
- package/components/ui-editor-surface/ui-editor-surface.html +23 -0
- package/components/ui-scroll-area/ui-scroll-area.html +5 -0
- package/components/ui-stack/ui-stack.html +17 -1
- package/components/ui-text/ui-text.html +5 -0
- package/components/ui-textarea/ui-textarea.html +7 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/styles/ui-card.css +24 -0
- package/styles/ui-cluster.css +25 -0
- package/styles/ui-editor-surface.css +19 -0
- package/styles/ui-scroll-area.css +4 -0
- package/styles/ui-stack.css +13 -0
- package/styles/ui-text.css +4 -0
- package/styles/ui-textarea.css +4 -0
- package/vanilla/UiCard.d.ts +1 -1
- package/vanilla/UiCard.js +1 -1
- package/vanilla/UiCluster.d.ts +3 -0
- package/vanilla/UiCluster.js +9 -3
- package/vanilla/UiEditorSurface.d.ts +14 -0
- package/vanilla/UiEditorSurface.js +27 -0
- package/vanilla/UiScrollArea.d.ts +1 -0
- package/vanilla/UiScrollArea.js +1 -1
- package/vanilla/UiStack.d.ts +2 -0
- package/vanilla/UiStack.js +8 -9
- package/vanilla/UiText.d.ts +1 -0
- package/vanilla/UiText.js +1 -1
- package/vanilla/UiTextarea.d.ts +1 -0
- package/vanilla/UiTextarea.js +4 -1
- package/vanilla/index.js +1 -0
- package/vue/UiCard.d.ts +3 -3
- package/vue/UiCard.vue +34 -5
- package/vue/UiCluster.d.ts +27 -0
- package/vue/UiCluster.vue +95 -1
- package/vue/UiEditorSurface.d.ts +26 -0
- package/vue/UiEditorSurface.js +2 -0
- package/vue/UiEditorSurface.vue +129 -0
- package/vue/UiScrollArea.d.ts +9 -0
- package/vue/UiScrollArea.vue +28 -2
- package/vue/UiStack.d.ts +18 -0
- package/vue/UiStack.vue +58 -1
- package/vue/UiText.d.ts +9 -0
- package/vue/UiText.vue +33 -0
- package/vue/UiTextarea.d.ts +9 -0
- package/vue/UiTextarea.vue +37 -2
- package/vue/chunks/UiCard.js +10 -3
- package/vue/chunks/UiCluster.js +82 -1
- package/vue/chunks/UiEditorSurface.js +71 -0
- package/vue/chunks/UiScrollArea.js +28 -2
- package/vue/chunks/UiStack.js +46 -1
- package/vue/chunks/UiText.js +43 -1
- package/vue/chunks/UiTextarea.js +28 -2
- package/vue/components.css +188 -104
- package/vue/editor/LoomaEditor.d.ts +12 -0
- package/vue/editor/index.js +7 -2
- package/vue/index.d.ts +1 -0
- package/vue/index.js +2 -1
package/vue/UiCluster.d.ts
CHANGED
|
@@ -8,6 +8,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
8
8
|
type: PropType<"start" | "center" | "end" | "stretch" | null>;
|
|
9
9
|
default: null;
|
|
10
10
|
};
|
|
11
|
+
fixed: {
|
|
12
|
+
type: PropType<boolean | null>;
|
|
13
|
+
default: boolean;
|
|
14
|
+
};
|
|
11
15
|
gap: {
|
|
12
16
|
type: PropType<"xs" | "s" | "m" | "l" | "xl" | null>;
|
|
13
17
|
default: null;
|
|
@@ -16,6 +20,14 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
16
20
|
type: PropType<"start" | "center" | "end" | "between" | null>;
|
|
17
21
|
default: null;
|
|
18
22
|
};
|
|
23
|
+
padding: {
|
|
24
|
+
type: PropType<"none" | "s" | "m" | "l" | null>;
|
|
25
|
+
default: string;
|
|
26
|
+
};
|
|
27
|
+
paddingEnd: {
|
|
28
|
+
type: PropType<"none" | "s" | "m" | "l" | "xl" | null>;
|
|
29
|
+
default: string;
|
|
30
|
+
};
|
|
19
31
|
wrap: {
|
|
20
32
|
type: PropType<"wrap" | "nowrap" | null>;
|
|
21
33
|
default: null;
|
|
@@ -25,6 +37,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
25
37
|
type: PropType<"start" | "center" | "end" | "stretch" | null>;
|
|
26
38
|
default: null;
|
|
27
39
|
};
|
|
40
|
+
fixed: {
|
|
41
|
+
type: PropType<boolean | null>;
|
|
42
|
+
default: boolean;
|
|
43
|
+
};
|
|
28
44
|
gap: {
|
|
29
45
|
type: PropType<"xs" | "s" | "m" | "l" | "xl" | null>;
|
|
30
46
|
default: null;
|
|
@@ -33,15 +49,26 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
33
49
|
type: PropType<"start" | "center" | "end" | "between" | null>;
|
|
34
50
|
default: null;
|
|
35
51
|
};
|
|
52
|
+
padding: {
|
|
53
|
+
type: PropType<"none" | "s" | "m" | "l" | null>;
|
|
54
|
+
default: string;
|
|
55
|
+
};
|
|
56
|
+
paddingEnd: {
|
|
57
|
+
type: PropType<"none" | "s" | "m" | "l" | "xl" | null>;
|
|
58
|
+
default: string;
|
|
59
|
+
};
|
|
36
60
|
wrap: {
|
|
37
61
|
type: PropType<"wrap" | "nowrap" | null>;
|
|
38
62
|
default: null;
|
|
39
63
|
};
|
|
40
64
|
}>> & Readonly<{}>, {
|
|
41
65
|
align: "center" | "start" | "stretch" | "end" | null;
|
|
66
|
+
padding: "s" | "none" | "m" | "l" | null;
|
|
67
|
+
fixed: boolean | null;
|
|
42
68
|
gap: "s" | "xs" | "m" | "l" | "xl" | null;
|
|
43
69
|
justify: "center" | "start" | "end" | "between" | null;
|
|
44
70
|
wrap: "wrap" | "nowrap" | null;
|
|
71
|
+
paddingEnd: "s" | "none" | "m" | "l" | "xl" | null;
|
|
45
72
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
46
73
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
47
74
|
declare const _default: typeof __VLS_export;
|
package/vue/UiCluster.vue
CHANGED
|
@@ -16,6 +16,13 @@ const propValidityContract = {
|
|
|
16
16
|
'How items line up within each row: center (the default) aligns their middles, start their tops, end their bottoms, and stretch makes every item as tall as\n its row.',
|
|
17
17
|
values: ['start', 'center', 'end', 'stretch'],
|
|
18
18
|
},
|
|
19
|
+
fixed: {
|
|
20
|
+
type: { kind: 'terminal', name: 'boolean' },
|
|
21
|
+
required: false,
|
|
22
|
+
target: { attribute: 'fixed' },
|
|
23
|
+
description: 'Keeps this group at its content size inside a flex layout.',
|
|
24
|
+
default: false,
|
|
25
|
+
},
|
|
19
26
|
gap: {
|
|
20
27
|
type: { kind: 'terminal', name: 'keyword' },
|
|
21
28
|
required: false,
|
|
@@ -32,6 +39,23 @@ const propValidityContract = {
|
|
|
32
39
|
'Where items sit along each row: start (the default), center, end, or between, which pushes the first and last items to the ends of the row and spreads the\n spare space between them, as for a title with its actions.',
|
|
33
40
|
values: ['start', 'center', 'end', 'between'],
|
|
34
41
|
},
|
|
42
|
+
padding: {
|
|
43
|
+
type: { kind: 'terminal', name: 'keyword' },
|
|
44
|
+
required: false,
|
|
45
|
+
target: { attribute: 'padding' },
|
|
46
|
+
description: 'Optional internal space for an action group, using the shared spacing scale.',
|
|
47
|
+
values: ['none', 's', 'm', 'l'],
|
|
48
|
+
default: 'none',
|
|
49
|
+
},
|
|
50
|
+
paddingEnd: {
|
|
51
|
+
type: { kind: 'terminal', name: 'keyword' },
|
|
52
|
+
required: false,
|
|
53
|
+
target: { attribute: 'paddingend' },
|
|
54
|
+
description:
|
|
55
|
+
'Optional extra space at the inline end, such as clearance beside another control. xl is 4rem.',
|
|
56
|
+
values: ['none', 's', 'm', 'l', 'xl'],
|
|
57
|
+
default: 'none',
|
|
58
|
+
},
|
|
35
59
|
wrap: {
|
|
36
60
|
type: { kind: 'terminal', name: 'keyword' },
|
|
37
61
|
required: false,
|
|
@@ -47,14 +71,28 @@ const props = defineProps({
|
|
|
47
71
|
type: null as unknown as PropType<'start' | 'center' | 'end' | 'stretch' | null>,
|
|
48
72
|
default: null,
|
|
49
73
|
},
|
|
74
|
+
fixed: { type: null as unknown as PropType<boolean | null>, default: false },
|
|
50
75
|
gap: { type: null as unknown as PropType<'xs' | 's' | 'm' | 'l' | 'xl' | null>, default: null },
|
|
51
76
|
justify: {
|
|
52
77
|
type: null as unknown as PropType<'start' | 'center' | 'end' | 'between' | null>,
|
|
53
78
|
default: null,
|
|
54
79
|
},
|
|
80
|
+
padding: { type: null as unknown as PropType<'none' | 's' | 'm' | 'l' | null>, default: 'none' },
|
|
81
|
+
paddingEnd: {
|
|
82
|
+
type: null as unknown as PropType<'none' | 's' | 'm' | 'l' | 'xl' | null>,
|
|
83
|
+
default: 'none',
|
|
84
|
+
},
|
|
55
85
|
wrap: { type: null as unknown as PropType<'wrap' | 'nowrap' | null>, default: null },
|
|
56
86
|
})
|
|
57
|
-
const acceptedProps: Record<string, unknown> = {
|
|
87
|
+
const acceptedProps: Record<string, unknown> = {
|
|
88
|
+
align: null,
|
|
89
|
+
fixed: false,
|
|
90
|
+
gap: null,
|
|
91
|
+
justify: null,
|
|
92
|
+
padding: 'none',
|
|
93
|
+
paddingEnd: 'none',
|
|
94
|
+
wrap: null,
|
|
95
|
+
}
|
|
58
96
|
const checkedProps = computed(() => ({
|
|
59
97
|
align: checkedProp<'start' | 'center' | 'end' | 'stretch'>(
|
|
60
98
|
props['align'],
|
|
@@ -63,6 +101,13 @@ const checkedProps = computed(() => ({
|
|
|
63
101
|
'align',
|
|
64
102
|
acceptedProps,
|
|
65
103
|
),
|
|
104
|
+
fixed: checkedProp<boolean>(
|
|
105
|
+
props['fixed'],
|
|
106
|
+
{ kind: 'terminal', name: 'boolean' },
|
|
107
|
+
false,
|
|
108
|
+
'fixed',
|
|
109
|
+
acceptedProps,
|
|
110
|
+
) as boolean,
|
|
66
111
|
gap: checkedProp<'xs' | 's' | 'm' | 'l' | 'xl'>(
|
|
67
112
|
props['gap'],
|
|
68
113
|
{ kind: 'terminal', name: 'keyword' },
|
|
@@ -77,6 +122,20 @@ const checkedProps = computed(() => ({
|
|
|
77
122
|
'justify',
|
|
78
123
|
acceptedProps,
|
|
79
124
|
),
|
|
125
|
+
padding: checkedProp<'none' | 's' | 'm' | 'l'>(
|
|
126
|
+
props['padding'],
|
|
127
|
+
{ kind: 'terminal', name: 'keyword' },
|
|
128
|
+
false,
|
|
129
|
+
'padding',
|
|
130
|
+
acceptedProps,
|
|
131
|
+
) as 'none' | 's' | 'm' | 'l',
|
|
132
|
+
paddingEnd: checkedProp<'none' | 's' | 'm' | 'l' | 'xl'>(
|
|
133
|
+
props['paddingEnd'],
|
|
134
|
+
{ kind: 'terminal', name: 'keyword' },
|
|
135
|
+
false,
|
|
136
|
+
'paddingEnd',
|
|
137
|
+
acceptedProps,
|
|
138
|
+
) as 'none' | 's' | 'm' | 'l' | 'xl',
|
|
80
139
|
wrap: checkedProp<'wrap' | 'nowrap'>(
|
|
81
140
|
props['wrap'],
|
|
82
141
|
{ kind: 'terminal', name: 'keyword' },
|
|
@@ -143,6 +202,13 @@ if (
|
|
|
143
202
|
/** The values the styles' :host-state() rules test. */
|
|
144
203
|
const hostState = computed(() =>
|
|
145
204
|
[
|
|
205
|
+
checkedProps.value.fixed && 'fixed',
|
|
206
|
+
checkedProps.value.padding && 'padding',
|
|
207
|
+
checkedProps.value.padding != null
|
|
208
|
+
&& `padding=${encodeURIComponent(checkedProps.value.padding)}`,
|
|
209
|
+
checkedProps.value.paddingEnd && 'paddingEnd',
|
|
210
|
+
checkedProps.value.paddingEnd != null
|
|
211
|
+
&& `paddingEnd=${encodeURIComponent(checkedProps.value.paddingEnd)}`,
|
|
146
212
|
checkedProps.value.gap && 'gap',
|
|
147
213
|
checkedProps.value.gap != null && `gap=${encodeURIComponent(checkedProps.value.gap)}`,
|
|
148
214
|
checkedProps.value.align && 'align',
|
|
@@ -162,8 +228,11 @@ const hostState = computed(() =>
|
|
|
162
228
|
v-bind="nativeAttrs($attrs)"
|
|
163
229
|
v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
|
|
164
230
|
:data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
|
|
231
|
+
:data-fixed="reflectedProp('fixed', 'fixed', checkedProps.fixed, undefined, false)"
|
|
165
232
|
:data-gap="reflectedProp('gap', 'gap', checkedProps.gap, undefined, false)"
|
|
166
233
|
:data-justify="reflectedProp('justify', 'justify', checkedProps.justify, undefined, false)"
|
|
234
|
+
:data-padding="reflectedProp('padding', 'padding', checkedProps.padding, undefined, false)"
|
|
235
|
+
:data-padding-end="reflectedProp('paddingEnd', 'padding-end', checkedProps.paddingEnd, undefined, false)"
|
|
167
236
|
:data-wrap="reflectedProp('wrap', 'wrap', checkedProps.wrap, undefined, false)"
|
|
168
237
|
:data-ui-cluster-state="hostState || undefined"
|
|
169
238
|
>
|
|
@@ -189,6 +258,31 @@ const hostState = computed(() =>
|
|
|
189
258
|
margin: 0;
|
|
190
259
|
}
|
|
191
260
|
|
|
261
|
+
[data-component~="ui-cluster"][data-ui-cluster-state~="fixed"] {
|
|
262
|
+
flex: none;
|
|
263
|
+
}
|
|
264
|
+
[data-component~="ui-cluster"][data-ui-cluster-state~="padding=s"] {
|
|
265
|
+
padding: var(--ui-space-2);
|
|
266
|
+
}
|
|
267
|
+
[data-component~="ui-cluster"][data-ui-cluster-state~="padding=m"] {
|
|
268
|
+
padding: var(--ui-space-3);
|
|
269
|
+
}
|
|
270
|
+
[data-component~="ui-cluster"][data-ui-cluster-state~="padding=l"] {
|
|
271
|
+
padding: var(--ui-space-4);
|
|
272
|
+
}
|
|
273
|
+
[data-component~="ui-cluster"][data-ui-cluster-state~="paddingEnd=s"] {
|
|
274
|
+
padding-inline-end: var(--ui-space-2);
|
|
275
|
+
}
|
|
276
|
+
[data-component~="ui-cluster"][data-ui-cluster-state~="paddingEnd=m"] {
|
|
277
|
+
padding-inline-end: var(--ui-space-3);
|
|
278
|
+
}
|
|
279
|
+
[data-component~="ui-cluster"][data-ui-cluster-state~="paddingEnd=l"] {
|
|
280
|
+
padding-inline-end: var(--ui-space-4);
|
|
281
|
+
}
|
|
282
|
+
[data-component~="ui-cluster"][data-ui-cluster-state~="paddingEnd=xl"] {
|
|
283
|
+
padding-inline-end: calc(var(--ui-space-4) * 4);
|
|
284
|
+
}
|
|
285
|
+
|
|
192
286
|
[data-component~="ui-cluster"][data-ui-cluster-state~="gap=xs"] {
|
|
193
287
|
--_layout-gap: var(--ui-space-2);
|
|
194
288
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PropType } from 'vue';
|
|
2
|
+
declare var __VLS_1: {};
|
|
3
|
+
type __VLS_Slots = {} & {
|
|
4
|
+
default?: (props: typeof __VLS_1) => any;
|
|
5
|
+
};
|
|
6
|
+
declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
7
|
+
density: {
|
|
8
|
+
type: PropType<"comfortable" | "compact" | null>;
|
|
9
|
+
default: string;
|
|
10
|
+
};
|
|
11
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
12
|
+
density: {
|
|
13
|
+
type: PropType<"comfortable" | "compact" | null>;
|
|
14
|
+
default: string;
|
|
15
|
+
};
|
|
16
|
+
}>> & Readonly<{}>, {
|
|
17
|
+
density: "comfortable" | "compact" | null;
|
|
18
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
19
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
20
|
+
declare const _default: typeof __VLS_export;
|
|
21
|
+
export default _default;
|
|
22
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
23
|
+
new (): {
|
|
24
|
+
$slots: S;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
<!-- Generated by HTML Next 1.0.0-alpha.29 for Vue 3.5. Do not edit. -->
|
|
2
|
+
<script setup lang="ts">
|
|
3
|
+
import { computed, getCurrentInstance, watchSyncEffect } from 'vue'
|
|
4
|
+
import type { PropType } from 'vue'
|
|
5
|
+
import { checkedProp, vPropValidity } from './props'
|
|
6
|
+
|
|
7
|
+
defineOptions({ inheritAttrs: false })
|
|
8
|
+
|
|
9
|
+
const propValidityContract = {
|
|
10
|
+
props: {
|
|
11
|
+
density: {
|
|
12
|
+
type: { kind: 'terminal', name: 'keyword' },
|
|
13
|
+
required: false,
|
|
14
|
+
target: { attribute: 'density' },
|
|
15
|
+
description:
|
|
16
|
+
'The document canvas. comfortable preserves the editor\'s normal room and mobile toolbar clearance. compact fits a read-only excerpt to its content without\n outer padding.',
|
|
17
|
+
values: ['comfortable', 'compact'],
|
|
18
|
+
default: 'comfortable',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
} as const
|
|
22
|
+
const props = defineProps({
|
|
23
|
+
density: {
|
|
24
|
+
type: null as unknown as PropType<'comfortable' | 'compact' | null>,
|
|
25
|
+
default: 'comfortable',
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
const acceptedProps: Record<string, unknown> = { density: 'comfortable' }
|
|
29
|
+
const checkedProps = computed(() => ({
|
|
30
|
+
density: checkedProp<'comfortable' | 'compact'>(
|
|
31
|
+
props['density'],
|
|
32
|
+
{ kind: 'terminal', name: 'keyword' },
|
|
33
|
+
false,
|
|
34
|
+
'density',
|
|
35
|
+
acceptedProps,
|
|
36
|
+
) as 'comfortable' | 'compact',
|
|
37
|
+
}))
|
|
38
|
+
void checkedProps.value
|
|
39
|
+
watchSyncEffect(() => {
|
|
40
|
+
void checkedProps.value
|
|
41
|
+
})
|
|
42
|
+
function nativeAttrs(attrs: Record<string, unknown>): Record<string, unknown> {
|
|
43
|
+
const names = Object.keys(attrs)
|
|
44
|
+
if (!names.some((name) => Object.hasOwn(Object.prototype, name))) return attrs
|
|
45
|
+
return Object.fromEntries(names.map((name) => [
|
|
46
|
+
Object.hasOwn(Object.prototype, name)
|
|
47
|
+
? name === '__proto__' ? '__Proto__' : name[0]!.toUpperCase() + name.slice(1)
|
|
48
|
+
: name,
|
|
49
|
+
attrs[name],
|
|
50
|
+
]))
|
|
51
|
+
}
|
|
52
|
+
const componentInstance = getCurrentInstance()
|
|
53
|
+
function reflectedProp(
|
|
54
|
+
name: string,
|
|
55
|
+
kebab: string,
|
|
56
|
+
value: unknown,
|
|
57
|
+
fallback: string | undefined,
|
|
58
|
+
bound: boolean,
|
|
59
|
+
separator?: string,
|
|
60
|
+
): string | undefined {
|
|
61
|
+
const incoming = componentInstance?.vnode.props
|
|
62
|
+
if (
|
|
63
|
+
!bound
|
|
64
|
+
&& (incoming === null || incoming === undefined
|
|
65
|
+
|| (!Object.hasOwn(incoming, name) && !Object.hasOwn(incoming, kebab)))
|
|
66
|
+
) return fallback
|
|
67
|
+
if (value === null || value === undefined) return undefined
|
|
68
|
+
return Array.isArray(value) && separator !== undefined
|
|
69
|
+
? value.join(separator)
|
|
70
|
+
: typeof value === 'object'
|
|
71
|
+
? JSON.stringify(value)
|
|
72
|
+
: String(value)
|
|
73
|
+
}
|
|
74
|
+
const hydrationInstance = getCurrentInstance()
|
|
75
|
+
|
|
76
|
+
const hydrationNode = hydrationInstance?.vnode.el
|
|
77
|
+
if (
|
|
78
|
+
typeof window !== 'undefined' && hydrationNode != null
|
|
79
|
+
&& (!(hydrationNode instanceof Element) || hydrationNode.localName !== ('div'))
|
|
80
|
+
) {
|
|
81
|
+
throw Object.assign(
|
|
82
|
+
new Error('HR005: Server markup for <ui-editor-surface> has an incompatible root.'),
|
|
83
|
+
{
|
|
84
|
+
name: 'HtmlDiagnosticError',
|
|
85
|
+
diagnostic: Object.freeze({
|
|
86
|
+
code: 'HR005',
|
|
87
|
+
message: 'Server markup for <ui-editor-surface> has an incompatible root.',
|
|
88
|
+
}),
|
|
89
|
+
},
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** The values the styles' :host-state() rules test. */
|
|
94
|
+
const hostState = computed(() =>
|
|
95
|
+
[
|
|
96
|
+
checkedProps.value.density && 'density',
|
|
97
|
+
checkedProps.value.density != null
|
|
98
|
+
&& `density=${encodeURIComponent(checkedProps.value.density)}`,
|
|
99
|
+
].filter(Boolean).join(' ')
|
|
100
|
+
)
|
|
101
|
+
</script>
|
|
102
|
+
|
|
103
|
+
<template>
|
|
104
|
+
<div
|
|
105
|
+
data-component="ui-editor-surface"
|
|
106
|
+
v-bind="nativeAttrs($attrs)"
|
|
107
|
+
v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
|
|
108
|
+
:data-density="reflectedProp('density', 'density', checkedProps.density, undefined, false)"
|
|
109
|
+
:data-ui-editor-surface-state="hostState || undefined"
|
|
110
|
+
>
|
|
111
|
+
<slot />
|
|
112
|
+
</div>
|
|
113
|
+
</template>
|
|
114
|
+
|
|
115
|
+
<style scoped>
|
|
116
|
+
[data-component~="ui-editor-surface"] {
|
|
117
|
+
display: flex;
|
|
118
|
+
flex-direction: column;
|
|
119
|
+
min-inline-size: 0;
|
|
120
|
+
max-inline-size: 100%;
|
|
121
|
+
}
|
|
122
|
+
/* The document renderer consumes these inherited surface settings. They do not style controls. */
|
|
123
|
+
[data-component~="ui-editor-surface"][data-ui-editor-surface-state~="density=compact"] {
|
|
124
|
+
--_ui-editor-content-min-height: 0px;
|
|
125
|
+
--_ui-editor-content-padding-block: 0px;
|
|
126
|
+
--_ui-editor-content-padding-inline: 0px;
|
|
127
|
+
--_ui-editor-mobile-bottom-space: 0px;
|
|
128
|
+
}
|
|
129
|
+
</style>
|
package/vue/UiScrollArea.d.ts
CHANGED
|
@@ -4,6 +4,10 @@ type __VLS_Slots = {} & {
|
|
|
4
4
|
default?: (props: typeof __VLS_1) => any;
|
|
5
5
|
};
|
|
6
6
|
declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
7
|
+
fill: {
|
|
8
|
+
type: PropType<boolean | null>;
|
|
9
|
+
default: boolean;
|
|
10
|
+
};
|
|
7
11
|
orientation: {
|
|
8
12
|
type: PropType<"vertical" | "horizontal" | null>;
|
|
9
13
|
default: string;
|
|
@@ -13,6 +17,10 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
13
17
|
default: string;
|
|
14
18
|
};
|
|
15
19
|
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
20
|
+
fill: {
|
|
21
|
+
type: PropType<boolean | null>;
|
|
22
|
+
default: boolean;
|
|
23
|
+
};
|
|
16
24
|
orientation: {
|
|
17
25
|
type: PropType<"vertical" | "horizontal" | null>;
|
|
18
26
|
default: string;
|
|
@@ -22,6 +30,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
22
30
|
default: string;
|
|
23
31
|
};
|
|
24
32
|
}>> & Readonly<{}>, {
|
|
33
|
+
fill: boolean | null;
|
|
25
34
|
size: "sm" | "md" | "content" | "lg" | null;
|
|
26
35
|
orientation: "vertical" | "horizontal" | null;
|
|
27
36
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
package/vue/UiScrollArea.vue
CHANGED
|
@@ -9,6 +9,14 @@ defineOptions({ inheritAttrs: false })
|
|
|
9
9
|
|
|
10
10
|
const propValidityContract = {
|
|
11
11
|
props: {
|
|
12
|
+
fill: {
|
|
13
|
+
type: { kind: 'terminal', name: 'boolean' },
|
|
14
|
+
required: false,
|
|
15
|
+
target: { attribute: 'fill' },
|
|
16
|
+
description:
|
|
17
|
+
'Grows into remaining space within a flex layout while keeping content independently scrollable.',
|
|
18
|
+
default: false,
|
|
19
|
+
},
|
|
12
20
|
orientation: {
|
|
13
21
|
type: { kind: 'terminal', name: 'keyword' },
|
|
14
22
|
required: false,
|
|
@@ -30,6 +38,7 @@ const propValidityContract = {
|
|
|
30
38
|
},
|
|
31
39
|
} as const
|
|
32
40
|
const props = defineProps({
|
|
41
|
+
fill: { type: null as unknown as PropType<boolean | null>, default: false },
|
|
33
42
|
orientation: {
|
|
34
43
|
type: null as unknown as PropType<'vertical' | 'horizontal' | null>,
|
|
35
44
|
default: 'vertical',
|
|
@@ -39,8 +48,19 @@ const props = defineProps({
|
|
|
39
48
|
default: 'content',
|
|
40
49
|
},
|
|
41
50
|
})
|
|
42
|
-
const acceptedProps: Record<string, unknown> = {
|
|
51
|
+
const acceptedProps: Record<string, unknown> = {
|
|
52
|
+
fill: false,
|
|
53
|
+
orientation: 'vertical',
|
|
54
|
+
size: 'content',
|
|
55
|
+
}
|
|
43
56
|
const checkedProps = computed(() => ({
|
|
57
|
+
fill: checkedProp<boolean>(
|
|
58
|
+
props['fill'],
|
|
59
|
+
{ kind: 'terminal', name: 'boolean' },
|
|
60
|
+
false,
|
|
61
|
+
'fill',
|
|
62
|
+
acceptedProps,
|
|
63
|
+
) as boolean,
|
|
44
64
|
orientation: checkedProp<'vertical' | 'horizontal'>(
|
|
45
65
|
props['orientation'],
|
|
46
66
|
{ kind: 'terminal', name: 'keyword' },
|
|
@@ -116,6 +136,7 @@ if (
|
|
|
116
136
|
/** The values the styles' :host-state() rules test. */
|
|
117
137
|
const hostState = computed(() =>
|
|
118
138
|
[
|
|
139
|
+
checkedProps.value.fill && 'fill',
|
|
119
140
|
checkedProps.value.orientation && 'orientation',
|
|
120
141
|
checkedProps.value.orientation != null
|
|
121
142
|
&& `orientation=${encodeURIComponent(checkedProps.value.orientation)}`,
|
|
@@ -141,7 +162,7 @@ useComponentHost(() => import('../components/ui-scroll-area/ui-scroll-area.js'),
|
|
|
141
162
|
? (incoming[name] ?? incoming[kebab] ?? null)
|
|
142
163
|
: null
|
|
143
164
|
},
|
|
144
|
-
propNames: ['orientation', 'size'],
|
|
165
|
+
propNames: ['fill', 'orientation', 'size'],
|
|
145
166
|
propValidity: (name: string) =>
|
|
146
167
|
propValidityState({ contract: propValidityContract, values: { ...props } }, name),
|
|
147
168
|
refs: { content: contentElement },
|
|
@@ -153,6 +174,7 @@ useComponentHost(() => import('../components/ui-scroll-area/ui-scroll-area.js'),
|
|
|
153
174
|
data-component="ui-scroll-area"
|
|
154
175
|
v-bind="nativeAttrs($attrs)"
|
|
155
176
|
v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
|
|
177
|
+
:data-fill="reflectedProp('fill', 'fill', checkedProps.fill, undefined, false)"
|
|
156
178
|
:data-orientation="reflectedProp('orientation', 'orientation', checkedProps.orientation, undefined, false)"
|
|
157
179
|
:data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
|
|
158
180
|
:data-ui-scroll-area-state="hostState || undefined"
|
|
@@ -166,6 +188,10 @@ useComponentHost(() => import('../components/ui-scroll-area/ui-scroll-area.js'),
|
|
|
166
188
|
/* The controller sets each fade length from overflow and scroll position. The mask blends
|
|
167
189
|
into whatever is behind the area without needing to know its colour. Before upgrade, its
|
|
168
190
|
zero-length defaults leave the authored scroll area fully visible. */
|
|
191
|
+
[data-component~="ui-scroll-area"][data-ui-scroll-area-state~="fill"] {
|
|
192
|
+
flex: 1;
|
|
193
|
+
}
|
|
194
|
+
|
|
169
195
|
[data-component~="ui-scroll-area"] {
|
|
170
196
|
display: block;
|
|
171
197
|
box-sizing: border-box;
|
package/vue/UiStack.d.ts
CHANGED
|
@@ -8,10 +8,18 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
8
8
|
type: PropType<"start" | "center" | "end" | "stretch" | null>;
|
|
9
9
|
default: null;
|
|
10
10
|
};
|
|
11
|
+
fill: {
|
|
12
|
+
type: PropType<boolean | null>;
|
|
13
|
+
default: boolean;
|
|
14
|
+
};
|
|
11
15
|
gap: {
|
|
12
16
|
type: PropType<"none" | "xs" | "s" | "m" | "l" | "xl" | null>;
|
|
13
17
|
default: null;
|
|
14
18
|
};
|
|
19
|
+
height: {
|
|
20
|
+
type: PropType<number | null>;
|
|
21
|
+
default: null;
|
|
22
|
+
};
|
|
15
23
|
justify: {
|
|
16
24
|
type: PropType<"start" | "center" | "end" | "between" | null>;
|
|
17
25
|
default: null;
|
|
@@ -21,15 +29,25 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
21
29
|
type: PropType<"start" | "center" | "end" | "stretch" | null>;
|
|
22
30
|
default: null;
|
|
23
31
|
};
|
|
32
|
+
fill: {
|
|
33
|
+
type: PropType<boolean | null>;
|
|
34
|
+
default: boolean;
|
|
35
|
+
};
|
|
24
36
|
gap: {
|
|
25
37
|
type: PropType<"none" | "xs" | "s" | "m" | "l" | "xl" | null>;
|
|
26
38
|
default: null;
|
|
27
39
|
};
|
|
40
|
+
height: {
|
|
41
|
+
type: PropType<number | null>;
|
|
42
|
+
default: null;
|
|
43
|
+
};
|
|
28
44
|
justify: {
|
|
29
45
|
type: PropType<"start" | "center" | "end" | "between" | null>;
|
|
30
46
|
default: null;
|
|
31
47
|
};
|
|
32
48
|
}>> & Readonly<{}>, {
|
|
49
|
+
fill: boolean | null;
|
|
50
|
+
height: number | null;
|
|
33
51
|
align: "center" | "start" | "stretch" | "end" | null;
|
|
34
52
|
gap: "s" | "none" | "xs" | "m" | "l" | "xl" | null;
|
|
35
53
|
justify: "center" | "start" | "end" | "between" | null;
|
package/vue/UiStack.vue
CHANGED
|
@@ -16,6 +16,14 @@ const propValidityContract = {
|
|
|
16
16
|
'How items sit across the stack: stretch (the default) makes each fill the stack\'s width; start, center, and end keep each at its own width, against the\n start, in the middle, or against the end.',
|
|
17
17
|
values: ['start', 'center', 'end', 'stretch'],
|
|
18
18
|
},
|
|
19
|
+
fill: {
|
|
20
|
+
type: { kind: 'terminal', name: 'boolean' },
|
|
21
|
+
required: false,
|
|
22
|
+
target: { attribute: 'fill' },
|
|
23
|
+
description:
|
|
24
|
+
'Grows into the remaining space of a flex layout and allows its scrolling children to shrink.',
|
|
25
|
+
default: false,
|
|
26
|
+
},
|
|
19
27
|
gap: {
|
|
20
28
|
type: { kind: 'terminal', name: 'keyword' },
|
|
21
29
|
required: false,
|
|
@@ -24,6 +32,13 @@ const propValidityContract = {
|
|
|
24
32
|
'Space between items, on the spacing scale: none is zero, xs is 0.5rem, s 0.75rem, m 1rem (also the default), l 1.5rem, and xl 2rem. The --ui-stack-gap\n custom property, set on the stack itself, overrides it; set on an ancestor, it does nothing.',
|
|
25
33
|
values: ['none', 'xs', 's', 'm', 'l', 'xl'],
|
|
26
34
|
},
|
|
35
|
+
height: {
|
|
36
|
+
type: { kind: 'terminal', name: 'number' },
|
|
37
|
+
required: false,
|
|
38
|
+
target: { attribute: 'height' },
|
|
39
|
+
description:
|
|
40
|
+
'An optional measured height in CSS pixels, for a viewport-bounded composition. Omit it to retain intrinsic sizing.',
|
|
41
|
+
},
|
|
27
42
|
justify: {
|
|
28
43
|
type: { kind: 'terminal', name: 'keyword' },
|
|
29
44
|
required: false,
|
|
@@ -39,16 +54,24 @@ const props = defineProps({
|
|
|
39
54
|
type: null as unknown as PropType<'start' | 'center' | 'end' | 'stretch' | null>,
|
|
40
55
|
default: null,
|
|
41
56
|
},
|
|
57
|
+
fill: { type: null as unknown as PropType<boolean | null>, default: false },
|
|
42
58
|
gap: {
|
|
43
59
|
type: null as unknown as PropType<'none' | 'xs' | 's' | 'm' | 'l' | 'xl' | null>,
|
|
44
60
|
default: null,
|
|
45
61
|
},
|
|
62
|
+
height: { type: null as unknown as PropType<number | null>, default: null },
|
|
46
63
|
justify: {
|
|
47
64
|
type: null as unknown as PropType<'start' | 'center' | 'end' | 'between' | null>,
|
|
48
65
|
default: null,
|
|
49
66
|
},
|
|
50
67
|
})
|
|
51
|
-
const acceptedProps: Record<string, unknown> = {
|
|
68
|
+
const acceptedProps: Record<string, unknown> = {
|
|
69
|
+
align: null,
|
|
70
|
+
fill: false,
|
|
71
|
+
gap: null,
|
|
72
|
+
height: null,
|
|
73
|
+
justify: null,
|
|
74
|
+
}
|
|
52
75
|
const checkedProps = computed(() => ({
|
|
53
76
|
align: checkedProp<'start' | 'center' | 'end' | 'stretch'>(
|
|
54
77
|
props['align'],
|
|
@@ -57,6 +80,13 @@ const checkedProps = computed(() => ({
|
|
|
57
80
|
'align',
|
|
58
81
|
acceptedProps,
|
|
59
82
|
),
|
|
83
|
+
fill: checkedProp<boolean>(
|
|
84
|
+
props['fill'],
|
|
85
|
+
{ kind: 'terminal', name: 'boolean' },
|
|
86
|
+
false,
|
|
87
|
+
'fill',
|
|
88
|
+
acceptedProps,
|
|
89
|
+
) as boolean,
|
|
60
90
|
gap: checkedProp<'none' | 'xs' | 's' | 'm' | 'l' | 'xl'>(
|
|
61
91
|
props['gap'],
|
|
62
92
|
{ kind: 'terminal', name: 'keyword' },
|
|
@@ -64,6 +94,13 @@ const checkedProps = computed(() => ({
|
|
|
64
94
|
'gap',
|
|
65
95
|
acceptedProps,
|
|
66
96
|
),
|
|
97
|
+
height: checkedProp<number>(
|
|
98
|
+
props['height'],
|
|
99
|
+
{ kind: 'terminal', name: 'number' },
|
|
100
|
+
false,
|
|
101
|
+
'height',
|
|
102
|
+
acceptedProps,
|
|
103
|
+
),
|
|
67
104
|
justify: checkedProp<'start' | 'center' | 'end' | 'between'>(
|
|
68
105
|
props['justify'],
|
|
69
106
|
{ kind: 'terminal', name: 'keyword' },
|
|
@@ -127,6 +164,9 @@ if (
|
|
|
127
164
|
/** The values the styles' :host-state() rules test. */
|
|
128
165
|
const hostState = computed(() =>
|
|
129
166
|
[
|
|
167
|
+
checkedProps.value.fill && 'fill',
|
|
168
|
+
checkedProps.value.height && 'height',
|
|
169
|
+
checkedProps.value.height != null && `height=${checkedProps.value.height}`,
|
|
130
170
|
checkedProps.value.gap && 'gap',
|
|
131
171
|
checkedProps.value.gap != null && `gap=${encodeURIComponent(checkedProps.value.gap)}`,
|
|
132
172
|
checkedProps.value.align && 'align',
|
|
@@ -142,9 +182,12 @@ const hostState = computed(() =>
|
|
|
142
182
|
<div
|
|
143
183
|
data-component="ui-stack"
|
|
144
184
|
v-bind="nativeAttrs($attrs)"
|
|
185
|
+
:style="{ '--ui-stack-height': checkedProps.height ?? undefined }"
|
|
145
186
|
v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
|
|
146
187
|
:data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
|
|
188
|
+
:data-fill="reflectedProp('fill', 'fill', checkedProps.fill, undefined, false)"
|
|
147
189
|
:data-gap="reflectedProp('gap', 'gap', checkedProps.gap, undefined, false)"
|
|
190
|
+
:data-height="reflectedProp('height', 'height', checkedProps.height, undefined, false)"
|
|
148
191
|
:data-justify="reflectedProp('justify', 'justify', checkedProps.justify, undefined, false)"
|
|
149
192
|
:data-ui-stack-state="hostState || undefined"
|
|
150
193
|
>
|
|
@@ -154,6 +197,11 @@ const hostState = computed(() =>
|
|
|
154
197
|
|
|
155
198
|
<style scoped>
|
|
156
199
|
/* This component's hooks style the element they are set on, and never a nested one. */
|
|
200
|
+
@property --ui-stack-height {
|
|
201
|
+
syntax: "*";
|
|
202
|
+
inherits: false;
|
|
203
|
+
}
|
|
204
|
+
|
|
157
205
|
@property --ui-stack-gap {
|
|
158
206
|
syntax: "*";
|
|
159
207
|
inherits: false;
|
|
@@ -170,6 +218,15 @@ const hostState = computed(() =>
|
|
|
170
218
|
margin: 0;
|
|
171
219
|
}
|
|
172
220
|
|
|
221
|
+
[data-component~="ui-stack"][data-ui-stack-state~="fill"] {
|
|
222
|
+
flex: 1;
|
|
223
|
+
min-block-size: 0;
|
|
224
|
+
}
|
|
225
|
+
[data-component~="ui-stack"][data-ui-stack-state~="height"] {
|
|
226
|
+
block-size: calc(var(--ui-stack-height, 0) * 1px);
|
|
227
|
+
min-block-size: 0;
|
|
228
|
+
}
|
|
229
|
+
|
|
173
230
|
[data-component~="ui-stack"][data-ui-stack-state~="gap=none"] {
|
|
174
231
|
--_layout-gap: 0px;
|
|
175
232
|
}
|