@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
|
@@ -57,6 +57,85 @@ declare class PlotDataSeries {
|
|
|
57
57
|
clear(): void;
|
|
58
58
|
}
|
|
59
59
|
//#endregion
|
|
60
|
+
//#region src/plots/multi-axis.d.ts
|
|
61
|
+
type PlotMultiAxisLayout = `overlap` | `horizontal` | `vertical` | `grid`;
|
|
62
|
+
type PlotMultiAxisDataPointClickDetail = {
|
|
63
|
+
readonly value: number;
|
|
64
|
+
readonly index: number;
|
|
65
|
+
readonly series: string;
|
|
66
|
+
};
|
|
67
|
+
type PlotMultiAxisDataPointClickEvent = CustomEvent<PlotMultiAxisDataPointClickDetail>;
|
|
68
|
+
interface PlotMultiAxisElementEventMap {
|
|
69
|
+
'plot-datapoint-click': PlotMultiAxisDataPointClickEvent;
|
|
70
|
+
}
|
|
71
|
+
declare class PlotMultiAxis extends LitElement {
|
|
72
|
+
#private;
|
|
73
|
+
layout: PlotMultiAxisLayout;
|
|
74
|
+
gridMinWidth: number;
|
|
75
|
+
/** Override to customize tooltip value display. */
|
|
76
|
+
valueFormat: (v: number | undefined) => string;
|
|
77
|
+
addData(data: Record<string, number>): void;
|
|
78
|
+
addData(name: string, value: number): void;
|
|
79
|
+
styleSeries(name: string, styles: Record<string, string>): void;
|
|
80
|
+
clear(): void;
|
|
81
|
+
clearSeries(name: string): void;
|
|
82
|
+
get series(): string[];
|
|
83
|
+
protected render(): import("lit").TemplateResult<1>;
|
|
84
|
+
static styles: import("lit").CSSResult;
|
|
85
|
+
}
|
|
86
|
+
declare global {
|
|
87
|
+
interface HTMLElementTagNameMap {
|
|
88
|
+
'ixfx-plot-multi-axis': PlotMultiAxis;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
interface PlotMultiAxis {
|
|
92
|
+
addEventListener: {
|
|
93
|
+
<K extends keyof PlotMultiAxisElementEventMap>(type: K, listener: (this: PlotMultiAxis, event: PlotMultiAxisElementEventMap[K]) => void, options?: boolean | AddEventListenerOptions): void;
|
|
94
|
+
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/plots/plot-histogram.d.ts
|
|
99
|
+
type PlotHistogramOrientation = 'horizontal' | 'vertical';
|
|
100
|
+
type PlotHistogramBucketClickDetail = {
|
|
101
|
+
readonly bucketIndex: number;
|
|
102
|
+
readonly valueMin: number;
|
|
103
|
+
readonly valueMax: number;
|
|
104
|
+
readonly relativeValue: number;
|
|
105
|
+
};
|
|
106
|
+
type PlotHistogramBucketClickEvent = CustomEvent<PlotHistogramBucketClickDetail>;
|
|
107
|
+
interface PlotHistogramElementEventMap {
|
|
108
|
+
'plot-bucket-click': PlotHistogramBucketClickEvent;
|
|
109
|
+
}
|
|
110
|
+
declare class PlotHistogram extends LitElement {
|
|
111
|
+
#private;
|
|
112
|
+
orientation: PlotHistogramOrientation;
|
|
113
|
+
resolution: number;
|
|
114
|
+
min?: number;
|
|
115
|
+
max?: number;
|
|
116
|
+
capacity: number;
|
|
117
|
+
title: string;
|
|
118
|
+
paused: boolean;
|
|
119
|
+
private _width;
|
|
120
|
+
private _height;
|
|
121
|
+
add(v: number): void;
|
|
122
|
+
set(values: number[]): void;
|
|
123
|
+
clear(): void;
|
|
124
|
+
protected firstUpdated(_changed: PropertyValues): void;
|
|
125
|
+
protected updated(changed: PropertyValues): void;
|
|
126
|
+
render(): import("lit").TemplateResult<1>;
|
|
127
|
+
static styles: import("lit").CSSResult;
|
|
128
|
+
}
|
|
129
|
+
declare global {
|
|
130
|
+
interface HTMLElementTagNameMap {
|
|
131
|
+
'ixfx-plot-histogram': PlotHistogram;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
interface PlotHistogram {
|
|
135
|
+
addEventListener<K extends keyof PlotHistogramElementEventMap>(type: K, listener: (this: PlotHistogram, event: PlotHistogramElementEventMap[K]) => void, options?: boolean | AddEventListenerOptions): void;
|
|
136
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
60
139
|
//#region src/plots/single-axis.d.ts
|
|
61
140
|
type SingleAxisDrawStyle = `line-sharp` | `line-round` | `circles` | `squares` | `vbar` | `hbar` | `hist-bottom` | `hist-top` | `hist-middle`;
|
|
62
141
|
type SingleAxisAgeStyle = `none` | `opacity` | `desaturation` | `size`;
|
|
@@ -82,6 +161,10 @@ declare class PlotSingleAxis extends LitElement {
|
|
|
82
161
|
private _height;
|
|
83
162
|
/** Override to customize tooltip label. */
|
|
84
163
|
valueFormat: (v: number | undefined) => string;
|
|
164
|
+
get values(): readonly number[];
|
|
165
|
+
get dataCount(): number;
|
|
166
|
+
getValueAt(index: number): number | undefined;
|
|
167
|
+
getIndexFromClientX(clientX: number): number;
|
|
85
168
|
add(v: number): void;
|
|
86
169
|
set(values: number[]): void;
|
|
87
170
|
clear(): void;
|
|
@@ -90,11 +173,27 @@ declare class PlotSingleAxis extends LitElement {
|
|
|
90
173
|
render(): import("lit").TemplateResult<1>;
|
|
91
174
|
static styles: import("lit").CSSResult;
|
|
92
175
|
}
|
|
176
|
+
type PlotSingleAxisPointerMoveDetail = {
|
|
177
|
+
readonly clientX: number;
|
|
178
|
+
readonly clientY: number;
|
|
179
|
+
readonly index: number;
|
|
180
|
+
};
|
|
181
|
+
type PlotSingleAxisPointerMoveEvent = CustomEvent<PlotSingleAxisPointerMoveDetail>;
|
|
182
|
+
interface PlotSingleAxisElementEventMap {
|
|
183
|
+
'plot-pointer-move': PlotSingleAxisPointerMoveEvent;
|
|
184
|
+
'plot-pointer-leave': Event;
|
|
185
|
+
}
|
|
93
186
|
declare global {
|
|
94
187
|
interface HTMLElementTagNameMap {
|
|
95
188
|
'ixfx-plot-single-axis': PlotSingleAxis;
|
|
96
189
|
}
|
|
97
|
-
}
|
|
190
|
+
}
|
|
191
|
+
interface PlotSingleAxis {
|
|
192
|
+
addEventListener: {
|
|
193
|
+
<K extends keyof PlotSingleAxisElementEventMap>(type: K, listener: (this: PlotSingleAxis, event: PlotSingleAxisElementEventMap[K]) => void, options?: boolean | AddEventListenerOptions): void;
|
|
194
|
+
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
195
|
+
};
|
|
196
|
+
}
|
|
98
197
|
//#endregion
|
|
99
198
|
//#region src/plots/xy-axis.d.ts
|
|
100
199
|
type XyDrawStyle = `circles` | `squares`;
|
|
@@ -136,5 +235,5 @@ declare global {
|
|
|
136
235
|
}
|
|
137
236
|
} //# sourceMappingURL=xy-axis.d.ts.map
|
|
138
237
|
//#endregion
|
|
139
|
-
export {
|
|
140
|
-
//# sourceMappingURL=xy-axis-
|
|
238
|
+
export { ColourMode as C, parseColourScaleAttr as D, computeColour as E, readBaseColour as O, ColourMapConfig as S, applyAgeModification as T, PlotMultiAxisDataPointClickEvent as _, PlotSingleAxisElementEventMap as a, PlotDataSeries as b, SingleAxisAgeStyle as c, PlotHistogramBucketClickDetail as d, PlotHistogramBucketClickEvent as f, PlotMultiAxisDataPointClickDetail as g, PlotMultiAxis as h, PlotSingleAxis as i, SingleAxisDrawStyle as l, PlotHistogramOrientation as m, XyAgeStyle as n, PlotSingleAxisPointerMoveDetail as o, PlotHistogramElementEventMap as p, XyDrawStyle as r, PlotSingleAxisPointerMoveEvent as s, PlotXyAxis as t, PlotHistogram as u, PlotMultiAxisElementEventMap as v, ColourResult as w, PlotDataSeriesOptions as x, PlotMultiAxisLayout as y };
|
|
239
|
+
//# sourceMappingURL=xy-axis-McdUpcYr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xy-axis-McdUpcYr.d.ts","names":[],"sources":["../src/plots/colour-map.ts","../src/plots/data.ts","../src/plots/multi-axis.ts","../src/plots/plot-histogram.ts","../src/plots/single-axis.ts","../src/plots/xy-axis.ts"],"mappings":"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"}
|
package/dist/xy-pad.d.ts
CHANGED
package/dist/xy-pad.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xy-pad.d.ts","names":[],"sources":["../src/xy-pad.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"xy-pad.d.ts","names":[],"sources":["../src/xy-pad/xy-pad.ts"],"mappings":";;;cAyEa,KAAA,SAAc,UAAA;EAAA,OACT,MAAA,gBAAM,SAAA;EAoHM,IAAA;EACA,IAAA;EACA,CAAA;EAEA,IAAA;EACA,IAAA;EACA,CAAA;EAEA,MAAA;EACA,MAAA;EAC0B,SAAA;EACA,SAAA;EAE1B,MAAA;EACA,MAAA;EAE8C,cAAA;EACN,QAAA;EACE,UAAA;EAC1B,QAAA;EAsOlC;EAnOkB,KAAA;;EAGsB,MAAA;EAkOxC;EA/NwC,MAAA;EAAA,QAE1C,SAAA;EAAA,QACA,WAAA;EAAA,QACA,WAAA;EAAA,QACA,YAAA;EAAA,QAEA,UAAA;EAAA,QAuBA,QAAA;EAAA,QAIA,mBAAA;EAAA,QA2CA,cAAA;EAAA,QAeA,cAAA;EAAA,QAOA,YAAA;EAAA,QAeA,kBAAA;EAAA,QA+BA,WAAA;EAqFc;;AAAA;EAjEtB,YAAA;EAqE4B;;;EA7D5B,YAAA;EA8DO;;;;AACgB;EArDvB,QAAA;IAAc,MAAA;IAAgB,KAAA;EAAA;EAUrB,OAAA,CAAQ,QAAA,EAAU,cAAA;EAKlB,oBAAA;EAMA,MAAA,IAAU,UAAA,QAAkB,IAAA;AAAA;AAAA,KAiB3B,gBAAA;EAAA,SACD,CAAA;EAAA,SACA,CAAC;AAAA;AAAA,KAGA,eAAA,GAAkB,WAAW,CAAC,gBAAA;AAAA,QAElC,MAAA;EAAA,UACI,qBAAA;IACR,aAAA,EAAe,KAAK;EAAA;AAAA;AAAA,UAIP,aAAA;EACf,KAAA,EAAO,eAAA;EACP,MAAA,EAAQ,eAAe;AAAA;AAAA,UAGR,KAAA;EACf,gBAAA,oBAAoC,aAAA,EAClC,IAAA,EAAM,CAAA,EACN,QAAA,GAAW,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,aAAA,CAAc,CAAA,YAC7C,OAAA,aAAoB,uBAAA,eAEpB,IAAA,UACA,QAAA,EAAU,kCAAA,EACV,OAAA,aAAoB,uBAAA;AAAA"}
|
package/dist/xy-pad.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
import { t as
|
|
1
|
+
import { t as themeFallbacks } from "./fallbacks-pNMOMx38.js";
|
|
2
|
+
import { n as safeCustomElement, t as __decorate } from "./decorate-DdjvVHS-.js";
|
|
3
|
+
import { t as prominenceStyles } from "./prominence-DlFShic3.js";
|
|
4
|
+
import { t as resolveStep } from "./keyboard-CimiEskD.js";
|
|
4
5
|
import { LitElement, css, html } from "lit";
|
|
5
6
|
import { property } from "lit/decorators.js";
|
|
6
|
-
//#region src/xy-pad.ts
|
|
7
|
+
//#region src/xy-pad/xy-pad.ts
|
|
7
8
|
/**
|
|
8
9
|
* <x-xy-pad> — 2D touch-friendly XY pad for controlling two parameters.
|
|
9
10
|
*
|
|
@@ -176,7 +177,10 @@ let XyPad = class XyPad extends LitElement {
|
|
|
176
177
|
};
|
|
177
178
|
}
|
|
178
179
|
static {
|
|
179
|
-
this.styles = [
|
|
180
|
+
this.styles = [
|
|
181
|
+
themeFallbacks,
|
|
182
|
+
prominenceStyles,
|
|
183
|
+
css`
|
|
180
184
|
:host {
|
|
181
185
|
display: block;
|
|
182
186
|
width: 200px;
|
|
@@ -290,7 +294,8 @@ let XyPad = class XyPad extends LitElement {
|
|
|
290
294
|
height:100%;
|
|
291
295
|
text-align:center;
|
|
292
296
|
}
|
|
293
|
-
`
|
|
297
|
+
`
|
|
298
|
+
];
|
|
294
299
|
}
|
|
295
300
|
_updateFromPointer(e) {
|
|
296
301
|
const pad = this.renderRoot.querySelector(`.xy-pad-area`);
|
package/dist/xy-pad.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xy-pad.js","names":["customElement"],"sources":["../src/xy-pad.ts"],"sourcesContent":["import type { PropertyValues } from 'lit';\n/**\n * <x-xy-pad> — 2D touch-friendly XY pad for controlling two parameters.\n *\n * Generic pad that accepts min/max/value for both axes with configurable labels.\n * Each axis can independently use logarithmic or linear scaling.\n * Y axis is inverted (top = high value).\n *\n * Properties\n * xMin, xMax, x – horizontal range and current value\n * yMin, yMax, y – vertical range and current value\n * xScale, yScale – 'log' (default) or 'linear'\n * xSnapStep, ySnapStep – snap granularity for pointer and keyboard moves (defaults: 1 / 0.01)\n * xLabel, yLabel – axis labels (displayed in corners)\n * showCrosshairs – show X/Y axis lines (default: false)\n * showGrid – show background grid (default: false)\n *\n * CSS variables:\n * --marker-size – size of the position marker (default: 10cqb)\n * --crosshair-color – colour of both crosshair lines (default: surface-hh)\n * --crosshair-width – thickness of both crosshair lines (default: 2px)\n * --crosshair-x-color – colour of the vertical (X) crosshair line; falls back to --crosshair-color\n * --crosshair-x-width – thickness of the vertical (X) crosshair line; falls back to --crosshair-width\n * --crosshair-y-color – colour of the horizontal (Y) crosshair line; falls back to --crosshair-color\n * --crosshair-y-width – thickness of the horizontal (Y) crosshair line; falls back to --crosshair-width\n * --grid-color – colour of grid lines (default: surface-hh)\n * --grid-width – thickness of grid lines (default: 1px)\n * --x-pct – current X position as unitless number (0–100), set on host so external styles can use it\n * --y-pct – current Y position as unitless number (0–100), set on host so external styles can use it\n * --radius-pct – distance from center as unitless number (0–100), set on host so external styles can use it\n * hide-cursor – boolean, hide cursor during drag and hover (default: false)\n *\n * Events\n * input – CustomEvent { detail: { x: number, y: number } }, bubbles + composed, fires continuously during drag\n * change – CustomEvent { detail: { x: number, y: number } }, bubbles + composed, fires when drag ends\n *\n * Methods\n * getRelativeX() – returns X position as 0–1 fraction\n * getRelativeY() – returns Y position as 0–1 fraction\n * getPolar() – returns { radius: number, angle: number } where radius is 0–1 and angle is in radians (0 to 2π, 0 = right, clockwise)\n */\nimport { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { KEY_STEP_DIVISOR, resolveStep } from './keyboard.js';\nimport { prominenceStyles } from './styles/prominence.js';\nimport { safeCustomElement as customElement } from './util/custom-elements.js';\n\n// ---------------------------------------------------------------------------\n// Scale helpers — log or linear, selected per-axis\n// ---------------------------------------------------------------------------\n\nfunction valueToFrac(value: number, min: number, max: number, scale: string): number {\n if (scale === `linear`)\n return (value - min) / (max - min);\n return Math.log(value / min) / Math.log(max / min);\n}\n\nfunction fracToValue(frac: number, min: number, max: number, scale: string): number {\n if (scale === `linear`)\n return min + frac * (max - min);\n return min * (max / min) ** frac;\n}\n\nfunction quantise(value: number, min: number, max: number, stops?: number): number {\n if (!stops || stops <= 1)\n return value;\n const range = max - min;\n const step = range / stops;\n return Math.round((value - min) / step) * step + min;\n}\n\n@customElement(`ixfx-xy-pad`)\nexport class XyPad extends LitElement {\n static override styles = [prominenceStyles, css`\n :host {\n display: block;\n width: 200px;\n height: 200px;\n touch-action: none;\n user-select: none;\n container-type: size;\n --marker-size: 10cqb;\n --crosshair-color: var(--surface-6);\n --crosshair-width: 2px;\n --crosshair-x-color: var(--crosshair-color);\n --crosshair-x-width: var(--crosshair-width);\n --crosshair-y-color: var(--crosshair-color);\n --crosshair-y-width: var(--crosshair-width);\n --grid-color: var(--surface-6);\n --grid-width: 1px;\n --_space-s: var(--space-s, 4px);\n --_space-m: var(--space-m, 8px);\n }\n .xy-pad-area {\n position: relative;\n width: 100%;\n height: 100%;\n background: var(--xy-pad-bg, var(--surface-3));\n border: var(--border);\n border-radius: var(--radius-m);\n overflow: hidden;\n box-shadow: var(--deboss-3);\n cursor: var(--cursor-display, crosshair);\n }\n :host([dragging]) .xy-pad-area {\n cursor: none;\n }\n\n .xy-pad-area:focus {\n outline: none;\n }\n\n .xy-pad-area:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n .xy-pad-area::before,\n .xy-pad-area::after {\n content: '';\n position: absolute;\n pointer-events: none;\n opacity: var(--show-crosshairs, 0);\n }\n :host([show-crosshairs]) {\n --show-crosshairs: 1;\n }\n .xy-pad-area::before {\n left: 0;\n right: 0;\n top: calc(100% - var(--y-pct, 50) * 1%);\n height: var(--crosshair-y-width);\n background: var(--crosshair-y-color);\n }\n .xy-pad-area::after {\n top: 0;\n bottom: 0;\n left: calc(var(--x-pct, 50) * 1%);\n width: var(--crosshair-x-width);\n background: var(--crosshair-x-color);\n }\n\n .xy-pad-grid {\n position: absolute;\n inset: 0;\n background-image:\n linear-gradient(to right, var(--grid-color) var(--grid-width), transparent var(--grid-width)),\n linear-gradient(to bottom, var(--grid-color) var(--grid-width), transparent var(--grid-width));\n background-size: 10cqb 10cqb;\n pointer-events: none;\n opacity: var(--show-grid, 0);\n }\n :host([show-grid]) {\n --show-grid: 1;\n }\n \n .xy-pad-marker {\n position: absolute;\n width: var(--marker-size, 10cqb);\n height: var(--marker-size, 10cqb);\n border-radius: 50%;\n background: var(--surface-2-accent, var(--accent));\n top: calc(100% - var(--y-pct, 50) * 1%);\n left: calc(var(--x-pct, 50) * 1%);\n transform: translate(-50%, -50%);\n pointer-events: none;\n z-index: 2;\n }\n .xy-pad-label-x {\n position: absolute;\n bottom: var(--_space-s);\n color: var(--surface-muted-text);\n font-size: var(--text-s, 12px);\n pointer-events: none;\n width: 100%;\n text-align: center;\n }\n .xy-pad-label-y {\n position: absolute;\n top: var(--_space-s);\n left: var(--_space-m);\n color: var(--surface-muted-text);\n font-size: var(--text-s, 12px);\n pointer-events: none;\n writing-mode: sideways-lr;\n height:100%;\n text-align:center;\n }\n `];\n\n @property({ type: Number }) xMin = 1;\n @property({ type: Number }) xMax = 100;\n @property({ type: Number }) x = 50;\n\n @property({ type: Number }) yMin = 1;\n @property({ type: Number }) yMax = 100;\n @property({ type: Number }) y = 50;\n\n @property({ type: String }) xScale = `linear`;\n @property({ type: String }) yScale = `linear`;\n @property({ type: Number, attribute: `x-snap-step` }) xSnapStep?: number;\n @property({ type: Number, attribute: `y-snap-step` }) ySnapStep?: number;\n\n @property({ type: String }) xLabel = `X`;\n @property({ type: String }) yLabel = `Y`;\n\n @property({ type: Boolean, reflect: true, attribute: `show-crosshairs` }) showCrosshairs = false;\n @property({ type: Boolean, reflect: true, attribute: `show-grid` }) showGrid = false;\n @property({ type: Boolean, reflect: true, attribute: `hide-cursor` }) hideCursor = false;\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Number of quantised stops for both axes. Overridden by stops-x/stops-y if set. */\n @property({ type: Number }) stops?: number;\n\n /** Number of quantised stops for X axis. If set, overrides the stops setting for X. */\n @property({ type: Number, attribute: `stops-x` }) stopsX?: number;\n\n /** Number of quantised stops for Y axis. If set, overrides the stops setting for Y. */\n @property({ type: Number, attribute: `stops-y` }) stopsY?: number;\n\n private _dragging = false;\n private _dragStartX = 0;\n private _dragStartY = 0;\n private _pressedKeys = new Set<string>();\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (this.disabled)\n return;\n if ([`ArrowLeft`, `ArrowRight`, `ArrowUp`, `ArrowDown`].includes(e.key)) {\n e.preventDefault();\n this._pressedKeys.add(e.key);\n this._handleKeyboardMove(e.shiftKey);\n } else if (e.key === `Home` || e.key === `End`) {\n e.preventDefault();\n const newX = e.key === `Home` ? this.xMin : this.xMax;\n const newY = e.key === `Home` ? this.yMin : this.yMax;\n if (newX !== this.x || newY !== this.y) {\n this.x = newX;\n this.y = newY;\n this.dispatchEvent(new CustomEvent<XyPadInputDetail>(`input`, {\n detail: { x: this.x, y: this.y },\n bubbles: true,\n composed: true,\n }));\n }\n }\n };\n\n private _onKeyUp = (e: KeyboardEvent): void => {\n this._pressedKeys.delete(e.key);\n };\n\n private _handleKeyboardMove = (shiftKey: boolean): void => {\n const shiftDivisor = shiftKey ? KEY_STEP_DIVISOR : 1;\n const xRange = this.xMax - this.xMin;\n const yRange = this.yMax - this.yMin;\n const effectiveStopsX = this.stopsX ?? this.stops;\n const effectiveStopsY = this.stopsY ?? this.stops;\n\n const xStep = resolveStep(xRange, effectiveStopsX, undefined) / shiftDivisor;\n const yStep = resolveStep(yRange, effectiveStopsY, undefined) / shiftDivisor;\n\n let newX = this.x;\n let newY = this.y;\n\n if (this._pressedKeys.has(`ArrowLeft`)) {\n newX = Math.max(this.xMin, this.x - xStep);\n }\n if (this._pressedKeys.has(`ArrowRight`)) {\n newX = Math.min(this.xMax, this.x + xStep);\n }\n if (this._pressedKeys.has(`ArrowUp`)) {\n newY = Math.min(this.yMax, this.y + yStep);\n }\n if (this._pressedKeys.has(`ArrowDown`)) {\n newY = Math.max(this.yMin, this.y - yStep);\n }\n\n if (newX !== this.x || newY !== this.y) {\n let finalX = (this.xSnapStep && this.xSnapStep > 0) ? Math.round(newX / this.xSnapStep) * this.xSnapStep : newX;\n let finalY = (this.ySnapStep && this.ySnapStep > 0) ? Math.round(newY / this.ySnapStep) * this.ySnapStep : newY;\n\n finalX = quantise(finalX, this.xMin, this.xMax, effectiveStopsX);\n finalY = quantise(finalY, this.yMin, this.yMax, effectiveStopsY);\n\n this.x = finalX;\n this.y = finalY;\n this.dispatchEvent(new CustomEvent<XyPadInputDetail>(`input`, {\n detail: { x: this.x, y: this.y },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n private _onPointerDown = (e: PointerEvent): void => {\n e.preventDefault();\n const pad = this.renderRoot.querySelector(`.xy-pad-area`) as HTMLElement | undefined;\n pad?.focus();\n if (pad)\n pad.setPointerCapture(e.pointerId);\n this._dragging = true;\n this._dragStartX = this.x;\n this._dragStartY = this.y;\n this.setAttribute(`dragging`, ``);\n this._updateFromPointer(e);\n globalThis.addEventListener(`pointermove`, this._onPointerMove);\n globalThis.addEventListener(`pointerup`, this._onPointerUp);\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (!this._dragging)\n return;\n e.preventDefault();\n this._updateFromPointer(e);\n };\n\n private _onPointerUp = (): void => {\n const hasChanged = this.x !== this._dragStartX || this.y !== this._dragStartY;\n this._dragging = false;\n this.removeAttribute(`dragging`);\n globalThis.removeEventListener(`pointermove`, this._onPointerMove);\n globalThis.removeEventListener(`pointerup`, this._onPointerUp);\n if (hasChanged) {\n this.dispatchEvent(new CustomEvent<XyPadInputDetail>(`change`, {\n detail: { x: this.x, y: this.y },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n private _updateFromPointer(e: PointerEvent): void {\n const pad = this.renderRoot.querySelector(`.xy-pad-area`);\n if (!pad)\n return;\n\n const rect = pad.getBoundingClientRect();\n const xFrac = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n const yFrac = Math.max(0, Math.min(1, 1 - (e.clientY - rect.top) / rect.height));\n\n const newX = fracToValue(xFrac, this.xMin, this.xMax, this.xScale);\n const newY = fracToValue(yFrac, this.yMin, this.yMax, this.yScale);\n\n let finalX = (this.xSnapStep && this.xSnapStep > 0) ? Math.round(newX / this.xSnapStep) * this.xSnapStep : newX;\n let finalY = (this.ySnapStep && this.ySnapStep > 0) ? Math.round(newY / this.ySnapStep) * this.ySnapStep : newY;\n\n const effectiveStopsX = this.stopsX ?? this.stops;\n const effectiveStopsY = this.stopsY ?? this.stops;\n\n finalX = quantise(finalX, this.xMin, this.xMax, effectiveStopsX);\n finalY = quantise(finalY, this.yMin, this.yMax, effectiveStopsY);\n\n this.x = finalX;\n this.y = finalY;\n\n this.dispatchEvent(new CustomEvent<XyPadInputDetail>(`input`, {\n detail: { x: this.x, y: this.y },\n bubbles: true,\n composed: true,\n }));\n }\n\n private _setPctVars(): void {\n const cx = Math.max(this.xMin, Math.min(this.xMax, this.x));\n const cy = Math.max(this.yMin, Math.min(this.yMax, this.y));\n const xPct = valueToFrac(cx, this.xMin, this.xMax, this.xScale) * 100;\n const yPct = valueToFrac(cy, this.yMin, this.yMax, this.yScale) * 100;\n this.style.setProperty(`--x-pct`, `${xPct}`);\n this.style.setProperty(`--y-pct`, `${yPct}`);\n\n // Calculate radius from center (50, 50) - distance as 0-100\n const dx = xPct - 50;\n const dy = yPct - 50;\n const radiusPct = Math.sqrt(dx * dx + dy * dy);\n this.style.setProperty(`--radius-pct`, `${radiusPct}`);\n }\n\n // ── Public API ─────────────────────────────────────────────────────────────\n\n /**\n * Returns X position as a 0–1 fraction.\n */\n getRelativeX(): number {\n const cx = Math.max(this.xMin, Math.min(this.xMax, this.x));\n return valueToFrac(cx, this.xMin, this.xMax, this.xScale);\n }\n\n /**\n * Returns Y position as a 0–1 fraction.\n */\n getRelativeY(): number {\n const cy = Math.max(this.yMin, Math.min(this.yMax, this.y));\n return valueToFrac(cy, this.yMin, this.yMax, this.yScale);\n }\n\n /**\n * Returns polar coordinates.\n * - radius: 0–1 distance from center\n * - angle: radians, 0 = right, clockwise (0 to 2π)\n */\n getPolar(): { radius: number; angle: number } {\n const xRel = this.getRelativeX() - 0.5; // -0.5 to 0.5\n const yRel = this.getRelativeY() - 0.5; // -0.5 to 0.5\n const radius = Math.sqrt(xRel * xRel + yRel * yRel) * 2; // 0 to 1\n let angle = Math.atan2(yRel, xRel); // -π to π\n if (angle < 0)\n angle += 2 * Math.PI; // 0 to 2π\n return { radius, angle };\n }\n\n override updated(_changed: PropertyValues): void {\n super.updated(_changed);\n this._setPctVars();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._onPointerUp();\n this._pressedKeys.clear();\n }\n\n override render(): ReturnType<typeof html> {\n return html`\n <div class=\"xy-pad-area\"\n tabindex=${this.disabled ? -1 : 0}\n @pointerdown=${this._onPointerDown}\n @keydown=${this._onKeyDown}\n @keyup=${this._onKeyUp}\n @blur=${() => this._pressedKeys.clear()}>\n ${this.showGrid ? html`<div class=\"xy-pad-grid\"></div>` : ``}\n <div class=\"xy-pad-marker\"></div>\n <div class=\"xy-pad-label-x\">${this.xLabel}</div>\n <div class=\"xy-pad-label-y\">${this.yLabel}</div>\n </div>\n `;\n }\n}\n\nexport type XyPadInputDetail = {\n readonly x: number;\n readonly y: number;\n};\n\nexport type XyPadInputEvent = CustomEvent<XyPadInputDetail>;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-xy-pad': XyPad;\n }\n}\n\nexport interface XyPadEventMap {\n input: XyPadInputEvent;\n change: XyPadInputEvent;\n}\n\nexport interface XyPad {\n addEventListener: (<K extends keyof XyPadEventMap>(\n type: K,\n listener: (this: XyPad, event: XyPadEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"xy-pad.js","names":["customElement"],"sources":["../src/xy-pad/xy-pad.ts"],"sourcesContent":["import type { PropertyValues } from 'lit';\n/**\n * <x-xy-pad> — 2D touch-friendly XY pad for controlling two parameters.\n *\n * Generic pad that accepts min/max/value for both axes with configurable labels.\n * Each axis can independently use logarithmic or linear scaling.\n * Y axis is inverted (top = high value).\n *\n * Properties\n * xMin, xMax, x – horizontal range and current value\n * yMin, yMax, y – vertical range and current value\n * xScale, yScale – 'log' (default) or 'linear'\n * xSnapStep, ySnapStep – snap granularity for pointer and keyboard moves (defaults: 1 / 0.01)\n * xLabel, yLabel – axis labels (displayed in corners)\n * showCrosshairs – show X/Y axis lines (default: false)\n * showGrid – show background grid (default: false)\n *\n * CSS variables:\n * --marker-size – size of the position marker (default: 10cqb)\n * --crosshair-color – colour of both crosshair lines (default: surface-hh)\n * --crosshair-width – thickness of both crosshair lines (default: 2px)\n * --crosshair-x-color – colour of the vertical (X) crosshair line; falls back to --crosshair-color\n * --crosshair-x-width – thickness of the vertical (X) crosshair line; falls back to --crosshair-width\n * --crosshair-y-color – colour of the horizontal (Y) crosshair line; falls back to --crosshair-color\n * --crosshair-y-width – thickness of the horizontal (Y) crosshair line; falls back to --crosshair-width\n * --grid-color – colour of grid lines (default: surface-hh)\n * --grid-width – thickness of grid lines (default: 1px)\n * --x-pct – current X position as unitless number (0–100), set on host so external styles can use it\n * --y-pct – current Y position as unitless number (0–100), set on host so external styles can use it\n * --radius-pct – distance from center as unitless number (0–100), set on host so external styles can use it\n * hide-cursor – boolean, hide cursor during drag and hover (default: false)\n *\n * Events\n * input – CustomEvent { detail: { x: number, y: number } }, bubbles + composed, fires continuously during drag\n * change – CustomEvent { detail: { x: number, y: number } }, bubbles + composed, fires when drag ends\n *\n * Methods\n * getRelativeX() – returns X position as 0–1 fraction\n * getRelativeY() – returns Y position as 0–1 fraction\n * getPolar() – returns { radius: number, angle: number } where radius is 0–1 and angle is in radians (0 to 2π, 0 = right, clockwise)\n */\nimport { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { KEY_STEP_DIVISOR, resolveStep } from '../keyboard.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\n// ---------------------------------------------------------------------------\n// Scale helpers — log or linear, selected per-axis\n// ---------------------------------------------------------------------------\n\nfunction valueToFrac(value: number, min: number, max: number, scale: string): number {\n if (scale === `linear`)\n return (value - min) / (max - min);\n return Math.log(value / min) / Math.log(max / min);\n}\n\nfunction fracToValue(frac: number, min: number, max: number, scale: string): number {\n if (scale === `linear`)\n return min + frac * (max - min);\n return min * (max / min) ** frac;\n}\n\nfunction quantise(value: number, min: number, max: number, stops?: number): number {\n if (!stops || stops <= 1)\n return value;\n const range = max - min;\n const step = range / stops;\n return Math.round((value - min) / step) * step + min;\n}\n\n@customElement(`ixfx-xy-pad`)\nexport class XyPad extends LitElement {\n static override styles = [themeFallbacks, prominenceStyles, css`\n :host {\n display: block;\n width: 200px;\n height: 200px;\n touch-action: none;\n user-select: none;\n container-type: size;\n --marker-size: 10cqb;\n --crosshair-color: var(--surface-6);\n --crosshair-width: 2px;\n --crosshair-x-color: var(--crosshair-color);\n --crosshair-x-width: var(--crosshair-width);\n --crosshair-y-color: var(--crosshair-color);\n --crosshair-y-width: var(--crosshair-width);\n --grid-color: var(--surface-6);\n --grid-width: 1px;\n --_space-s: var(--space-s, 4px);\n --_space-m: var(--space-m, 8px);\n }\n .xy-pad-area {\n position: relative;\n width: 100%;\n height: 100%;\n background: var(--xy-pad-bg, var(--surface-3));\n border: var(--border);\n border-radius: var(--radius-m);\n overflow: hidden;\n box-shadow: var(--deboss-3);\n cursor: var(--cursor-display, crosshair);\n }\n :host([dragging]) .xy-pad-area {\n cursor: none;\n }\n\n .xy-pad-area:focus {\n outline: none;\n }\n\n .xy-pad-area:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n .xy-pad-area::before,\n .xy-pad-area::after {\n content: '';\n position: absolute;\n pointer-events: none;\n opacity: var(--show-crosshairs, 0);\n }\n :host([show-crosshairs]) {\n --show-crosshairs: 1;\n }\n .xy-pad-area::before {\n left: 0;\n right: 0;\n top: calc(100% - var(--y-pct, 50) * 1%);\n height: var(--crosshair-y-width);\n background: var(--crosshair-y-color);\n }\n .xy-pad-area::after {\n top: 0;\n bottom: 0;\n left: calc(var(--x-pct, 50) * 1%);\n width: var(--crosshair-x-width);\n background: var(--crosshair-x-color);\n }\n\n .xy-pad-grid {\n position: absolute;\n inset: 0;\n background-image:\n linear-gradient(to right, var(--grid-color) var(--grid-width), transparent var(--grid-width)),\n linear-gradient(to bottom, var(--grid-color) var(--grid-width), transparent var(--grid-width));\n background-size: 10cqb 10cqb;\n pointer-events: none;\n opacity: var(--show-grid, 0);\n }\n :host([show-grid]) {\n --show-grid: 1;\n }\n \n .xy-pad-marker {\n position: absolute;\n width: var(--marker-size, 10cqb);\n height: var(--marker-size, 10cqb);\n border-radius: 50%;\n background: var(--surface-2-accent, var(--accent));\n top: calc(100% - var(--y-pct, 50) * 1%);\n left: calc(var(--x-pct, 50) * 1%);\n transform: translate(-50%, -50%);\n pointer-events: none;\n z-index: 2;\n }\n .xy-pad-label-x {\n position: absolute;\n bottom: var(--_space-s);\n color: var(--surface-muted-text);\n font-size: var(--text-s, 12px);\n pointer-events: none;\n width: 100%;\n text-align: center;\n }\n .xy-pad-label-y {\n position: absolute;\n top: var(--_space-s);\n left: var(--_space-m);\n color: var(--surface-muted-text);\n font-size: var(--text-s, 12px);\n pointer-events: none;\n writing-mode: sideways-lr;\n height:100%;\n text-align:center;\n }\n `];\n\n @property({ type: Number }) xMin = 1;\n @property({ type: Number }) xMax = 100;\n @property({ type: Number }) x = 50;\n\n @property({ type: Number }) yMin = 1;\n @property({ type: Number }) yMax = 100;\n @property({ type: Number }) y = 50;\n\n @property({ type: String }) xScale = `linear`;\n @property({ type: String }) yScale = `linear`;\n @property({ type: Number, attribute: `x-snap-step` }) xSnapStep?: number;\n @property({ type: Number, attribute: `y-snap-step` }) ySnapStep?: number;\n\n @property({ type: String }) xLabel = `X`;\n @property({ type: String }) yLabel = `Y`;\n\n @property({ type: Boolean, reflect: true, attribute: `show-crosshairs` }) showCrosshairs = false;\n @property({ type: Boolean, reflect: true, attribute: `show-grid` }) showGrid = false;\n @property({ type: Boolean, reflect: true, attribute: `hide-cursor` }) hideCursor = false;\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Number of quantised stops for both axes. Overridden by stops-x/stops-y if set. */\n @property({ type: Number }) stops?: number;\n\n /** Number of quantised stops for X axis. If set, overrides the stops setting for X. */\n @property({ type: Number, attribute: `stops-x` }) stopsX?: number;\n\n /** Number of quantised stops for Y axis. If set, overrides the stops setting for Y. */\n @property({ type: Number, attribute: `stops-y` }) stopsY?: number;\n\n private _dragging = false;\n private _dragStartX = 0;\n private _dragStartY = 0;\n private _pressedKeys = new Set<string>();\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (this.disabled)\n return;\n if ([`ArrowLeft`, `ArrowRight`, `ArrowUp`, `ArrowDown`].includes(e.key)) {\n e.preventDefault();\n this._pressedKeys.add(e.key);\n this._handleKeyboardMove(e.shiftKey);\n } else if (e.key === `Home` || e.key === `End`) {\n e.preventDefault();\n const newX = e.key === `Home` ? this.xMin : this.xMax;\n const newY = e.key === `Home` ? this.yMin : this.yMax;\n if (newX !== this.x || newY !== this.y) {\n this.x = newX;\n this.y = newY;\n this.dispatchEvent(new CustomEvent<XyPadInputDetail>(`input`, {\n detail: { x: this.x, y: this.y },\n bubbles: true,\n composed: true,\n }));\n }\n }\n };\n\n private _onKeyUp = (e: KeyboardEvent): void => {\n this._pressedKeys.delete(e.key);\n };\n\n private _handleKeyboardMove = (shiftKey: boolean): void => {\n const shiftDivisor = shiftKey ? KEY_STEP_DIVISOR : 1;\n const xRange = this.xMax - this.xMin;\n const yRange = this.yMax - this.yMin;\n const effectiveStopsX = this.stopsX ?? this.stops;\n const effectiveStopsY = this.stopsY ?? this.stops;\n\n const xStep = resolveStep(xRange, effectiveStopsX, undefined) / shiftDivisor;\n const yStep = resolveStep(yRange, effectiveStopsY, undefined) / shiftDivisor;\n\n let newX = this.x;\n let newY = this.y;\n\n if (this._pressedKeys.has(`ArrowLeft`)) {\n newX = Math.max(this.xMin, this.x - xStep);\n }\n if (this._pressedKeys.has(`ArrowRight`)) {\n newX = Math.min(this.xMax, this.x + xStep);\n }\n if (this._pressedKeys.has(`ArrowUp`)) {\n newY = Math.min(this.yMax, this.y + yStep);\n }\n if (this._pressedKeys.has(`ArrowDown`)) {\n newY = Math.max(this.yMin, this.y - yStep);\n }\n\n if (newX !== this.x || newY !== this.y) {\n let finalX = (this.xSnapStep && this.xSnapStep > 0) ? Math.round(newX / this.xSnapStep) * this.xSnapStep : newX;\n let finalY = (this.ySnapStep && this.ySnapStep > 0) ? Math.round(newY / this.ySnapStep) * this.ySnapStep : newY;\n\n finalX = quantise(finalX, this.xMin, this.xMax, effectiveStopsX);\n finalY = quantise(finalY, this.yMin, this.yMax, effectiveStopsY);\n\n this.x = finalX;\n this.y = finalY;\n this.dispatchEvent(new CustomEvent<XyPadInputDetail>(`input`, {\n detail: { x: this.x, y: this.y },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n private _onPointerDown = (e: PointerEvent): void => {\n e.preventDefault();\n const pad = this.renderRoot.querySelector(`.xy-pad-area`) as HTMLElement | undefined;\n pad?.focus();\n if (pad)\n pad.setPointerCapture(e.pointerId);\n this._dragging = true;\n this._dragStartX = this.x;\n this._dragStartY = this.y;\n this.setAttribute(`dragging`, ``);\n this._updateFromPointer(e);\n globalThis.addEventListener(`pointermove`, this._onPointerMove);\n globalThis.addEventListener(`pointerup`, this._onPointerUp);\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (!this._dragging)\n return;\n e.preventDefault();\n this._updateFromPointer(e);\n };\n\n private _onPointerUp = (): void => {\n const hasChanged = this.x !== this._dragStartX || this.y !== this._dragStartY;\n this._dragging = false;\n this.removeAttribute(`dragging`);\n globalThis.removeEventListener(`pointermove`, this._onPointerMove);\n globalThis.removeEventListener(`pointerup`, this._onPointerUp);\n if (hasChanged) {\n this.dispatchEvent(new CustomEvent<XyPadInputDetail>(`change`, {\n detail: { x: this.x, y: this.y },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n private _updateFromPointer(e: PointerEvent): void {\n const pad = this.renderRoot.querySelector(`.xy-pad-area`);\n if (!pad)\n return;\n\n const rect = pad.getBoundingClientRect();\n const xFrac = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n const yFrac = Math.max(0, Math.min(1, 1 - (e.clientY - rect.top) / rect.height));\n\n const newX = fracToValue(xFrac, this.xMin, this.xMax, this.xScale);\n const newY = fracToValue(yFrac, this.yMin, this.yMax, this.yScale);\n\n let finalX = (this.xSnapStep && this.xSnapStep > 0) ? Math.round(newX / this.xSnapStep) * this.xSnapStep : newX;\n let finalY = (this.ySnapStep && this.ySnapStep > 0) ? Math.round(newY / this.ySnapStep) * this.ySnapStep : newY;\n\n const effectiveStopsX = this.stopsX ?? this.stops;\n const effectiveStopsY = this.stopsY ?? this.stops;\n\n finalX = quantise(finalX, this.xMin, this.xMax, effectiveStopsX);\n finalY = quantise(finalY, this.yMin, this.yMax, effectiveStopsY);\n\n this.x = finalX;\n this.y = finalY;\n\n this.dispatchEvent(new CustomEvent<XyPadInputDetail>(`input`, {\n detail: { x: this.x, y: this.y },\n bubbles: true,\n composed: true,\n }));\n }\n\n private _setPctVars(): void {\n const cx = Math.max(this.xMin, Math.min(this.xMax, this.x));\n const cy = Math.max(this.yMin, Math.min(this.yMax, this.y));\n const xPct = valueToFrac(cx, this.xMin, this.xMax, this.xScale) * 100;\n const yPct = valueToFrac(cy, this.yMin, this.yMax, this.yScale) * 100;\n this.style.setProperty(`--x-pct`, `${xPct}`);\n this.style.setProperty(`--y-pct`, `${yPct}`);\n\n // Calculate radius from center (50, 50) - distance as 0-100\n const dx = xPct - 50;\n const dy = yPct - 50;\n const radiusPct = Math.sqrt(dx * dx + dy * dy);\n this.style.setProperty(`--radius-pct`, `${radiusPct}`);\n }\n\n // ── Public API ─────────────────────────────────────────────────────────────\n\n /**\n * Returns X position as a 0–1 fraction.\n */\n getRelativeX(): number {\n const cx = Math.max(this.xMin, Math.min(this.xMax, this.x));\n return valueToFrac(cx, this.xMin, this.xMax, this.xScale);\n }\n\n /**\n * Returns Y position as a 0–1 fraction.\n */\n getRelativeY(): number {\n const cy = Math.max(this.yMin, Math.min(this.yMax, this.y));\n return valueToFrac(cy, this.yMin, this.yMax, this.yScale);\n }\n\n /**\n * Returns polar coordinates.\n * - radius: 0–1 distance from center\n * - angle: radians, 0 = right, clockwise (0 to 2π)\n */\n getPolar(): { radius: number; angle: number } {\n const xRel = this.getRelativeX() - 0.5; // -0.5 to 0.5\n const yRel = this.getRelativeY() - 0.5; // -0.5 to 0.5\n const radius = Math.sqrt(xRel * xRel + yRel * yRel) * 2; // 0 to 1\n let angle = Math.atan2(yRel, xRel); // -π to π\n if (angle < 0)\n angle += 2 * Math.PI; // 0 to 2π\n return { radius, angle };\n }\n\n override updated(_changed: PropertyValues): void {\n super.updated(_changed);\n this._setPctVars();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._onPointerUp();\n this._pressedKeys.clear();\n }\n\n override render(): ReturnType<typeof html> {\n return html`\n <div class=\"xy-pad-area\"\n tabindex=${this.disabled ? -1 : 0}\n @pointerdown=${this._onPointerDown}\n @keydown=${this._onKeyDown}\n @keyup=${this._onKeyUp}\n @blur=${() => this._pressedKeys.clear()}>\n ${this.showGrid ? html`<div class=\"xy-pad-grid\"></div>` : ``}\n <div class=\"xy-pad-marker\"></div>\n <div class=\"xy-pad-label-x\">${this.xLabel}</div>\n <div class=\"xy-pad-label-y\">${this.yLabel}</div>\n </div>\n `;\n }\n}\n\nexport type XyPadInputDetail = {\n readonly x: number;\n readonly y: number;\n};\n\nexport type XyPadInputEvent = CustomEvent<XyPadInputDetail>;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-xy-pad': XyPad;\n }\n}\n\nexport interface XyPadEventMap {\n input: XyPadInputEvent;\n change: XyPadInputEvent;\n}\n\nexport interface XyPad {\n addEventListener: (<K extends keyof XyPadEventMap>(\n type: K,\n listener: (this: XyPad, event: XyPadEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Component Documentation
|
|
2
|
+
|
|
3
|
+
This directory contains documentation for each component and some architectural overviews. See [the catalog of components](./user-catalog.md) for a comprehensive list of all components.
|
|
4
|
+
|
|
5
|
+
## Components
|
|
6
|
+
|
|
7
|
+
- [ac-text](./ac-text.md)
|
|
8
|
+
- [ac-token](./ac-token.md)
|
|
9
|
+
- [button](./button.md)
|
|
10
|
+
- [checkbox](./checkbox.md)
|
|
11
|
+
- [colour-picker](./colour-picker.md)
|
|
12
|
+
- [crumbs](./crumbs.md)
|
|
13
|
+
- [data-display](./data-display.md)
|
|
14
|
+
- [editable-label](./editable-label.md)
|
|
15
|
+
- [grouped-item-lister](./grouped-item-lister.md)
|
|
16
|
+
- [icons](./icons.md)
|
|
17
|
+
- [incr-search](./incr-search.md)
|
|
18
|
+
- [labelled-radial-input](./labelled-radial-input.md)
|
|
19
|
+
- [labelled-range-input](./labelled-range-input.md)
|
|
20
|
+
- [led](./led.md)
|
|
21
|
+
- [menu](./menu.md)
|
|
22
|
+
- [miller](./miller.md)
|
|
23
|
+
- [narrowed-text](./narrowed-text.md)
|
|
24
|
+
- [panel](./panel.md)
|
|
25
|
+
- [plots](./plots.md)
|
|
26
|
+
- [polar-pad](./polar-pad.md)
|
|
27
|
+
- [radial-input](./radial-input.md)
|
|
28
|
+
- [range](./range.md)
|
|
29
|
+
- [range-input](./range-input.md)
|
|
30
|
+
- [selecthorizontal](./selecthorizontal.md)
|
|
31
|
+
- [snap-container](./snap-container.md)
|
|
32
|
+
- [split-layout](./split-layout.md)
|
|
33
|
+
- [swipe](./swipe.md)
|
|
34
|
+
- [tabs](./tabs.md)
|
|
35
|
+
- [timeline](./timeline.md)
|
|
36
|
+
- [transitory-label](./transitory-label.md)
|
|
37
|
+
- [tree](./tree.md)
|
|
38
|
+
- [util](./util.md)
|
|
39
|
+
- [vertical-list](./vertical-list.md)
|
|
40
|
+
- [xy-pad](./xy-pad.md)
|
|
41
|
+
|
|
42
|
+
## Architectural Overviews
|
|
43
|
+
|
|
44
|
+
- [user-catalog.md](user-catalog.md)
|
|
45
|
+
- [user-theming.md](user-theming.md)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# `ixfx-ac-text`
|
|
2
|
+
|
|
3
|
+
VS Code command-palette style autocomplete text input. Shows a popup with matching results as the user types.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<ixfx-ac-text placeholder="Search commands…"></ixfx-ac-text>
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
const input = document.querySelector('ixfx-ac-text');
|
|
11
|
+
|
|
12
|
+
input.completionProvider = async (query, signal) => {
|
|
13
|
+
const allCommands = await fetchCommands();
|
|
14
|
+
return allCommands
|
|
15
|
+
.filter(c => c.label.toLowerCase().includes(query.toLowerCase()))
|
|
16
|
+
.map(c => ({ label: c.label, icon: c.icon, key: c.id }));
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
input.addEventListener('change', e => {
|
|
20
|
+
console.log(e.detail.value, e.detail.source); // 'Save', 'autocomplete'
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Properties / attributes
|
|
25
|
+
|
|
26
|
+
| Attribute / Property | Type | Default | Description |
|
|
27
|
+
|---------------------|-----------------------------|----------|--------------------------------------------------|
|
|
28
|
+
| `completionProvider`| `AcTextCompletionProvider \| undefined` | `undefined` | Function returning completion results |
|
|
29
|
+
| `placeholder` | `string` | `''` | Placeholder text |
|
|
30
|
+
| `value` | `string` | `''` | Current text value |
|
|
31
|
+
| `tabSuffix` | `string` | `''` | Appended when Tab-accepts a non-leaf item |
|
|
32
|
+
| `cacheSize` | `number` | `20` | LRU cache size for query results |
|
|
33
|
+
| `debounceMs` | `number` | `150` | Debounce delay before invoking provider |
|
|
34
|
+
|
|
35
|
+
### Events
|
|
36
|
+
|
|
37
|
+
| Event | Detail | Description |
|
|
38
|
+
|--------------|---------------------------------------------------------------------|------------------------------------------|
|
|
39
|
+
| `ac-select` | `{ item: AcTextItem, query: string }` | When an autocomplete item is selected |
|
|
40
|
+
| `change` | `{ value, key, data?, source: 'text' \| 'autocomplete' }` | When value is committed (Enter or select)|
|
|
41
|
+
|
|
42
|
+
### Keyboard navigation
|
|
43
|
+
|
|
44
|
+
| Key | Action |
|
|
45
|
+
|--------------|------------------------------------------------|
|
|
46
|
+
| `ArrowDown` | Move highlight to next result |
|
|
47
|
+
| `ArrowUp` | Move highlight to previous result |
|
|
48
|
+
| `Enter` | Commit highlighted item or typed text |
|
|
49
|
+
| `Tab` | Accept highlight + append `tabSuffix` if not leaf |
|
|
50
|
+
| `Escape` | Close popup without committing |
|
|
51
|
+
|
|
52
|
+
### CSS custom properties
|
|
53
|
+
|
|
54
|
+
| Property | Default | Description |
|
|
55
|
+
|-----------------------------|--------------------------------------|------------------------------|
|
|
56
|
+
| `--ac-input-padding` | `var(--space-m) var(--space-l)` | Input padding |
|
|
57
|
+
| `--ac-input-background` | `var(--surface-3)` | Input background |
|
|
58
|
+
| `--ac-input-border-radius` | `var(--radius-m)` | Input border radius |
|
|
59
|
+
| `--ac-popup-font-size` | `var(--text-s)` | Popup item font size |
|
|
60
|
+
| `--ac-highlight-background` | `var(--accent)` | Text highlight background |
|
|
61
|
+
| `--ac-highlight-color` | `var(--accent-text)` | Text highlight color |
|
|
62
|
+
|
|
63
|
+
### TypeScript types
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import type { AcTextItem, AcTextCompletionProvider, AcTextChangeDetail } from 'ixfxfun-components';
|
|
67
|
+
```
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# `ixfx-ac-token`
|
|
2
|
+
|
|
3
|
+
Token/tag input with per-token autocomplete. Looks like a text box — committed tokens appear as inline chips, and a suggestion popup follows the typing cursor. Typical use cases are email To: fields and tag pickers.
|
|
4
|
+
|
|
5
|
+
Tokens are delimited by space, comma, or semicolon by default. Typing a delimiter commits the current word as a chip. Pressing Enter commits the current text (non-strict mode) or the highlighted suggestion (strict mode).
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<!-- Static suggestion list from attribute -->
|
|
9
|
+
<ixfx-ac-token
|
|
10
|
+
placeholder="Add tags…"
|
|
11
|
+
data-tokens="javascript typescript python rust go"
|
|
12
|
+
></ixfx-ac-token>
|
|
13
|
+
|
|
14
|
+
<!-- Dynamic async provider -->
|
|
15
|
+
<ixfx-ac-token placeholder="Add recipients…"></ixfx-ac-token>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
const el = document.querySelector('ixfx-ac-token');
|
|
20
|
+
|
|
21
|
+
el.completionProvider = async (token, signal) => {
|
|
22
|
+
const results = await searchPeople(token);
|
|
23
|
+
return results.map(p => ({ label: p.name, subLabel: p.email }));
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
el.addEventListener('ac-token-change', e => {
|
|
27
|
+
console.log(e.detail.tokens.map(t => t.label)); // ['Alice', 'Bob']
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
### Properties / attributes
|
|
34
|
+
|
|
35
|
+
| Attribute / Property | Type | Default | Description |
|
|
36
|
+
|-----------------------|-----------------------------------|-------------|---------------------------------------------------------------------|
|
|
37
|
+
| `completionProvider` | `AcTokenCompletionProvider \| undefined` | `undefined` | Async or sync function returning suggestions for the current draft token. Takes precedence over `data-tokens`. |
|
|
38
|
+
| `tokenizer` | `AcTokenizerFn \| undefined` | `undefined` | Custom function to split text into tokens. Default splits on space, comma, semicolon. |
|
|
39
|
+
| `data-tokens` | `string` (attribute only) | `''` | Space/comma/semicolon-separated list of static suggestion labels. Used when no `completionProvider` is set. |
|
|
40
|
+
| `placeholder` | `string` | `''` | Placeholder shown when no tokens or draft text are present. |
|
|
41
|
+
| `strict` | `boolean` | `false` | When true, only suggestions from the popup can be committed. Free-form typed text is ignored. |
|
|
42
|
+
| `cacheSize` | `number` | `20` | LRU cache size for provider results. |
|
|
43
|
+
| `debounceMs` | `number` | `150` | Debounce delay in ms before invoking the provider after a keystroke.|
|
|
44
|
+
| `tokens` (property) | `readonly AcTokenItem[]` | `[]` | Get or set the full token list programmatically. |
|
|
45
|
+
| `value` (property, read-only) | `string` | — | All committed token labels joined with `, `. |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
### Events
|
|
50
|
+
|
|
51
|
+
| Event | Detail | Description |
|
|
52
|
+
|-------------------|---------------------------------------------|------------------------------------|
|
|
53
|
+
| `ac-token-change` | `{ tokens: readonly AcTokenItem[] }` | Fired on any change to the token list (add or remove). |
|
|
54
|
+
| `ac-token-add` | `{ item: AcTokenItem, index: number }` | Fired when a single token is committed. |
|
|
55
|
+
| `ac-token-remove` | `{ item: AcTokenItem, index: number }` | Fired when a single token is removed. |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
### Keyboard interactions
|
|
60
|
+
|
|
61
|
+
| Key | Condition | Action |
|
|
62
|
+
|-------------------------|--------------------------------|----------------------------------------------------------|
|
|
63
|
+
| Space / `,` / `;` | Typed in the draft input | Commit the current draft as a token and start a new one. |
|
|
64
|
+
| `Enter` | Suggestion highlighted | Accept the highlighted suggestion. |
|
|
65
|
+
| `Enter` | No suggestion, non-strict mode | Commit the current draft as a free-form token. |
|
|
66
|
+
| `ArrowDown` / `ArrowUp` | Popup open | Move the suggestion highlight. |
|
|
67
|
+
| `ArrowLeft` | Draft cursor at position 0 | Move selection to the previous chip (or last if none selected). |
|
|
68
|
+
| `ArrowRight` | A chip is selected | Move selection to the next chip (or back to the draft input if at last). |
|
|
69
|
+
| `Backspace` | Draft empty, no chip selected | Delete the last chip. |
|
|
70
|
+
| `Backspace` | A chip is selected | Delete the selected chip. |
|
|
71
|
+
| Any printable key | A chip is selected | Remove the selected chip and pre-fill the draft with its label + the typed key. |
|
|
72
|
+
| `Escape` | Popup open | Close the popup without committing. |
|
|
73
|
+
| `Cmd/Ctrl+A` | — | Copy all token labels and current draft to the clipboard as plain text. |
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### Touch / pointer interactions
|
|
78
|
+
|
|
79
|
+
| Gesture | Action |
|
|
80
|
+
|--------------------------|-------------------------|
|
|
81
|
+
| Click a chip | Select / deselect it (for keyboard editing or deletion). |
|
|
82
|
+
| Drag a chip up or down | Remove it (threshold: 28 px vertical movement). |
|
|
83
|
+
| Click outside any chip | Focus the draft input. |
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### Paste
|
|
88
|
+
|
|
89
|
+
Pasting plain text tokenizes it using the configured tokenizer. Complete tokens are committed immediately; any partial trailing text becomes the new draft.
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
Paste: "alice, bob, carol" → chips [alice] [bob], draft "carol"
|
|
93
|
+
Paste: "alice, bob, carol " → chips [alice] [bob] [carol], draft ""
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### Completion provider
|
|
99
|
+
|
|
100
|
+
The provider receives the current draft token (not the full input value) and an `AbortSignal`. It can return a `Promise` or a plain array.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
el.completionProvider = async (token: string, signal: AbortSignal) => {
|
|
104
|
+
const res = await fetch(`/api/tags?q=${token}`, { signal });
|
|
105
|
+
const data = await res.json();
|
|
106
|
+
return data.map((item: Tag) => ({
|
|
107
|
+
label: item.name,
|
|
108
|
+
subLabel: item.count + ' uses',
|
|
109
|
+
key: item.id,
|
|
110
|
+
data: item,
|
|
111
|
+
}));
|
|
112
|
+
};
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
When `token` is an empty string the provider is still called — use this to show all available options when the user hasn't typed anything yet.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### Custom tokenizer
|
|
120
|
+
|
|
121
|
+
The default tokenizer splits on whitespace, comma, and semicolon. Supply a custom function to change what counts as a token boundary:
|
|
122
|
+
|
|
123
|
+
```js
|
|
124
|
+
// Colon-separated path segments
|
|
125
|
+
el.tokenizer = text => text.split(':');
|
|
126
|
+
|
|
127
|
+
// Only comma-separated (spaces allowed inside tokens)
|
|
128
|
+
el.tokenizer = text => text.split(',').map(s => s.trimStart());
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The tokenizer is also used when pasting text to bulk-commit multiple tokens at once.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### `AcTokenItem` shape
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
type AcTokenItem = {
|
|
139
|
+
readonly label: string; // displayed text and committed value
|
|
140
|
+
readonly subLabel?: string; // right-aligned secondary text in popup
|
|
141
|
+
readonly icon?: string; // icon registry name (shown in chip and popup)
|
|
142
|
+
readonly key?: string; // stable identifier (defaults to label)
|
|
143
|
+
readonly data?: unknown; // arbitrary payload, passed through in events
|
|
144
|
+
};
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
### CSS custom properties
|
|
150
|
+
|
|
151
|
+
| Property | Default | Description |
|
|
152
|
+
|---------------------------------------|--------------------------|------------------------------------------|
|
|
153
|
+
| `--ac-token-input-background` | `var(--surface-3)` | Wrapper background. |
|
|
154
|
+
| `--ac-token-input-border` | `var(--border)` | Wrapper border. |
|
|
155
|
+
| `--ac-token-input-border-radius` | `var(--radius-m)` | Wrapper corner radius. |
|
|
156
|
+
| `--ac-token-input-padding` | `var(--space-xs) var(--space-m)` | Wrapper padding. |
|
|
157
|
+
| `--ac-token-chip-gap` | `var(--space-xs)` | Gap between chips and the draft input. |
|
|
158
|
+
| `--ac-token-chip-background` | `var(--surface-4)` | Chip background. |
|
|
159
|
+
| `--ac-token-chip-border` | `var(--border)` | Chip border. |
|
|
160
|
+
| `--ac-token-chip-border-radius` | `var(--radius-s)` | Chip corner radius. |
|
|
161
|
+
| `--ac-token-chip-selected-background` | `var(--accent)` | Chip background when selected. |
|
|
162
|
+
| `--ac-token-chip-selected-color` | `var(--accent-text)` | Chip text color when selected. |
|
|
163
|
+
| `--ac-token-popup-font-size` | `var(--text-s)` | Suggestion popup font size. |
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
### TypeScript types
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
import type {
|
|
171
|
+
AcTokenItem,
|
|
172
|
+
AcTokenCompletionProvider,
|
|
173
|
+
AcTokenizerFn,
|
|
174
|
+
AcTokensChangeDetail,
|
|
175
|
+
AcTokenAddDetail,
|
|
176
|
+
AcTokenRemoveDetail,
|
|
177
|
+
AcTokenElementEventMap,
|
|
178
|
+
} from 'ixfxfun-components';
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### Popup positioning
|
|
184
|
+
|
|
185
|
+
The suggestion popup uses CSS anchor positioning (`anchor-name` / `position-anchor` / `@position-try`) to stay anchored to the draft input. It opens below the input by default and automatically flips above when there is insufficient space below the viewport. No JavaScript resize or scroll listeners are involved.
|
|
186
|
+
|
|
187
|
+
Browser support: Chrome 125+. In browsers without CSS anchor positioning support the popup still renders but will not auto-flip.
|