@threadlabs/looma 0.5.2 → 0.6.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/components/shared/overlay.js +3 -0
  2. package/components/ui-button/ui-button.html +14 -14
  3. package/components/ui-callout/ui-callout.html +1 -1
  4. package/components/ui-checkbox/ui-checkbox.html +1 -1
  5. package/components/ui-cluster/ui-cluster.html +6 -6
  6. package/components/ui-combobox/ui-combobox.html +23 -23
  7. package/components/ui-container/ui-container.html +4 -4
  8. package/components/ui-context-menu/ui-context-menu.html +2 -2
  9. package/components/ui-dialog/ui-dialog.html +12 -12
  10. package/components/ui-disclosure/ui-disclosure.html +19 -4
  11. package/components/ui-editable/ui-editable.html +6 -6
  12. package/components/ui-editor-insert-table-grid/ui-editor-insert-table-grid.html +20 -20
  13. package/components/ui-editor-mention-menu/ui-editor-mention-menu.html +25 -25
  14. package/components/ui-editor-slash-menu/ui-editor-slash-menu.html +39 -39
  15. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.html +20 -20
  16. package/components/ui-editor-table-overlay/ui-editor-table-overlay.html +48 -48
  17. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +34 -34
  18. package/components/ui-editor-toolbar/ui-editor-toolbar.html +9 -9
  19. package/components/ui-floating-action-button/ui-floating-action-button.html +16 -22
  20. package/components/ui-grid/ui-grid.html +6 -6
  21. package/components/ui-icon-button/ui-icon-button.html +42 -38
  22. package/components/ui-input/ui-input.html +2 -2
  23. package/components/ui-menu/ui-menu.html +15 -4
  24. package/components/ui-menu-item/ui-menu-item.html +5 -5
  25. package/components/ui-popover/ui-popover.html +3 -3
  26. package/components/ui-reel/ui-reel.html +6 -6
  27. package/components/ui-search-result-row/ui-search-result-row.html +9 -9
  28. package/components/ui-search-shell/ui-search-shell.html +3 -3
  29. package/components/ui-select/ui-select.html +2 -2
  30. package/components/ui-sidebar/ui-sidebar.html +11 -11
  31. package/components/ui-stack/ui-stack.html +6 -6
  32. package/components/ui-switcher/ui-switcher.html +6 -6
  33. package/components/ui-tabs/ui-tabs.html +18 -4
  34. package/components/ui-textarea/ui-textarea.html +2 -2
  35. package/components/ui-toast-region/ui-toast-region.html +2 -2
  36. package/components/ui-tooltip/ui-tooltip.html +1 -1
  37. package/components/ui-top-bar/ui-top-bar.html +5 -5
  38. package/components/ui-tree/ui-tree.html +7 -0
  39. package/components/ui-tree-item/ui-tree-item.html +15 -7
  40. package/dist/index.js +1 -1
  41. package/package.json +1 -1
  42. package/styles/ui-button.css +14 -14
  43. package/styles/ui-callout.css +1 -1
  44. package/styles/ui-checkbox.css +1 -1
  45. package/styles/ui-cluster.css +6 -6
  46. package/styles/ui-combobox.css +23 -23
  47. package/styles/ui-container.css +4 -4
  48. package/styles/ui-context-menu.css +2 -2
  49. package/styles/ui-dialog.css +12 -12
  50. package/styles/ui-disclosure.css +22 -6
  51. package/styles/ui-editable.css +6 -6
  52. package/styles/ui-editor-insert-table-grid.css +20 -20
  53. package/styles/ui-editor-mention-menu.css +25 -25
  54. package/styles/ui-editor-slash-menu.css +39 -39
  55. package/styles/ui-editor-table-context-menu.css +20 -20
  56. package/styles/ui-editor-table-overlay.css +48 -48
  57. package/styles/ui-editor-table-toolbar.css +34 -34
  58. package/styles/ui-editor-toolbar.css +9 -9
  59. package/styles/ui-floating-action-button.css +16 -22
  60. package/styles/ui-grid.css +6 -6
  61. package/styles/ui-icon-button.css +42 -38
  62. package/styles/ui-input.css +2 -2
  63. package/styles/ui-menu-item.css +5 -5
  64. package/styles/ui-menu.css +18 -6
  65. package/styles/ui-popover.css +3 -3
  66. package/styles/ui-reel.css +6 -6
  67. package/styles/ui-search-result-row.css +9 -9
  68. package/styles/ui-search-shell.css +3 -3
  69. package/styles/ui-select.css +2 -2
  70. package/styles/ui-sidebar.css +11 -11
  71. package/styles/ui-stack.css +6 -6
  72. package/styles/ui-switcher.css +6 -6
  73. package/styles/ui-tabs.css +20 -6
  74. package/styles/ui-textarea.css +2 -2
  75. package/styles/ui-toast-region.css +2 -2
  76. package/styles/ui-tooltip.css +1 -1
  77. package/styles/ui-top-bar.css +5 -5
  78. package/styles/ui-tree-item.css +21 -8
  79. package/styles/ui-tree.css +7 -1
  80. package/theme-dark.css +42 -103
  81. package/theme-high-contrast.css +18 -22
  82. package/theme-light.css +15 -41
  83. package/tokens.css +149 -201
  84. package/vanilla/UiDisclosure.d.ts +1 -0
  85. package/vanilla/UiDisclosure.js +1 -1
  86. package/vanilla/UiMenu.d.ts +1 -0
  87. package/vanilla/UiMenu.js +1 -1
  88. package/vanilla/UiTabs.d.ts +1 -0
  89. package/vanilla/UiTabs.js +1 -1
  90. package/vanilla/UiTree.d.ts +1 -0
  91. package/vanilla/UiTree.js +1 -1
  92. package/vue/UiButton.vue +20 -14
  93. package/vue/UiCallout.vue +1 -1
  94. package/vue/UiCheckbox.vue +1 -1
  95. package/vue/UiCluster.vue +6 -6
  96. package/vue/UiCombobox.vue +23 -23
  97. package/vue/UiContainer.vue +4 -4
  98. package/vue/UiContextMenu.vue +2 -2
  99. package/vue/UiDialog.vue +12 -12
  100. package/vue/UiDisclosure.d.ts +2 -0
  101. package/vue/UiDisclosure.vue +21 -4
  102. package/vue/UiEditable.vue +6 -6
  103. package/vue/UiEditorInsertTableGrid.vue +20 -20
  104. package/vue/UiEditorMentionMenu.vue +25 -25
  105. package/vue/UiEditorSlashMenu.vue +39 -39
  106. package/vue/UiEditorTableContextMenu.vue +20 -20
  107. package/vue/UiEditorTableOverlay.vue +48 -57
  108. package/vue/UiEditorTableToolbar.vue +34 -34
  109. package/vue/UiEditorToolbar.vue +9 -9
  110. package/vue/UiFloatingActionButton.vue +17 -22
  111. package/vue/UiGrid.vue +6 -6
  112. package/vue/UiIconButton.vue +46 -42
  113. package/vue/UiInput.vue +2 -2
  114. package/vue/UiMenu.d.ts +2 -0
  115. package/vue/UiMenu.vue +17 -7
  116. package/vue/UiMenuItem.vue +6 -5
  117. package/vue/UiPopover.vue +3 -3
  118. package/vue/UiReel.vue +6 -6
  119. package/vue/UiSearchResultRow.vue +10 -13
  120. package/vue/UiSearchShell.vue +3 -3
  121. package/vue/UiSelect.vue +2 -2
  122. package/vue/UiSidebar.vue +11 -16
  123. package/vue/UiStack.vue +6 -6
  124. package/vue/UiSwitcher.vue +6 -6
  125. package/vue/UiTabs.d.ts +2 -0
  126. package/vue/UiTabs.vue +21 -4
  127. package/vue/UiTextarea.vue +2 -2
  128. package/vue/UiToastRegion.vue +2 -2
  129. package/vue/UiTooltip.vue +1 -1
  130. package/vue/UiTopBar.vue +5 -5
  131. package/vue/UiTree.d.ts +2 -0
  132. package/vue/UiTree.vue +24 -1
  133. package/vue/UiTreeItem.vue +16 -8
  134. package/vue/chunks/UiButton.js +1 -1
  135. package/vue/chunks/UiCallout.js +1 -1
  136. package/vue/chunks/UiCheckbox.js +1 -1
  137. package/vue/chunks/UiCluster.js +1 -1
  138. package/vue/chunks/UiCombobox.js +1 -1
  139. package/vue/chunks/UiContainer.js +1 -1
  140. package/vue/chunks/UiContextMenu.js +1 -1
  141. package/vue/chunks/UiDialog.js +1 -1
  142. package/vue/chunks/UiDisclosure.js +3 -2
  143. package/vue/chunks/UiEditable.js +1 -1
  144. package/vue/chunks/UiEditorInsertTableGrid.js +1 -1
  145. package/vue/chunks/UiEditorMentionMenu.js +1 -1
  146. package/vue/chunks/UiEditorSlashMenu.js +1 -1
  147. package/vue/chunks/UiEditorTableContextMenu.js +1 -1
  148. package/vue/chunks/UiEditorTableOverlay.js +1 -1
  149. package/vue/chunks/UiEditorTableToolbar.js +1 -1
  150. package/vue/chunks/UiEditorToolbar.js +1 -1
  151. package/vue/chunks/UiFloatingActionButton.js +1 -1
  152. package/vue/chunks/UiGrid.js +1 -1
  153. package/vue/chunks/UiIconButton.js +1 -1
  154. package/vue/chunks/UiInput.js +1 -1
  155. package/vue/chunks/UiMenu.js +3 -2
  156. package/vue/chunks/UiMenuItem.js +1 -1
  157. package/vue/chunks/UiPopover.js +1 -1
  158. package/vue/chunks/UiReel.js +1 -1
  159. package/vue/chunks/UiSearchResultRow.js +1 -1
  160. package/vue/chunks/UiSearchShell.js +1 -1
  161. package/vue/chunks/UiSelect.js +1 -1
  162. package/vue/chunks/UiSidebar.js +1 -1
  163. package/vue/chunks/UiStack.js +1 -1
  164. package/vue/chunks/UiSwitcher.js +1 -1
  165. package/vue/chunks/UiTabs.js +7 -2
  166. package/vue/chunks/UiTextarea.js +1 -1
  167. package/vue/chunks/UiToastRegion.js +1 -1
  168. package/vue/chunks/UiTooltip.js +1 -1
  169. package/vue/chunks/UiTopBar.js +1 -1
  170. package/vue/chunks/UiTree.js +8 -2
  171. package/vue/chunks/UiTreeItem.js +1 -1
  172. package/vue/components.css +1082 -1048
  173. package/vue/editor/LoomaEditor.d.ts +11 -0
  174. package/vue/editor/index.js +9 -0
