@ixfx/components 0.3.1 → 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.
- package/bundle/index.d.ts +1086 -603
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +16527 -14258
- package/bundle/index.js.map +1 -1
- package/bundle/style.css +14 -4
- package/dist/ac-text.d.ts.map +1 -1
- package/dist/ac-text.js +11 -6
- package/dist/ac-text.js.map +1 -1
- package/dist/{button-DMt5XWUK.js → button-C3fLMKUv.js} +4 -4
- package/dist/{button-DMt5XWUK.js.map → button-C3fLMKUv.js.map} +1 -1
- package/dist/button.d.ts.map +1 -1
- package/dist/button.js +1 -1
- package/dist/checkbox.d.ts +2 -2
- package/dist/checkbox.d.ts.map +1 -1
- package/dist/checkbox.js +14 -8
- package/dist/checkbox.js.map +1 -1
- package/dist/{colour-C3MQIjFJ-BLXg8W3U.js → colour-C3MQIjFJ-vRCdr8W-.js} +146 -552
- package/dist/colour-C3MQIjFJ-vRCdr8W-.js.map +1 -0
- package/dist/{colour-picker-K6zu82lm.js → colour-picker-0sgAha1T.js} +14 -9
- package/dist/colour-picker-0sgAha1T.js.map +1 -0
- package/dist/colour-picker.d.ts +1 -1
- package/dist/colour-picker.js +1 -1
- package/dist/crumbs.d.ts +1 -1
- package/dist/crumbs.d.ts.map +1 -1
- package/dist/crumbs.js +11 -6
- package/dist/crumbs.js.map +1 -1
- package/dist/data-display.d.ts +9 -4
- package/dist/data-display.d.ts.map +1 -1
- package/dist/data-display.js +270 -43
- package/dist/data-display.js.map +1 -1
- package/dist/data-provider-DgI909FP.js +23 -0
- package/dist/data-provider-DgI909FP.js.map +1 -0
- package/dist/{decorate-D7rC1gLP.js → decorate-DdjvVHS-.js} +2 -2
- package/dist/{decorate-D7rC1gLP.js.map → decorate-DdjvVHS-.js.map} +1 -1
- package/dist/{defaults-C7elhuyJ.js → defaults-C3b9OWJD.js} +2 -2
- package/dist/{defaults-C7elhuyJ.js.map → defaults-C3b9OWJD.js.map} +1 -1
- package/dist/{dist-TAGYwaju.js → dist-CA13FvMn.js} +7 -66
- package/dist/dist-CA13FvMn.js.map +1 -0
- package/dist/editable-label.d.ts.map +1 -1
- package/dist/editable-label.js +3 -2
- package/dist/editable-label.js.map +1 -1
- package/dist/fallbacks-pNMOMx38.js +168 -0
- package/dist/fallbacks-pNMOMx38.js.map +1 -0
- package/dist/{hex-editor-DlfoA65y.d.ts → hex-editor-CMIxtNgT.d.ts} +1 -1
- package/dist/hex-editor-CMIxtNgT.d.ts.map +1 -0
- package/dist/{hex-editor-CsN_ySkH.js → hex-editor-WZrjRtvL.js} +3 -3
- package/dist/{hex-editor-CsN_ySkH.js.map → hex-editor-WZrjRtvL.js.map} +1 -1
- package/dist/hex.d.ts +1 -1
- package/dist/hex.js +1 -1
- package/dist/{highlight-TPbSHruI.js → highlight-B-eQrhhb.js} +1 -1
- package/dist/{highlight-TPbSHruI.js.map → highlight-B-eQrhhb.js.map} +1 -1
- package/dist/{icon-CeTDJhC7.d.ts → icon-Bd5BiU4b.d.ts} +2 -2
- package/dist/icon-Bd5BiU4b.d.ts.map +1 -0
- package/dist/{icon-9NWTXtE1.js → icon-Ndo40kNO.js} +6 -5
- package/dist/icon-Ndo40kNO.js.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +3 -3
- package/dist/{incr-search-DSKKsk6w.js → incr-search-CeERfijK.js} +2 -2
- package/dist/{incr-search-DSKKsk6w.js.map → incr-search-CeERfijK.js.map} +1 -1
- package/dist/incr-search.d.ts +1 -1
- package/dist/incr-search.js +2 -2
- package/dist/{index-hXFn14tM.d.ts → index-BMjri2-S.d.ts} +2 -2
- package/dist/{index-hXFn14tM.d.ts.map → index-BMjri2-S.d.ts.map} +1 -1
- package/dist/{index-DSlPeWLK.d.ts → index-CWpNcQKE.d.ts} +5 -5
- package/dist/index-CWpNcQKE.d.ts.map +1 -0
- package/dist/{index--hrxPBkQ.d.ts → index-CowKi2mo.d.ts} +2 -1
- package/dist/index-CowKi2mo.d.ts.map +1 -0
- package/dist/{index-B1hNR7Z9.d.ts → index-D87kRcEs.d.ts} +1 -1
- package/dist/{index-B1hNR7Z9.d.ts.map → index-D87kRcEs.d.ts.map} +1 -1
- package/dist/{index-CnL9krsH.d.ts → index-DgXpCg_G.d.ts} +32 -26
- package/dist/index-DgXpCg_G.d.ts.map +1 -0
- package/dist/{index-DrQjA8Gs.d.ts → index-s_IhSnwc.d.ts} +2 -2
- package/dist/index-s_IhSnwc.d.ts.map +1 -0
- package/dist/index.d.ts +432 -121
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2370 -1707
- package/dist/index.js.map +1 -1
- package/dist/interaction-D6efrBLo.js +1 -0
- package/dist/{keyboard-De_vOHLg.js → keyboard-CimiEskD.js} +1 -1
- package/dist/{keyboard-De_vOHLg.js.map → keyboard-CimiEskD.js.map} +1 -1
- package/dist/{labelled-input-base-CqPL5rKm.js → labelled-input-base-9K_w3oLj.js} +2 -2
- package/dist/{labelled-input-base-CqPL5rKm.js.map → labelled-input-base-9K_w3oLj.js.map} +1 -1
- package/dist/{labelled-input-base-D-Y7agky.d.ts → labelled-input-base-ORb1rGq6.d.ts} +1 -1
- package/dist/labelled-input-base-ORb1rGq6.d.ts.map +1 -0
- package/dist/labelled-radial-input.d.ts +2 -2
- package/dist/labelled-radial-input.d.ts.map +1 -1
- package/dist/labelled-radial-input.js +7 -6
- package/dist/labelled-radial-input.js.map +1 -1
- package/dist/labelled-range-input.d.ts +1 -1
- package/dist/labelled-range-input.js +2 -2
- package/dist/led.d.ts +1 -1
- package/dist/led.d.ts.map +1 -1
- package/dist/led.js +2 -2
- package/dist/led.js.map +1 -1
- package/dist/{menu-item-CKRfP0pN.js → menu-item-BrIuORYD.js} +20 -10
- package/dist/menu-item-BrIuORYD.js.map +1 -0
- package/dist/{menu-item-ClQF2DKN.d.ts → menu-item-COx-Azgj.d.ts} +1 -1
- package/dist/menu-item-COx-Azgj.d.ts.map +1 -0
- package/dist/{menu-DJJuCm-5.js → menu-vjoiHZ13.js} +30 -17
- package/dist/menu-vjoiHZ13.js.map +1 -0
- package/dist/menu.d.ts +2 -2
- package/dist/menu.js +2 -2
- package/dist/miller.d.ts +2 -2
- package/dist/miller.d.ts.map +1 -1
- package/dist/miller.js +18 -11
- package/dist/miller.js.map +1 -1
- package/dist/narrowed-text.d.ts.map +1 -1
- package/dist/narrowed-text.js +7 -5
- package/dist/narrowed-text.js.map +1 -1
- package/dist/panel.d.ts +1 -1
- package/dist/panel.d.ts.map +1 -1
- package/dist/panel.js +5 -4
- package/dist/panel.js.map +1 -1
- package/dist/plots.d.ts +2 -2
- package/dist/plots.js +2 -2
- package/dist/polar-pad.d.ts +1 -1
- package/dist/polar-pad.d.ts.map +1 -1
- package/dist/polar-pad.js +10 -4
- package/dist/polar-pad.js.map +1 -1
- package/dist/{popup-ImtS9KnS.js → popup-DiWMxsWj.js} +1 -1
- package/dist/{popup-ImtS9KnS.js.map → popup-DiWMxsWj.js.map} +1 -1
- package/dist/prominence-DlFShic3.js +104 -0
- package/dist/prominence-DlFShic3.js.map +1 -0
- package/dist/{radial-input-LUSBEycd.d.ts → radial-input-CpQPs1Mp.d.ts} +1 -1
- package/dist/radial-input-CpQPs1Mp.d.ts.map +1 -0
- package/dist/{radial-input-DZA6WaFu.js → radial-input-DZ7eQCcM.js} +11 -6
- package/dist/radial-input-DZ7eQCcM.js.map +1 -0
- package/dist/radial-input.d.ts +1 -1
- package/dist/radial-input.js +1 -1
- package/dist/range-input.d.ts +1 -1
- package/dist/range-input.d.ts.map +1 -1
- package/dist/range-input.js +9 -4
- package/dist/range-input.js.map +1 -1
- package/dist/range.d.ts +1 -1
- package/dist/range.d.ts.map +1 -1
- package/dist/range.js +5 -3
- package/dist/range.js.map +1 -1
- package/dist/{registry-Q2gYQCHM.js → registry-CkW7q09Q.js} +1 -1
- package/dist/{registry-Q2gYQCHM.js.map → registry-CkW7q09Q.js.map} +1 -1
- package/dist/selecthorizontal.d.ts +1 -1
- package/dist/selecthorizontal.d.ts.map +1 -1
- package/dist/selecthorizontal.js +4 -3
- package/dist/selecthorizontal.js.map +1 -1
- package/dist/snap-container.d.ts.map +1 -1
- package/dist/snap-container.js +1 -1
- package/dist/split-layout.d.ts +1 -1
- package/dist/split-layout.d.ts.map +1 -1
- package/dist/split-layout.js +6 -5
- package/dist/split-layout.js.map +1 -1
- package/dist/style.css +14 -4
- package/dist/swipe.d.ts.map +1 -1
- package/dist/swipe.js +9 -4
- package/dist/swipe.js.map +1 -1
- package/dist/{tab-list-BnqISNvO.d.ts → tab-list-DLzb-m-I.d.ts} +2 -2
- package/dist/tab-list-DLzb-m-I.d.ts.map +1 -0
- package/dist/tabs.d.ts +1 -1
- package/dist/tabs.js +10 -4
- package/dist/tabs.js.map +1 -1
- package/dist/{tickled-controller-Cq1Va0rR.d.ts → tickled-controller-BjYCzGrU.d.ts} +2 -2
- package/dist/tickled-controller-BjYCzGrU.d.ts.map +1 -0
- package/dist/{tickled-styles-Bg3QbcrD.js → tickled-styles-fNDdqf6l.js} +1 -17
- package/dist/{tickled-styles-Bg3QbcrD.js.map → tickled-styles-fNDdqf6l.js.map} +1 -1
- package/dist/{timeline-Cv75Th2U.js → timeline-2OFtN4Ta.js} +1437 -36
- package/dist/timeline-2OFtN4Ta.js.map +1 -0
- package/dist/timeline.d.ts +1 -1
- package/dist/timeline.js +1 -1
- package/dist/{tooltip-DMxmBNky.js → tooltip-CJt3WLmN.js} +1 -1
- package/dist/{tooltip-DMxmBNky.js.map → tooltip-CJt3WLmN.js.map} +1 -1
- package/dist/{tooltip-CwGfb4lp.d.ts → tooltip-RGVIwHrZ.d.ts} +1 -1
- package/dist/{tooltip-CwGfb4lp.d.ts.map → tooltip-RGVIwHrZ.d.ts.map} +1 -1
- package/dist/{tree-CvvKbO-f.js → tree-CJWpMUvD.js} +113 -103
- package/dist/tree-CJWpMUvD.js.map +1 -0
- package/dist/{tree-component-D8Bg48tt.d.ts → tree-component-BcO26Xvt.d.ts} +65 -3
- package/dist/tree-component-BcO26Xvt.d.ts.map +1 -0
- package/dist/tree.d.ts +15 -15
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +1 -1
- package/dist/{types-BKaqnpwx.d.ts → types-DSfbtHs3.d.ts} +1 -1
- package/dist/types-DSfbtHs3.d.ts.map +1 -0
- package/dist/{xy-axis-DL0tfJDr.js → xy-axis-CK64haaK.js} +1831 -359
- package/dist/xy-axis-CK64haaK.js.map +1 -0
- package/dist/{xy-axis-D9uwpGTT.d.ts → xy-axis-McdUpcYr.d.ts} +102 -3
- package/dist/xy-axis-McdUpcYr.d.ts.map +1 -0
- package/dist/xy-pad.d.ts +1 -1
- package/dist/xy-pad.d.ts.map +1 -1
- package/dist/xy-pad.js +11 -6
- package/dist/xy-pad.js.map +1 -1
- package/docs-user/README.md +45 -0
- package/docs-user/ac-text.md +67 -0
- package/docs-user/ac-token.md +187 -0
- package/docs-user/button.md +355 -0
- package/docs-user/checkbox.md +62 -0
- package/docs-user/colour-picker.md +237 -0
- package/docs-user/crumbs.md +66 -0
- package/docs-user/data-display.md +98 -0
- package/docs-user/editable-label.md +244 -0
- package/docs-user/grouped-item-lister.md +424 -0
- package/docs-user/icons.md +191 -0
- package/docs-user/incr-search.md +94 -0
- package/docs-user/labelled-radial-input.md +204 -0
- package/docs-user/labelled-range-input.md +194 -0
- package/docs-user/led.md +40 -0
- package/docs-user/menu.md +319 -0
- package/docs-user/miller.md +453 -0
- package/docs-user/narrowed-text.md +72 -0
- package/docs-user/panel.md +250 -0
- package/docs-user/plots.md +361 -0
- package/docs-user/polar-pad.md +228 -0
- package/docs-user/radial-input.md +559 -0
- package/docs-user/range-input.md +264 -0
- package/docs-user/range.md +12 -0
- package/docs-user/selecthorizontal.md +32 -0
- package/docs-user/snap-container.md +132 -0
- package/docs-user/split-layout.md +232 -0
- package/docs-user/swipe.md +44 -0
- package/docs-user/tabs.md +217 -0
- package/docs-user/timeline.md +116 -0
- package/docs-user/transitory-label.md +120 -0
- package/docs-user/tree.md +592 -0
- package/docs-user/user-catalog.md +165 -0
- package/docs-user/user-theming.md +379 -0
- package/docs-user/util.md +122 -0
- package/docs-user/vertical-list.md +351 -0
- package/docs-user/xy-pad.md +94 -0
- package/package.json +19 -18
- package/dist/colour-C3MQIjFJ-BLXg8W3U.js.map +0 -1
- package/dist/colour-picker-K6zu82lm.js.map +0 -1
- package/dist/dist-BX0OVIm7.js +0 -1290
- package/dist/dist-BX0OVIm7.js.map +0 -1
- package/dist/dist-TAGYwaju.js.map +0 -1
- package/dist/hex-editor-DlfoA65y.d.ts.map +0 -1
- package/dist/icon-9NWTXtE1.js.map +0 -1
- package/dist/icon-CeTDJhC7.d.ts.map +0 -1
- package/dist/index--hrxPBkQ.d.ts.map +0 -1
- package/dist/index-CnL9krsH.d.ts.map +0 -1
- package/dist/index-DSlPeWLK.d.ts.map +0 -1
- package/dist/index-DrQjA8Gs.d.ts.map +0 -1
- package/dist/interaction-DG7X1rhI.js +0 -1
- package/dist/labelled-input-base-D-Y7agky.d.ts.map +0 -1
- package/dist/menu-DJJuCm-5.js.map +0 -1
- package/dist/menu-item-CKRfP0pN.js.map +0 -1
- package/dist/menu-item-ClQF2DKN.d.ts.map +0 -1
- package/dist/prominence--ic9uWBl.js +0 -98
- package/dist/prominence--ic9uWBl.js.map +0 -1
- package/dist/radial-input-DZA6WaFu.js.map +0 -1
- package/dist/radial-input-LUSBEycd.d.ts.map +0 -1
- package/dist/tab-list-BnqISNvO.d.ts.map +0 -1
- package/dist/tickled-controller-Cq1Va0rR.d.ts.map +0 -1
- package/dist/timeline-Cv75Th2U.js.map +0 -1
- package/dist/tree-CvvKbO-f.js.map +0 -1
- package/dist/tree-component-D8Bg48tt.d.ts.map +0 -1
- package/dist/types-BKaqnpwx.d.ts.map +0 -1
- package/dist/xy-axis-D9uwpGTT.d.ts.map +0 -1
- package/dist/xy-axis-DL0tfJDr.js.map +0 -1
- /package/bundle/{chunk-pbuEa-1d.js → chunk-D7D4PA-g.js} +0 -0
- /package/dist/{chunk-pbuEa-1d.js → chunk-D7D4PA-g.js} +0 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# `<ixfx-range-input>`
|
|
2
|
+
|
|
3
|
+
A label-free, fully styled range slider wrapping `<input type="range">`. Supports horizontal and vertical orientations, CSS variable theming, gradient fills, custom thumb shapes, and an optional value tooltip.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Basic usage
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<ixfx-range-input value="0.5"></ixfx-range-input>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
const slider = document.querySelector('ixfx-range-input');
|
|
15
|
+
slider.addEventListener('input', e => console.log(e.detail.value));
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Attributes / properties
|
|
21
|
+
|
|
22
|
+
| Attribute / Property | Type | Default | Description |
|
|
23
|
+
|-----------------------|-----------------------------|----------------|--------------------------------------------------|
|
|
24
|
+
| `value` | `number` | `0` | Current value within `min`..`max` |
|
|
25
|
+
| `min` | `number` | `0` | Minimum value |
|
|
26
|
+
| `max` | `number` | `1` | Maximum value |
|
|
27
|
+
| `step` | `number` | `0.01` | Step increment |
|
|
28
|
+
| `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Slider axis |
|
|
29
|
+
| `tooltip` | `boolean` | `false` | Show value tooltip on hover/focus |
|
|
30
|
+
| `tooltip-orientation` | `"top" \| "right"` | `"top"` | Tooltip position relative to thumb |
|
|
31
|
+
| `labelFormatter` | `(raw, scaled) => string` | — | JS property (not an attribute) — custom tooltip formatter. `raw` is the value within `min`..`max`; `scaled` is the normalised 0..1 position. |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Events
|
|
36
|
+
|
|
37
|
+
Both events are `CustomEvent` instances with `{ bubbles: true, composed: true }`.
|
|
38
|
+
|
|
39
|
+
| Event | `detail` type | Description |
|
|
40
|
+
|----------|------------------------|----------------------------------------------------|
|
|
41
|
+
| `input` | `{ value: number }` | Fires continuously while dragging |
|
|
42
|
+
| `change` | `{ value: number }` | Fires once on release (same semantics as native) |
|
|
43
|
+
|
|
44
|
+
`value` in both events is the raw value within `min`..`max` (not normalised).
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Sizing
|
|
49
|
+
|
|
50
|
+
The component fills whatever dimensions you give it via `--width` / `--height`, or explicit CSS sizing.
|
|
51
|
+
|
|
52
|
+
| CSS variable | Default (horizontal) | Default (vertical) | Description |
|
|
53
|
+
|---|---|---|---|
|
|
54
|
+
| `--width` | `200px` | `2em` | Component width |
|
|
55
|
+
| `--height` | `2em` | `200px` | Component height |
|
|
56
|
+
|
|
57
|
+
```html
|
|
58
|
+
<!-- Full-width, default height -->
|
|
59
|
+
<ixfx-range-input style="--width:100%"></ixfx-range-input>
|
|
60
|
+
|
|
61
|
+
<!-- Tall horizontal slider -->
|
|
62
|
+
<ixfx-range-input style="--width:100%; --height:4em"></ixfx-range-input>
|
|
63
|
+
|
|
64
|
+
<!-- Vertical, filling a flex container -->
|
|
65
|
+
<div style="height:160px; display:flex; align-items:stretch">
|
|
66
|
+
<ixfx-range-input orientation="vertical" style="--width:2em; --height:100%"></ixfx-range-input>
|
|
67
|
+
</div>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Track CSS variables
|
|
73
|
+
|
|
74
|
+
| Variable | Default | Description |
|
|
75
|
+
|---------------------------------------------|-------------------------------|------------------------------------------|
|
|
76
|
+
| `--track-thickness` | `100%` | Track cross-axis size (% of component height in horizontal mode) |
|
|
77
|
+
| `--background-track` | `var(--surface-ll)` | Unfilled track background |
|
|
78
|
+
| `--background-track-hover` | `--background-track` | Unfilled track on hover |
|
|
79
|
+
| `--background-track-value` | `var(--surface-hh)` | Filled track color (supports gradients) |
|
|
80
|
+
| `--background-track-value-hover` | `var(--accent)` | Filled track on hover |
|
|
81
|
+
| `--background-track-value-active` | `var(--accent)` | Filled track while dragging |
|
|
82
|
+
|
|
83
|
+
### Vertical-only overrides
|
|
84
|
+
|
|
85
|
+
When `orientation="vertical"` these take precedence over the horizontal vars (falling back to them when unset):
|
|
86
|
+
|
|
87
|
+
| Variable | Falls back to |
|
|
88
|
+
|--------------------------------------------------|--------------------------------------|
|
|
89
|
+
| `--background-track-vertical` | `--background-track` |
|
|
90
|
+
| `--background-track-value-vertical` | `--background-track-value` |
|
|
91
|
+
| `--background-track-value-hover-vertical` | `--background-track-value-hover` |
|
|
92
|
+
| `--background-track-value-active-vertical` | `--background-track-value-active` |
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Thumb CSS variables
|
|
97
|
+
|
|
98
|
+
| Variable | Default | Description |
|
|
99
|
+
|-----------------------|---------------------------|-------------------------------------------------|
|
|
100
|
+
| `--thumb-thickness` | `2em` | Thumb size along the track axis |
|
|
101
|
+
| `--thumb-size` | `--track-thickness` | Thumb size across the track axis |
|
|
102
|
+
| `--thumb-color` | `var(--surface-text)` | Thumb fill at rest |
|
|
103
|
+
| `--thumb-color-active`| `var(--accent)` | Thumb fill on hover / active |
|
|
104
|
+
| `--thumb-radius` | `0` | `border-radius` of the thumb |
|
|
105
|
+
| `--thumb-border` | `none` | `border` shorthand for the thumb |
|
|
106
|
+
| `--thumb-shadow` | `none` | `box-shadow` for the thumb |
|
|
107
|
+
|
|
108
|
+
### Using container query units for thumb sizing
|
|
109
|
+
|
|
110
|
+
Because the component uses `container-type: size` internally, you can use `cqh` (1% of component height) and `cqw` (1% of component width) for reliable, dimension-agnostic sizing:
|
|
111
|
+
|
|
112
|
+
```css
|
|
113
|
+
/* Thumb is always a square equal to the component height */
|
|
114
|
+
ixfx-range-input {
|
|
115
|
+
--thumb-thickness: 100cqh;
|
|
116
|
+
--thumb-size: 100cqh;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Thumb is 80% of component height */
|
|
120
|
+
ixfx-range-input {
|
|
121
|
+
--thumb-thickness: 80cqh;
|
|
122
|
+
--thumb-size: 80cqh;
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
For vertical sliders, use `cqw` (component width) to size the thumb relative to the narrow dimension:
|
|
127
|
+
|
|
128
|
+
```css
|
|
129
|
+
ixfx-range-input[orientation="vertical"] {
|
|
130
|
+
--thumb-thickness: 100cqw;
|
|
131
|
+
--thumb-size: 100cqw;
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Tooltip
|
|
138
|
+
|
|
139
|
+
Add the `tooltip` attribute to show the current value above the thumb on hover/focus.
|
|
140
|
+
|
|
141
|
+
```html
|
|
142
|
+
<!-- Default: shows value rounded to 2 decimal places -->
|
|
143
|
+
<ixfx-range-input tooltip value="0.5"></ixfx-range-input>
|
|
144
|
+
|
|
145
|
+
<!-- Integer range: step=1 → no decimal places shown -->
|
|
146
|
+
<ixfx-range-input tooltip min="0" max="100" step="1" value="42"></ixfx-range-input>
|
|
147
|
+
|
|
148
|
+
<!-- Vertical slider: show tooltip to the right of the thumb -->
|
|
149
|
+
<ixfx-range-input orientation="vertical" tooltip tooltip-orientation="right" value="0.6"></ixfx-range-input>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Custom tooltip formatter
|
|
153
|
+
|
|
154
|
+
Assign a function to the `labelFormatter` JS property:
|
|
155
|
+
|
|
156
|
+
```js
|
|
157
|
+
const slider = document.querySelector('ixfx-range-input');
|
|
158
|
+
slider.labelFormatter = (rawValue, scaledValue) =>
|
|
159
|
+
`${Math.round(scaledValue * 100)}%`;
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
- `rawValue` — the value within `min`..`max`
|
|
163
|
+
- `scaledValue` — normalised 0..1 position
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Examples
|
|
168
|
+
|
|
169
|
+
### Accent colour override
|
|
170
|
+
|
|
171
|
+
```css
|
|
172
|
+
.my-slider {
|
|
173
|
+
--background-track-value: hsl(280 60% 35%);
|
|
174
|
+
--background-track-value-hover: hsl(280 80% 55%);
|
|
175
|
+
--background-track-value-active: hsl(280 80% 55%);
|
|
176
|
+
--thumb-color-active: hsl(280 80% 65%);
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
```html
|
|
181
|
+
<ixfx-range-input class="my-slider" value="0.5" style="--width:100%"></ixfx-range-input>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Gradient fill
|
|
185
|
+
|
|
186
|
+
The filled-track area uses a CSS mask, so any gradient set on `--background-track-value` shows through only up to the current value position.
|
|
187
|
+
|
|
188
|
+
```css
|
|
189
|
+
.gradient-fire {
|
|
190
|
+
--background-track-value: linear-gradient(to right, hsl(50 100% 45%), hsl(15 90% 50%));
|
|
191
|
+
--background-track-value-hover: linear-gradient(to right, hsl(55 100% 55%), hsl(15 100% 60%));
|
|
192
|
+
--background-track-value-active: linear-gradient(to right, hsl(55 100% 55%), hsl(15 100% 60%));
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Pill thumb
|
|
197
|
+
|
|
198
|
+
```css
|
|
199
|
+
.pill {
|
|
200
|
+
--thumb-radius: 999px;
|
|
201
|
+
--thumb-thickness: 20px;
|
|
202
|
+
--thumb-size: 200cqh;
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Circle dot thumb
|
|
207
|
+
|
|
208
|
+
```css
|
|
209
|
+
.dot {
|
|
210
|
+
--thumb-thickness: 100cqh;
|
|
211
|
+
--thumb-size: 100cqh;
|
|
212
|
+
--thumb-radius: 50%;
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Ghost (outlined) thumb
|
|
217
|
+
|
|
218
|
+
```css
|
|
219
|
+
.ghost {
|
|
220
|
+
--thumb-color: transparent;
|
|
221
|
+
--thumb-color-active: transparent;
|
|
222
|
+
--thumb-border: 2px solid var(--accent);
|
|
223
|
+
--thumb-radius: 3px;
|
|
224
|
+
--thumb-shadow: 0 0 6px var(--accent);
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Orientation-specific colours
|
|
229
|
+
|
|
230
|
+
Both orientations can share one CSS class, with the vertical variant overriding only what it needs:
|
|
231
|
+
|
|
232
|
+
```css
|
|
233
|
+
.dual-color {
|
|
234
|
+
--background-track-value: hsl(210 70% 40%); /* horizontal → blue */
|
|
235
|
+
--background-track-value-vertical: hsl(30 70% 45%); /* vertical → orange */
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
```html
|
|
240
|
+
<ixfx-range-input class="dual-color" value="0.6" style="--width:100%"></ixfx-range-input>
|
|
241
|
+
<ixfx-range-input class="dual-color" orientation="vertical" value="0.6"></ixfx-range-input>
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Listening to events
|
|
245
|
+
|
|
246
|
+
```js
|
|
247
|
+
const slider = document.querySelector('ixfx-range-input');
|
|
248
|
+
|
|
249
|
+
// Fires on every move
|
|
250
|
+
slider.addEventListener('input', ({ detail }) => {
|
|
251
|
+
console.log('moving:', detail.value);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// Fires once on release
|
|
255
|
+
slider.addEventListener('change', ({ detail }) => {
|
|
256
|
+
console.log('settled:', detail.value);
|
|
257
|
+
});
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Setting value programmatically
|
|
261
|
+
|
|
262
|
+
```js
|
|
263
|
+
slider.value = 0.75;
|
|
264
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Range elements
|
|
2
|
+
|
|
3
|
+
## Styling
|
|
4
|
+
|
|
5
|
+
Range: Coloured bar that suggests values
|
|
6
|
+
--range-background: (AccentColor)
|
|
7
|
+
--range-thickness: (1em)
|
|
8
|
+
--thumb-background: (ButtonFace)
|
|
9
|
+
Tooltip
|
|
10
|
+
|
|
11
|
+
--tooltip-background: (ButtonFace)
|
|
12
|
+
--tooltip-color: (ButtonText)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# `ixfx-selecthorizontal-element`
|
|
2
|
+
|
|
3
|
+
A horizontally scrolling container with snap points for child elements. Useful for scrollable lists of items that should snap into alignment.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<ixfx-selecthorizontal-element>
|
|
7
|
+
<div>Item 1</div>
|
|
8
|
+
<div>Item 2</div>
|
|
9
|
+
<div>Item 3</div>
|
|
10
|
+
</ixfx-selecthorizontal-element>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Properties / attributes
|
|
14
|
+
|
|
15
|
+
| Attribute / Property | Type | Default | Description |
|
|
16
|
+
|----------------------|----------|---------|----------------------------|
|
|
17
|
+
| `editMode` | `boolean`| `false` | (Reserved for future use) |
|
|
18
|
+
|
|
19
|
+
### CSS custom properties
|
|
20
|
+
|
|
21
|
+
Inherits border styling from global `--border` and `--accent` variables applied to slotted children.
|
|
22
|
+
|
|
23
|
+
### CSS parts
|
|
24
|
+
|
|
25
|
+
The component styles slotted elements with scroll snapping behavior.
|
|
26
|
+
|
|
27
|
+
### Usage notes
|
|
28
|
+
|
|
29
|
+
- Children should have `data-value` attribute for identification
|
|
30
|
+
- Component handles `slotchange` events to update available items
|
|
31
|
+
- Uses `scroll-snap-type: x mandatory` for snap alignment
|
|
32
|
+
- Hidden scrollbar via `scrollbar-width: none`
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# `ixfx-snap-container`
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<ixfx-snap-container snap-positions="3" orientation="horizontal">
|
|
7
|
+
<button>Drag me</button>
|
|
8
|
+
</ixfx-snap-container>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Properties / attributes
|
|
14
|
+
|
|
15
|
+
| Attribute / Property | Type | Default | Description |
|
|
16
|
+
|------------------------|-------------------------------|-------------|--------------------------------------------------------------------|
|
|
17
|
+
| `orientation` | `'horizontal'` \| `'vertical'` | `'horizontal'` | Axis along which snapping occurs. Horizontal uses x-axis; vertical uses y-axis |
|
|
18
|
+
| `snap-positions` | number | `3` | Number of snap positions |
|
|
19
|
+
| `snap-logic` | `'centre'` \| `'balanced'` | `'balanced'` | How snap positions are distributed (see [Snap logic](#snap-logic)) |
|
|
20
|
+
| `click-snap` | `'closest'` \| `'step'` | `'closest'` | How clicking in empty space snaps (see [Click snap modes](#click-snap-modes)) |
|
|
21
|
+
| `snap` | number | `0` | Current snap index (0-based) |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Snap logic
|
|
26
|
+
|
|
27
|
+
### `balanced` (default)
|
|
28
|
+
|
|
29
|
+
First snap position aligns with container's left/top edge. Last snap position aligns with container's right/bottom edge. Middle positions are evenly distributed.
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
Position 0 ─┬── Position 1 ─┬── Position 2 ─┬── Position 3 ─┬── Position 4
|
|
33
|
+
│ │ │ │
|
|
34
|
+
────────────┼────────────────┼────────────────┼────────────────┼────────────
|
|
35
|
+
Left edge │ evenly │ evenly │ evenly │ Right edge
|
|
36
|
+
│ spaced │ spaced │ spaced │
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### `centre`
|
|
40
|
+
|
|
41
|
+
All snap positions are evenly distributed, ignoring edge alignment.
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Position 0 ─┬── Position 1 ─┬── Position 2 ─┬── Position 3 ─┬── Position 4
|
|
45
|
+
│ │ │ │
|
|
46
|
+
────────────┼────────────────┼────────────────┼────────────────┼────────────
|
|
47
|
+
│ │ centred │ │
|
|
48
|
+
│ │ │ │
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Click snap modes
|
|
54
|
+
|
|
55
|
+
### `closest` (default)
|
|
56
|
+
|
|
57
|
+
Clicking anywhere in the container (not on the child) moves the child to the nearest snap position to the click point.
|
|
58
|
+
|
|
59
|
+
### `step`
|
|
60
|
+
|
|
61
|
+
Clicking to the **right** of the child's center moves it one position right. Clicking to the **left** moves it one position left. Similarly for vertical orientation (up/down).
|
|
62
|
+
|
|
63
|
+
This is useful for incremental navigation without dragging.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Events
|
|
68
|
+
|
|
69
|
+
| Event | Detail | Description |
|
|
70
|
+
|---------------|-------------------------------------|------------------------------------------|
|
|
71
|
+
| `snap-change` | `{ previousSnap, newSnap }` | Fired when snap index changes |
|
|
72
|
+
| `snap-input` | `{ index }` | Fired continuously during drag operation |
|
|
73
|
+
|
|
74
|
+
Both events bubble and are composed.
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
container.addEventListener('snap-change', (e) => {
|
|
78
|
+
console.log(`Moved from ${e.detail.previousSnap} to ${e.detail.newSnap}`);
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## CSS custom properties
|
|
85
|
+
|
|
86
|
+
| Property | Default | Description |
|
|
87
|
+
|------------------------|------------|--------------------------------------------------|
|
|
88
|
+
| `--transition-duration`| `200ms` | Duration of snap transitions |
|
|
89
|
+
|
|
90
|
+
The child element also receives a `--snap-index` custom property reflecting its current position:
|
|
91
|
+
|
|
92
|
+
```css
|
|
93
|
+
child {
|
|
94
|
+
background: hsl(calc(var(--snap-index) * 60), 70%, 50%);
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Keyboard navigation
|
|
101
|
+
|
|
102
|
+
When the container or its child has focus:
|
|
103
|
+
|
|
104
|
+
| Orientation | Key | Action |
|
|
105
|
+
|---------------|-----------|-------------------------------|
|
|
106
|
+
| horizontal | LEFT | Move to previous snap position|
|
|
107
|
+
| horizontal | RIGHT | Move to next snap position |
|
|
108
|
+
| vertical | UP | Move to previous snap position|
|
|
109
|
+
| vertical | DOWN | Move to next snap position |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Programmatic control
|
|
114
|
+
|
|
115
|
+
All properties are writable at runtime:
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
const container = document.querySelector('ixfx-snap-container');
|
|
119
|
+
|
|
120
|
+
container.snap = 2; // Jump to position 2
|
|
121
|
+
container.snapPositions = 5; // Change to 5 positions
|
|
122
|
+
container.orientation = 'vertical'; // Switch to vertical
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Usage notes
|
|
128
|
+
|
|
129
|
+
- The child element should have a fixed or intrinsic size
|
|
130
|
+
- The container has `overflow: hidden` and positions the child absolutely
|
|
131
|
+
- Drag requires moving at least 10px before snapping engages
|
|
132
|
+
- In `step` mode, clicking when already at the boundary (0 or max) does nothing
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Split Layout
|
|
2
|
+
|
|
3
|
+
A Lit web component that lays out two elements within a container with a resize handle to adjust their proportions.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## `ixfx-split-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 resize handle |
|
|
36
|
+
| `--handle-colour` | `var(--surface-5)` | Colour of the resize handle |
|
|
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
|
+
|
|
40
|
+
### Events
|
|
41
|
+
|
|
42
|
+
| Event | Detail | Description |
|
|
43
|
+
|-------|--------|-------------|
|
|
44
|
+
| `ixfx-split-collapsed` | `{ panel: 'A' \| 'B', collapsed: boolean }` | Fired when a panel is collapsed or uncollapsed via drag. |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Basic Usage
|
|
49
|
+
|
|
50
|
+
### Vertical Split (Left/Right)
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<ixfx-split-layout layout="vertical" style="width: 100%; height: 400px;">
|
|
54
|
+
<div slot="a" style="background: var(--surface-3);">Left Panel</div>
|
|
55
|
+
<div slot="b" style="background: var(--surface-5);">Right Panel</div>
|
|
56
|
+
</ixfx-split-layout>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Horizontal Split (Top/Bottom)
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<ixfx-split-layout layout="horizontal" style="width: 100%; height: 400px;">
|
|
63
|
+
<div slot="a" style="background: var(--surface-3);">Top Panel</div>
|
|
64
|
+
<div slot="b" style="background: var(--surface-5);">Bottom Panel</div>
|
|
65
|
+
</ixfx-split-layout>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### With Fixed Panel
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<!-- Left panel fixed at 200px, right panel takes remaining space -->
|
|
72
|
+
<ixfx-split-layout fixedA layout="vertical" style="width: 100%; height: 400px;">
|
|
73
|
+
<div slot="a" style="background: var(--surface-3);">Left Panel (200px)</div>
|
|
74
|
+
<div slot="b" style="background: var(--surface-5);">Right Panel (flexible)</div>
|
|
75
|
+
</ixfx-split-layout>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Collapsible Panels
|
|
81
|
+
|
|
82
|
+
When `collapsible` is set, dragging a resize handle to the edge collapses that panel. The other panel expands to fill the space. Dragging away from the edge uncollapses the panel.
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
<ixfx-split-layout collapsible layout="horizontal" style="width: 100%; height: 400px;">
|
|
86
|
+
<div slot="a" style="background: var(--surface-3);">Top Panel</div>
|
|
87
|
+
<div slot="b" style="background: var(--surface-5);">Bottom Panel</div>
|
|
88
|
+
</ixfx-split-layout>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Collapse Events
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
const split = document.querySelector('ixfx-split-layout[collapsible]');
|
|
95
|
+
|
|
96
|
+
split.addEventListener('ixfx-split-collapsed', ({ detail }) => {
|
|
97
|
+
console.log(`Panel ${detail.panel} is now ${detail.collapsed ? 'collapsed' : 'uncollapsed'}`);
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Min/Max Size Constraints
|
|
104
|
+
|
|
105
|
+
Use `minSizeA`, `maxSizeA`, `minSizeB`, and `maxSizeB` to constrain panel sizes:
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<ixfx-split-layout
|
|
109
|
+
minSizeA="100px"
|
|
110
|
+
maxSizeA="70%"
|
|
111
|
+
minSizeB="50px"
|
|
112
|
+
layout="horizontal"
|
|
113
|
+
style="width: 100%; height: 400px;">
|
|
114
|
+
<div slot="a" style="background: var(--surface-3);">Top Panel</div>
|
|
115
|
+
<div slot="b" style="background: var(--surface-5);">Bottom Panel</div>
|
|
116
|
+
</ixfx-split-layout>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Constraint rules:**
|
|
120
|
+
- **Min constraints take precedence**: If both panels' minimums exceed 100% combined, they're scaled proportionally
|
|
121
|
+
- **Max constraints are secondary**: If a max constraint conflicts with a min constraint, the max is ignored to satisfy the min
|
|
122
|
+
- **The constrained panel gets clamped**: The other panel receives the remaining space
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Nested Splits with Two-Way Corner Resize
|
|
127
|
+
|
|
128
|
+
When a `ixfx-split-layout` is nested inside slot A of an outer split, a corner zone appears at the intersection of the two resize handles. This enables simultaneous resize of both splits.
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
┌─────────────────┬────────────┐
|
|
132
|
+
│ │ │
|
|
133
|
+
│ ┌─────────────┤ │
|
|
134
|
+
│ │ Editor │ │
|
|
135
|
+
│ │ │ │
|
|
136
|
+
│ ├─────────────┤ Sidebar │
|
|
137
|
+
│ │ Terminal │ │
|
|
138
|
+
│ │ │ │
|
|
139
|
+
│ └─────────────┘ │
|
|
140
|
+
└─────────────────┴────────────┘
|
|
141
|
+
↑
|
|
142
|
+
Corner Zone
|
|
143
|
+
(drag here for two-way resize)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Structure
|
|
147
|
+
|
|
148
|
+
```html
|
|
149
|
+
<ixfx-split-layout layout="vertical" style="width: 100%; height: 400px;">
|
|
150
|
+
<!-- Nested split is a direct child of slot A -->
|
|
151
|
+
<ixfx-split-layout slot="a" layout="horizontal" style="width: 100%; height: 100%;">
|
|
152
|
+
<div slot="a" style="background: var(--surface);">Editor</div>
|
|
153
|
+
<div slot="b" style="background: var(--surface-3);">Terminal</div>
|
|
154
|
+
</ixfx-split-layout>
|
|
155
|
+
<div slot="b" style="background: var(--surface-5);">Sidebar</div>
|
|
156
|
+
</ixfx-split-layout>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**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).
|
|
160
|
+
|
|
161
|
+
### Corner Zone Behavior
|
|
162
|
+
|
|
163
|
+
- **Visual indicator**: A small magenta circle (12px) appears at the intersection point
|
|
164
|
+
- **Cursor change**: Shows `nwse-resize` cursor when hovering over the corner zone (for vertical-outer/horizontal-inner splits)
|
|
165
|
+
- **Two-way resize**: Dragging the corner zone adjusts both the outer vertical split and the inner horizontal split simultaneously
|
|
166
|
+
- **Position tracking**: The corner zone follows the resize handles as they move, staying at their intersection
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## CSS Customisation
|
|
171
|
+
|
|
172
|
+
### Handle Styling
|
|
173
|
+
|
|
174
|
+
```css
|
|
175
|
+
ixfx-split-layout {
|
|
176
|
+
--handle-size: 4px;
|
|
177
|
+
--handle-colour: var(--surface-4);
|
|
178
|
+
--handle-hover-colour: var(--surface-6);
|
|
179
|
+
--handle-active-colour: var(--accent);
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Hide Collapsed Panels Completely
|
|
184
|
+
|
|
185
|
+
```css
|
|
186
|
+
ixfx-split-layout[data-collapsed-a] slot[name="a"] {
|
|
187
|
+
display: none;
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Programmatic Control
|
|
194
|
+
|
|
195
|
+
### Setting Sizes
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
const split = document.querySelector('ixfx-split-layout');
|
|
199
|
+
|
|
200
|
+
// Set to 30% / 70%
|
|
201
|
+
split.sizeA = '30%';
|
|
202
|
+
split.sizeB = '70%';
|
|
203
|
+
|
|
204
|
+
// Set to fixed pixel widths
|
|
205
|
+
split.fixedA = true;
|
|
206
|
+
split.sizeA = '200px'; // Panel A is 200px
|
|
207
|
+
// Panel B automatically gets remaining space
|
|
208
|
+
|
|
209
|
+
// Collapse a panel programmatically
|
|
210
|
+
split.collapsedA = true;
|
|
211
|
+
split.collapsedB = false;
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Reading State
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
console.log('Panel A size:', split.sizeA);
|
|
218
|
+
console.log('Panel B size:', split.sizeB);
|
|
219
|
+
console.log('Is A collapsed?', split.collapsedA);
|
|
220
|
+
console.log('Is B collapsed?', split.collapsedB);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Implementation Notes
|
|
226
|
+
|
|
227
|
+
- Uses Shadow DOM for style encapsulation
|
|
228
|
+
- Slots use `display: block` and `overflow: hidden` by default
|
|
229
|
+
- When no size is specified for a panel, it defaults to `auto` (fill remaining space)
|
|
230
|
+
- When both sizes are empty, both default to `50%`
|
|
231
|
+
- The resize handle is `flex-shrink: 0` to prevent it from collapsing
|
|
232
|
+
- Nested splits detect their parent through slot assignment and automatically enable corner resize
|