@ixfx/components 0.6.2 → 0.7.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 (181) hide show
  1. package/bundle/index.d.ts +1918 -835
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +22137 -16840
  4. package/bundle/index.js.map +1 -1
  5. package/bundle/style.css +1 -1
  6. package/dist/ac-text.d.ts +1 -1
  7. package/dist/ac-text.js +3 -2
  8. package/dist/ac-text.js.map +1 -1
  9. package/dist/{ac-token-BAa6ke09.d.ts → ac-token--_vCHXWw.d.ts} +2 -2
  10. package/dist/{ac-token-BAa6ke09.d.ts.map → ac-token--_vCHXWw.d.ts.map} +1 -1
  11. package/dist/ac-token.d.ts +1 -1
  12. package/dist/ac-token.js +3 -2
  13. package/dist/ac-token.js.map +1 -1
  14. package/dist/{button-Bn0BuLpO.js → button-DsFbV4XD.js} +5 -4
  15. package/dist/button-DsFbV4XD.js.map +1 -0
  16. package/dist/button.d.ts.map +1 -1
  17. package/dist/button.js +1 -1
  18. package/dist/checkbox.js +1 -1
  19. package/dist/{colour-picker-0stHB90J.js → colour-picker-Ddsk-7E_.js} +4 -3
  20. package/dist/{colour-picker-0stHB90J.js.map → colour-picker-Ddsk-7E_.js.map} +1 -1
  21. package/dist/colour-picker.js +1 -1
  22. package/dist/crumbs.d.ts +1 -1
  23. package/dist/crumbs.js +4 -2
  24. package/dist/crumbs.js.map +1 -1
  25. package/dist/data-display.js +1 -1
  26. package/dist/{data-grid-C8qIo1-u.d.ts → data-grid-Bh4YrQGK.d.ts} +2 -2
  27. package/dist/{data-grid-C8qIo1-u.d.ts.map → data-grid-Bh4YrQGK.d.ts.map} +1 -1
  28. package/dist/data-grid.d.ts +1 -1
  29. package/dist/data-grid.js +4 -2
  30. package/dist/data-grid.js.map +1 -1
  31. package/dist/{defaults-BCiDhZbF.js → defaults-BJwDsMH4.js} +27 -20
  32. package/dist/defaults-BJwDsMH4.js.map +1 -0
  33. package/dist/editable-label-rzXkjf1H.d.ts +75 -0
  34. package/dist/editable-label-rzXkjf1H.d.ts.map +1 -0
  35. package/dist/editable-label.d.ts +2 -75
  36. package/dist/editable-label.js +2 -1
  37. package/dist/editable-label.js.map +1 -1
  38. package/dist/{fallbacks-DEE1nCTt.js → fallbacks-DNI9xt0F.js} +2 -2
  39. package/dist/{fallbacks-DEE1nCTt.js.map → fallbacks-DNI9xt0F.js.map} +1 -1
  40. package/dist/{grouped-item-lister-_pMDwIo1.d.ts → grouped-item-lister-DnWB-eFT.d.ts} +2 -2
  41. package/dist/{grouped-item-lister-_pMDwIo1.d.ts.map → grouped-item-lister-DnWB-eFT.d.ts.map} +1 -1
  42. package/dist/grouped-item-lister.d.ts +1 -1
  43. package/dist/{hex-editor-Bk6rxhfg.js → hex-editor-BiRfwTz1.js} +2 -2
  44. package/dist/{hex-editor-Bk6rxhfg.js.map → hex-editor-BiRfwTz1.js.map} +1 -1
  45. package/dist/hex.js +1 -1
  46. package/dist/{icon-DpA9x2Ve.d.ts → icon-CDGprSdE.d.ts} +1 -12
  47. package/dist/icon-CDGprSdE.d.ts.map +1 -0
  48. package/dist/{icons-Bm2ByQ3s.js → icon-DcEEGQa_.js} +38 -12
  49. package/dist/icon-DcEEGQa_.js.map +1 -0
  50. package/dist/icons.d.ts +3 -3
  51. package/dist/icons.js +9 -3
  52. package/dist/icons.js.map +1 -0
  53. package/dist/{index-CKtLhgYj.d.ts → index-9AhaHIT2.d.ts} +3 -3
  54. package/dist/{index-CKtLhgYj.d.ts.map → index-9AhaHIT2.d.ts.map} +1 -1
  55. package/dist/index-CG2vIgPv.d.ts +101 -0
  56. package/dist/index-CG2vIgPv.d.ts.map +1 -0
  57. package/dist/{index-BtGFYfaK.d.ts → index-CS9yM8L-.d.ts} +14 -4
  58. package/dist/index-CS9yM8L-.d.ts.map +1 -0
  59. package/dist/index.d.ts +861 -71
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +4257 -931
  62. package/dist/index.js.map +1 -1
  63. package/dist/interaction-D5XdKzbR.js +2 -0
  64. package/dist/labelled-radial-input.js +2 -1
  65. package/dist/labelled-radial-input.js.map +1 -1
  66. package/dist/labelled-slider-input-DzigjMwP.js +808 -0
  67. package/dist/labelled-slider-input-DzigjMwP.js.map +1 -0
  68. package/dist/labelled-slider-input.d.ts +2 -0
  69. package/dist/labelled-slider-input.js +2 -0
  70. package/dist/{types-DlVNJez_.d.ts → list-selection-types-DSuRNWpx.d.ts} +10 -2
  71. package/dist/list-selection-types-DSuRNWpx.d.ts.map +1 -0
  72. package/dist/menu-CXDFJxNm.js +825 -0
  73. package/dist/menu-CXDFJxNm.js.map +1 -0
  74. package/dist/{menu-item-Bs2MYyHq.d.ts → menu-item-CZi9vy5O.d.ts} +4 -2
  75. package/dist/menu-item-CZi9vy5O.d.ts.map +1 -0
  76. package/dist/menu-item-D2S4i8u1.js +809 -0
  77. package/dist/menu-item-D2S4i8u1.js.map +1 -0
  78. package/dist/menu.d.ts +2 -2
  79. package/dist/menu.js +2 -1
  80. package/dist/miller.d.ts +1 -1
  81. package/dist/miller.js +3 -2
  82. package/dist/miller.js.map +1 -1
  83. package/dist/narrowed-text.js +4 -2
  84. package/dist/narrowed-text.js.map +1 -1
  85. package/dist/notification-pill-DyZydXoZ.d.ts.map +1 -1
  86. package/dist/notifier.js +4 -3
  87. package/dist/notifier.js.map +1 -1
  88. package/dist/panel.d.ts +13 -13
  89. package/dist/panel.d.ts.map +1 -1
  90. package/dist/panel.js +37 -253
  91. package/dist/panel.js.map +1 -1
  92. package/dist/plots.js +1 -1
  93. package/dist/polar-pad.js +1 -1
  94. package/dist/{radial-input-Dk8Wydp5.js → radial-input-Dp5qz0ly.js} +2 -2
  95. package/dist/{radial-input-Dk8Wydp5.js.map → radial-input-Dp5qz0ly.js.map} +1 -1
  96. package/dist/radial-input.js +1 -1
  97. package/dist/range-input.js +1 -1
  98. package/dist/range.js +1 -1
  99. package/dist/registry-BEtb8_wB.js +46 -0
  100. package/dist/registry-BEtb8_wB.js.map +1 -0
  101. package/dist/select-horiz.js +3 -2
  102. package/dist/select-horiz.js.map +1 -1
  103. package/dist/{slider-input-XppH3vcy.d.ts → slider-input-BfRUW2ZB.d.ts} +16 -3
  104. package/dist/slider-input-BfRUW2ZB.d.ts.map +1 -0
  105. package/dist/{slider-input-CT4gcF-o.js → slider-input-De4eoT11.js} +382 -67
  106. package/dist/slider-input-De4eoT11.js.map +1 -0
  107. package/dist/slider-input.d.ts +1 -1
  108. package/dist/slider-input.js +1 -1
  109. package/dist/snackbar.js +1 -1
  110. package/dist/split-layout-BFSbUZQv.js +969 -0
  111. package/dist/split-layout-BFSbUZQv.js.map +1 -0
  112. package/dist/split-layout-JK3xWVX2.d.ts +179 -0
  113. package/dist/split-layout-JK3xWVX2.d.ts.map +1 -0
  114. package/dist/split-layout.d.ts +2 -60
  115. package/dist/split-layout.js +1 -617
  116. package/dist/style.css +1 -1
  117. package/dist/swipe.js +1 -1
  118. package/dist/{tab-list-D_1cYhB_.d.ts → tab-list-CGyPt07Z.d.ts} +10 -2
  119. package/dist/tab-list-CGyPt07Z.d.ts.map +1 -0
  120. package/dist/tabs.d.ts +1 -1
  121. package/dist/tabs.js +128 -27
  122. package/dist/tabs.js.map +1 -1
  123. package/dist/{tickled-controller-BtevrRLV.d.ts → tickled-controller-CRzdIEjJ.d.ts} +7 -1
  124. package/dist/tickled-controller-CRzdIEjJ.d.ts.map +1 -0
  125. package/dist/{tickled-controller-DkAU-0qL.js → tickled-controller-h9GmJ_bU.js} +8 -2
  126. package/dist/tickled-controller-h9GmJ_bU.js.map +1 -0
  127. package/dist/titlebar-Bj5pfdw_.d.ts +50 -0
  128. package/dist/titlebar-Bj5pfdw_.d.ts.map +1 -0
  129. package/dist/titlebar.d.ts +2 -0
  130. package/dist/titlebar.js +324 -0
  131. package/dist/titlebar.js.map +1 -0
  132. package/dist/tooltip-BlvBUQxx.d.ts.map +1 -1
  133. package/dist/{tree-BO6BXI2b.js → tree-Ch4W8qXQ.js} +4 -3
  134. package/dist/{tree-BO6BXI2b.js.map → tree-Ch4W8qXQ.js.map} +1 -1
  135. package/dist/tree.d.ts +1 -1
  136. package/dist/tree.js +1 -1
  137. package/dist/vertical-list-ClnqTkF3.js +814 -0
  138. package/dist/vertical-list-ClnqTkF3.js.map +1 -0
  139. package/dist/vertical-list.d.ts +8 -9
  140. package/dist/vertical-list.d.ts.map +1 -1
  141. package/dist/vertical-list.js +1 -736
  142. package/dist/{xy-axis-B6yMjckW.js → xy-axis-DWizs0bt.js} +109 -3
  143. package/dist/xy-axis-DWizs0bt.js.map +1 -0
  144. package/dist/xy-pad.js +1 -1
  145. package/docs-user/README.md +5 -0
  146. package/docs-user/detail-list.md +398 -0
  147. package/docs-user/dock.md +461 -0
  148. package/docs-user/icons.md +4 -0
  149. package/docs-user/index.json +28 -3
  150. package/docs-user/labelled-slider-input.md +198 -0
  151. package/docs-user/llms.txt +6 -1
  152. package/docs-user/panel.md +20 -1
  153. package/docs-user/slider-input.md +55 -15
  154. package/docs-user/split-layout.md +136 -170
  155. package/docs-user/tabs.md +54 -0
  156. package/docs-user/titlebar.md +102 -0
  157. package/docs-user/toolbar.md +95 -22
  158. package/docs-user/twosplit-layout.md +254 -0
  159. package/docs-user/user-catalog.md +8 -1
  160. package/docs-user/user-theming.md +109 -0
  161. package/llms.txt +6 -1
  162. package/package.json +1 -2
  163. package/dist/button-Bn0BuLpO.js.map +0 -1
  164. package/dist/defaults-BCiDhZbF.js.map +0 -1
  165. package/dist/editable-label.d.ts.map +0 -1
  166. package/dist/icon-DpA9x2Ve.d.ts.map +0 -1
  167. package/dist/icons-Bm2ByQ3s.js.map +0 -1
  168. package/dist/index-BtGFYfaK.d.ts.map +0 -1
  169. package/dist/menu-DIfU70AA.js +0 -1609
  170. package/dist/menu-DIfU70AA.js.map +0 -1
  171. package/dist/menu-item-Bs2MYyHq.d.ts.map +0 -1
  172. package/dist/slider-input-CT4gcF-o.js.map +0 -1
  173. package/dist/slider-input-XppH3vcy.d.ts.map +0 -1
  174. package/dist/split-layout.d.ts.map +0 -1
  175. package/dist/split-layout.js.map +0 -1
  176. package/dist/tab-list-D_1cYhB_.d.ts.map +0 -1
  177. package/dist/tickled-controller-BtevrRLV.d.ts.map +0 -1
  178. package/dist/tickled-controller-DkAU-0qL.js.map +0 -1
  179. package/dist/types-DlVNJez_.d.ts.map +0 -1
  180. package/dist/vertical-list.js.map +0 -1
  181. package/dist/xy-axis-B6yMjckW.js.map +0 -1