@@ -2,46 +2,42 @@
2
2
  @media (prefers-contrast: more) {
3
3
  :root:not([data-contrast]) {
4
4
  color-scheme: light;
5
- --ui-surface-canvas: #ffffff;
6
- --ui-surface-default: #ffffff;
7
- --ui-surface-muted: #f8f8f6;
8
- --ui-surface-subtle: #f0f0ec;
9
- --ui-surface-elevated: #ffffff;
10
- --ui-text-primary: #000000;
5
+ --ui-surface: #ffffff;
6
+ --ui-surface-raised: #ffffff;
7
+ --ui-surface-sunken: #f0f0ec;
8
+ --ui-text: #000000;
11
9
  --ui-text-secondary: #111111;
12
10
  --ui-text-muted: #222222;
13
- --ui-border-default: #000000;
11
+ --ui-border: #000000;
14
12
  --ui-border-strong: #000000;
13
+ --ui-control-border: #000000;
15
14
  --ui-focus-ring: #0000ff;
16
- --ui-accent-solid: #0000cc;
15
+ --ui-accent: #0000cc;
17
16
  --ui-accent-hover: #000080;
18
17
  --ui-accent-active: #000066;
19
- --ui-accent-soft: #e6e6ff;
20
- --ui-danger-solid: #8b0000;
18
+ --ui-accent-subtle: #e6e6ff;
19
+ --ui-danger: #8b0000;
21
20
  --ui-danger-hover: #5c0000;
22
- --ui-danger-soft: #fff0f0;
23
21
  }
24
22
  }
