@jxsuite/ui 0.0.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/components/jx-accordion-item.json +281 -0
  2. package/components/jx-accordion.json +33 -0
  3. package/components/jx-action-button.json +268 -34
  4. package/components/jx-action-group.json +131 -0
  5. package/components/jx-button.json +141 -26
  6. package/components/jx-checkbox.json +222 -0
  7. package/components/jx-color-area.json +263 -0
  8. package/components/jx-color-field.json +565 -0
  9. package/components/jx-color-slider.json +216 -0
  10. package/components/jx-combobox.json +551 -0
  11. package/components/jx-dialog.json +416 -0
  12. package/components/jx-divider.json +52 -0
  13. package/components/jx-dot.json +38 -0
  14. package/components/jx-field.json +162 -0
  15. package/components/jx-kbd.json +24 -0
  16. package/components/jx-listbox.json +76 -0
  17. package/components/jx-menu-item.json +6 -13
  18. package/components/jx-menu.json +45 -6
  19. package/components/jx-number-field.json +441 -0
  20. package/components/jx-option.json +350 -0
  21. package/components/jx-popover.json +227 -0
  22. package/components/jx-select.json +637 -0
  23. package/components/jx-spinner.json +129 -0
  24. package/components/jx-split.json +221 -0
  25. package/components/jx-swatch-group.json +107 -0
  26. package/components/jx-swatch.json +262 -0
  27. package/components/jx-switch.json +331 -0
  28. package/components/jx-tab-panel.json +58 -0
  29. package/components/jx-tab.json +296 -0
  30. package/components/jx-tabs.json +124 -0
  31. package/components/jx-textfield.json +645 -0
  32. package/components/jx-toast-host.json +121 -0
  33. package/components/jx-toast.json +255 -0
  34. package/components/jx-toolbar.json +81 -0
  35. package/components/jx-tooltip.json +207 -0
  36. package/components/jx-tree-item.json +325 -0
  37. package/components/jx-tree.json +202 -0
  38. package/icons/list.json +4 -0
  39. package/icons/manifest.json +12 -0
  40. package/package.json +27 -5
  41. package/project.json +164 -153
  42. package/src/behaviors/action-group.ts +255 -0
  43. package/src/behaviors/color-area.ts +303 -0
  44. package/src/behaviors/color-field.ts +465 -0
  45. package/src/behaviors/color-slider.ts +154 -0
  46. package/src/behaviors/combobox.ts +474 -0
  47. package/src/behaviors/dialog.ts +137 -0
  48. package/src/behaviors/listbox.ts +118 -0
  49. package/src/behaviors/menu.ts +80 -48
  50. package/src/behaviors/number-field.ts +161 -0
  51. package/src/behaviors/popover.ts +399 -0
  52. package/src/behaviors/select.ts +154 -0
  53. package/src/behaviors/split.ts +478 -0
  54. package/src/behaviors/swatch-group.ts +297 -0
  55. package/src/behaviors/tabs.ts +319 -0
  56. package/src/behaviors/textfield.ts +164 -0
  57. package/src/behaviors/toast-host.ts +241 -0
  58. package/src/behaviors/toast.ts +261 -0
  59. package/src/behaviors/toolbar.ts +413 -0
  60. package/src/behaviors/tooltip.ts +719 -0
  61. package/src/behaviors/tree.ts +830 -0
  62. package/src/color.ts +433 -0
  63. package/src/documents.ts +91 -1
  64. package/src/index.ts +41 -1
  65. package/src/loaders.ts +47 -0
  66. package/src/testing/anchor-support.ts +28 -0
  67. package/src/testing/popover-shim.ts +39 -6
  68. package/src/theme.ts +30 -6
  69. package/stylebook/jx-accordion-item.json +195 -0
  70. package/stylebook/jx-accordion.json +220 -0
  71. package/stylebook/jx-action-button.json +191 -23
  72. package/stylebook/jx-action-group.json +335 -0
  73. package/stylebook/jx-button.json +129 -26
  74. package/stylebook/jx-checkbox.json +245 -0
  75. package/stylebook/jx-color-area.json +272 -0
  76. package/stylebook/jx-color-field.json +261 -0
  77. package/stylebook/jx-color-slider.json +220 -0
  78. package/stylebook/jx-combobox.json +332 -0
  79. package/stylebook/jx-dialog.json +186 -0
  80. package/stylebook/jx-divider.json +125 -0
  81. package/stylebook/jx-dot.json +92 -0
  82. package/stylebook/jx-field.json +313 -0
  83. package/stylebook/jx-icon.json +4 -0
  84. package/stylebook/jx-kbd.json +90 -0
  85. package/stylebook/jx-listbox.json +337 -0
  86. package/stylebook/jx-menu.json +0 -1
  87. package/stylebook/jx-number-field.json +203 -0
  88. package/stylebook/jx-option.json +285 -0
  89. package/stylebook/jx-popover.json +123 -0
  90. package/stylebook/jx-select.json +407 -0
  91. package/stylebook/jx-spinner.json +111 -0
  92. package/stylebook/jx-split.json +170 -0
  93. package/stylebook/jx-swatch-group.json +175 -0
  94. package/stylebook/jx-swatch.json +249 -0
  95. package/stylebook/jx-switch.json +240 -0
  96. package/stylebook/jx-tab-panel.json +147 -0
  97. package/stylebook/jx-tab.json +201 -0
  98. package/stylebook/jx-tabs.json +278 -0
  99. package/stylebook/jx-textfield.json +309 -0
  100. package/stylebook/jx-toast-host.json +157 -0
  101. package/stylebook/jx-toast.json +266 -0
  102. package/stylebook/jx-toolbar.json +435 -0
  103. package/stylebook/jx-tooltip.json +162 -0
  104. package/stylebook/jx-tree-item.json +258 -0
  105. package/stylebook/jx-tree.json +429 -0