@@ -26,13 +26,14 @@ A responsive toolbar container that handles overflow by moving items to a popove
26
26
 
27
27
  ### Properties / attributes
28
28
 
29
- | Attribute / Property | Type | Default | Description |
30
- |---------------------|---------------------------------------------------|----------------|------------------------------------------------------|
31
- | `orientation` | `'horizontal'` \| `'vertical-left'` \| `'vertical-right'` | `'horizontal'` | Layout direction. `vertical-left` flips text upward. |
32
- | `layout` | `'one-line'` \| `'wrap'` | `'one-line'` | Whether items wrap or overflow |
33
- | `vertical-writing` | `'auto'` \| `'up'` \| `'down'` \| `'none'` | `'auto'` | Writing mode for vertical orientations |
34
- | `show-group-labels` | boolean | `false` | Show labels as rows above group content |
35
- | `invisible-groups` | boolean | `false` | Hide group borders and backgrounds |
29
+ | Attribute / Property | Type | Default | Description |
30
+ |---------------------|------|---------|-------------|
31
+ | `orientation` | `'horizontal'` \| `'vertical-left'` \| `'vertical-right'` | `'horizontal'` | Layout direction. `vertical-left` flips text upward. |
32
+ | `layout` | `'one-line'` \| `'wrap'` | `'one-line'` | `'one-line'` enables overflow handling; `'wrap'` allows items to wrap to multiple lines |
33
+ | `vertical-writing` | `'auto'` \| `'up'` \| `'down'` \| `'none'` | `'auto'` | Writing mode for vertical orientations |
34
+ | `toolbar-align` | `'near'` \| `'far'` | `'near'` | Horizontal justification: `near` = left, `far` = right |
35
+ | `show-group-labels` | boolean | `false` | Show labels as rows above group content |
36
+ | `invisible-groups` | boolean | `false` | Hide group borders and backgrounds |
36
37
 