25
23
 
26
24
  [data-contrast="high"] {
27
25
  color-scheme: light;
28
- --ui-surface-canvas: #ffffff;
29
- --ui-surface-default: #ffffff;
30
- --ui-surface-muted: #f8f8f6;
31
- --ui-surface-subtle: #f0f0ec;
32
- --ui-surface-elevated: #ffffff;
33
- --ui-text-primary: #000000;
26
+ --ui-surface: #ffffff;
27
+ --ui-surface-raised: #ffffff;
28
+ --ui-surface-sunken: #f0f0ec;
29
+ --ui-text: #000000;
34
30
  --ui-text-secondary: #111111;
35
31
  --ui-text-muted: #222222;
36
- --ui-border-default: #000000;
32
+ --ui-border: #000000;
37
33
  --ui-border-strong: #000000;
34
+ --ui-control-border: #000000;
38
35
  --ui-focus-ring: #0000ff;
39
- --ui-accent-solid: #0000cc;
36
+ --ui-accent: #0000cc;
40
37
  --ui-accent-hover: #000080;
41
38
  --ui-accent-active: #000066;
42
- --ui-accent-soft: #e6e6ff;
43
- --ui-danger-solid: #8b0000;
39
+ --ui-accent-subtle: #e6e6ff;
40
+ --ui-danger: #8b0000;
44
41
  --ui-danger-hover: #5c0000;
45
- --ui-danger-soft: #fff0f0;
46
42
  }
47
43
  }
package/theme-light.css CHANGED
@@ -2,58 +2,32 @@
2
2
  :root:not([data-theme]),
3
3
  [data-theme="light"] {
4
4
  color-scheme: light;
5
- --ui-surface-canvas: #ffffff;
6
- --ui-surface-default: #ffffff;
7
- --ui-surface-muted: #f8f8f6;
8
- --ui-surface-subtle: #f0f0ec;
9
- --ui-surface-elevated: #ffffff;
5
+ --ui-surface: #ffffff;
6
+ --ui-surface-raised: #ffffff;
7
+ --ui-surface-sunken: #f0f0ec;
10
8
 
11
- --ui-text-primary: #1a1a1a;
9
+ --ui-text: #1a1a1a;
12
10
  --ui-text-secondary: #5c5c5c;
13
11
  --ui-text-muted: #9b9b9b;
14
- --ui-text-on-accent: #ffffff;
12
+ --ui-on-accent: #ffffff;
13
+ --ui-on-danger: #ffffff;
15
14
 
16
- --ui-border-subtle: #ecece8;
17
- --ui-border-default: #e4e4e0;
15
+ --ui-border: #e4e4e0;
18
16
  --ui-border-strong: #c8c8c4;
19
17
  --ui-focus-ring: #5b55d6;
20
-
21
- /* Form controls need a visible 3:1 boundary and 4.5:1 placeholder text;
22
- general dividers intentionally remain quieter. */
23
- --ui-control-surface: #ffffff;
24
- --ui-control-surface-disabled: #f0f0ec;
18
+ /* A control needs a visible 3:1 boundary; general dividers stay quieter. */
25
19
  --ui-control-border: #858580;
26
- --ui-control-border-hover: #5c5c58;
27
- --ui-control-placeholder: #62625e;
28
20
 
29
- --ui-accent-solid: #5b55d6;
21
+ --ui-accent: #5b55d6;
30
22
  --ui-accent-hover: #4b45bd;
31
23
  --ui-accent-active: #3e399e;
32
- --ui-accent-soft: #efeffc;
24
+ --ui-accent-subtle: #efeffc;
33
25
 
34
- --ui-danger-solid: #b4233f;
26
+ --ui-danger: #b4233f;
35
27
  --ui-danger-hover: #941d35;
36
- --ui-danger-soft: #fceef1;
37
- --ui-success-solid: #007a33;
38
- --ui-success-soft: #edf7f1;
39
- --ui-warning-solid: #cc8800;
40
- --ui-warning-soft: #fdf7e6;
41
- --ui-info-solid: #0066cc;
42
- --ui-info-soft: #e8f0fb;
43
- --ui-accent-strong-surface: #5b55d6;
44
- --ui-accent-on-strong: #ffffff;
45
- --ui-accent-subtle-text: #3e399e;
46
- --ui-danger-strong-surface: #b4233f;
47
- --ui-danger-on-strong: #ffffff;
48
- --ui-danger-subtle-text: #941d35;
49
- --ui-success-strong-surface: #007a33;
50
- --ui-success-on-strong: #ffffff;
51
- --ui-success-subtle-text: #006629;
52
- --ui-warning-strong-surface: #b45309;
53
- --ui-warning-on-strong: #ffffff;
54
- --ui-warning-subtle-text: #704800;
55
- --ui-info-strong-surface: #0066cc;
56
- --ui-info-on-strong: #ffffff;
57
- --ui-info-subtle-text: #0058b0;
28
+ --ui-success: #007a33;
29
+ /* Deep amber, so a solid warning surface carries white text like the other tones (5:1). */
30
+ --ui-warning: #b45309;
31
+ --ui-info: #0066cc;
58
32
  }
59
33
  }