@@ -0,0 +1,565 @@
1
+ {
2
+ "$schema": "https://jxsuite.com/schema/v1",
3
+ "$id": "JxColorField",
4
+ "tagName": "jx-color-field",
5
+ "observedAttributes": [
6
+ "value",
7
+ "resolved",
8
+ "format",
9
+ "alpha",
10
+ "label",
11
+ "labelledby",
12
+ "size",
13
+ "disabled",
14
+ "system",
15
+ "eyedropper"
16
+ ],
17
+ "$elements": [
18
+ {
19
+ "$ref": "./jx-icon.json"
20
+ },
21
+ {
22
+ "$ref": "./jx-action-button.json"
23
+ },
24
+ {
25
+ "$ref": "./jx-textfield.json"
26
+ },
27
+ {
28
+ "$ref": "./jx-popover.json"
29
+ },
30
+ {
31
+ "$ref": "./jx-color-area.json"
32
+ },
33
+ {
34
+ "$ref": "./jx-color-slider.json"
35
+ }
36
+ ],
37
+ "state": {
38
+ "value": {
39
+ "type": "string",
40
+ "default": "",
41
+ "attribute": "value",
42
+ "description": "The colour, spelled as format says. This is what the element HOLDS; the four channels behind the picker are a working copy of it, and the sidecar rewrites that copy only when the two genuinely disagree. The empty string means no colour has been chosen and draws the slashed chip rather than black."
43
+ },
44
+ "resolved": {
45
+ "type": "string",
46
+ "default": "",
47
+ "attribute": "resolved",
48
+ "description": "The colour behind value, for a value the page cannot resolve: a var() naming a token whose definition lives in the document being EDITED rather than in the one drawing this field, which is what Studio's palette commits. Empty, the chip draws value itself, which is right whenever the browser can resolve it. Set, it is what the chip draws and what the picker opens on, so the first drag starts from the token's own colour rather than from wherever the sliders last were; value is untouched, and the text field still shows the reference. A host that sets it is answering for the value it also set, so it clears it when the value stops being a reference."
49
+ },
50
+ "format": {
51
+ "type": "string",
52
+ "default": "hex",
53
+ "attribute": "format",
54
+ "description": "hex or oklch: which spelling the element writes when the reader moves anything. It changes what is WRITTEN, never what is read — a reader may type any of hex, rgb() or oklch() into the text field whatever this says, because refusing a colour the element itself could have produced would be a trap."
55
+ },
56
+ "alpha": {
57
+ "type": "boolean",
58
+ "default": false,
59
+ "attribute": "alpha",
60
+ "description": "Whether the colour has an opacity at all: it adds the alpha track to the picker and the alpha channel to the value. Off, every value the element writes is opaque, so a field that feeds a property with no alpha cannot be handed one by accident."
61
+ },
62
+ "label": {
63
+ "type": "string",
64
+ "default": "",
65
+ "attribute": "label",
66
+ "description": "What the colour is FOR — \"Background\", \"Border\" — and the stem every control inside the element takes its own name from: the text field is named this, the swatch button is \"Pick <label>\", the screen picker is \"Pick <label> from the screen\". Required: five controls named only by their roles is five sliders and two buttons in a row, and a reader has no way to tell this field from the next one."
67
+ },
68
+ "labelledby": {
69
+ "type": "string",
70
+ "default": "",
71
+ "attribute": "labelledby",
72
+ "description": "Forwarded to the text field as aria-labelledby, for a visible label the element does not own. The other controls keep their composed names, because a visible label naming the row does not name the button inside it."
73
+ },
74
+ "size": {
75
+ "type": "string",
76
+ "default": "md",
77
+ "attribute": "size",
78
+ "description": "sm, md or lg, forwarded to the text field so a row of controls lines up."
79
+ },
80
+ "disabled": {
81
+ "type": "boolean",
82
+ "default": false,
83
+ "attribute": "disabled",
84
+ "description": "Cannot be opened or edited. Forwarded to every control inside, and checked again by the handlers that open the picker and the screen picker, because those act on a click rather than on a control's own refusal."
85
+ },
86
+ "system": {
87
+ "type": "boolean",
88
+ "default": true,
89
+ "attribute": "system",
90
+ "description": "Offer the operating system's own colour picker, through a native input type=color. It is a DOOR and never the control: it opens the platform's dialog, takes what comes back, and has no part in how the element is operated. Turn it off where a project's colours must come from its own palette."
91
+ },
92
+ "eyedropper": {
93
+ "type": "boolean",
94
+ "default": true,
95
+ "attribute": "eyedropper",
96
+ "description": "Offer the screen picker, where the engine has one. The button is drawn only when BOTH this and the EyeDropper API are there, so an engine without it shows no dead control rather than one that does nothing when pressed."
97
+ },
98
+ "tabindex": {
99
+ "type": "string",
100
+ "default": "",
101
+ "description": "Forwarded to the swatch button as its tabindex, which is what makes a roving caret possible: a jx-toolbar moving focus writes this rather than reaching into the element's internals. It is a PROPERTY ONLY (el.tabindex = \"0\") and deliberately not an observed attribute: written as an attribute it would land on the host as well, and a host carrying tabindex is itself focusable, so the one control would become two tab stops. The swatch is THE stop, and it is named part=control for that reason, which is the kit's name for the node a roving container focuses. It is the opener, so Enter on it reaches the whole picker and a reader parked on it can choose any colour; it is the one control the element always draws; and it is first in the row, so Tab lands where the eye does. While the prop is set the text field, the screen picker and the system door step out of the tab order (tabindex -1): a container that has been told this element is one stop must find exactly one, and those three are then the pointer's. Unset, which is every form, each keeps its own stop."
102
+ },
103
+ "hue": {
104
+ "type": "number",
105
+ "default": 0,
106
+ "description": "The working hue, 0-360. It is kept across a colour going grey, which is why it is state rather than something derived from value each time: a round trip through the string would send the hue track back to red the moment the reader dragged the saturation to zero."
107
+ },
108
+ "saturation": {
109
+ "type": "number",
110
+ "default": 0,
111
+ "description": "The working saturation, 0-100: the square's horizontal axis."
112
+ },
113
+ "brightness": {
114
+ "type": "number",
115
+ "default": 0,
116
+ "description": "The working brightness, 0-100: the square's vertical axis, measured upward."
117
+ },
118
+ "opacity": {
119
+ "type": "number",
120
+ "default": 100,
121
+ "description": "The working opacity, 0-100, in the alpha track's own units. Only ever written into the value when alpha is on."
122
+ },
123
+ "text": {
124
+ "type": "string",
125
+ "default": "",
126
+ "description": "What the text field is showing, which is NOT value while the reader is mid-word: a half-typed hex is not a colour and the element must not refuse it or reformat it under the caret. It becomes the value on the commit, and follows the value whenever anything else moves it."
127
+ },
128
+ "invalid": {
129
+ "type": "boolean",
130
+ "default": false,
131
+ "description": "Whether the text field is holding something that is not a colour. Raised on the COMMIT rather than on each keystroke, and forwarded to the text field so the refusal is announced there."
132
+ },
133
+ "expanded": {
134
+ "type": "boolean",
135
+ "default": false,
136
+ "description": "Whether the picker is showing. It follows the panel's own toggle event, so light dismissal and Escape move it as surely as the button does; writing it opens nothing."
137
+ },
138
+ "ink": {
139
+ "type": "string",
140
+ "default": "",
141
+ "description": "black or white, whichever can be seen on the current colour. The preview chip's boundary is drawn in it, because a neutral border disappears against a neutral colour and a control whose edge cannot be seen is a WCAG 1.4.11 failure."
142
+ },
143
+ "solid": {
144
+ "type": "string",
145
+ "default": "",
146
+ "description": "The current colour at full opacity, as hex. Two things need it and neither can compute it: the alpha track fades from it, and a native input type=color accepts the six-digit form and nothing else."
147
+ },
148
+ "uid": {
149
+ "type": "string",
150
+ "default": "",
151
+ "description": "This element's own id stem, minted on mount. The picker panel takes its id from it and the swatch button names that id in aria-controls, so nothing a consumer writes has to be unique."
152
+ },
153
+ "dropperAvailable": {
154
+ "$prototype": "Function",
155
+ "$src": "jx-ui:/behaviors/color-field.ts",
156
+ "$export": "eyeDropperAvailable",
157
+ "parameters": ["offered"],
158
+ "description": "Whether the screen picker is both offered here and present in the engine. A capability question, asked by the document rather than assumed by it. It takes the opt-in as an argument because a Function entry with no declared parameters is an event handler rather than a callable, and calling one from a template throws mid-render and takes the element's whole child tree with it."
159
+ },
160
+ "hasDropper": "${state.dropperAvailable(state.eyedropper)}",
161
+ "preview": "${state.resolved || state.value || 'transparent'}",
162
+ "pickerId": "${state.uid ? state.uid + '-picker' : ''}",
163
+ "onInput": {
164
+ "$prototype": "Function",
165
+ "$src": "jx-ui:/behaviors/color-field.ts",
166
+ "$export": "onFieldInput",
167
+ "emits": [
168
+ {
169
+ "name": "input",
170
+ "description": "The colour is moving under the reader's hand. It comes from the ELEMENT, so e.target.value is the colour whichever of the five controls moved it."
171
+ }
172
+ ],
173
+ "description": "The one listener the whole composed control speaks through: it works out which channel fired from the data-channel beside each part, stops the original, and re-says the platform's own name from the host."
174
+ },
175
+ "onChange": {
176
+ "$prototype": "Function",
177
+ "$src": "jx-ui:/behaviors/color-field.ts",
178
+ "$export": "onFieldChange",
179
+ "emits": [
180
+ {
181
+ "name": "change",
182
+ "description": "The reader committed a colour; e.target is the element."
183
+ }
184
+ ],
185
+ "description": "The same routing, for the commit. It is also where a typed colour is parsed: a keystroke is not a colour and the refusal waits for this."
186
+ },
187
+ "onOpen": {
188
+ "$prototype": "Function",
189
+ "$src": "jx-ui:/behaviors/color-field.ts",
190
+ "$export": "onOpenPicker",
191
+ "description": "Positions the panel under the field and shows it, or hides it when it is already showing. The coordinates are written before the panel is shown, which is what jx-popover asks of whoever opens it."
192
+ },
193
+ "onDropper": {
194
+ "$prototype": "Function",
195
+ "$src": "jx-ui:/behaviors/color-field.ts",
196
+ "$export": "onEyeDropper",
197
+ "description": "Opens the system's screen picker and takes what comes back. A reader who dismisses it has cancelled rather than failed, so the rejection is swallowed and the colour is left where it was."
198
+ },
199
+ "onReady": {
200
+ "$prototype": "Function",
201
+ "$src": "jx-ui:/behaviors/color-field.ts",
202
+ "$export": "onFieldMount",
203
+ "description": "Learns the element, mints its id stem, takes the value apart into the working channels, and keeps them in step with value for as long as it lives — through data-value, which is the one thing that moves when a host writes el.value."
204
+ },
205
+ "onMount": {
206
+ "$prototype": "Function",
207
+ "body": [
208
+ {
209
+ "dispatchEvent": "jx-ready",
210
+ "bubbles": true
211
+ }
212
+ ],
213
+ "emits": [
214
+ {
215
+ "name": "jx-ready",
216
+ "description": "The element has rendered, which is how onReady reaches the element itself."
217
+ }
218
+ ],
219
+ "description": "Announces that the element has rendered. Its own onReady listens for it, and a host may too."
220
+ }
221
+ },
222
+ "oninput": {
223
+ "$ref": "#/state/onInput"
224
+ },
225
+ "onchange": {
226
+ "$ref": "#/state/onChange"
227
+ },
228
+ "onjx-ready": {
229
+ "$ref": "#/state/onReady"
230
+ },
231
+ "attributes": {
232
+ "data-value": "${state.value}",
233
+ "data-resolved": "${state.resolved}",
234
+ "data-size": "${state.size}",
235
+ "data-expanded": "${state.expanded ? '' : null}",
236
+ "data-disabled": "${state.disabled ? '' : null}"
237
+ },
238
+ "style": {
239
+ "display": "inline-flex",
240
+ "&[hidden]": {
241
+ "display": "none"
242
+ },
243
+ "verticalAlign": "middle",
244
+ "minInlineSize": "0",
245
+ "--jx-color-checkerboard": "repeating-conic-gradient(var(--jx-gray-300) 0% 25%, var(--jx-bg-input) 0% 50%) 50% / 8px 8px",
246
+ "--jx-color-field-preview": "${state.preview}",
247
+ "--jx-color-field-ink": "${state.ink || 'var(--jx-border-strong)'}",
248
+ "& > [part=\"row\"]": {
249
+ "display": "inline-flex",
250
+ "alignItems": "center",
251
+ "gap": "var(--jx-space-2)",
252
+ "minInlineSize": "0"
253
+ },
254
+ "& > [part=\"row\"] > [part=\"control\"]": {
255
+ "appearance": "none",
256
+ "font": "inherit",
257
+ "display": "inline-flex",
258
+ "alignItems": "center",
259
+ "justifyContent": "center",
260
+ "flex": "none",
261
+ "inlineSize": "var(--jx-control-h)",
262
+ "blockSize": "var(--jx-control-h)",
263
+ "margin": "0",
264
+ "padding": "var(--jx-space-1)",
265
+ "border": "1px solid var(--jx-border-strong)",
266
+ "borderRadius": "var(--jx-radius-sm)",
267
+ "background": "var(--jx-bg-input)",
268
+ "cursor": "pointer",
269
+ "outline": "none",
270
+ ":hover": {
271
+ "background": "var(--jx-hover-bg)"
272
+ },
273
+ ":focus-visible": {
274
+ "outline": "var(--jx-focus-ring)",
275
+ "outlineOffset": "1px"
276
+ },
277
+ ":disabled": {
278
+ "opacity": "0.5",
279
+ "cursor": "default"
280
+ }
281
+ },
282
+ "& [part=\"preview\"]": {
283
+ "display": "block",
284
+ "inlineSize": "100%",
285
+ "blockSize": "100%",
286
+ "borderRadius": "var(--jx-radius-xs)",
287
+ "background": "linear-gradient(var(--jx-color-field-preview), var(--jx-color-field-preview)), var(--jx-color-checkerboard)",
288
+ "boxShadow": "inset 0 0 0 1px var(--jx-color-field-ink)"
289
+ },
290
+ "& [part=\"text\"]": {
291
+ "minInlineSize": "0",
292
+ "inlineSize": "11ch"
293
+ },
294
+ "& [part=\"system-slot\"], & [part=\"dropper-slot\"], & [part=\"opacity-slot\"]": {
295
+ "display": "contents"
296
+ },
297
+ "& [part=\"system\"]": {
298
+ "appearance": "none",
299
+ "inlineSize": "var(--jx-control-h)",
300
+ "blockSize": "var(--jx-control-h)",
301
+ "flex": "none",
302
+ "margin": "0",
303
+ "padding": "2px",
304
+ "border": "1px solid var(--jx-border-strong)",
305
+ "borderRadius": "var(--jx-radius-sm)",
306
+ "background": "var(--jx-bg-input)",
307
+ "cursor": "pointer",
308
+ "outline": "none",
309
+ ":focus-visible": {
310
+ "outline": "var(--jx-focus-ring)",
311
+ "outlineOffset": "1px"
312
+ },
313
+ ":disabled": {
314
+ "opacity": "0.5",
315
+ "cursor": "default"
316
+ }
317
+ },
318
+ "& [part=\"picker\"]": {
319
+ "--jx-popover-offset": "6px"
320
+ },
321
+ "& [part=\"panel\"]": {
322
+ "display": "flex",
323
+ "flexDirection": "column",
324
+ "gap": "var(--jx-space-3)",
325
+ "inlineSize": "200px"
326
+ },
327
+ "& [part=\"tokens\"]": {
328
+ "display": "block"
329
+ },
330
+ "& [part=\"tokens\"]:empty": {
331
+ "display": "none"
332
+ }
333
+ },
334
+ "children": [
335
+ {
336
+ "tagName": "div",
337
+ "attributes": {
338
+ "part": "row"
339
+ },
340
+ "children": [
341
+ {
342
+ "tagName": "button",
343
+ "attributes": {
344
+ "part": "control",
345
+ "type": "button",
346
+ "aria-label": "Pick ${state.label}",
347
+ "aria-haspopup": "dialog",
348
+ "aria-expanded": "${state.expanded ? 'true' : 'false'}",
349
+ "aria-controls": "${state.pickerId || null}",
350
+ "tabindex": "${state.tabindex || null}",
351
+ "disabled": {
352
+ "$ref": "#/state/disabled"
353
+ }
354
+ },
355
+ "onclick": {
356
+ "$ref": "#/state/onOpen"
357
+ },
358
+ "children": [
359
+ {
360
+ "tagName": "span",
361
+ "attributes": {
362
+ "part": "preview",
363
+ "aria-hidden": "true"
364
+ }
365
+ }
366
+ ]
367
+ },
368
+ {
369
+ "tagName": "jx-textfield",
370
+ "attributes": {
371
+ "part": "text",
372
+ "data-jx-channel": "text"
373
+ },
374
+ "$props": {
375
+ "label": {
376
+ "$ref": "#/state/label"
377
+ },
378
+ "labelledby": {
379
+ "$ref": "#/state/labelledby"
380
+ },
381
+ "value": {
382
+ "$ref": "#/state/text"
383
+ },
384
+ "size": {
385
+ "$ref": "#/state/size"
386
+ },
387
+ "invalid": {
388
+ "$ref": "#/state/invalid"
389
+ },
390
+ "disabled": {
391
+ "$ref": "#/state/disabled"
392
+ },
393
+ "mono": true,
394
+ "autocomplete": "off",
395
+ "spellcheck": false,
396
+ "tabindex": "${state.tabindex ? '-1' : ''}"
397
+ }
398
+ },
399
+ {
400
+ "tagName": "span",
401
+ "attributes": {
402
+ "part": "dropper-slot"
403
+ },
404
+ "$switch": {
405
+ "$ref": "#/state/hasDropper"
406
+ },
407
+ "cases": {
408
+ "true": {
409
+ "tagName": "jx-action-button",
410
+ "attributes": {
411
+ "part": "dropper"
412
+ },
413
+ "$props": {
414
+ "icon": "eyedropper",
415
+ "label": "Pick ${state.label} from the screen",
416
+ "hint": "Pick ${state.label} from the screen",
417
+ "quiet": false,
418
+ "tabindex": "${state.tabindex ? '-1' : ''}",
419
+ "disabled": {
420
+ "$ref": "#/state/disabled"
421
+ }
422
+ },
423
+ "onclick": {
424
+ "$ref": "#/state/onDropper"
425
+ }
426
+ }
427
+ }
428
+ },
429
+ {
430
+ "tagName": "span",
431
+ "attributes": {
432
+ "part": "system-slot"
433
+ },
434
+ "$switch": {
435
+ "$ref": "#/state/system"
436
+ },
437
+ "cases": {
438
+ "true": {
439
+ "tagName": "input",
440
+ "attributes": {
441
+ "part": "system",
442
+ "data-jx-channel": "system",
443
+ "type": "color",
444
+ "aria-label": "Choose ${state.label} in the system picker",
445
+ "value": "${state.solid}",
446
+ "tabindex": "${state.tabindex ? '-1' : null}",
447
+ "disabled": {
448
+ "$ref": "#/state/disabled"
449
+ }
450
+ },
451
+ "value": {
452
+ "$ref": "#/state/solid"
453
+ }
454
+ }
455
+ }
456
+ }
457
+ ]
458
+ },
459
+ {
460
+ "tagName": "jx-popover",
461
+ "attributes": {
462
+ "part": "picker",
463
+ "id": "${state.pickerId || null}"
464
+ },
465
+ "$props": {
466
+ "label": "${state.label} picker"
467
+ },
468
+ "children": [
469
+ {
470
+ "tagName": "div",
471
+ "attributes": {
472
+ "part": "panel"
473
+ },
474
+ "children": [
475
+ {
476
+ "tagName": "jx-color-area",
477
+ "attributes": {
478
+ "part": "area",
479
+ "data-jx-channel": "area"
480
+ },
481
+ "$props": {
482
+ "label": "Saturation and brightness",
483
+ "hue": {
484
+ "$ref": "#/state/hue"
485
+ },
486
+ "saturation": {
487
+ "$ref": "#/state/saturation"
488
+ },
489
+ "brightness": {
490
+ "$ref": "#/state/brightness"
491
+ },
492
+ "disabled": {
493
+ "$ref": "#/state/disabled"
494
+ }
495
+ }
496
+ },
497
+ {
498
+ "tagName": "jx-color-slider",
499
+ "attributes": {
500
+ "part": "hue",
501
+ "data-jx-channel": "hue"
502
+ },
503
+ "$props": {
504
+ "label": "Hue",
505
+ "channel": "hue",
506
+ "value": {
507
+ "$ref": "#/state/hue"
508
+ },
509
+ "disabled": {
510
+ "$ref": "#/state/disabled"
511
+ }
512
+ }
513
+ },
514
+ {
515
+ "tagName": "span",
516
+ "attributes": {
517
+ "part": "opacity-slot"
518
+ },
519
+ "$switch": {
520
+ "$ref": "#/state/alpha"
521
+ },
522
+ "cases": {
523
+ "true": {
524
+ "tagName": "jx-color-slider",
525
+ "attributes": {
526
+ "part": "opacity",
527
+ "data-jx-channel": "opacity"
528
+ },
529
+ "$props": {
530
+ "label": "Opacity",
531
+ "channel": "alpha",
532
+ "value": {
533
+ "$ref": "#/state/opacity"
534
+ },
535
+ "color": {
536
+ "$ref": "#/state/solid"
537
+ },
538
+ "disabled": {
539
+ "$ref": "#/state/disabled"
540
+ }
541
+ }
542
+ }
543
+ }
544
+ },
545
+ {
546
+ "tagName": "div",
547
+ "attributes": {
548
+ "part": "tokens",
549
+ "data-jx-channel": "palette"
550
+ },
551
+ "children": [
552
+ {
553
+ "tagName": "slot",
554
+ "attributes": {
555
+ "name": "tokens"
556
+ }
557
+ }
558
+ ]
559
+ }
560
+ ]
561
+ }
562
+ ]
563
+ }
564
+ ]
565
+ }