@ixfx/components 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/bundle/index.d.ts +1086 -603
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +16153 -15296
  4. package/bundle/index.js.map +1 -1
  5. package/bundle/style.css +14 -4
  6. package/dist/ac-text.d.ts.map +1 -1
  7. package/dist/ac-text.js +11 -6
  8. package/dist/ac-text.js.map +1 -1
  9. package/dist/{button-DMt5XWUK.js → button-C3fLMKUv.js} +4 -4
  10. package/dist/{button-DMt5XWUK.js.map → button-C3fLMKUv.js.map} +1 -1
  11. package/dist/button.d.ts +1 -1
  12. package/dist/button.d.ts.map +1 -1
  13. package/dist/button.js +1 -1
  14. package/dist/checkbox.d.ts +2 -2
  15. package/dist/checkbox.d.ts.map +1 -1
  16. package/dist/checkbox.js +14 -8
  17. package/dist/checkbox.js.map +1 -1
  18. package/dist/{colour-C3MQIjFJ-BLXg8W3U.js → colour-C3MQIjFJ-vRCdr8W-.js} +146 -552
  19. package/dist/colour-C3MQIjFJ-vRCdr8W-.js.map +1 -0
  20. package/dist/{colour-picker-K6zu82lm.js → colour-picker-0sgAha1T.js} +14 -9
  21. package/dist/colour-picker-0sgAha1T.js.map +1 -0
  22. package/dist/colour-picker.d.ts +1 -1
  23. package/dist/colour-picker.js +1 -1
  24. package/dist/crumbs.d.ts +1 -1
  25. package/dist/crumbs.d.ts.map +1 -1
  26. package/dist/crumbs.js +11 -6
  27. package/dist/crumbs.js.map +1 -1
  28. package/dist/data-display.d.ts +9 -4
  29. package/dist/data-display.d.ts.map +1 -1
  30. package/dist/data-display.js +270 -43
  31. package/dist/data-display.js.map +1 -1
  32. package/dist/data-provider-DgI909FP.js +23 -0
  33. package/dist/data-provider-DgI909FP.js.map +1 -0
  34. package/dist/{decorate-D7rC1gLP.js → decorate-DdjvVHS-.js} +2 -2
  35. package/dist/{decorate-D7rC1gLP.js.map → decorate-DdjvVHS-.js.map} +1 -1
  36. package/dist/{defaults-C7elhuyJ.js → defaults-C3b9OWJD.js} +2 -2
  37. package/dist/{defaults-C7elhuyJ.js.map → defaults-C3b9OWJD.js.map} +1 -1
  38. package/dist/{dist-TAGYwaju.js → dist-CA13FvMn.js} +7 -66
  39. package/dist/dist-CA13FvMn.js.map +1 -0
  40. package/dist/editable-label.d.ts.map +1 -1
  41. package/dist/editable-label.js +3 -2
  42. package/dist/editable-label.js.map +1 -1
  43. package/dist/fallbacks-pNMOMx38.js +168 -0
  44. package/dist/fallbacks-pNMOMx38.js.map +1 -0
  45. package/dist/{hex-editor-DlfoA65y.d.ts → hex-editor-CMIxtNgT.d.ts} +1 -1
  46. package/dist/hex-editor-CMIxtNgT.d.ts.map +1 -0
  47. package/dist/{hex-editor-CsN_ySkH.js → hex-editor-WZrjRtvL.js} +3 -3
  48. package/dist/{hex-editor-CsN_ySkH.js.map → hex-editor-WZrjRtvL.js.map} +1 -1
  49. package/dist/hex.d.ts +1 -1
  50. package/dist/hex.js +1 -1
  51. package/dist/{highlight-TPbSHruI.js → highlight-B-eQrhhb.js} +1 -1
  52. package/dist/{highlight-TPbSHruI.js.map → highlight-B-eQrhhb.js.map} +1 -1
  53. package/dist/{icon-Dm_DHDz6.d.ts → icon-Bd5BiU4b.d.ts} +3 -3
  54. package/dist/icon-Bd5BiU4b.d.ts.map +1 -0
  55. package/dist/{icon-9NWTXtE1.js → icon-Ndo40kNO.js} +6 -5
  56. package/dist/icon-Ndo40kNO.js.map +1 -0
  57. package/dist/icons.d.ts +2 -2
  58. package/dist/icons.js +3 -3
  59. package/dist/{incr-search-DSKKsk6w.js → incr-search-CeERfijK.js} +2 -2
  60. package/dist/{incr-search-DSKKsk6w.js.map → incr-search-CeERfijK.js.map} +1 -1
  61. package/dist/incr-search.d.ts +1 -1
  62. package/dist/incr-search.js +2 -2
  63. package/dist/{index-hXFn14tM.d.ts → index-BMjri2-S.d.ts} +2 -2
  64. package/dist/{index-hXFn14tM.d.ts.map → index-BMjri2-S.d.ts.map} +1 -1
  65. package/dist/{index-DSlPeWLK.d.ts → index-CWpNcQKE.d.ts} +5 -5
  66. package/dist/index-CWpNcQKE.d.ts.map +1 -0
  67. package/dist/{index-DLkSKL4T.d.ts → index-CowKi2mo.d.ts} +1 -1
  68. package/dist/index-CowKi2mo.d.ts.map +1 -0
  69. package/dist/{index-B1hNR7Z9.d.ts → index-D87kRcEs.d.ts} +1 -1
  70. package/dist/{index-B1hNR7Z9.d.ts.map → index-D87kRcEs.d.ts.map} +1 -1
  71. package/dist/{index-CnL9krsH.d.ts → index-DgXpCg_G.d.ts} +32 -26
  72. package/dist/index-DgXpCg_G.d.ts.map +1 -0
  73. package/dist/{index-iZLld8Ca.d.ts → index-s_IhSnwc.d.ts} +2 -2
  74. package/dist/index-s_IhSnwc.d.ts.map +1 -0
  75. package/dist/index.d.ts +432 -121
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +2369 -1706
  78. package/dist/index.js.map +1 -1
  79. package/dist/interaction-D6efrBLo.js +1 -0
  80. package/dist/{keyboard-De_vOHLg.js → keyboard-CimiEskD.js} +1 -1
  81. package/dist/{keyboard-De_vOHLg.js.map → keyboard-CimiEskD.js.map} +1 -1
  82. package/dist/{labelled-input-base-CqPL5rKm.js → labelled-input-base-9K_w3oLj.js} +2 -2
  83. package/dist/{labelled-input-base-CqPL5rKm.js.map → labelled-input-base-9K_w3oLj.js.map} +1 -1
  84. package/dist/{labelled-input-base-BVvNeb5R.d.ts → labelled-input-base-ORb1rGq6.d.ts} +2 -2
  85. package/dist/labelled-input-base-ORb1rGq6.d.ts.map +1 -0
  86. package/dist/labelled-radial-input.d.ts +3 -3
  87. package/dist/labelled-radial-input.d.ts.map +1 -1
  88. package/dist/labelled-radial-input.js +7 -6
  89. package/dist/labelled-radial-input.js.map +1 -1
  90. package/dist/labelled-range-input.d.ts +1 -1
  91. package/dist/labelled-range-input.js +2 -2
  92. package/dist/led.d.ts +1 -1
  93. package/dist/led.d.ts.map +1 -1
  94. package/dist/led.js +2 -2
  95. package/dist/led.js.map +1 -1
  96. package/dist/{menu-item-CKRfP0pN.js → menu-item-BrIuORYD.js} +20 -10
  97. package/dist/menu-item-BrIuORYD.js.map +1 -0
  98. package/dist/{menu-item-ClQF2DKN.d.ts → menu-item-COx-Azgj.d.ts} +1 -1
  99. package/dist/menu-item-COx-Azgj.d.ts.map +1 -0
  100. package/dist/{menu-DJJuCm-5.js → menu-vjoiHZ13.js} +30 -17
  101. package/dist/menu-vjoiHZ13.js.map +1 -0
  102. package/dist/menu.d.ts +2 -2
  103. package/dist/menu.js +2 -2
  104. package/dist/miller.d.ts +2 -2
  105. package/dist/miller.d.ts.map +1 -1
  106. package/dist/miller.js +18 -11
  107. package/dist/miller.js.map +1 -1
  108. package/dist/narrowed-text.d.ts.map +1 -1
  109. package/dist/narrowed-text.js +7 -5
  110. package/dist/narrowed-text.js.map +1 -1
  111. package/dist/panel.d.ts +1 -1
  112. package/dist/panel.d.ts.map +1 -1
  113. package/dist/panel.js +5 -4
  114. package/dist/panel.js.map +1 -1
  115. package/dist/plots.d.ts +2 -2
  116. package/dist/plots.js +2 -2
  117. package/dist/polar-pad.d.ts +1 -1
  118. package/dist/polar-pad.d.ts.map +1 -1
  119. package/dist/polar-pad.js +10 -4
  120. package/dist/polar-pad.js.map +1 -1
  121. package/dist/{popup-ImtS9KnS.js → popup-DiWMxsWj.js} +1 -1
  122. package/dist/{popup-ImtS9KnS.js.map → popup-DiWMxsWj.js.map} +1 -1
  123. package/dist/prominence-DlFShic3.js +104 -0
  124. package/dist/prominence-DlFShic3.js.map +1 -0
  125. package/dist/{radial-input-LUSBEycd.d.ts → radial-input-CpQPs1Mp.d.ts} +1 -1
  126. package/dist/radial-input-CpQPs1Mp.d.ts.map +1 -0
  127. package/dist/{radial-input-DZA6WaFu.js → radial-input-DZ7eQCcM.js} +11 -6
  128. package/dist/radial-input-DZ7eQCcM.js.map +1 -0
  129. package/dist/radial-input.d.ts +1 -1
  130. package/dist/radial-input.js +1 -1
  131. package/dist/range-input.d.ts +1 -1
  132. package/dist/range-input.d.ts.map +1 -1
  133. package/dist/range-input.js +9 -4
  134. package/dist/range-input.js.map +1 -1
  135. package/dist/range.d.ts +1 -1
  136. package/dist/range.d.ts.map +1 -1
  137. package/dist/range.js +5 -3
  138. package/dist/range.js.map +1 -1
  139. package/dist/{registry-Q2gYQCHM.js → registry-CkW7q09Q.js} +1 -1
  140. package/dist/{registry-Q2gYQCHM.js.map → registry-CkW7q09Q.js.map} +1 -1
  141. package/dist/selecthorizontal.d.ts +1 -1
  142. package/dist/selecthorizontal.d.ts.map +1 -1
  143. package/dist/selecthorizontal.js +4 -3
  144. package/dist/selecthorizontal.js.map +1 -1
  145. package/dist/snap-container.d.ts.map +1 -1
  146. package/dist/snap-container.js +1 -1
  147. package/dist/split-layout.d.ts +1 -1
  148. package/dist/split-layout.d.ts.map +1 -1
  149. package/dist/split-layout.js +6 -5
  150. package/dist/split-layout.js.map +1 -1
  151. package/dist/style.css +14 -4
  152. package/dist/swipe.d.ts.map +1 -1
  153. package/dist/swipe.js +9 -4
  154. package/dist/swipe.js.map +1 -1
  155. package/dist/{tab-list-BnqISNvO.d.ts → tab-list-DLzb-m-I.d.ts} +2 -2
  156. package/dist/tab-list-DLzb-m-I.d.ts.map +1 -0
  157. package/dist/tabs.d.ts +1 -1
  158. package/dist/tabs.js +10 -4
  159. package/dist/tabs.js.map +1 -1
  160. package/dist/{tickled-controller-Cq1Va0rR.d.ts → tickled-controller-BjYCzGrU.d.ts} +2 -2
  161. package/dist/tickled-controller-BjYCzGrU.d.ts.map +1 -0
  162. package/dist/{tickled-styles-Bg3QbcrD.js → tickled-styles-fNDdqf6l.js} +1 -17
  163. package/dist/{tickled-styles-Bg3QbcrD.js.map → tickled-styles-fNDdqf6l.js.map} +1 -1
  164. package/dist/{timeline-Bh0PhlKW.js → timeline-2OFtN4Ta.js} +2 -2
  165. package/dist/{timeline-Bh0PhlKW.js.map → timeline-2OFtN4Ta.js.map} +1 -1
  166. package/dist/timeline.d.ts +1 -1
  167. package/dist/timeline.js +1 -1
  168. package/dist/{tooltip-DMxmBNky.js → tooltip-CJt3WLmN.js} +1 -1
  169. package/dist/{tooltip-DMxmBNky.js.map → tooltip-CJt3WLmN.js.map} +1 -1
  170. package/dist/{tooltip-CwGfb4lp.d.ts → tooltip-RGVIwHrZ.d.ts} +1 -1
  171. package/dist/{tooltip-CwGfb4lp.d.ts.map → tooltip-RGVIwHrZ.d.ts.map} +1 -1
  172. package/dist/{tree-CvvKbO-f.js → tree-CJWpMUvD.js} +113 -103
  173. package/dist/tree-CJWpMUvD.js.map +1 -0
  174. package/dist/{tree-component-D8Bg48tt.d.ts → tree-component-BcO26Xvt.d.ts} +65 -3
  175. package/dist/tree-component-BcO26Xvt.d.ts.map +1 -0
  176. package/dist/tree.d.ts +15 -15
  177. package/dist/tree.d.ts.map +1 -1
  178. package/dist/tree.js +1 -1
  179. package/dist/{types-BKaqnpwx.d.ts → types-DSfbtHs3.d.ts} +1 -1
  180. package/dist/types-DSfbtHs3.d.ts.map +1 -0
  181. package/dist/{xy-axis-DL0tfJDr.js → xy-axis-CK64haaK.js} +1831 -359
  182. package/dist/xy-axis-CK64haaK.js.map +1 -0
  183. package/dist/{xy-axis-D9uwpGTT.d.ts → xy-axis-McdUpcYr.d.ts} +102 -3
  184. package/dist/xy-axis-McdUpcYr.d.ts.map +1 -0
  185. package/dist/xy-pad.d.ts +1 -1
  186. package/dist/xy-pad.d.ts.map +1 -1
  187. package/dist/xy-pad.js +11 -6
  188. package/dist/xy-pad.js.map +1 -1
  189. package/docs-user/README.md +45 -0
  190. package/docs-user/ac-text.md +67 -0
  191. package/docs-user/ac-token.md +187 -0
  192. package/docs-user/button.md +355 -0
  193. package/docs-user/checkbox.md +62 -0
  194. package/docs-user/colour-picker.md +237 -0
  195. package/docs-user/crumbs.md +66 -0
  196. package/docs-user/data-display.md +98 -0
  197. package/docs-user/editable-label.md +244 -0
  198. package/docs-user/grouped-item-lister.md +424 -0
  199. package/docs-user/icons.md +191 -0
  200. package/docs-user/incr-search.md +94 -0
  201. package/docs-user/labelled-radial-input.md +204 -0
  202. package/docs-user/labelled-range-input.md +194 -0
  203. package/docs-user/led.md +40 -0
  204. package/docs-user/menu.md +319 -0
  205. package/docs-user/miller.md +453 -0
  206. package/docs-user/narrowed-text.md +72 -0
  207. package/docs-user/panel.md +250 -0
  208. package/docs-user/plots.md +361 -0
  209. package/docs-user/polar-pad.md +228 -0
  210. package/docs-user/radial-input.md +559 -0
  211. package/docs-user/range-input.md +264 -0
  212. package/docs-user/range.md +12 -0
  213. package/docs-user/selecthorizontal.md +32 -0
  214. package/docs-user/snap-container.md +132 -0
  215. package/docs-user/split-layout.md +232 -0
  216. package/docs-user/swipe.md +44 -0
  217. package/docs-user/tabs.md +217 -0
  218. package/docs-user/timeline.md +116 -0
  219. package/docs-user/transitory-label.md +120 -0
  220. package/docs-user/tree.md +592 -0
  221. package/docs-user/user-catalog.md +165 -0
  222. package/docs-user/user-theming.md +379 -0
  223. package/docs-user/util.md +122 -0
  224. package/docs-user/vertical-list.md +351 -0
  225. package/docs-user/xy-pad.md +94 -0
  226. package/package.json +18 -17
  227. package/dist/colour-C3MQIjFJ-BLXg8W3U.js.map +0 -1
  228. package/dist/colour-picker-K6zu82lm.js.map +0 -1
  229. package/dist/dist-BX0OVIm7.js +0 -1290
  230. package/dist/dist-BX0OVIm7.js.map +0 -1
  231. package/dist/dist-TAGYwaju.js.map +0 -1
  232. package/dist/hex-editor-DlfoA65y.d.ts.map +0 -1
  233. package/dist/icon-9NWTXtE1.js.map +0 -1
  234. package/dist/icon-Dm_DHDz6.d.ts.map +0 -1
  235. package/dist/index-CnL9krsH.d.ts.map +0 -1
  236. package/dist/index-DLkSKL4T.d.ts.map +0 -1
  237. package/dist/index-DSlPeWLK.d.ts.map +0 -1
  238. package/dist/index-iZLld8Ca.d.ts.map +0 -1
  239. package/dist/interaction-DG7X1rhI.js +0 -1
  240. package/dist/labelled-input-base-BVvNeb5R.d.ts.map +0 -1
  241. package/dist/menu-DJJuCm-5.js.map +0 -1
  242. package/dist/menu-item-CKRfP0pN.js.map +0 -1
  243. package/dist/menu-item-ClQF2DKN.d.ts.map +0 -1
  244. package/dist/prominence--ic9uWBl.js +0 -98
  245. package/dist/prominence--ic9uWBl.js.map +0 -1
  246. package/dist/radial-input-DZA6WaFu.js.map +0 -1
  247. package/dist/radial-input-LUSBEycd.d.ts.map +0 -1
  248. package/dist/tab-list-BnqISNvO.d.ts.map +0 -1
  249. package/dist/tickled-controller-Cq1Va0rR.d.ts.map +0 -1
  250. package/dist/tree-CvvKbO-f.js.map +0 -1
  251. package/dist/tree-component-D8Bg48tt.d.ts.map +0 -1
  252. package/dist/types-BKaqnpwx.d.ts.map +0 -1
  253. package/dist/xy-axis-D9uwpGTT.d.ts.map +0 -1
  254. package/dist/xy-axis-DL0tfJDr.js.map +0 -1
  255. /package/bundle/{chunk-pbuEa-1d.js → chunk-D7D4PA-g.js} +0 -0
  256. /package/dist/{chunk-pbuEa-1d.js → chunk-D7D4PA-g.js} +0 -0