package/tokens.css CHANGED
@@ -1,6 +1,39 @@
1
1
  @layer tokens {
2
+ /* The theme contract.
3
+ These are the values a product sets to theme Looma. Everything else in this file is derived
4
+ from them, so a theme that sets only these still looks coherent. A component reads a derived
5
+ value or its own `--ui-<component>-*` token; it never needs the product to set either. */
2
6
  :root {
3
- --ui-font-stack-system:
7
+ /* Colour: intent and neutrals. */
8
+ --ui-accent: #5b55d6;
9
+ --ui-accent-hover: #4b45bd;
10
+ --ui-accent-active: #3e399e;
11
+ --ui-accent-subtle: #efeffc;
12
+ --ui-on-accent: #ffffff;
13
+ --ui-danger: #b4233f;
14
+ --ui-danger-hover: #941d35;
15
+ --ui-on-danger: #ffffff;
16
+ --ui-success: #007a33;
17
+ --ui-warning: #b45309;
18
+ --ui-info: #0066cc;
19
+ --ui-surface: #ffffff;
20
+ --ui-surface-raised: #ffffff;
21
+ --ui-surface-sunken: #f0f0ec;
22
+ /* The middle neutral step. It defaults to a mix of the two either side, but a palette with its
23
+ own value for it sets this rather than accepting the mix. */
24
+ --ui-surface-muted: color-mix(in srgb, var(--ui-surface-sunken) 50%, var(--ui-surface));
25
+ --ui-text: #1a1a1a;
26
+ --ui-text-secondary: #5c5c5c;
27
+ --ui-text-muted: #9b9b9b;
28
+ --ui-border: #e4e4e0;
29
+ --ui-border-strong: #c8c8c4;
30
+
31
+ /* Focus. */
32
+ --ui-focus-ring: #5b55d6;
33
+ --ui-focus-halo: 0 0 0 3px color-mix(in srgb, var(--ui-focus-ring) 40%, transparent);
34
+
35
+ /* Type. */
36
+ --ui-font-sans:
4
37
  system-ui,
5
38
  -apple-system,
6
39
  BlinkMacSystemFont,
@@ -11,246 +44,161 @@
11
44
  sans-serif,
12
45
  "Apple Color Emoji",
13
46
  "Segoe UI Emoji";
14
- --ui-font-stack-neo-grotesque:
15
- Inter,
16
- Roboto,
17
- "Helvetica Neue",
18
- "Arial Nova",
19
- "Nimbus Sans",
20
- Arial,
21
- sans-serif;
22
- --ui-font-stack-humanist:
23
- Seravek,
24
- "Gill Sans Nova",
25
- Ubuntu,
26
- Calibri,
27
- "DejaVu Sans",
28
- source-sans-pro,
29
- sans-serif;
30
- --ui-font-stack-rounded:
31
- ui-rounded,
32
- "Hiragino Maru Gothic ProN",
33
- Quicksand,
34
- Comfortaa,
35
- Manjari,
36
- "Arial Rounded MT",
37
- "Arial Rounded MT Bold",
38
- Calibri,
39
- source-sans-pro,
40
- sans-serif;
41
- --ui-font-family-sans: var(--ui-font-stack-system);
42
- /* Quiet metadata scale for compact, non-interactive component labels. */
43
- --ui-font-size-2xs: 0.6875rem;
44
- --ui-font-size-xs: 0.75rem;
47
+ --ui-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
48
+ --ui-font-size: 1rem;
45
49
  --ui-font-size-sm: 0.875rem;
46
- /* Dense interactive text: legible at 15px without body-copy spacing. */
47
- --ui-font-size-ui: 0.9375rem;
48
- --ui-font-size-md: 1rem;
49
- --ui-font-size-lg: 1.125rem;
50
- --ui-font-size-xl: 1.25rem;
51
- --ui-font-size-2xl: 1.5rem;
52
- --ui-line-height-tight: 1.2;
53
- --ui-line-height-md: 1.4;
54
- --ui-line-height-relaxed: 1.6;
55
-
56
- --ui-font-normal: 400;
57
50
  --ui-font-medium: 500;
58
- --ui-font-semibold: 600;
59
- --ui-font-bold: 700;
51
+ --ui-line-height: 1.4;
60
52
 
61
- --ui-space-0-5: 0.125rem;
53
+ /* Space: the steps components lay out with. */
62
54
  --ui-space-1: 0.25rem;
63
55
  --ui-space-2: 0.5rem;
64
56
  --ui-space-3: 0.75rem;
65
57
  --ui-space-4: 1rem;
66
- --ui-space-5: 1.5rem;
67
- --ui-space-6: 2rem;
68
- --ui-space-7: 2.5rem;
69
- --ui-space-8: 3rem;
70
58
 
71
- --ui-radius-1: 0.25rem;
72
- --ui-radius-2: 0.5rem;
73
- --ui-radius-3: 0.75rem;
74
- --ui-radius-4: 1rem;
75
- --ui-radius-dialog: 1rem;
59
+ /* Radius. */
60
+ --ui-radius-sm: 0.25rem;
61
+ --ui-radius-md: 0.5rem;
62
+ /* Derived from --ui-radius-md by default, in the contract because a product that rounds large
63
+ surfaces differently needs to pin it. */
64
+ --ui-radius-lg: calc(var(--ui-radius-md) * 1.5);
76
65
  --ui-radius-round: 999px;
77
66
 
78
- --ui-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.04);
67
+ /* Elevation: a resting shadow and a floating one. */
79
68
  --ui-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
80
- --ui-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
81
69
  --ui-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12), 0 4px 8px rgba(0, 0, 0, 0.06);
82
- --ui-shadow-xl: 0 16px 40px rgba(0, 0, 0, 0.14), 0 8px 16px rgba(0, 0, 0, 0.08);
83
- --ui-shadow-dialog: var(--ui-shadow-xl);
84
-
85
- /* Semantic elevation: every floating surface uses one of these so overlays read consistently. */
86
- --ui-elevation-tooltip: var(--ui-shadow-md);
87
- --ui-elevation-overlay: var(--ui-shadow-lg);
88
- --ui-elevation-dialog: var(--ui-shadow-xl);
89
- --ui-overlay-backdrop: rgba(0, 0, 0, 0.4);
90
70
 
71
+ /* Motion. */
91
72
  --ui-motion-fast: 120ms;
92
- --ui-motion-base: 180ms;
93
73
  --ui-motion-ease: cubic-bezier(0.2, 0, 0.2, 1);
94
- /* Fast start, gentle settle: for reveals that should feel immediate (expanding panels). */
95
- --ui-motion-ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
96
74
 