37
38
  ### Slots
38
39
 
@@ -43,12 +44,35 @@ A responsive toolbar container that handles overflow by moving items to a popove
43
44
 
44
45
  ### CSS custom properties
45
46
 
46
- | Property | Default | Description |
47
- |----------|---------|--------------------------------------|
48
- | `--toolbar-gap` | `var(--space-s)` | Gap between toolbar items |
49
- | `--toolbar-bg` | `var(--surface-2)` | Toolbar background |
47
+ | Property | Default | Description |
48
+ |----------|---------|-------------|
49
+ | `--toolbar-gap` | `var(--space-s)` | Gap between toolbar items |
50
+ | `--toolbar-group-gap` | `var(--space-m)` | Gap between nested `ixfx-toolbar-group` elements |
51
+ | `--toolbar-bg` | `var(--surface-2)` | Toolbar background |
50
52
  | `--toolbar-padding` | `var(--space-s)` | Toolbar padding |
51
- | `--toolbar-border` | `var(--border-subtle)` | Toolbar border |
53
+ | `--toolbar-border` | `var(--border-subtle)` | Toolbar border |
54
+ | `--toolbar-group-padding` | `var(--space-xs)` | Padding for nested `ixfx-toolbar-group` elements (set here to affect all groups) |
55
+ | `--toolbar-overflow` | `'auto'` | Overflow mode: `'auto'` (show items, hide overflow button when not needed), `'collapsed'` (all items in overflow, button always visible), `'disabled'` (no overflow, items always visible) |
56
+
57
+ ### Alignment
58
+
59
+ `toolbar-align` controls justification along the main axis. For horizontal toolbars (the default orientation), `near` (default) left-justifies content (`justify-content: flex-start`) and `far` right-justifies it (`justify-content: flex-end`). The attribute is ignored for vertical orientations. Overflow handling (`layout="one-line"`) works with both values — the overflow popover remains right-aligned when `far` is set.
60
+
61
+ ```html
62
+ <!-- Left-aligned (default) -->
63
+ <ixfx-toolbar toolbar-align="near">
64
+ <ixfx-button>Save</ixfx-button>
65
+ <ixfx-button>Cancel</ixfx-button>
66
+ </ixfx-toolbar>
67
+
68
+ <!-- Right-aligned horizontal toolbar -->
69
+ <ixfx-toolbar toolbar-align="far">
70
+ <ixfx-button>Save</ixfx-button>
71
+ <ixfx-button>Cancel</ixfx-button>
72
+ </ixfx-toolbar>
73
+ ```
74
+
75
+ See `demo/toolbar.html` “Alignment – toolbar-align” for a live demo: side-by-side `near` vs `far` comparison, a `far` toolbar with many groups (resize to see overflow stay right-aligned), and an interactive toggle (`select#select-align` driving `toolbar#toolbar-align-demo`).
52
76
 
53
77
  ### Writing mode
54
78
 
@@ -59,6 +83,22 @@ For vertical toolbars, `vertical-writing` controls how text is displayed:
59
83
  - `'down'` — Forces `vertical-lr` (text runs downward)
60
84
  - `'none'` — Forces `horizontal-tb` (no vertical writing)
61
85
 
86
+ ### Layout mode
87
+
88
+ The `layout` attribute controls how items handle available space:
89
+
90
+ - `'one-line'` (default): Items stay on a single line. Items that don't fit are moved to an overflow popover.
91
+ - `'wrap'`: Items wrap to multiple lines as needed. No overflow handling occurs.
92
+
93
+ ```html
94
+ <!-- Items wrap to new lines when they don't fit -->
95
+ <ixfx-toolbar layout="wrap">
96
+ <ixfx-button>A</ixfx-button>
97
+ <ixfx-button>B</ixfx-button>
98
+ <ixfx-button>C</ixfx-button>
99
+ </ixfx-toolbar>
100
+ ```
101
+
62
102
  ### Overflow handling
63
103
 
64
104
  When `layout="one-line"` and items exceed available space, excess items are moved to an overflow popover. The popover is positioned using CSS Anchor Positioning relative to the overflow button.
@@ -72,6 +112,30 @@ When `layout="one-line"` and items exceed available space, excess items are move
72
112
  </ixfx-toolbar>
73
113
  ```
74
114
 
115
+ #### Overflow modes
116
+
117
+ The `--toolbar-overflow` CSS variable controls how overflow behaves:
118
+
119
+ - `'auto'` (default): Items are shown initially. When they don't fit, they move to overflow and the overflow button appears.
120
+ - `'collapsed'`: All items start in overflow. The overflow button is always visible.
121
+ - `'disabled'`: Overflow is disabled. Items always remain visible and may overflow the container.
122
+
123
+ ```css
124
+ /* All items hidden behind overflow button */
125
+ ixfx-toolbar {
126
+ --toolbar-overflow: collapsed;
127
+ }
128
+
129
+ /* Never collapse - always show all items */
130
+ ixfx-toolbar {
131
+ --toolbar-overflow: disabled;
132
+ }
133
+ ```
134
+
135
+ #### Groups and overflow
136
+
137
+ Items with the `grow` attribute never go into overflow — they always remain visible and take remaining space.
138
+
75
139
  ---
76
140
 
77
141
  ## `ixfx-toolbar-group`
@@ -91,17 +155,23 @@ A grouping container for toolbar items. Groups can have a label and support grow
91
155
 
92
156
  ### Properties / attributes
93
157
 
94
- | Attribute / Property | Type | Default | Description |
95
- |---------------------|---------|---------|------------------------------------------|
96
- | `label` | string | `''` | Label text displayed above content |
97
- | `grow` | boolean | `false` | Group grows to fill remaining space |
158
+ | Attribute / Property | Type | Default | Description |
159
+ |---------------------|------|---------|-------------|
160
+ | `label` | string | `''` | Label text displayed above content |
161
+ | `grow` | boolean | `false` | Group grows to fill remaining space |
162
+
163
+ The `show-group-labels` attribute on the parent `ixfx-toolbar` controls whether group labels are displayed as rows above the group content.
98
164
 
99
165
  ### CSS custom properties
100
166
 
101
- | Property | Default | Description |
102
- |-----------------------------------|-------------|----------------------------------------------|
103
- | `--toolbar-group-justify-content` | `flex-start` | Horizontal alignment of group contents |
104
- | `--toolbar-group-align-items` | `center` | Vertical alignment of group contents |
167
+ | Property | Default | Description |
168
+ |----------|---------|-------------|
169
+ | `--toolbar-group-padding` | `var(--space-xs)` | Padding inside the group (can be set on parent `ixfx-toolbar`) |
170
+ | `--toolbar-group-justify-content` | `flex-start` | Horizontal alignment of group contents |
171
+ | `--toolbar-group-align-items` | `center` | Vertical alignment of group contents |
172
+ | `--toolbar-group-border` | `var(--border-subtle)` | Border around the group (set to `none` with `invisible-groups` on parent to hide borders) |
173
+
174
+ The `--toolbar-gap` property is inherited from the parent `ixfx-toolbar`.
105
175
 
106
176
  ```html
