@threadlabs/looma 0.25.3 → 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.
Files changed (69) hide show
  1. package/components/ui-badge/ui-badge.html +59 -3
  2. package/components/ui-button/ui-button.html +1 -1
  3. package/components/ui-card/ui-card.html +27 -2
  4. package/components/ui-cluster/ui-cluster.html +30 -0
  5. package/components/ui-editor-surface/ui-editor-surface.html +23 -0
  6. package/components/ui-scroll-area/ui-scroll-area.html +5 -0
  7. package/components/ui-stack/ui-stack.html +17 -1
  8. package/components/ui-text/ui-text.html +5 -0
  9. package/components/ui-textarea/ui-textarea.html +7 -0
  10. package/dist/index.js +1 -1
  11. package/package.json +1 -1
  12. package/styles/ui-badge.css +61 -4
  13. package/styles/ui-button.css +1 -1
  14. package/styles/ui-card.css +24 -0
  15. package/styles/ui-cluster.css +25 -0
  16. package/styles/ui-editor-surface.css +19 -0
  17. package/styles/ui-scroll-area.css +4 -0
  18. package/styles/ui-stack.css +13 -0
  19. package/styles/ui-text.css +4 -0
  20. package/styles/ui-textarea.css +4 -0
  21. package/vanilla/UiBadge.js +16 -3
  22. package/vanilla/UiCard.d.ts +1 -1
  23. package/vanilla/UiCard.js +1 -1
  24. package/vanilla/UiCluster.d.ts +3 -0
  25. package/vanilla/UiCluster.js +9 -3
  26. package/vanilla/UiEditorSurface.d.ts +14 -0
  27. package/vanilla/UiEditorSurface.js +27 -0
  28. package/vanilla/UiScrollArea.d.ts +1 -0
  29. package/vanilla/UiScrollArea.js +1 -1
  30. package/vanilla/UiStack.d.ts +2 -0
  31. package/vanilla/UiStack.js +8 -9
  32. package/vanilla/UiText.d.ts +1 -0
  33. package/vanilla/UiText.js +1 -1
  34. package/vanilla/UiTextarea.d.ts +1 -0
  35. package/vanilla/UiTextarea.js +4 -1
  36. package/vanilla/index.js +1 -0
  37. package/vue/UiBadge.d.ts +4 -2
  38. package/vue/UiBadge.vue +57 -3
  39. package/vue/UiButton.vue +1 -1
  40. package/vue/UiCard.d.ts +3 -3
  41. package/vue/UiCard.vue +34 -5
  42. package/vue/UiCluster.d.ts +27 -0
  43. package/vue/UiCluster.vue +95 -1
  44. package/vue/UiEditorSlashMenuItem.d.ts +1 -1
  45. package/vue/UiEditorSurface.d.ts +26 -0
  46. package/vue/UiEditorSurface.js +2 -0
  47. package/vue/UiEditorSurface.vue +129 -0
  48. package/vue/UiScrollArea.d.ts +9 -0
  49. package/vue/UiScrollArea.vue +28 -2
  50. package/vue/UiStack.d.ts +18 -0
  51. package/vue/UiStack.vue +58 -1
  52. package/vue/UiText.d.ts +9 -0
  53. package/vue/UiText.vue +33 -0
  54. package/vue/UiTextarea.d.ts +9 -0
  55. package/vue/UiTextarea.vue +37 -2
  56. package/vue/chunks/UiBadge.js +7 -3
  57. package/vue/chunks/UiButton.js +1 -1
  58. package/vue/chunks/UiCard.js +10 -3
  59. package/vue/chunks/UiCluster.js +82 -1
  60. package/vue/chunks/UiEditorSurface.js +71 -0
  61. package/vue/chunks/UiScrollArea.js +28 -2
  62. package/vue/chunks/UiStack.js +46 -1
  63. package/vue/chunks/UiText.js +43 -1
  64. package/vue/chunks/UiTextarea.js +28 -2
  65. package/vue/components.css +321 -190
  66. package/vue/editor/LoomaEditor.d.ts +12 -0
  67. package/vue/editor/index.js +7 -2
  68. package/vue/index.d.ts +1 -0
  69. package/vue/index.js +2 -1