97
- /* Anticipatory interaction: guide → near → direct → active. */
98
- --ui-affordance-guide-size: 0.25rem;
99
- --ui-affordance-guide-opacity: 0.42;
100
- --ui-affordance-guide-color: var(--ui-border-strong);
101
- --ui-affordance-near-color: var(--ui-text-secondary);
102
- --ui-affordance-direct-color: var(--ui-accent-solid);
103
- --ui-affordance-active-color: var(--ui-accent-active);
104
- --ui-affordance-motion: var(--ui-motion-fast);
105
-
106
- --ui-surface-canvas: #ffffff;
107
- --ui-surface-default: #ffffff;
108
- --ui-surface-muted: #f8f8f6;
109
- --ui-surface-subtle: #f0f0ec;
110
- --ui-surface-elevated: #ffffff;
111
-
112
- --ui-text-primary: #1a1a1a;
113
- --ui-text-secondary: #5c5c5c;
114
- --ui-text-muted: #9b9b9b;
115
- --ui-text-on-accent: #ffffff;
116
-
117
- --ui-border-subtle: #ecece8;
118
- --ui-border-default: #e4e4e0;
119
- --ui-border-strong: #c8c8c4;
120
- --ui-focus-ring: #5b55d6;
75
+ /* Controls: the contract every button and field shares. */
76
+ --ui-control-size: 2.5rem;
77
+ --ui-control-size-sm: 2rem;
78
+ /* WCAG 2.5.5 counts CSS pixels, so this one stays in px: a smaller root font must not shrink
79
+ a touch target below 44. */
80
+ --ui-control-min-block-size: 44px;
81
+ --ui-control-border: #858580;
82
+ }
121
83
 
122
- --ui-accent-solid: #5b55d6;
123
- --ui-accent-hover: #4b45bd;
124
- --ui-accent-active: #3e399e;
125
- --ui-accent-soft: #efeffc;
84
+ /* Derived values.
85
+ Each is computed from the contract above. A theme may set one to diverge deliberately, but
86
+ never has to: these exist so components share one vocabulary, not to be configured. */
87
+ :root,
88
+ :where([data-theme], [data-contrast]) {
89
+ /* Type scale, from the base size. */
90
+ --ui-font-size-2xs: calc(var(--ui-font-size) * 0.6875);
91
+ --ui-font-size-xs: calc(var(--ui-font-size) * 0.75);
92
+ /* Dense interactive text: legible without body-copy spacing. */
93
+ --ui-font-size-ui: calc(var(--ui-font-size) * 0.9375);
94
+ --ui-font-size-md: var(--ui-font-size);
95
+ --ui-font-size-lg: calc(var(--ui-font-size) * 1.125);
96
+ --ui-line-height-tight: 1.2;
97
+ --ui-line-height-md: var(--ui-line-height);
98
+ --ui-font-normal: 400;
99
+ --ui-font-semibold: 600;
100
+ --ui-font-bold: 700;
101
+ --ui-font-family-sans: var(--ui-font-sans);
102
+ --ui-font-family-mono: var(--ui-font-mono);
126
103
 
127
- --ui-danger-solid: #b4233f;
128
- --ui-danger-hover: #941d35;
129
- --ui-danger-soft: #fceef1;
130
- --ui-success-solid: #007a33;
131
- --ui-success-soft: #edf7f1;
132
- --ui-warning-solid: #cc8800;
133
- --ui-warning-soft: #fdf7e6;
134
- --ui-info-solid: #0066cc;
135
- --ui-info-soft: #e8f0fb;
104
+ /* Space steps either side of the contract's four. */
105
+ --ui-space-0-5: calc(var(--ui-space-1) * 0.5);
106
+ --ui-space-5: calc(var(--ui-space-4) * 1.5);
107
+ --ui-space-6: calc(var(--ui-space-4) * 2);
136
108
 
137
- /* Intent colors split readable foreground use from filled-surface use. */
138
- --ui-accent-strong-surface: #5b55d6;
139
- --ui-accent-on-strong: #ffffff;
140
- --ui-accent-subtle-text: #3e399e;
141
- --ui-danger-strong-surface: #b4233f;
142
- --ui-danger-on-strong: #ffffff;
143
- --ui-danger-subtle-text: #941d35;
144
- --ui-success-strong-surface: #007a33;
145
- --ui-success-on-strong: #ffffff;
146
- --ui-success-subtle-text: #006629;
147
- /* Deeper amber so the solid warning badge carries white text like the other tones (5:1). */
148
- --ui-warning-strong-surface: #b45309;
149
- --ui-warning-on-strong: #ffffff;
150
- --ui-warning-subtle-text: #704800;
151
- --ui-info-strong-surface: #0066cc;
152
- --ui-info-on-strong: #ffffff;
153
- --ui-info-subtle-text: #0058b0;
109
+ --ui-radius-dialog: calc(var(--ui-radius-md) * 2);
154
110
 
155
- /* Depth and focus. Fields read as a shallow well; buttons as gently raised. Focus is a soft halo
156
- that transitions in (no hard outline ring). */
111
+ /* Elevation: one resting shadow, one floating, and the overlays in between. */
112
+ --ui-shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.04);
113
+ --ui-shadow-md: var(--ui-shadow-sm);
114
+ --ui-shadow-xl: var(--ui-shadow-lg);
115
+ --ui-elevation-tooltip: var(--ui-shadow-sm);
116
+ --ui-elevation-overlay: var(--ui-shadow-lg);
117
+ --ui-elevation-dialog: var(--ui-shadow-lg);
118
+ --ui-overlay-backdrop: rgba(0, 0, 0, 0.4);
157
119
  --ui-control-inset: inset 0 1px 2px rgb(0 0 0 / 0.07), inset 0 1px 0 rgb(0 0 0 / 0.02);
158
- --ui-control-focus-halo-shadow: 0 0 0 3px var(--ui-control-focus-halo, color-mix(in srgb, var(--ui-focus-ring) 24%, transparent));
159
120
  --ui-raised: 0 1px 2px rgb(0 0 0 / 0.07), 0 1px 1px rgb(0 0 0 / 0.04);
160
121
  --ui-raised-highlight: linear-gradient(rgb(255 255 255 / 0.5), rgb(255 255 255 / 0));
161
- --ui-focus-halo: 0 0 0 3px color-mix(in srgb, var(--ui-focus-ring) 40%, transparent);
162
-
163
- /* Icon sizes, used by icon buttons and field affordances. */
164
- --ui-icon-size-sm: 1rem;
165
- --ui-icon-size-md: 1.25rem;
166
- --ui-icon-size-lg: 1.5rem;
167
122
 