107
177
  <!-- Right-align items within a group -->
@@ -118,9 +188,11 @@ See `demo/toolbar.html` for complete examples including:
118
188
 
119
189
  - Word-style horizontal toolbar with font selection, formatting buttons, and paragraph controls
120
190
  - Chrome-style toolbar with a growable search input
121
- - Vertical toolbars with different writing modes
191
+ - Vertical toolbars with different orientations (`vertical-right`, `vertical-left`) and writing modes
192
+ - Horizontal alignment – `toolbar-align="near"` (left) vs `far` (right) with static examples, overflow example, and interactive toggle
122
193
  - Footer toolbar with far-right justified group
123
194
  - Toolbar with group labels displayed as rows
195
+ - Overflow modes: `collapsed` and `disabled` examples
124
196
 
125
197
  ---
126
198
 
@@ -130,6 +202,7 @@ See `demo/toolbar.html` for complete examples including:
130
202
  import type {
131
203
  ToolbarOrientation, // 'horizontal' | 'vertical-left' | 'vertical-right'
132
204
  ToolbarLayout, // 'one-line' | 'wrap'
133
- ToolbarVerticalWriting // 'auto' | 'up' | 'down' | 'none'
205
+ ToolbarVerticalWriting, // 'auto' | 'up' | 'down' | 'none'
206
+ ToolbarAlign // 'near' | 'far'
134
207
  } from 'ixfxfun-components';