@@ -0,0 +1,250 @@
1
+ # Panel
2
+
3
+ An collapsible panel component with support for titles, icons, toolbars, and multiple visual variants.
4
+
5
+ ```html
6
+ <ixfx-panel title="Settings">
7
+ <p>Panel content goes here.</p>
8
+ </ixfx-panel>
9
+ ```
10
+
11
+ ---
12
+
13
+ ## `ixfx-panel`
14
+
15
+ ### Properties / attributes
16
+
17
+ | Attribute / Property | Type | Default | Description |
18
+ |--------------------------|---------------------------------------------------|---------------|--------------------------------------------------|
19
+ | `collapsed` | boolean | `false` | Whether the panel is collapsed (content hidden) |
20
+ | `orientation` | `'horizontal'` \| `'vertical'` | `'horizontal'`| Layout direction of title bar |
21
+ | `title` | string | `''` | Panel title text |
22
+ | `icon-name` | string | `''` | Icon name from the registry |
23
+ | `closable` | boolean | `false` | Shows a close button that removes the panel |
24
+ | `toggle-interaction` | `'implicit'` \| `'explicit'` \| `'disabled'` | `'implicit'` | How users can toggle the panel (see below) |
25
+ | `variant` | `'titlebar'` \| `'midline'` | `'titlebar'` | Visual style of the panel |
26
+
27
+ ### Toggle interaction modes
28
+
29
+ | Mode | Behavior |
30
+ |------------|--------------------------------------------------------------------------|
31
+ | `implicit` | Clicking the caret button or anywhere in the title bar toggles the panel |
32
+ | `explicit` | Only clicking the caret button toggles the panel |
33
+ | `disabled` | Caret is hidden; no user toggle possible (programmatic only) |
34
+
35
+ ### Slots
36
+
37
+ | Slot | Description |
38
+ |-------------|--------------------------------------------------|
39
+ | default | Panel content (shown when expanded) |
40
+ | `toolbar` | Buttons or other elements in the title bar toolbar |
41
+
42
+ ### Events
43
+
44
+ | Event | Detail | Description |
45
+ |----------|------------------------------------|---------------------------------------|
46
+ | `toggle` | `{ collapsed: boolean }` | Fired when panel expand/collapse state changes |
47
+ | `close` | — | Fired when close button is clicked; panel is removed from DOM |
48
+
49
+ ```js
50
+ const panel = document.querySelector('ixfx-panel');
51
+
52
+ panel.addEventListener('toggle', e => {
53
+ console.log('Panel collapsed:', e.detail.collapsed);
54
+ });
55
+
56
+ panel.addEventListener('close', () => {
57
+ console.log('Panel closed and removed');
58
+ });
59
+ ```
60
+
61
+ ### Icons
62
+
63
+ Icon names resolve against the icon registry. Register custom icons with `registerIcon(name, svgString)` from `src/icons/registry.ts`.
64
+
65
+ Built-in icon names: `check`, `chevron-down`, `chevron-right`, `close`.
66
+
67
+ ---
68
+
69
+ ## Visual variants
70
+
71
+ ### `titlebar` variant (default)
72
+
73
+ The standard panel style with a visible header bar above the content area:
74
+
75
+ ```html
76
+ <ixfx-panel title="Settings" icon-name="settings">
77
+ <p>Content here</p>
78
+ </ixfx-panel>
79
+ ```
80
+
81
+ - Header uses `--surface-4` background
82
+ - Content area has inset shadow for depth
83
+ - Rounded corners (`--radius-m`)
84
+
85
+ ### `midline` variant
86
+
87
+ A lightweight, minimal style with a horizontal line running through the title text:
88
+
89
+ ```html
90
+ <ixfx-panel title="Settings" variant="midline" icon-name="settings">
91
+ <p>Content here</p>
92
+ </ixfx-panel>
93
+ ```
94
+
95
+ - No background or border on the host element
96
+ - Title bar is transparent with the title text overlaid
97
+ - A debossed line runs horizontally (or vertically for `orientation="vertical"`) behind the title text
98
+ - The line is visible between the title text and toolbar buttons
99
+ - Useful for section headers or metadata display
100
+
101
+ ---
102
+
103
+ ## Vertical orientation
104
+
105
+ Panels can display vertically with the title bar on the left side:
106
+
107
+ ```html
108
+ <ixfx-panel title="Device" orientation="vertical" icon-name="server">
109
+ <p>Content here</p>
110
+ </ixfx-panel>
111
+ ```
112
+
113
+ For `variant="midline"` with `orientation="vertical"`, the debossed line runs vertically alongside the rotated title text.
114
+
115
+ ---
116
+
117
+ ## With toolbar
118
+
119
+ Add buttons or other controls to the title bar using the `toolbar` slot:
120
+
121
+ ```html
122
+ <ixfx-panel title="Document">
123
+ <div slot="toolbar">
124
+ <button type="button" data-tooltip="Print">
125
+ <ixfx-icon name="printer"></ixfx-icon>
126
+ </button>
127
+ </div>
128
+ <p>Document content</p>
129
+ </ixfx-panel>
130
+ ```
131
+
132
+ Clicking toolbar buttons does not toggle the panel when `toggle-interaction="implicit"`.
133
+
134
+ ---
135
+
136
+ ## Collapsed by default
137
+
138
+ Use the `collapsed` attribute to start the panel in collapsed state:
139
+
140
+ ```html
141
+ <ixfx-panel title="Advanced" collapsed>
142
+ <p>This content is hidden initially</p>
143
+ </ixfx-panel>
144
+ ```
145
+
146
+ ---
147
+
148
+ ## CSS custom properties
149
+
150
+ | Property | Default | Description |
151
+ |-------------------------|--------------------------|--------------------------------------------------|
152
+ | `--surface-3` | theme-dependent | Panel background |
153
+ | `--surface-3-text` | theme-dependent | Title text color |
154
+ | `--surface-4` | theme-dependent | Title bar background (titlebar variant) |
155
+ | `--border-subtle` | theme-dependent | Border color (titlebar variant) |
156
+ | `--radius-m` | `4px` | Border radius (titlebar variant) |
157
+ | `--space-s` | `4px` | Small spacing |
158
+ | `--space-m` | `8px` | Medium spacing |
159
+ | `--transition` | `0.15s ease-out` | Animation transition duration |
160
+ | `--panel-width` | `auto` | Width for vertical panels |
161
+ | `--panel-height` | `auto` | Height for horizontal panels |
162
+ | `--prominence-idle-opacity` | `0.6` | Opacity of caret when idle |
163
+ | `--prominence-tickled-opacity` | `1.0` | Opacity of caret on hover |
164
+
165
+ ### Midline-specific line appearance
166
+
167
+ | Property | Description |
168
+ |--------------|------------------------------------------------|
169
+ | `--surface-1` | Shadow color for debossed line (darker) |
170
+ | `--surface-2` | Line background color |
171
+ | `--surface-5` | Highlight color for debossed line (lighter) |
172
+
173
+ ---
174
+
175
+ ## `ixfx-panel-group`
176
+
177
+ A container component that manages multiple panels with exclusive open behavior (accordion style).
178
+
179
+ ### Properties / attributes
180
+
181
+ | Attribute / Property | Type | Default | Description |
182
+ |------------------------|---------------------------------------------------|----------------|---------------------------------------------------------------|
183
+ | `orientation` | `'horizontal'` \| `'vertical'` | `'horizontal'` | Layout direction of the group |
184
+ | `variant` | `'titlebar'` \| `'midline'` | `'titlebar'` | Visual style applied to all child panels |
185
+ | `toggle-interaction` | `'implicit'` \| `'explicit'` \| `'disabled'` | `'implicit'` | Toggle behavior applied to all child panels |
186
+ | `allow-multiple` | boolean | `false` | Allow multiple panels to be open simultaneously |
187
+ | `gap` | string | `'var(--space-m)'` | CSS gap between panels |
188
+
189
+ ### Group orientation vs child panel orientation
190
+
191
+ The group's `orientation` controls:
192
+ 1. How the group lays out its child panels (flex row vs flex column)
193
+ 2. What `orientation` is automatically applied to child panels
194
+
195
+ | Group `orientation` | Group layout direction | Child panels get `orientation` |
196
+ |---------------------|------------------------|-------------------------------|
197
+ | `horizontal` | Flex row (horizontal) | `vertical` |
198
+ | `vertical` | Flex column (vertical) | `horizontal` |
199
+
200
+ Explicit attributes on child panels take precedence over group-propagated values.
201
+
202
+ ### Example
203
+
204
+ ```html
205
+ <ixfx-panel-group orientation="horizontal">
206
+ <ixfx-panel title="Panel 1">
207
+ <p>Content 1</p>
208
+ </ixfx-panel>
209
+ <ixfx-panel title="Panel 2">
210
+ <p>Content 2</p>
211
+ </ixfx-panel>
212
+ <ixfx-panel title="Panel 3">
213
+ <p>Content 3</p>
214
+ </ixfx-panel>
215
+ </ixfx-panel-group>
216
+ ```
217
+
218
+ By default, only one panel can be open at a time. Set `allow-multiple` to allow multiple panels to be open:
219
+
220
+ ```html
221
+ <ixfx-panel-group orientation="horizontal" allow-multiple>
222
+ <!-- panels -->
223
+ </ixfx-panel-group>
224
+ ```
225
+
226
+ ### Group-propagated properties
227
+
228
+ When you set `variant` or `toggle-interaction` on the group, those values are automatically applied to all child panels that don't have an explicit value set. This simplifies declaration when all panels in a group share the same styling:
229
+
230
+ ```html
231
+ <ixfx-panel-group variant="midline" toggle-interaction="explicit">
232
+ <ixfx-panel title="Settings">...</ixfx-panel>
233
+ <ixfx-panel title="Account">...</ixfx-panel>
234
+ <ixfx-panel title="Help">...</ixfx-panel>
235
+ </ixfx-panel-group>
236
+ ```
237
+
238
+ ---
239
+
240
+ ## TypeScript types
241
+
242
+ ```ts
243
+ import type { PanelOrientation, PanelVariant, PanelToggleInteraction, PanelToggleDetail, PanelGroupOrientation } from 'ixfxfun-components';
244
+ ```
245
+
246
+ ---
247
+
248
+ ## See also
249
+
250
+ - [`ixfx-icon`](../icons/README.md) — Icon component used by panel
@@ -0,0 +1,361 @@
1
+ # Plot Components
2
+
3
+ SVG-based plotting components for visualising data streams.
4
+
5
+ ```bash
6
+ npm install @ixfx/plots
7
+ ```
8
+
9
+ ---
10
+
11
+ ## Overview
12
+
13
+ All plot components share a common rendering approach (SVG, intrinsic sizing via ResizeObserver, theme-aware CSS variables) but differ in what they visualise:
14
+
15
+ | Component | Data shape | Axis meaning | Draw styles | Age/colour | Key use case |
16
+ |-----------|-----------|--------------|-------------|------------|-------------|
17
+ | `<ixfx-plot-single-axis>` | 1D values (ordered sequence) | X = index/order, Y = value | 9 styles (line, marker, bar, hist) | Age + colour | Time series, sensor readings |
18
+ | `<ixfx-plot-xy-axis>` | 2D (x, y) pairs | X = value, Y = value | 2 styles (circle, square) | Age + colour | Scatter plots, Lissajous |
19
+ | `<ixfx-plot-multi-axis>` | Named 1D series | Same as single-axis per series | Defined per series via `styleSeries()` | Per-series colour | Multiple simultaneous signals |
20
+ | `<ixfx-plot-histogram>` | 1D values (unordered distribution) | X/Y = value bins, bar length = density | Single bar style | Opacity via `--value` | Value distribution, heat map |
21
+
22
+ ---
23
+
24
+ ## Common Features
25
+
26
+ ### Adding Data
27
+
28
+ ```typescript
29
+ // single-axis / histogram
30
+ plot.add(42);
31
+ plot.set([1, 2, 3, 4, 5]);
32
+ plot.clear();
33
+
34
+ // xy-axis — requires x and y
35
+ plot.add(0.5, 0.8);
36
+ plot.setXY([1,2,3], [4,5,6]);
37
+ plot.clear();
38
+
39
+ // multi-axis — named values
40
+ plot.addData({ temperature: 22, humidity: 60 });
41
+ plot.clear();
42
+ ```
43
+
44
+ ### Common Properties
45
+
46
+ | Property | Type | Default | Applies to | Description |
47
+ |----------|------|---------|-------------|-------------|
48
+ | `title` | `string` | `""` | all | Title displayed on the plot |
49
+ | `capacity` | `number` | `100` | single-axis, xy-axis, histogram | Max data points to store |
50
+ | `paused` | `boolean` | `false` | all but multi-axis | Pause rendering updates |
51
+
52
+ ### Inline (Declarative) Data
53
+
54
+ Provide initial data directly in the HTML for **single-axis** and **histogram**:
55
+
56
+ ```html
57
+ <ixfx-plot-single-axis>1, 2, 0.5, 0.3, -1</ixfx-plot-single-axis>
58
+ <ixfx-plot-histogram>0.1 0.4 0.7 0.3 0.9</ixfx-plot-histogram>
59
+ ```
60
+
61
+ Numbers can be separated by commas, spaces, or semicolons. Programmatic `set()` / `add()` calls take precedence.
62
+
63
+ ### CSS Variables (shared)
64
+
65
+ | Variable | Default | Applies to | Description |
66
+ |----------|---------|-------------|-------------|
67
+ | `--plot-color` | `var(--accent)` | single-axis, xy-axis | Base colour for data points |
68
+ | `--plot-text` | `var(--surface-2-text, #fff)` | all | Text colour for title |
69
+
70
+ ### Sizing
71
+
72
+ All components use `display: inline-block` with `width: 100%; height: 100%` by default. They observe their container via `ResizeObserver`, so sizing is controlled entirely by the parent:
73
+
74
+ ```css
75
+ .plot-container {
76
+ width: 100%;
77
+ height: 200px;
78
+ }
79
+ .plot-container > ixfx-plot-* {
80
+ width: 100%;
81
+ height: 100%;
82
+ }
83
+ ```
84
+
85
+ ---
86
+
87
+ ## `<ixfx-plot-single-axis>`
88
+
89
+ Renders a 1D data series as a time-series / ordered-sequence plot.
90
+
91
+ **Tag:** `<ixfx-plot-single-axis>`
92
+
93
+ ### Properties
94
+
95
+ | Property | Type | Default | Description |
96
+ |----------|------|---------|-------------|
97
+ | `drawStyle` | `SingleAxisDrawStyle` | `line-sharp` | Rendering style |
98
+ | `ageStyle` | `SingleAxisAgeStyle` | `none` | Ageing effect |
99
+ | `tooltips` | `boolean` | `true` | Show tooltip on hover |
100
+ | `precise` | `boolean` | `false` | Show latest value in corner |
101
+ | `persistentScale` | `boolean` | `true` | Keep same scale; if `false`, scale adjusts to visible data |
102
+ | `clickPauses` | `boolean` | `false` | Toggle pause on click |
103
+ | `shaded` | `boolean` | `false` | Shaded area under line |
104
+ | `areaColor` | `string` | `""` | Custom shade colour |
105
+ | `colorMode` | `ColourMode` | `fixed` | Colour mapping |
106
+ | `colorEasing` | `string` | `""` | Easing for colour mapping |
107
+ | `colorScale` | `string` | `""` | Colour palette for `scale` mode |
108
+
109
+ ### Draw Styles
110
+
111
+ | Style | Description |
112
+ |-------|-------------|
113
+ | `line-sharp` | Sharp line segments (default) |
114
+ | `line-round` | Rounded line segments |
115
+ | `circles` | Circle markers |
116
+ | `squares` | Square markers |
117
+ | `vbar` | Vertical bars from baseline |
118
+ | `hbar` | Horizontal bars |
119
+ | `hist-bottom` | Histogram bars from bottom |
120
+ | `hist-top` | Histogram bars from top |
121
+ | `hist-middle` | Histogram bars from middle |
122
+
123
+ ### Age Styles
124
+
125
+ | Style | Description |
126
+ |-------|-------------|
127
+ | `none` | No effect (default) |
128
+ | `opacity` | Older points fade out |
129
+ | `desaturation` | Older points grayscale |
130
+ | `size` | Older points shrink |
131
+
132
+ Applies to discrete draw styles only (`circles`, `squares`, `vbar`, `hbar`, `hist-*`).
133
+
134
+ ### Colour Mapping
135
+
136
+ | Mode | Description |
137
+ |------|-------------|
138
+ | `fixed` | Single colour (default) |
139
+ | `opacity` | Varying opacity |
140
+ | `hue` | Map value to hue |
141
+ | `saturation` | Map value to saturation |
142
+ | `lightness` | Map value to lightness |
143
+ | `scale` | Interpolate through a colour palette |
144
+
145
+ Use `color-easing` for easing functions or `color-scale` for custom palettes:
146
+
147
+ ```html
148
+ <ixfx-plot-single-axis color-mode="scale" color-scale="green,yellow,red">
149
+ ```
150
+
151
+ ### Events
152
+
153
+ - **`plot-datapoint-click`** — `{ value: number, index: number }`
154
+
155
+ ### Example
156
+
157
+ ```html
158
+ <ixfx-plot-single-axis draw-style="line-round" title="Temperature" capacity="50"></ixfx-plot-single-axis>
159
+ <script type="module">
160
+ import '@ixfx/plots';
161
+ const plot = document.querySelector('ixfx-plot-single-axis');
162
+ setInterval(() => plot.add(Math.random() * 100), 100);
163
+ </script>
164
+ ```
165
+
166
+ ---
167
+
168
+ ## `<ixfx-plot-xy-axis>`
169
+
170
+ Renders a 2D X/Y scatter or line plot.
171
+
172
+ **Tag:** `<ixfx-plot-xy-axis>`
173
+
174
+ ### Properties
175
+
176
+ Same colour/age properties as single-axis. Add via `plot.add(x, y)` or `plot.setXY(xArray, yArray)`.
177
+
178
+ ### Draw Styles
179
+
180
+ | Style | Description |
181
+ |-------|-------------|
182
+ | `circles` | Circle markers (default) |
183
+ | `squares` | Square markers |
184
+
185
+ ### Events
186
+
187
+ - **`plot-datapoint-click`** — `{ x: number, y: number, index: number }`
188
+
189
+ ### Custom Formatting
190
+
191
+ Override `valueFormat`:
192
+
193
+ ```typescript
194
+ plot.valueFormat = (x, y) => `(${x.toFixed(2)}, ${y.toFixed(2)})`;
195
+ ```
196
+
197
+ ### Example
198
+
199
+ ```html
200
+ <ixfx-plot-xy-axis draw-style="circles" age-style="opacity" title="Position"></ixfx-plot-xy-axis>
201
+ <script type="module">
202
+ import '@ixfx/plots';
203
+ const plot = document.querySelector('ixfx-plot-xy-axis');
204
+ let t = 0;
205
+ setInterval(() => { plot.add(Math.sin(t), Math.cos(t)); t += 0.1; }, 50);
206
+ </script>
207
+ ```
208
+
209
+ ---
210
+
211
+ ## `<ixfx-plot-multi-axis>`
212
+
213
+ Displays multiple named 1D series simultaneously with configurable layout.
214
+
215
+ **Tag:** `<ixfx-plot-multi-axis>`
216
+
217
+ Unlike the other plot components, multi-axis manages multiple independent data streams. Each series has its own colour, and the layout can arrange them as overlapped, horizontal, vertical, or in a grid.
218
+
219
+ ### Properties
220
+
221
+ | Property | Type | Default | Description |
222
+ |----------|------|---------|-------------|
223
+ | `layout` | `"overlap"` \| `"horizontal"` \| `"vertical"` \| `"grid"` | `overlap` | How to arrange the series |
224
+ | `gridMinWidth` | `number` | `180` | Min column width in `grid` layout (px) |
225
+ | `capacity` | `number` | `100` | Max data points per series |
226
+
227
+ ### Methods
228
+
229
+ ```typescript
230
+ plot.addData({ temperature: 22, humidity: 60, pressure: 1013 });
231
+ plot.styleSeries('temperature', { 'plot-color': '#ff6b6b' });
232
+ plot.clear();
233
+ ```
234
+
235
+ ### Layouts
236
+
237
+ | Layout | Description |
238
+ |--------|-------------|
239
+ | `overlap` | All series drawn on the same axes (default) |
240
+ | `horizontal` | Each series in its own row |
241
+ | `vertical` | Each series in its own column |
242
+ | `grid` | Auto-fill grid, each cell holds one series |
243
+
244
+ ### Per-Series Styling
245
+
246
+ ```typescript
247
+ plot.styleSeries('temperature', {
248
+ 'plot-color': '#ff6b6b',
249
+ 'draw-style': 'line-round',
250
+ });
251
+ plot.styleSeries('humidity', {
252
+ 'plot-color': '#4ecdc4',
253
+ 'draw-style': 'hist-bottom',
254
+ });
255
+ ```
256
+
257
+ ### Events
258
+
259
+ - **`plot-datapoint-click`** — `{ series: string, value: number, index: number }`
260
+ - **`plot-series-add`**, **`plot-series-remove`** — Series lifecycle
261
+
262
+ ### Example
263
+
264
+ ```html
265
+ <ixfx-plot-multi-axis layout="horizontal" class="plot-lg"></ixfx-plot-multi-axis>
266
+ <script type="module">
267
+ import '@ixfx/plots';
268
+ const plot = document.querySelector('ixfx-plot-multi-axis');
269
+ let t = 0;
270
+ setInterval(() => {
271
+ plot.addData({ x: Math.sin(t), y: Math.cos(t), z: Math.sin(t * 0.5) });
272
+ t += 0.1;
273
+ }, 80);
274
+ </script>
275
+ ```
276
+
277
+ ---
278
+
279
+ ## `<ixfx-plot-histogram>`
280
+
281
+ Renders a histogram of value distributions. Unlike `ixfx-plot-single-axis` (where the X-axis represents ordering), this component shows a pure distribution — all values in the current buffer are binned into buckets spanning the data range. There is no time or sequence axis.
282
+
283
+ **Tag:** `<ixfx-plot-histogram>`
284
+
285
+ ### Orientation
286
+
287
+ | Value | Description |
288
+ |-------|-------------|
289
+ | `horizontal` (default) | X-axis = value range → vertical bars rising from bottom |
290
+ | `vertical` | Y-axis = value range → horizontal bars extending from left (bottom-to-top = min-to-max) |
291
+
292
+ ### Resolution
293
+
294
+ Controls bucket granularity. Value is a fraction of the available space. Default `0.10` = 10 buckets.
295
+
296
+ ```html
297
+ <ixfx-plot-histogram resolution="0.05"></ixfx-plot-histogram> <!-- 20 buckets -->
298
+ <ixfx-plot-histogram resolution="0.20"></ixfx-plot-histogram> <!-- 5 buckets -->
299
+ ```
300
+
301
+ ### Fixed Range
302
+
303
+ Set `min` / `max` attributes to fix the value range and disable automatic RangeStream scaling:
304
+
305
+ ```html
306
+ <ixfx-plot-histogram min="0" max="1" resolution="0.05"></ixfx-plot-histogram>
307
+ ```
308
+
309
+ ### Bar Length
310
+
311
+ By default, each bar's length (height in horizontal, width in vertical) is proportional to the fraction of values in that bucket — a classic histogram. Override via `--plot-histogram-bar-length` to produce a **heat-map** appearance where all bars are full-length and only colour varies:
312
+
313
+ ```css
314
+ ixfx-plot-histogram {
315
+ --plot-histogram-bar-length: 1;
316
+ --plot-histogram-fill: oklch(65% 0.2 30);
317
+ --plot-histogram-gap: 0px;
318
+ }
319
+ ```
320
+
321
+ ### CSS Variables
322
+
323
+ | Variable | Default | Description |
324
+ |----------|---------|-------------|
325
+ | `--plot-histogram-fill` | `currentColor` | Fill colour of each bucket bar |
326
+ | `--plot-histogram-gap` | `1px` | Gap between adjacent buckets |
327
+ | `--plot-histogram-border-radius` | `0` | Corner radius of each bucket |
328
+ | `--plot-histogram-bar-length` | `auto` | Fixed bar length fraction (0–1); `auto` = proportional to density |
329
+
330
+ Opacity is derived from `--value` (set inline on each bucket bar):
331
+ ```css
332
+ rect.bar {
333
+ opacity: calc(0.15 + var(--value) * 0.85);
334
+ }
335
+ ```
336
+
337
+ ### Events
338
+
339
+ - **`plot-bucket-click`** — `{ bucketIndex: number, valueMin: number, valueMax: number, relativeValue: number }`
340
+
341
+ ### Example
342
+
343
+ ```html
344
+ <ixfx-plot-histogram title="distribution" capacity="500"></ixfx-plot-histogram>
345
+ <script type="module">
346
+ import '@ixfx/plots';
347
+ const plot = document.querySelector('ixfx-plot-histogram');
348
+ setInterval(() => plot.add(Math.random()), 50);
349
+ </script>
350
+ ```
351
+
352
+ ---
353
+
354
+ ## TypeScript
355
+
356
+ ```typescript
357
+ import type { SingleAxisDrawStyle, SingleAxisAgeStyle } from '@ixfx/plots';
358
+ import type { XyDrawStyle, XyAgeStyle } from '@ixfx/plots';
359
+ import type { PlotHistogramOrientation, PlotHistogramBucketClickDetail } from '@ixfx/plots';
360
+ import type { MultiAxisLayout, PlotMultiAxis } from '@ixfx/plots';
361
+ ```