168
- /* One height scale for every form control and button size. */
169
- --ui-control-size-sm: 2rem;
170
- --ui-control-size-md: 2.5rem;
171
- --ui-control-size-lg: 3rem;
172
- /* Touch-target floor applied under coarse pointers. */
173
- --ui-control-min-block-size: 2.75rem;
123
+ --ui-motion-base: calc(var(--ui-motion-fast) * 1.5);
124
+ /* Fast start, gentle settle: for reveals that should feel immediate. */
125
+ --ui-motion-ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
174
126
 
175
- /* Compatibility aliases used by the editor's public styling surface.
176
- Each alias resolves through the canonical semantic token so an app only
177
- needs to override the canonical Looma theme contract. */
178
- --ui-surface: var(--ui-surface-elevated);
127
+ /* Surfaces and text, in the names components use. */
128
+ --ui-surface-canvas: var(--ui-surface);
129
+ --ui-surface-default: var(--ui-surface);
130
+ --ui-surface-elevated: var(--ui-surface-raised);
131
+ --ui-surface-subtle: var(--ui-surface-sunken);
179
132
  --ui-surface-hover: var(--ui-surface-muted);
180
- --ui-text: var(--ui-text-primary);
181
- --ui-border: var(--ui-border-default);
182
- --ui-accent: var(--ui-accent-solid);
183
- --ui-accent-subtle: var(--ui-accent-soft);
184
- --ui-accent-contrast: var(--ui-text-on-accent);
185
- --ui-danger: var(--ui-danger-solid);
186
- --ui-radius-sm: var(--ui-radius-1);
187
- --ui-radius-md: var(--ui-radius-2);
188
- --ui-radius-lg: var(--ui-radius-3);
189
- --ui-radius-xl: var(--ui-radius-4);
190
- --ui-text-sm: var(--ui-font-size-sm);
191
- }
192
-
193
- /* Custom-property references resolve where declared, before inheritance.
194
- Rebind semantic roles at theme boundaries to use the local palette. */
195
- :root,
196
- :where([data-theme], [data-contrast]) {
197
- /* Semantic interaction roles. Products can theme intent without coupling
198
- every component to a single brand accent. */
199
- --ui-action-primary-surface: var(--ui-accent-solid);
133
+ --ui-text-primary: var(--ui-text);
134
+ --ui-text-on-accent: var(--ui-on-accent);
135
+ --ui-border-subtle: color-mix(in srgb, var(--ui-border) 55%, var(--ui-surface));
136
+ --ui-border-default: var(--ui-border);
137
+
138
+ /* Intent tones: a solid surface, its foreground, and a soft tint of each. */
139
+ --ui-accent-solid: var(--ui-accent);
140
+ --ui-accent-soft: var(--ui-accent-subtle);
141
+ --ui-accent-contrast: var(--ui-on-accent);
142
+ --ui-accent-strong-surface: var(--ui-accent);
143
+ --ui-accent-on-strong: var(--ui-on-accent);
144
+ --ui-accent-subtle-text: var(--ui-accent-active);
145
+ --ui-danger-solid: var(--ui-danger);
146
+ --ui-danger-soft: color-mix(in srgb, var(--ui-danger) 8%, var(--ui-surface));
147
+ --ui-danger-strong-surface: var(--ui-danger);
148
+ --ui-danger-on-strong: var(--ui-on-danger);
149
+ --ui-danger-subtle-text: var(--ui-danger-hover);
150
+ --ui-success-solid: var(--ui-success);
151
+ --ui-success-hover: color-mix(in srgb, var(--ui-success) 85%, var(--ui-text));
152
+ --ui-success-soft: color-mix(in srgb, var(--ui-success) 8%, var(--ui-surface));
153
+ --ui-success-strong-surface: var(--ui-success);
154
+ --ui-success-on-strong: var(--ui-on-accent);
155
+ --ui-success-subtle-text: color-mix(in srgb, var(--ui-success) 85%, var(--ui-text));
156
+ --ui-warning-solid: var(--ui-warning);
157
+ --ui-warning-soft: color-mix(in srgb, var(--ui-warning) 8%, var(--ui-surface));
158
+ --ui-warning-strong-surface: var(--ui-warning);
159
+ --ui-warning-on-strong: var(--ui-on-accent);
160
+ --ui-warning-subtle-text: color-mix(in srgb, var(--ui-warning) 85%, var(--ui-text));
161
+ --ui-info-solid: var(--ui-info);
162
+ --ui-info-soft: color-mix(in srgb, var(--ui-info) 8%, var(--ui-surface));
163
+ --ui-info-strong-surface: var(--ui-info);
164
+ --ui-info-on-strong: var(--ui-on-accent);
165
+ --ui-info-subtle-text: color-mix(in srgb, var(--ui-info) 85%, var(--ui-text));
166
+
167
+ /* Interaction roles: what a control paints, whatever its intent. */
168
+ --ui-action-primary-surface: var(--ui-accent);
200
169
  --ui-action-primary-surface-hover: var(--ui-accent-hover);
201
170
  --ui-action-primary-surface-active: var(--ui-accent-active);
202
- --ui-action-primary-text: var(--ui-text-on-accent);
203
- --ui-action-secondary-surface: var(--ui-surface-default);
171
+ --ui-action-primary-text: var(--ui-on-accent);
204
172
  --ui-action-secondary-surface-hover: var(--ui-surface-muted);
205
- --ui-action-secondary-text: var(--ui-text-primary);
206
- --ui-control-surface: var(--ui-surface-default);
173
+ --ui-action-secondary-text: var(--ui-text);
174
+ --ui-control-surface: var(--ui-surface);
207
175
  --ui-control-surface-disabled: var(--ui-surface-muted);
208
- --ui-control-border: var(--ui-border-default);
209
176
  --ui-control-border-hover: var(--ui-border-strong);
177
+ --ui-control-placeholder: var(--ui-text-secondary);
210
178
  --ui-control-focus: var(--ui-focus-ring);
211
- /* Derived from the ring, not the near-white accent tint, so the halo shows on any surface. */
179
+ /* Derived from the ring, not a near-white tint, so the halo shows on any surface. */
212
180
  --ui-control-focus-halo: color-mix(in srgb, var(--ui-focus-ring) 24%, transparent);
213
- }
214
-
215
- @supports (color: oklch(0.5 0.1 240)) {
216
- :root {
217
- --ui-surface-canvas: oklch(0.99 0.01 250);
218
- --ui-surface-default: oklch(1 0 0);
219
- --ui-surface-muted: oklch(0.97 0.01 250);
220
- --ui-surface-subtle: oklch(0.95 0.01 250);
221
- --ui-surface-elevated: oklch(1 0 0);
181
+ --ui-control-focus-halo-shadow: 0 0 0 3px var(--ui-control-focus-halo);
182
+ --ui-control-size-md: var(--ui-control-size);
183
+ --ui-control-size-lg: calc(var(--ui-control-size) * 1.2);
222
184
 
223
- --ui-text-primary: oklch(0.23 0.02 260);
224
- --ui-text-secondary: oklch(0.36 0.02 260);
225
- --ui-text-muted: oklch(0.5 0.02 260);
226
- --ui-text-on-accent: oklch(0.99 0.01 250);
227
-
228
- --ui-border-subtle: oklch(0.9 0.01 250);
229
- --ui-border-default: oklch(0.84 0.01 250);
230
- --ui-border-strong: oklch(0.7 0.02 250);
231
- --ui-focus-ring: oklch(0.57 0.17 285);
232
-
233
- --ui-accent-solid: oklch(0.57 0.17 285);
234
- --ui-accent-hover: oklch(0.52 0.18 285);
235
- --ui-accent-active: oklch(0.46 0.16 285);
236
- --ui-accent-soft: oklch(0.96 0.025 285);
185
+ /* Icon sizes, used by icon buttons and field affordances. */
186
+ --ui-icon-size-sm: var(--ui-font-size);
187
+ --ui-icon-size-md: calc(var(--ui-font-size) * 1.25);
188
+ --ui-icon-size-lg: calc(var(--ui-font-size) * 1.5);
237
189
 
238
- --ui-danger-solid: oklch(0.5 0.17 18);
239
- --ui-danger-hover: oklch(0.44 0.16 18);
240
- --ui-danger-soft: oklch(0.97 0.025 18);
241
- --ui-success-solid: oklch(0.5 0.15 145);
242
- --ui-success-soft: oklch(0.96 0.03 145);
243
- --ui-warning-solid: oklch(0.7 0.15 85);
244
- --ui-warning-soft: oklch(0.97 0.04 85);
245
- --ui-info-solid: oklch(0.62 0.18 250);
246
- --ui-info-soft: oklch(0.95 0.03 250);
247
- }
190
+ /* Anticipatory interaction: guide → near → direct. */
191
+ --ui-affordance-guide-size: var(--ui-space-1);
192
+ --ui-affordance-guide-opacity: 0.42;
193
+ --ui-affordance-guide-color: var(--ui-border-strong);
194
+ --ui-affordance-near-color: var(--ui-text-secondary);
195
+ --ui-affordance-direct-color: var(--ui-accent);
196
+ --ui-affordance-motion: var(--ui-motion-fast);
248
197
  }