135
208
  ```
@@ -0,0 +1,254 @@
1
+ # Two-Way Split Layout
2
+
3
+ A Lit web component that lays out two elements within a container with a split bar to adjust their proportions.
4
+
5
+ ---
6
+
7
+ ## `ixfx-twosplit-layout`
8
+
9
+ ### Attributes
10
+
11
+ | Attribute | Type | Default | Description |
12
+ |-----------|------|---------|-------------|
13
+ | `layout` | `vertical` \| `horizontal` | `vertical` | Split orientation. `vertical` creates left/right panels, `horizontal` creates top/bottom panels. |
14
+ | `sizeA` | `String` | `""` | CSS size for panel A (slot `a`). Can use relative (`50%`) or absolute (`100px`) values. Empty string defaults to `auto`. |
15
+ | `sizeB` | `String` | `""` | CSS size for panel B (slot `b`). Same format as `sizeA`. |
16
+ | `fixedA` | `Boolean` | `false` | If `true`, `sizeA` is calculated in pixels rather than percentage of whole. |
17
+ | `fixedB` | `Boolean` | `false` | If `true`, `sizeB` is calculated in pixels rather than percentage of whole. |
18
+ | `collapsible` | `Boolean` | `false` | If `true`, panels can be collapsed by dragging the handle to the edge. The other panel expands to fill the space. |
19
+ | `minSizeA` | `String` | `""` | Minimum size for panel A (e.g., `"100px"` or `"20%"`). Empty means no minimum. |
20
+ | `maxSizeA` | `String` | `""` | Maximum size for panel A. Empty means no maximum. |
21
+ | `minSizeB` | `String` | `""` | Minimum size for panel B. |
22
+ | `maxSizeB` | `String` | `""` | Maximum size for panel B. |
23
+
24
+ ### Properties
25
+
26
+ | Property | Type | Description |
27
+ |----------|------|-------------|
28
+ | `collapsedA` | `Boolean` (reflects attribute) | `true` if panel A is currently collapsed. |
29
+ | `collapsedB` | `Boolean` (reflects attribute) | `true` if panel B is currently collapsed. |
30
+
31
+ ### CSS Variables
32
+
33
+ | Variable | Default | Description |
34
+ |----------|---------|-------------|
35
+ | `--handle-size` | `2px` | Width/height of the split bar |
36
+ | `--handle-colour` | `transparent` | Colour of the split bar |
37
+ | `--handle-hover-colour` | `var(--surface-6)` | Colour of handle when hovering |
38
+ | `--handle-active-colour` | `var(--accent)` | Colour of handle when being dragged |
39
+ | `--handle-bg` | `var(--handle-colour)` | Background colour of the grab handle rectangle |
40
+ | `--handle-grab-colour` | `var(--surface-muted-text)` | Colour of the grab handle dots |
41
+ | `--handle-grab-dot-size` | `3px` | Diameter of each grab handle dot |
42
+ | `--handle-grab-size` | `16px` | Length of the grab handle |
43
+ | `--handle-grab-thickness` | `8px` | Thickness of the grab handle |
44
+
45
+ ### Events
46
+
47
+ | Event | Detail | Description |
48
+ |-------|--------|-------------|
49
+ | `ixfx-split-collapsed` | `{ panel: 'A' \| 'B', collapsed: boolean }` | Fired when a panel is collapsed or uncollapsed via drag. |
50
+
51
+ ---
52
+
53
+ ## Basic Usage
54
+
55
+ ### Vertical Split (Left/Right)
56
+
57
+ ```html
58
+ <ixfx-twosplit-layout layout="vertical" style="width: 100%; height: 400px;">
59
+ <div slot="a" style="background: var(--surface-3);">Left Panel</div>
60
+ <div slot="b" style="background: var(--surface-5);">Right Panel</div>
61
+ </ixfx-twosplit-layout>
62
+ ```
63
+
64
+ ### Horizontal Split (Top/Bottom)
65
+
66
+ ```html
67
+ <ixfx-twosplit-layout layout="horizontal" style="width: 100%; height: 400px;">
68
+ <div slot="a" style="background: var(--surface-3);">Top Panel</div>
69
+ <div slot="b" style="background: var(--surface-5);">Bottom Panel</div>
70
+ </ixfx-twosplit-layout>
71
+ ```
72
+
73
+ ### With Fixed Panel
74
+
75
+ ```html
76
+ <!-- Left panel fixed at 200px, right panel takes remaining space -->
77
+ <ixfx-twosplit-layout fixedA layout="vertical" style="width: 100%; height: 400px;">
78
+ <div slot="a" style="background: var(--surface-3);">Left Panel (200px)</div>
79
+ <div slot="b" style="background: var(--surface-5);">Right Panel (flexible)</div>
80
+ </ixfx-twosplit-layout>
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Collapsible Panels
86
+
87
+ When `collapsible` is set, dragging a split bar to the edge collapses that panel. The other panel expands to fill the space. Dragging away from the edge uncollapses the panel.
88
+
89
+ ```html
90
+ <ixfx-twosplit-layout collapsible layout="horizontal" style="width: 100%; height: 400px;">
91
+ <div slot="a" style="background: var(--surface-3);">Top Panel</div>
92
+ <div slot="b" style="background: var(--surface-5);">Bottom Panel</div>
93
+ </ixfx-twosplit-layout>
94
+ ```
95
+
96
+ ### Collapse Events
97
+
98
+ ```javascript
99
+ const split = document.querySelector('ixfx-twosplit-layout[collapsible]');
100
+
101
+ split.addEventListener('ixfx-split-collapsed', ({ detail }) => {
102
+ console.log(`Panel ${detail.panel} is now ${detail.collapsed ? 'collapsed' : 'uncollapsed'}`);
103
+ });
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Min/Max Size Constraints
109
+
110
+ Use `minSizeA`, `maxSizeA`, `minSizeB`, and `maxSizeB` to constrain panel sizes:
111
+
112
+ ```html
113
+ <ixfx-twosplit-layout
114
+ minSizeA="100px"
115
+ maxSizeA="70%"
116
+ minSizeB="50px"
117
+ layout="horizontal"
118
+ style="width: 100%; height: 400px;">
119
+ <div slot="a" style="background: var(--surface-3);">Top Panel</div>
120
+ <div slot="b" style="background: var(--surface-5);">Bottom Panel</div>
121
+ </ixfx-twosplit-layout>
122
+ ```
123
+
124
+ **Constraint rules:**
125
+ - **Min constraints take precedence**: If both panels' minimums exceed 100% combined, they're scaled proportionally
126
+ - **Max constraints are secondary**: If a max constraint conflicts with a min constraint, the max is ignored to satisfy the min
127
+ - **The constrained panel gets clamped**: The other panel receives the remaining space
128
+
129
+ ---
130
+
131
+ ## Nested Splits with Two-Way Corner Resize
132
+
133
+ When a `ixfx-twosplit-layout` is nested inside slot A of an outer split, a corner zone appears at the intersection of the two split bars. This enables simultaneous resize of both splits.
134
+
135
+ ```
136
+ ┌─────────────────┬────────────┐
137
+ │ │ │
138
+ │ ┌─────────────┤ │
139
+ │ │ Editor │ │
140
+ │ │ │ │
141
+ │ ├─────────────┤ Sidebar │
142
+ │ │ Terminal │ │
143
+ │ │ │ │
144
+ │ └─────────────┘ │
145
+ └─────────────────┴────────────┘
146
+
147
+ Corner Zone
148
+ (drag here for two-way resize)
149
+ ```
150
+
151
+ ### Structure
152
+
153
+ ```html
154
+ <ixfx-twosplit-layout layout="vertical" style="width: 100%; height: 400px;">
155
+ <!-- Nested split is a direct child of slot A -->
156
+ <ixfx-twosplit-layout slot="a" layout="horizontal" style="width: 100%; height: 100%;">
157
+ <div slot="a" style="background: var(--surface);">Editor</div>
158
+ <div slot="b" style="background: var(--surface-3);">Terminal</div>
159
+ </ixfx-twosplit-layout>
160
+ <div slot="b" style="background: var(--surface-5);">Sidebar</div>
161
+ </ixfx-twosplit-layout>
162
+ ```
163
+
164
+ **Note**: For the corner zone to appear, the nested split must be a direct child of slot A (no wrapper elements between the split and slot A).
165
+
166
+ ### Corner Zone Behavior
167
+
168
+ - **Visual indicator**: A small magenta circle (12px) appears at the intersection point
169
+ - **Cursor change**: Shows `nwse-resize` cursor when hovering over the corner zone (for vertical-outer/horizontal-inner splits)
170
+ - **Two-way resize**: Dragging the corner zone adjusts both the outer vertical split and the inner horizontal split simultaneously
171
+ - **Position tracking**: The corner zone follows the split bars as they move, staying at their intersection
172
+
173
+ ---
174
+
175
+ ## CSS Customisation
176
+
177
+ ### Handle Styling
178
+
179
+ ```css
180
+ ixfx-twosplit-layout {
181
+ --handle-size: 4px;
182
+ --handle-colour: var(--surface-4);
183
+ --handle-hover-colour: var(--surface-6);
184
+ --handle-active-colour: var(--accent);
185
+ }
186
+ ```
187
+
188
+ ### Grab Handle
189
+
190
+ When `--handle-size` is greater than `5px`, a grab handle appears in the center of the split bar. The grab handle consists of a rectangle with three dots arranged perpendicular to the split direction:
191
+
192
+ - **Vertical split**: Rectangle with 3 vertical dots (⋮)
193
+ - **Horizontal split**: Rectangle with 3 horizontal dots (⁝)
194
+
195
+ ```css
196
+ ixfx-twosplit-layout {
197
+ --handle-bg: var(--handle-colour); /* Rectangle background */
198
+ --handle-grab-colour: var(--surface-muted-text); /* Dot colour */
199
+ --handle-grab-dot-size: 3px; /* Dot diameter */
200
+ --handle-grab-size: 16px; /* Rectangle length */
201
+ --handle-grab-thickness: 8px; /* Rectangle thickness */
202
+ }
203
+ ```
204
+
205
+ ### Hide Collapsed Panels Completely
206
+
207
+ ```css
208
+ ixfx-twosplit-layout[data-collapsed-a] slot[name="a"] {
209
+ display: none;
210
+ }
211
+ ```
212
+
213
+ ---
214
+
215
+ ## Programmatic Control
216
+
217
+ ### Setting Sizes
218
+
219
+ ```javascript
220
+ const split = document.querySelector('ixfx-twosplit-layout');
221
+
222
+ // Set to 30% / 70%
223
+ split.sizeA = '30%';
224
+ split.sizeB = '70%';
225
+
226
+ // Set to fixed pixel widths
227
+ split.fixedA = true;
228
+ split.sizeA = '200px'; // Panel A is 200px
229
+ // Panel B automatically gets remaining space
230
+
231
+ // Collapse a panel programmatically
232
+ split.collapsedA = true;
233
+ split.collapsedB = false;
234
+ ```
235
+
236
+ ### Reading State
237
+
238
+ ```javascript
239
+ console.log('Panel A size:', split.sizeA);
240
+ console.log('Panel B size:', split.sizeB);
241
+ console.log('Is A collapsed?', split.collapsedA);
242
+ console.log('Is B collapsed?', split.collapsedB);
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Implementation Notes
248
+
249
+ - Uses Shadow DOM for style encapsulation
250
+ - Slots use `display: block` and `overflow: hidden` by default
251
+ - When no size is specified for a panel, it defaults to `auto` (fill remaining space)
252
+ - When both sizes are empty, both default to `50%`
253
+ - The split bar is `flex-shrink: 0` to prevent it from collapsing
254
+ - Nested splits detect their parent through slot assignment and automatically enable corner resize
@@ -27,6 +27,9 @@ Combines a range slider with a label and optional input field for precise value
27
27
  ### ixfx-labelled-radial-input