package/vanilla/index.js CHANGED
@@ -25,6 +25,7 @@ export * from "./UiEditorMentionMenuItem.js";
25
25
  export * from "./UiEditorSlashMenu.js";
26
26
  export * from "./UiEditorSlashMenuGroup.js";
27
27
  export * from "./UiEditorSlashMenuItem.js";
28
+ export * from "./UiEditorSurface.js";
28
29
  export * from "./UiEditorTableContextMenu.js";
29
30
  export * from "./UiEditorTableOverlay.js";
30
31
  export * from "./UiEditorTableToolbar.js";
package/vue/UiBadge.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import type { PropType } from 'vue';
2
- declare var __VLS_1: {};
2
+ declare var __VLS_1: {}, __VLS_3: {};
3
3
  type __VLS_Slots = {} & {
4
- default?: (props: typeof __VLS_1) => any;
4
+ icon?: (props: typeof __VLS_1) => any;
5
+ } & {
6
+ default?: (props: typeof __VLS_3) => any;
5
7
  };
6
8
  declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
7
9
  shape: {
package/vue/UiBadge.vue CHANGED
@@ -177,7 +177,8 @@ const hostState = computed(() =>
177
177
  :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
178
178
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
179
179
  :data-ui-badge-state="hostState || undefined"
180
- ><span class="label"><slot /></span></span>
180
+ ><span class="icon" aria-hidden="true"><slot name="icon" /></span>
181
+ <span class="label"><slot /></span></span>
181
182
  </template>
182
183
 
183
184
  <style scoped>
@@ -261,6 +262,7 @@ const hostState = computed(() =>
261
262
  display: inline-flex;
262
263
  align-items: center;
263
264
  justify-content: center;
265
+ gap: var(--ui-space-1);
264
266
  box-sizing: border-box;
265
267
  min-inline-size: 0;
266
268
  max-inline-size: 100%;
@@ -287,8 +289,43 @@ const hostState = computed(() =>
287
289
  text-overflow: ellipsis;
288
290
  }
289
291
 
290
- /* Trim leading while retaining the font's ascent and descent. A cap-to-baseline box
291
- would crop glyphs where the label clips horizontal overflow for ellipsis. */
292
+ .label:empty {
293
+ display: none;
294
+ }
295
+
296
+ /* Icon content has its own flex item so label ellipsis never clips its strokes. */
297
+ .icon {
298
+ display: inline-flex;
299
+ align-items: center;
300
+ justify-content: center;
301
+ flex: none;
302
+ }
303
+
304
+ .icon:empty {
305
+ display: none;
306
+ }
307
+
308
+ .icon :slotted(svg) {
309
+ display: block;
310
+ inline-size: 1em;
311
+ block-size: 1em;
312
+ flex: none;
313
+ }
314
+
315
+ /* Ordinary icon-plus-text children keep inline ellipsis, with explicit glyph spacing. */
316
+ .label :slotted(svg) {
317
+ inline-size: 1em;
318
+ block-size: 1em;
319
+ vertical-align: middle;
320
+ margin-inline-end: var(--ui-space-1);
321
+ }
322
+
323
+ .label:has(svg) {
324
+ text-box-trim: none;
325
+ }
326
+
327
+ /* Text-only badges retain their trimmed inline baseline. Icon content needs a flex row;
328
+ trimming its label separately keeps the glyph centered without changing adjacent lines. */
292
329
  @supports (text-box-trim: trim-both) {
293
330
  [data-component~="ui-badge"] {
294
331
  display: inline-block;
@@ -298,6 +335,15 @@ const hostState = computed(() =>
298
335
  text-box-trim: trim-both;
299
336
  text-box-edge: text;
300
337
  }
338
+ [data-component~="ui-badge"]:has(.icon:not(:empty)),
339
+ [data-component~="ui-badge"]:has(.label svg) {
340
+ display: inline-flex;
341
+ text-box-trim: none;
342
+ }
343
+ [data-component~="ui-badge"]:has(.icon:not(:empty)) .label {
344
+ text-box-trim: trim-both;
345
+ text-box-edge: text;
346
+ }
301
347
  }
302
348
 
303
349
  [data-component~="ui-badge"][data-ui-badge-state~="size=xs"] {
@@ -436,6 +482,14 @@ const hostState = computed(() =>
436
482
  justify-content: center;
437
483
  }
438
484
 
485
+ [data-component~="ui-badge"][data-ui-badge-state~="shape=square"] .label :slotted(svg) {
486
+ margin-inline-end: 0;
487
+ }
488
+
489
+ [data-component~="ui-badge"][data-ui-badge-state~="shape=square"] .label:empty {
490
+ display: none;
491
+ }
492
+
439
493
  /* A dot uses the badge's tone recipe; only its silhouette and visible label change. */
440
494
  [data-component~="ui-badge"][data-ui-badge-state~="shape=dot"] {
441
495
  position: relative;
package/vue/UiButton.vue CHANGED
@@ -933,6 +933,7 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
933
933
  display: inline-flex;
934
934
  align-items: center;
935
935
  justify-content: center;
936
+ column-gap: var(--ui-space-2);
936
937
  vertical-align: middle;
937
938
  color: var(--_tone-text);
938
939
  }
@@ -982,7 +983,6 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
982
983
  .spinner-wrap {
983
984
  display: inline-flex;
984
985
  flex: none;
985
- margin-inline-end: var(--ui-space-2);
986
986
  vertical-align: middle;
987
987
  }
988
988
 
package/vue/UiCard.d.ts CHANGED
@@ -23,7 +23,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
23
23
  default: string;
24
24
  };
25
25
  tone: {
26
- type: PropType<"neutral" | "danger" | null>;
26
+ type: PropType<"neutral" | "accent" | "info" | "success" | "warning" | "danger" | null>;
27
27
  default: string;
28
28
  };
29
29
  variant: {
@@ -44,7 +44,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
44
44
  default: string;
45
45
  };
46
46
  tone: {
47
- type: PropType<"neutral" | "danger" | null>;
47
+ type: PropType<"neutral" | "accent" | "info" | "success" | "warning" | "danger" | null>;
48
48
  default: string;
49
49
  };
50
50
  variant: {
@@ -53,7 +53,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
53
53
  };
54
54
  }>> & Readonly<{}>, {
55
55
  size: "sm" | "md" | "content" | "lg" | null;
56
- tone: "neutral" | "danger" | null;
56
+ tone: "info" | "neutral" | "accent" | "success" | "warning" | "danger" | null;
57
57
  variant: "subtle" | "outlined" | "elevated" | null;
58
58
  as: "div" | "article" | "aside" | "section" | null;
59
59
  padding: "xs" | "sm" | "md" | "lg" | null;
package/vue/UiCard.vue CHANGED
@@ -41,8 +41,8 @@ const propValidityContract = {
41
41
  required: false,
42
42
  target: { attribute: 'tone' },
43
43
  description:
44
- 'danger adds a soft danger surface and a strong leading edge for consequential content.',
45
- values: ['neutral', 'danger'],
44
+ 'accent, info, success and warning add a quiet semantic surface. danger retains its strong leading edge for consequential content. Tone never changes child\n controls.',
45
+ values: ['neutral', 'accent', 'info', 'success', 'warning', 'danger'],
46
46
  default: 'neutral',
47
47
  },
48
48
  variant: {
@@ -66,7 +66,12 @@ const props = defineProps({
66
66
  type: null as unknown as PropType<'content' | 'sm' | 'md' | 'lg' | null>,
67
67
  default: 'content',
68
68
  },
69
- tone: { type: null as unknown as PropType<'neutral' | 'danger' | null>, default: 'neutral' },
69
+ tone: {
70
+ type: null as unknown as PropType<
71
+ 'neutral' | 'accent' | 'info' | 'success' | 'warning' | 'danger' | null
72
+ >,
73
+ default: 'neutral',
74
+ },
70
75
  variant: {
71
76
  type: null as unknown as PropType<'outlined' | 'subtle' | 'elevated' | null>,
72
77
  default: 'outlined',
@@ -101,13 +106,13 @@ const checkedProps = computed(() => ({
101
106
  'size',
102
107
  acceptedProps,
103
108
  ) as 'content' | 'sm' | 'md' | 'lg',
104
- tone: checkedProp<'neutral' | 'danger'>(
109
+ tone: checkedProp<'neutral' | 'accent' | 'info' | 'success' | 'warning' | 'danger'>(
105
110
  props['tone'],
106
111
  { kind: 'terminal', name: 'keyword' },
107
112
  false,
108
113
  'tone',
109
114
  acceptedProps,
110
- ) as 'neutral' | 'danger',
115
+ ) as 'neutral' | 'accent' | 'info' | 'success' | 'warning' | 'danger',
111
116
  variant: checkedProp<'outlined' | 'subtle' | 'elevated'>(
112
117
  props['variant'],
113
118
  { kind: 'terminal', name: 'keyword' },
@@ -295,6 +300,30 @@ const hostState = computed(() =>
295
300
  box-shadow: var(--ui-shadow-lg);
296
301
  }
297
302
 
303
+ [data-component~="ui-card"][data-ui-card-state~="tone=accent"] {
304
+ border-color: color-mix(in srgb, var(--ui-accent) 25%, var(--ui-border-default));
305
+ background: color-mix(in srgb, var(--ui-accent) 6%, var(--ui-surface-default));
306
+ }
307
+
308
+ [data-component~="ui-card"][data-ui-card-state~="tone=info"] {
309
+ border-color: color-mix(in srgb, var(--ui-info) 25%, var(--ui-border-default));
310
+ background: color-mix(in srgb, var(--ui-info) 6%, var(--ui-surface-default));
311
+ }
312
+
313
+ [data-component~="ui-card"][data-ui-card-state~="tone=success"] {
314
+ border-color: color-mix(in srgb, var(--ui-success) 25%, var(--ui-border-default));
315
+ background: color-mix(in srgb, var(--ui-success) 6%, var(--ui-surface-default));
316
+ }
317
+
318
+ [data-component~="ui-card"][data-ui-card-state~="tone=warning"] {
319
+ border-color: color-mix(in srgb, var(--ui-warning) 25%, var(--ui-border-default));
320
+ background: color-mix(in srgb, var(--ui-warning) 6%, var(--ui-surface-default));
321
+ }
322
+
323
+ [data-component~="ui-card"][data-ui-card-state~="variant=subtle"]:is([data-ui-card-state~="tone=accent"], [data-ui-card-state~="tone=info"], [data-ui-card-state~="tone=success"], [data-ui-card-state~="tone=warning"]) {
324
+ border-color: transparent;
325
+ }
326
+
298
327
  [data-component~="ui-card"][data-ui-card-state~="tone=danger"] {
299
328
  border-color: color-mix(in srgb, var(--ui-danger) 45%, var(--ui-border-default));
300
329
  border-inline-start: var(--ui-accent-line-width) solid var(--ui-danger);
@@ -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> = { align: null, gap: null, justify: null, wrap: null }
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
  }
@@ -47,8 +47,8 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
47
47
  };
48
48
  }>> & Readonly<{}>, {
49
49
  value: string | null;
50
- disabled: boolean | null;
51
50
  icon: string | null;
51
+ disabled: boolean | null;
52
52
  description: string | null;
53
53
  keywords: string | null;
54
54
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -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,2 @@
1
+ import { t as UiEditorSurface_default } from "./chunks/UiEditorSurface.js";
2
+ export { UiEditorSurface_default as default };
@@ -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>
@@ -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>;