249
198
 
250
199
  @media (prefers-reduced-motion: reduce) {
251
200
  :root {
252
201
  --ui-motion-fast: 0ms;
253
- --ui-motion-base: 0ms;
254
202
  }
255
203
  }
256
204
  }
@@ -8,6 +8,7 @@ export interface UiDisclosureElement extends HTMLDivElement {
8
8
  removeEventListener<K extends keyof UiDisclosureEventMap>(type: K, listener: (this: UiDisclosureElement, event: UiDisclosureEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
9
9
  }
10
10
  export interface UiDisclosureProps {
11
+ density?: "comfortable" | "compact" | null;
11
12
  disabled?: boolean | null;
12
13
  open?: boolean | null;
13
14
  summary?: string | null;
@@ -3,7 +3,7 @@ import { manageComponentLifecycle } from "@nextwebwg/html-next/runtime";
3
3
  import * as controller from "../components/ui-disclosure/ui-disclosure.js";
4
4
  import "../styles/ui-disclosure.css";
5
5
 
6
- const definition = {...{"contract":{"tag":"ui-disclosure","props":{"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"default":false},"open":{"type":"boolean","required":false,"target":{"attribute":"open"},"default":false},"summary":{"type":"string","required":false,"target":{"attribute":"summary"},"default":"Details"}}},"template":{"kind":"element","name":"div","attributes":[],"children":[{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"class","value":"trigger"},{"kind":"literal","name":"type","value":"button"},{"kind":"attribute","name":"aria-controls","expression":"contentId","expressionPlan":{"source":"contentId","ast":{"kind":"id","name":"contentId"},"dependencies":["contentId"]}},{"kind":"attribute","name":"aria-expanded","expression":"internalOpen","expressionPlan":{"source":"internalOpen","ast":{"kind":"id","name":"internalOpen"},"dependencies":["internalOpen"]}},{"kind":"attribute","name":"disabled","expression":"disabled","expressionPlan":{"source":"disabled","ast":{"kind":"id","name":"disabled"},"dependencies":["disabled"]}}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"directive","name":"value","expression":"summary","expressionPlan":{"source":"summary","ast":{"kind":"id","name":"summary"},"dependencies":["summary"]}}],"children":[]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"chevron"},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]}],"ref":"trigger"},{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"panel"},{"kind":"attribute","name":"id","expression":"contentId","expressionPlan":{"source":"contentId","ast":{"kind":"id","name":"contentId"},"dependencies":["contentId"]}},{"kind":"attribute","name":"inert","expression":"not internalOpen","expressionPlan":{"source":"not internalOpen","ast":{"kind":"unary","op":"not","operand":{"kind":"id","name":"internalOpen"}},"dependencies":["internalOpen"]}}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"panel-inner"}],"children":[{"kind":"slot"}]}]}]},"declarations":[{"kind":"state","name":"internalOpen","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"state","name":"contentId","expression":{"source":"''","ast":{"kind":"literal","value":""},"dependencies":[]}},{"kind":"event","name":"open","type":"object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false},{"kind":"event","name":"close","type":"object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false}],"root":{"kind":"native","element":"div","choices":["div"]}},source:{file:import.meta.url},css:""};
6
+ const definition = {...{"contract":{"tag":"ui-disclosure","props":{"density":{"type":{"enum":["comfortable","compact"]},"required":false,"target":{"attribute":"density"},"default":"comfortable"},"disabled":{"type":"boolean","required":false,"target":{"attribute":"disabled"},"default":false},"open":{"type":"boolean","required":false,"target":{"attribute":"open"},"default":false},"summary":{"type":"string","required":false,"target":{"attribute":"summary"},"default":"Details"}}},"template":{"kind":"element","name":"div","attributes":[],"children":[{"kind":"element","name":"button","attributes":[{"kind":"literal","name":"class","value":"trigger"},{"kind":"literal","name":"type","value":"button"},{"kind":"attribute","name":"aria-controls","expression":"contentId","expressionPlan":{"source":"contentId","ast":{"kind":"id","name":"contentId"},"dependencies":["contentId"]}},{"kind":"attribute","name":"aria-expanded","expression":"internalOpen","expressionPlan":{"source":"internalOpen","ast":{"kind":"id","name":"internalOpen"},"dependencies":["internalOpen"]}},{"kind":"attribute","name":"disabled","expression":"disabled","expressionPlan":{"source":"disabled","ast":{"kind":"id","name":"disabled"},"dependencies":["disabled"]}}],"children":[{"kind":"element","name":"span","attributes":[{"kind":"directive","name":"value","expression":"summary","expressionPlan":{"source":"summary","ast":{"kind":"id","name":"summary"},"dependencies":["summary"]}}],"children":[]},{"kind":"element","name":"span","attributes":[{"kind":"literal","name":"class","value":"chevron"},{"kind":"literal","name":"aria-hidden","value":"true"}],"children":[]}],"ref":"trigger"},{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"panel"},{"kind":"attribute","name":"id","expression":"contentId","expressionPlan":{"source":"contentId","ast":{"kind":"id","name":"contentId"},"dependencies":["contentId"]}},{"kind":"attribute","name":"inert","expression":"not internalOpen","expressionPlan":{"source":"not internalOpen","ast":{"kind":"unary","op":"not","operand":{"kind":"id","name":"internalOpen"}},"dependencies":["internalOpen"]}}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"panel-inner"}],"children":[{"kind":"slot"}]}]}]},"declarations":[{"kind":"state","name":"internalOpen","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"state","name":"contentId","expression":{"source":"''","ast":{"kind":"literal","value":""},"dependencies":[]}},{"kind":"event","name":"open","type":"object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false},{"kind":"event","name":"close","type":"object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false}],"root":{"kind":"native","element":"div","choices":["div"]}},source:{file:import.meta.url},css:""};
7
7
 
8
8
  export function createUiDisclosure(options = {}) {
9
9
  const { attributes = {}, children = [], slots = {}, as, ...componentProps } = options;
@@ -9,6 +9,7 @@ export interface UiMenuElement extends HTMLDivElement {
9
9
  removeEventListener<K extends keyof UiMenuEventMap>(type: K, listener: (this: UiMenuElement, event: UiMenuEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
10
10
  }
11
11
  export interface UiMenuProps {
12
+ density?: "comfortable" | "compact" | null;
12
13
  for?: string | null;
13
14
  open?: boolean | null;
14
15
  placement?: string | null;
package/vanilla/UiMenu.js CHANGED
@@ -3,7 +3,7 @@ import { manageComponentLifecycle } from "@nextwebwg/html-next/runtime";
3
3
  import * as controller from "../components/ui-menu/ui-menu.js";
4
4
  import "../styles/ui-menu.css";
5
5
 
6
- const definition = {...{"contract":{"tag":"ui-menu","props":{"for":{"type":"string","required":false,"target":{"attribute":"for"},"default":""},"open":{"type":"boolean","required":false,"target":{"attribute":"open"},"default":false},"placement":{"type":"string","required":false,"target":{"attribute":"placement"},"default":"bottom-start"}}},"template":{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"role","value":"menu"},{"kind":"literal","name":"aria-orientation","value":"vertical"}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"surface"}],"children":[{"kind":"slot"}]}]},"declarations":[{"kind":"state","name":"internalOpen","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"event","name":"select","type":"object({ value: string, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false},{"kind":"event","name":"open","type":"object({ open: boolean, reason: action | programmatic, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false},{"kind":"event","name":"close","type":"object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false}],"root":{"kind":"native","element":"div","choices":["div"]}},source:{file:import.meta.url},css:""};
6
+ const definition = {...{"contract":{"tag":"ui-menu","props":{"density":{"type":{"enum":["comfortable","compact"]},"required":false,"target":{"attribute":"density"},"default":"comfortable"},"for":{"type":"string","required":false,"target":{"attribute":"for"},"default":""},"open":{"type":"boolean","required":false,"target":{"attribute":"open"},"default":false},"placement":{"type":"string","required":false,"target":{"attribute":"placement"},"default":"bottom-start"}}},"template":{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"role","value":"menu"},{"kind":"literal","name":"aria-orientation","value":"vertical"}],"children":[{"kind":"element","name":"div","attributes":[{"kind":"literal","name":"class","value":"surface"}],"children":[{"kind":"slot"}]}]},"declarations":[{"kind":"state","name":"internalOpen","expression":{"source":"false","ast":{"kind":"literal","value":false},"dependencies":[]}},{"kind":"event","name":"select","type":"object({ value: string, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false},{"kind":"event","name":"open","type":"object({ open: boolean, reason: action | programmatic, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false},{"kind":"event","name":"close","type":"object({ open: boolean, reason: action | programmatic | light-dismiss | escape, trigger: keyboard | pointer | programmatic })","bubbles":true,"composed":true,"cancelable":false}],"root":{"kind":"native","element":"div","choices":["div"]}},source:{file:import.meta.url},css:""};
7
7
 
8
8
  export function createUiMenu(options = {}) {
9
9
  const { attributes = {}, children = [], slots = {}, as, ...componentProps } = options;
@@ -7,6 +7,7 @@ export interface UiTabsElement extends HTMLDivElement {
7
7
  removeEventListener<K extends keyof UiTabsEventMap>(type: K, listener: (this: UiTabsElement, event: UiTabsEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
8
8
  }
9
9
  export interface UiTabsProps {
10
+ density?: "comfortable" | "compact" | null;
10
11
  label?: string | null;
11
12
  orientation?: "horizontal" | "vertical" | null;
12
13
  stretch?: boolean | null;