28
28
  A circular input control for selecting values in a rotational manner. Ideal for color pickers, angle selectors, or any cyclical value selection.
29
29
 
30
+ ### ixfx-labelled-slider-input
31
+ Combines a linear SVG slider with a label and optional input field for precise value entry. Use when users need to select from a continuous range of values with both coarse and fine control, with marker and value-bar styling options.
32
+
30
33
  ### ixfx-ac-text
31
34
  An autocomplete text input that suggests options as the user type. Perfect for search boxes, tag entry, or any field where you want to assist users with predefined options.
32
35
 
@@ -120,8 +123,11 @@ A meta-component that renders a typed item list using any sub-component you supp
120
123
 
121
124
  ## Layout Components
122
125
 
126
+ ### ixfx-dock-host / ixfx-dock-panel
127
+ A dockable panel system in the style of VS Code. Author a flat pool of `ixfx-dock-panel` elements inside an `ixfx-dock-host`; drag panels by titlebar or tab to tab them together, split panels horizontally/vertically, or drag between hosts. Layouts serialize via `saveLayout()` / `loadLayout()` for persistence. Drop restrictions are available per host (`accepts` attribute, `canAccept()` callback) and per panel (`accepts`). Use for IDE-like workspaces, dashboards, or any composable multi-panel UI.
128
+
123
129
  ### ixfx-split-layout
124
- A resizable split pane that allows users to adjust the proportion between two adjacent sections. Use for editor layouts, file explorers with previews, or any interface where users need to control space allocation.
130
+ A resizable n-way split pane that allows users to adjust the proportion between adjacent sections. Supports `row`/`column` directions, positional `sizes` weights, per-child `size`/`min`/`collapsed` attributes, and nested splits for cross-axis layouts. Use for editor layouts, file explorers with previews, or any interface where users need to control space allocation.
125
131
 
126
132
  ### ixfx-snap-container
127
133
  A container that snaps child elements to specific positions or alignments. Useful for creating custom layouts, dashboards, or any interface where precise element positioning is needed.
@@ -186,6 +192,7 @@ When choosing components for your application, consider these patterns:
186
192
  - Use `ixfx-checkbox` for binary options
187
193
  - Use `ixfx-radio-group` for mutually exclusive choices
188
194
  - Use `ixfx-labelled-range-input` for numerical parameters with labels
195
+ - Use `ixfx-labelled-slider-input` for numerical parameters with labels and slider styling options
189
196
  - Use `ixfx-toggle-switch` for settings with clear on/off states
190
197
  - Use `ixfx-range-input` or `ixfx-slider-input` for plain slider-style numeric entry
191
198
  - Use `ixfx-editable-number` for values that benefit from both typing and dragging
@@ -116,6 +116,113 @@ Customize individual components using inline styles:
116
116
  </ixfx-button>
117
117
  ```
118
118
 
119
+ ## Icons
120
+
121
+ ### Built-in Icons
122
+
123
+ The library ships with a set of SVG icons registered by default. All use `fill="currentColor"` so they inherit CSS color automatically.
124
+
125
+ | Name | Description |
126
+ |---|---|
127
+ | `add` | Plus / add icon |
128
+ | `caret-right` | Caret pointing right (used by tree expand indicators) |
129
+ | `check` | Checkmark |
130
+ | `chevron-down` | Chevron pointing down (used by split-button dropdowns) |
131
+ | `chevron-right` | Chevron pointing right |
132
+ | `close` | X / close icon |
133
+ | `error` | Error/warning icon |
134
+ | `folder-up` | Folder with up-arrow |
135
+ | `info` | Info icon |
136
+ | `warning` | Warning icon |
137
+
138
+ ### `<ixfx-icon>` Element
139
+
140
+ Render any registered icon by name:
141
+
142
+ ```html
143
+ <ixfx-icon name="check"></ixfx-icon>
144
+ <ixfx-icon name="chevron-down" size="24"></ixfx-icon>
145
+ <ixfx-icon name="close" label="Dismiss dialog"></ixfx-icon>
146
+ <ixfx-icon name="check" rotate="45deg"></ixfx-icon>
147
+ <ixfx-icon name="settings" prominence></ixfx-icon>
148
+ ```
149
+
150
+ **Attributes:**
151
+
152
+ | Attribute | Type | Description |
153
+ |---|---|---|
154
+ | `name` | `string` | Registry name of the icon |
155
+ | `size` | `number` | Fixed pixel size |
156
+ | `label` | `string` | Accessible label; adds `aria-label` |
157
+ | `rotate` | `string` | CSS angle (e.g. `"90deg"`) |
158
+ | `prominence` | `boolean` | Enables idle/hover/disabled opacity |
159
+
160
+ Icon sizing is `1em × 1em` by default — override with CSS or the `size` attribute:
161
+
162
+ ```css
163
+ ixfx-icon { width: 24px; height: 24px; }
164
+ ```
165
+
166
+ ### Adding a Custom SVG Icon
167
+
168
+ Register an icon before use — it can be done at any time; components update automatically.
169
+
170
+ ```ts
171
+ import { registerIcon } from '@ixfx/components';
172
+
173
+ registerIcon('my-logo', `<svg viewBox="0 0 24 24" fill="currentColor">
174
+ <path d="M12 2L4 12h5v8h6v-8h5L12 2z"/>
175
+ </svg>`);
176
+ ```
177
+
178
+ ```html
179
+ <ixfx-icon name="my-logo"></ixfx-icon>
180
+ ```
181
+
182
+ ### Font Icons (Icon Fonts)
183
+
184
+ Icon fonts such as Nerd Fonts are supported alongside SVG icons. Set the font family globally once, then register individual icons by name and code point.
185
+
186
+ ```ts
187
+ import { setIconFont, registerFontIcon } from '@ixfx/components';
188
+
189
+ // Set the font family (load it via CSS first)
190
+ setIconFont('"Font Awesome 6 Free"');
191
+
192
+ // Register a gear icon by code point
193
+ registerFontIcon('gear', 0xf013);
194
+
195
+ // Or by literal character
196
+ registerFontIcon('heart', '\uf004');
197
+ ```
198
+
199
+ Use font icons exactly like SVG icons — no API change:
200
+
201
+ ```html
202
+ <ixfx-icon name="gear"></ixfx-icon>
203
+ <ixfx-button icon="gear">Settings</ixfx-button>
204
+ ```
205
+
206
+ Font icons inherit `color` and size to `1em` automatically. Rotation and prominence attributes work the same as for SVG icons.
207
+
208
+ > **Different fonts, different code points.** Icon fonts use different Private Use Area code points for the same glyphs. Switching fonts requires re-registering icons with the appropriate code points for that font. See the [icons demo](/demo/loader.html?demo=icons) for a live example of font switching.
209
+
210
+ ### Overriding a Built-in Icon
211
+
212
+ Both `registerIcon` (SVG) and `registerFontIcon` overwrite any existing entry for the same name. To swap a built-in icon globally:
213
+
214
+ ```ts
215
+ // Replace the built-in chevron-down with a custom SVG
216
+ registerIcon('chevron-down', `<svg viewBox="0 0 24 24" fill="currentColor">
217
+ <path d="M7 10l5 5 5-5H7z"/>
218
+ </svg>`);
219
+
220
+ // Replace it with a font icon instead
221
+ registerFontIcon('chevron-down', 0xe0b0);
222
+ ```
223
+
224
+ All components that use the overridden name update automatically on the next render.
225
+
119
226
  ## Complete Base Theme Reference
120
227
 
121
228
  Below is the full set of CSS variables used by the library. Copy this into your own stylesheet as a starting point and override the values you want to change.
@@ -375,5 +482,7 @@ If you're upgrading from previous versions:
375
482
 
376
483
  For implementation details, see:
377
484
  - [`docs/infra-theming.md`](infra-theming.md) - Internal theming specification
485
+ - [`docs-user/icons.md`](/docs-user/icons.md) - Full icon registry reference
486
+ - [`demo/loader.html?demo=icons`](/demo/loader.html?demo=icons) - Interactive icons demo
378
487
  - [`src/style.css`] - Base theme definitions
379
488
  - [`demo/shared/`] - Example theme implementations
package/llms.txt CHANGED
@@ -19,6 +19,8 @@ import '@ixfx/components/data-grid';
19
19
  - [crumbs](docs-user/crumbs.md): Breadcrumb navigation with lazy-loading child support. Uses the same `TreeNode` / `TreeItem` data model as `ixfx-tree-list`, allowing easy swapping between the two components.
20
20
  - [data-display](docs-user/data-display.md): A debug data display component that renders key-value pairs from a plain object. Supports 7 inline render modes (`led`, `plot`, `plot-xy`, `plot-heat`, `plot-histogram`, `time-elapsed`, `hide`) via `c
21
21
  - [data-grid](docs-user/data-grid.md): A virtualised data grid with sortable/resizable/reorderable columns, single/multi selection, grouping, and inline cell editing. Handles 200+ rows with windowed rendering and keyboard navigation.
22
+ - [detail-list](docs-user/detail-list.md): A list that scales horizontally, not vertically. Items are laid out in equal-width columns; they flow top→bottom down a column, then wrap to the top of the next column to the right. The component has
23
+ - [dock](docs-user/dock.md): Dockable, movable panels like VS Code / Photoshop. Drag a panel by its
22
24
  - [editable-label](docs-user/editable-label.md): Inline editable text components. `ixfx-editable-number` extends `ixfx-editable-label` with drag-to-adjust and fill-bar visualization.
23
25
  - [form](docs-user/form.md): Primitives for typical form layout with responsive label positioning and data binding.
24
26
  - [grouped-item-lister](docs-user/grouped-item-lister.md): A meta-component that renders a typed item list using any sub-component you supply. Items can be displayed in a single sub-component (_ungrouped_ mode) or split into labelled groups, each with its own
@@ -26,6 +28,7 @@ import '@ixfx/components/data-grid';
26
28
  - [incr-search](docs-user/incr-search.md): Utilities for incremental (type-ahead) search over data collections or DOM-backed lists.
27
29
  - [labelled-radial-input](docs-user/labelled-radial-input.md): A composite radial input that pairs an editable label (`ixfx-editable-number`) with a rotary dial (`ixfx-radial-input`). The two controls are always in sync — turning the dial updates the number, and
28
30
  - [labelled-range-input](docs-user/labelled-range-input.md): A composite range input that pairs an editable label (`ixfx-editable-number`) with a slider (`ixfx-range-input`). The two controls are always in sync — dragging the slider updates the number, and edit
31
+ - [labelled-slider-input](docs-user/labelled-slider-input.md): A composite slider input that pairs an editable label (`ixfx-editable-number`) with a slider (`ixfx-slider-input`). The two controls are always in sync — dragging the slider updates the number, and ed
29
32
  - [led](docs-user/led.md): An LED indicator component with color mixing and optional blinking animation.
30
33
  - [menu](docs-user/menu.md): A custom menu system built on native HTML popovers with keyboard navigation, tickled focus management, and command routing.
31
34
  - [miller](docs-user/miller.md): A Miller column component displays hierarchical data as multiple vertical columns, like macOS Finder or email clients. Each column shows the children of the selected item in the previous column.
@@ -42,13 +45,15 @@ import '@ixfx/components/data-grid';
42
45
  - [slider-input](docs-user/slider-input.md): A linear SVG-based slider. Supports horizontal and vertical orientations, three value modes (single/dual/triple), three single-mode styles (range/bipolar/unipolar), triangle/needle/dot markers, and `v
43
46
  - [snackbar](docs-user/snackbar.md): A small floating toolbar anchored in visual proximity to another element on the page (the "target"), built on the native Popover and CSS Anchor Positioning APIs.
44
47
  - [snap-container](docs-user/snap-container.md): A container that positions its child element at configurable snap positions along an axis. The child can be dragged, clicked to snap, or controlled via keyboard.
45
- - [split-layout](docs-user/split-layout.md): A Lit web component that lays out two elements within a container with a split bar to adjust their proportions.
48
+ - [split-layout](docs-user/split-layout.md): A Lit web component that lays out any number of panels along one axis with draggable gutters between them.
46
49
  - [swipe](docs-user/swipe.md): A touch-friendly swipe/nudge component. User taps and drags to generate a value in range [-1, 1]. Value is emitted only on pointer release.
47
50
  - [tabs](docs-user/tabs.md): A complete tabbed interface system using several coordinated components:
48
51
  - [timeline](docs-user/timeline.md): A canvas-based timeline component with tracks, events, zoom/pan, and vertical track resizing. Suitable for visualizing time-series data, event logs, or scheduling.
52
+ - [titlebar](docs-user/titlebar.md): Standalone titlebar chrome extracted from `ixfx-panel`: title text, icon, toolbar slot, close button and an optional collapse/expand caret. Use it when you need a panel-style header without the collap
49
53
  - [toolbar](docs-user/toolbar.md): Two components for building toolbars:
50
54
  - [transitory-label](docs-user/transitory-label.md): An inline text label that animates between values instead of changing instantly. Displays as `inline-block` and inherits text styling from its parent.
51
55
  - [tree](docs-user/tree.md): Three components share a common `TreeComponent` interface: **`ixfx-tree-list`**, **`ixfx-miller-list`**, and **`ixfx-crumb-navigation`**. This document describes the shared API, plus component-specifi
56
+ - [twosplit-layout](docs-user/twosplit-layout.md): A Lit web component that lays out two elements within a container with a split bar to adjust their proportions.
52
57
  - [util](docs-user/util.md): A tooltip component that renders a value with optional icon and formatted number display. Uses native render root (no shadow DOM).
53
58
  - [vertical-list](docs-user/vertical-list.md): A scrollable vertical list of items with selection, keyboard navigation, and incremental search. Items can be plain `<li>` elements declared in HTML or rich custom elements added programmatically.
54
59
  - [xy-pad](docs-user/xy-pad.md): A 2D touch-friendly XY pad for controlling two parameters simultaneously. Each axis supports independent linear/logarithmic scaling.
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "@ixfx/components",
3
3
  "type": "module",
4
- "version": "0.6.2",
4
+ "version": "0.7.1",
5
5
  "packageManager": "pnpm@10.0.0",
6
6
  "description": "Web components for ixfx — Lit-based UI toolkit",
7
7
  "author": "Clint Heyer",
8
8
  "license": "MIT",
9
9
  "keywords": ["web-components", "lit", "ixfx", "ui"],
10
- "sideEffects": false,
11
10
  "exports": {
12
11
  ".": {
13
12
  "types": "./dist/index.d.ts",
@@ -1 +0,0 @@
1
- {"version":3,"file":"button-Bn0BuLpO.js","names":["customElement"],"sources":["../src/button/button-styles.ts","../src/button/button.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const buttonStyles = css`\n :host {\n display: inline-flex;\n max-width: 100%;\n vertical-align: middle;\n user-select: none;\n -webkit-user-select: none;\n }\n\n :host([hidden]) {\n display: none;\n }\n\n button {\n cursor: pointer;\n appearance: none;\n background: var(--surface-4, #ccc);\n color: var(--surface-3-text, #000);\n border: var(--border, 1px solid #999);\n outline: var(--ixfx-button-outline, none);\n border-radius: var(--radius-xl, 8px);\n corner-shape: superellipse(1);\n padding: var(--space-m, 8px) var(--space-l, 12px);\n font-family: var(--font-family, inherit);\n font-size: var(--text-m, 14px);\n margin: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5em;\n width: 100%;\n overflow: hidden;\n white-space: nowrap;\n box-shadow: \n var(--ixfx-button-shade, none),\n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-4) 30%, transparent), inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 20%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 30%, transparent);\n transition: background var(--transition, 0.2s), border-color var(--transition, 0.2s);\n }\n\n button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n button:hover:not(:disabled) {\n background: color-mix(in oklch, var(--surface-4) 80%, transparent);\n border-color: var(--accent, #666);\n box-shadow: \n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-5) 70%, transparent), \n inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 60%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 90%, transparent);\n }\n\n button:active:not(:disabled) {\n background: var(--surface-2, #aaa);\n transform: translateY(1px);\n box-shadow: inset 1px 1px 0px 0.5px color-mix(in oklch,var(--surface-1),transparent);\n }\n\n .button-icon {\n display: var(--ixfx-button-hide-icon, inline-flex);\n align-items: center;\n flex-shrink: 0;\n }\n\n .button-label {\n white-space: nowrap;\n }\n\n :host([has-icon]) .button-label {\n display: var(--ixfx-button-hide-label, inline);\n }\n\n :host([hide-label]) .button-label {\n display: none;\n }\n\n :host([hide-icon]) .button-icon {\n display: none;\n }\n\n :host([subtle]) button {\n background: color-mix(in oklch, var(--surface-4, #ccc) 40%, transparent);\n }\n\n :host([subtle]) button:hover:not(:disabled),\n :host([subtle]) button:focus-visible:not(:disabled) {\n background: color-mix(in oklch, var(--surface-4, #ccc) 70%, transparent);\n }\n`;\n","import { html, LitElement, nothing } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { unsafeHTML } from \"lit/directives/unsafe-html.js\";\nimport { getIcon } from \"../icons/index.js\";\nimport { prominenceStyles } from \"../styles/prominence.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\nimport { buttonStyles } from \"./button-styles.js\";\n\n@customElement(`ixfx-button`)\nexport class ButtonElement extends LitElement {\n @property({ type: Boolean })\n disabled = false;\n\n @property({ type: String })\n icon?: string;\n\n @property({ type: Boolean, attribute: `hide-icon`, reflect: true })\n hideIcon = false;\n\n @property({ type: Boolean, attribute: `hide-label`, reflect: true })\n hideLabel = false;\n\n @property({ type: Boolean, attribute: `has-icon`, reflect: true })\n hasIcon = false;\n\n @property({ type: Boolean, reflect: true })\n subtle = false;\n\n protected _renderIcon() {\n if (this.hideIcon || !this.icon)\n return nothing;\n\n if (this.icon.startsWith(`<svg`)) {\n return html`<span class=\"button-icon\">${unsafeHTML(this.icon)}</span>`;\n }\n\n const svg = getIcon(this.icon);\n\n if (!svg)\n return nothing;\n\n return html`<ixfx-icon class=\"button-icon\" name=\"${this.icon}\"></ixfx-icon>`;\n }\n\n protected render() {\n this.hasIcon = !this.hideIcon && !!this.icon;\n const label = this.hideLabel\n ? nothing\n : html`<span class=\"button-label\"><slot></slot></span>`;\n return html`<button ?disabled=${this.disabled}>${this._renderIcon()}${label}</button>`;\n }\n\n static styles = [\n prominenceStyles,\n buttonStyles,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-button\": ButtonElement;\n }\n}\n"],"mappings":";;;;;;;AAEA,MAAa,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACOxB,IAAM,gBAAN,MAAM,sBAAsB,WAAW;;;EAEjC,KAAA,WAAA;EAMA,KAAA,WAAA;EAGC,KAAA,YAAA;EAGF,KAAA,UAAA;EAGD,KAAA,SAAA;;CAET,cAAwB;EACtB,IAAI,KAAK,YAAY,CAAC,KAAK,MACzB,OAAO;EAET,IAAI,KAAK,KAAK,WAAW,MAAM,GAC7B,OAAO,IAAI,6BAA6B,WAAW,KAAK,IAAI,EAAE;EAKhE,IAAI,CAFQ,QAAQ,KAAK,IAElB,GACL,OAAO;EAET,OAAO,IAAI,wCAAwC,KAAK,KAAK;CAC/D;CAEA,SAAmB;EACjB,KAAK,UAAU,CAAC,KAAK,YAAY,CAAC,CAAC,KAAK;EACxC,MAAM,QAAQ,KAAK,YACf,UACA,IAAI;EACR,OAAO,IAAI,qBAAqB,KAAK,SAAS,GAAG,KAAK,YAAY,IAAI,MAAM;CAC9E;;EAEgB,KAAA,SAAA,CACd,kBACA,YACF;;AACF;AA9CG,WAAA,CAAA,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,cAAA,WAAA,YAAA,KAAA,CAAA;AAG1B,WAAA,CAAA,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,cAAA,WAAA,QAAA,KAAA,CAAA;AAGzB,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,WAAW;CAAa,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,YAAA,KAAA,CAAA;AAGjE,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,WAAW;CAAc,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,aAAA,KAAA,CAAA;AAGlE,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,WAAW;CAAY,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,WAAA,KAAA,CAAA;AAGhE,WAAA,CAAA,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,cAAA,WAAA,UAAA,KAAA,CAAA;AAjB3CA,gBAAAA,WAAAA,CAAAA,kBAAc,aAAa,CAAA,GAAA,aAAA"}