@jxsuite/ui 0.0.0 → 0.1.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/components/jx-accordion-item.json +281 -0
- package/components/jx-accordion.json +33 -0
- package/components/jx-action-button.json +261 -33
- package/components/jx-action-group.json +123 -0
- package/components/jx-button.json +133 -25
- package/components/jx-checkbox.json +215 -0
- package/components/jx-color-area.json +263 -0
- package/components/jx-color-field.json +565 -0
- package/components/jx-color-slider.json +216 -0
- package/components/jx-combobox.json +544 -0
- package/components/jx-dialog.json +416 -0
- package/components/jx-divider.json +52 -0
- package/components/jx-dot.json +38 -0
- package/components/jx-field.json +162 -0
- package/components/jx-kbd.json +24 -0
- package/components/jx-listbox.json +76 -0
- package/components/jx-menu-item.json +5 -12
- package/components/jx-menu.json +45 -6
- package/components/jx-number-field.json +441 -0
- package/components/jx-option.json +350 -0
- package/components/jx-popover.json +227 -0
- package/components/jx-select.json +637 -0
- package/components/jx-spinner.json +129 -0
- package/components/jx-split.json +221 -0
- package/components/jx-swatch-group.json +107 -0
- package/components/jx-swatch.json +262 -0
- package/components/jx-switch.json +253 -0
- package/components/jx-tab-panel.json +58 -0
- package/components/jx-tab.json +296 -0
- package/components/jx-tabs.json +124 -0
- package/components/jx-textfield.json +639 -0
- package/components/jx-toast-host.json +121 -0
- package/components/jx-toast.json +255 -0
- package/components/jx-toolbar.json +81 -0
- package/components/jx-tooltip.json +207 -0
- package/components/jx-tree-item.json +325 -0
- package/components/jx-tree.json +202 -0
- package/icons/list.json +4 -0
- package/icons/manifest.json +12 -0
- package/package.json +27 -5
- package/project.json +164 -153
- package/src/behaviors/action-group.ts +255 -0
- package/src/behaviors/color-area.ts +303 -0
- package/src/behaviors/color-field.ts +465 -0
- package/src/behaviors/color-slider.ts +154 -0
- package/src/behaviors/combobox.ts +474 -0
- package/src/behaviors/dialog.ts +137 -0
- package/src/behaviors/listbox.ts +118 -0
- package/src/behaviors/menu.ts +80 -48
- package/src/behaviors/number-field.ts +161 -0
- package/src/behaviors/popover.ts +399 -0
- package/src/behaviors/select.ts +154 -0
- package/src/behaviors/split.ts +478 -0
- package/src/behaviors/swatch-group.ts +297 -0
- package/src/behaviors/tabs.ts +319 -0
- package/src/behaviors/textfield.ts +164 -0
- package/src/behaviors/toast-host.ts +241 -0
- package/src/behaviors/toast.ts +261 -0
- package/src/behaviors/toolbar.ts +413 -0
- package/src/behaviors/tooltip.ts +715 -0
- package/src/behaviors/tree.ts +830 -0
- package/src/color.ts +433 -0
- package/src/documents.ts +91 -1
- package/src/index.ts +41 -1
- package/src/loaders.ts +47 -0
- package/src/testing/anchor-support.ts +28 -0
- package/src/testing/popover-shim.ts +39 -6
- package/src/theme.ts +30 -6
- package/stylebook/jx-accordion-item.json +195 -0
- package/stylebook/jx-accordion.json +220 -0
- package/stylebook/jx-action-button.json +191 -23
- package/stylebook/jx-action-group.json +335 -0
- package/stylebook/jx-button.json +129 -26
- package/stylebook/jx-checkbox.json +245 -0
- package/stylebook/jx-color-area.json +272 -0
- package/stylebook/jx-color-field.json +261 -0
- package/stylebook/jx-color-slider.json +220 -0
- package/stylebook/jx-combobox.json +332 -0
- package/stylebook/jx-dialog.json +186 -0
- package/stylebook/jx-divider.json +125 -0
- package/stylebook/jx-dot.json +92 -0
- package/stylebook/jx-field.json +313 -0
- package/stylebook/jx-icon.json +4 -0
- package/stylebook/jx-kbd.json +90 -0
- package/stylebook/jx-listbox.json +337 -0
- package/stylebook/jx-menu.json +0 -1
- package/stylebook/jx-number-field.json +203 -0
- package/stylebook/jx-option.json +285 -0
- package/stylebook/jx-popover.json +123 -0
- package/stylebook/jx-select.json +407 -0
- package/stylebook/jx-spinner.json +111 -0
- package/stylebook/jx-split.json +170 -0
- package/stylebook/jx-swatch-group.json +175 -0
- package/stylebook/jx-swatch.json +249 -0
- package/stylebook/jx-switch.json +240 -0
- package/stylebook/jx-tab-panel.json +147 -0
- package/stylebook/jx-tab.json +201 -0
- package/stylebook/jx-tabs.json +278 -0
- package/stylebook/jx-textfield.json +309 -0
- package/stylebook/jx-toast-host.json +157 -0
- package/stylebook/jx-toast.json +266 -0
- package/stylebook/jx-toolbar.json +435 -0
- package/stylebook/jx-tooltip.json +162 -0
- package/stylebook/jx-tree-item.json +258 -0
- package/stylebook/jx-tree.json +429 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://jxsuite.com/schema/v1",
|
|
3
|
+
"$id": "JxSwatch",
|
|
4
|
+
"tagName": "jx-swatch",
|
|
5
|
+
"observedAttributes": ["color", "value", "label", "checked", "selected", "disabled", "size"],
|
|
6
|
+
"$elements": [
|
|
7
|
+
{
|
|
8
|
+
"$ref": "./jx-icon.json"
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
"state": {
|
|
12
|
+
"color": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"default": "",
|
|
15
|
+
"attribute": "color",
|
|
16
|
+
"description": "The colour the chip draws, as any CSS colour the page can resolve. Empty is a legal value and is the NO COLOUR chip: it draws a slashed square rather than nothing, because a blank square in a palette reads as a white swatch and picking it would be picking white."
|
|
17
|
+
},
|
|
18
|
+
"value": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"default": "",
|
|
21
|
+
"attribute": "value",
|
|
22
|
+
"description": "What the swatch stands for: the detail of the select it dispatches, and what a swatch group compares its own value against. Empty falls back to color, so a palette of literal colours needs no second attribute; set it when the swatch stands for a TOKEN whose colour is only how it looks, which is the case a project's palette is made of."
|
|
23
|
+
},
|
|
24
|
+
"label": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"default": "",
|
|
27
|
+
"attribute": "label",
|
|
28
|
+
"description": "The swatch's name, and its accessible name: it is written to aria-label, so it wins over anything slotted beside the chip. A COLOUR IS NOT A NAME. Without this the element falls back to the value and then to the colour, which announces \"#3b82f6\" one character at a time — legible, technically a name, and useless. Give every swatch in a palette the word a reader would use for it."
|
|
29
|
+
},
|
|
30
|
+
"checked": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"default": "",
|
|
33
|
+
"attribute": "checked",
|
|
34
|
+
"description": "Empty for a plain button; true or false for one member of a swatch group, which then carries role=radio and aria-checked on its control and puts role=none on the HOST so the radio is the group's own child rather than a grandchild behind a generic. jx-swatch-group is the single writer of this on its children, exactly as jx-tabs is of a tab's selected, so a host moves the selection by writing the group's value."
|
|
35
|
+
},
|
|
36
|
+
"selected": {
|
|
37
|
+
"type": "boolean",
|
|
38
|
+
"default": false,
|
|
39
|
+
"attribute": "selected",
|
|
40
|
+
"description": "Draws the chosen ring and the tick without announcing anything, for a swatch a host has chosen outside a radio group. It is the drawing alone: checked is what a reader is TOLD, and setting one never sets the other."
|
|
41
|
+
},
|
|
42
|
+
"disabled": {
|
|
43
|
+
"type": "boolean",
|
|
44
|
+
"default": false,
|
|
45
|
+
"attribute": "disabled",
|
|
46
|
+
"description": "Cannot be chosen or focused. Disabled, never absent."
|
|
47
|
+
},
|
|
48
|
+
"size": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"default": "md",
|
|
51
|
+
"attribute": "size",
|
|
52
|
+
"description": "sm, md or lg. The chip grows; the button's target does not shrink below the kit's control height, so a small swatch is still a target a finger can hit."
|
|
53
|
+
},
|
|
54
|
+
"tabindex": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"default": "",
|
|
57
|
+
"description": "Forwarded to the inner control as its tabindex, which is what makes a roving caret possible: the focusable node is the button inside, not the host, so a group moving focus writes this rather than reaching into a child's internals. It is a PROPERTY ONLY 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 one control would become two tab stops."
|
|
58
|
+
},
|
|
59
|
+
"inkOf": {
|
|
60
|
+
"$prototype": "Function",
|
|
61
|
+
"$src": "jx-ui:/color.ts",
|
|
62
|
+
"$export": "inkOn",
|
|
63
|
+
"parameters": ["color"],
|
|
64
|
+
"description": "Black or white, whichever can be seen on the swatch's own colour, or the empty string for a colour only the browser can resolve. Pure: it takes the colour and returns a word."
|
|
65
|
+
},
|
|
66
|
+
"ink": "${state.inkOf(state.color)}",
|
|
67
|
+
"token": "${state.value || state.color}",
|
|
68
|
+
"name": "${state.label || state.value || state.color || 'Colour'}",
|
|
69
|
+
"isChecked": {
|
|
70
|
+
"$expression": {
|
|
71
|
+
"operator": "===",
|
|
72
|
+
"target": {
|
|
73
|
+
"$ref": "#/state/checked"
|
|
74
|
+
},
|
|
75
|
+
"value": "true"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"chosen": {
|
|
79
|
+
"$expression": {
|
|
80
|
+
"operator": "||",
|
|
81
|
+
"target": {
|
|
82
|
+
"$ref": "#/state/isChecked"
|
|
83
|
+
},
|
|
84
|
+
"value": {
|
|
85
|
+
"$ref": "#/state/selected"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"onClick": {
|
|
90
|
+
"$prototype": "Function",
|
|
91
|
+
"body": [
|
|
92
|
+
{
|
|
93
|
+
"dispatchEvent": "select",
|
|
94
|
+
"detail": {
|
|
95
|
+
"$ref": "#/state/token"
|
|
96
|
+
},
|
|
97
|
+
"bubbles": true
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
"emits": [
|
|
101
|
+
{
|
|
102
|
+
"name": "select",
|
|
103
|
+
"description": "The swatch was activated; detail is what it stands for. A swatch group listens for it and answers with its own change."
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"description": "Activation says what the swatch stands for and nothing else. It does not write its own checked: inside a group the group owns that, and outside one the host does, and an element that chose itself would disagree with both."
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"onclick": {
|
|
110
|
+
"$ref": "#/state/onClick"
|
|
111
|
+
},
|
|
112
|
+
"attributes": {
|
|
113
|
+
"role": "${state.checked ? 'none' : null}",
|
|
114
|
+
"data-size": "${state.size}",
|
|
115
|
+
"data-chosen": "${state.chosen ? '' : null}",
|
|
116
|
+
"data-empty": "${state.color ? null : ''}",
|
|
117
|
+
"data-disabled": "${state.disabled ? '' : null}"
|
|
118
|
+
},
|
|
119
|
+
"style": {
|
|
120
|
+
"display": "inline-flex",
|
|
121
|
+
"&[hidden]": {
|
|
122
|
+
"display": "none"
|
|
123
|
+
},
|
|
124
|
+
"verticalAlign": "middle",
|
|
125
|
+
"--jx-swatch-size": "20px",
|
|
126
|
+
"--jx-swatch-color": "${state.color || 'transparent'}",
|
|
127
|
+
"--jx-swatch-ink": "${state.ink || 'var(--jx-border-strong)'}",
|
|
128
|
+
"--jx-color-checkerboard": "repeating-conic-gradient(var(--jx-gray-300) 0% 25%, var(--jx-bg-input) 0% 50%) 50% / 8px 8px",
|
|
129
|
+
"&[data-size=\"sm\"]": {
|
|
130
|
+
"--jx-swatch-size": "14px"
|
|
131
|
+
},
|
|
132
|
+
"&[data-size=\"lg\"]": {
|
|
133
|
+
"--jx-swatch-size": "28px"
|
|
134
|
+
},
|
|
135
|
+
"& > [part=\"control\"]": {
|
|
136
|
+
"appearance": "none",
|
|
137
|
+
"font": "inherit",
|
|
138
|
+
"fontFamily": "var(--jx-font-sans)",
|
|
139
|
+
"fontSize": "var(--jx-text-md)",
|
|
140
|
+
"display": "inline-flex",
|
|
141
|
+
"alignItems": "center",
|
|
142
|
+
"gap": "var(--jx-space-2)",
|
|
143
|
+
"minInlineSize": "var(--jx-control-h)",
|
|
144
|
+
"minBlockSize": "var(--jx-control-h)",
|
|
145
|
+
"margin": "0",
|
|
146
|
+
"padding": "var(--jx-space-1)",
|
|
147
|
+
"border": "0",
|
|
148
|
+
"borderRadius": "var(--jx-radius-sm)",
|
|
149
|
+
"background": "transparent",
|
|
150
|
+
"color": "var(--jx-fg)",
|
|
151
|
+
"cursor": "pointer",
|
|
152
|
+
"outline": "none",
|
|
153
|
+
":hover": {
|
|
154
|
+
"background": "var(--jx-hover-bg)"
|
|
155
|
+
},
|
|
156
|
+
":focus-visible": {
|
|
157
|
+
"outline": "var(--jx-focus-ring)",
|
|
158
|
+
"outlineOffset": "-2px"
|
|
159
|
+
},
|
|
160
|
+
":disabled": {
|
|
161
|
+
"opacity": "0.5",
|
|
162
|
+
"cursor": "default"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"& [part=\"chip\"]": {
|
|
166
|
+
"$description": "The ring is drawn with the ink the element worked out from its own colour rather than with a neutral border token, because a mid-grey boundary disappears against a mid-grey swatch and a control whose edge cannot be seen is a WCAG 1.4.11 failure. The checkerboard behind it is what makes a translucent colour read as translucent instead of as a paler opaque one.",
|
|
167
|
+
"position": "relative",
|
|
168
|
+
"display": "inline-flex",
|
|
169
|
+
"alignItems": "center",
|
|
170
|
+
"justifyContent": "center",
|
|
171
|
+
"flex": "none",
|
|
172
|
+
"inlineSize": "var(--jx-swatch-size)",
|
|
173
|
+
"blockSize": "var(--jx-swatch-size)",
|
|
174
|
+
"borderRadius": "var(--jx-radius-xs)",
|
|
175
|
+
"background": "linear-gradient(var(--jx-swatch-color), var(--jx-swatch-color)), var(--jx-color-checkerboard)",
|
|
176
|
+
"boxShadow": "inset 0 0 0 1px var(--jx-swatch-ink)",
|
|
177
|
+
"color": "var(--jx-swatch-ink)"
|
|
178
|
+
},
|
|
179
|
+
"&[data-empty] [part=\"chip\"]": {
|
|
180
|
+
"background": "linear-gradient(to bottom right, transparent calc(50% - 1px), var(--jx-danger) calc(50% - 1px), var(--jx-danger) calc(50% + 1px), transparent calc(50% + 1px)), var(--jx-bg-input)"
|
|
181
|
+
},
|
|
182
|
+
"&[data-chosen] [part=\"chip\"]": {
|
|
183
|
+
"outline": "2px solid var(--jx-fg)",
|
|
184
|
+
"outlineOffset": "2px"
|
|
185
|
+
},
|
|
186
|
+
"& [part=\"mark\"]": {
|
|
187
|
+
"display": "inline-flex",
|
|
188
|
+
"color": "inherit"
|
|
189
|
+
},
|
|
190
|
+
"& [part=\"label\"]": {
|
|
191
|
+
"minInlineSize": "0",
|
|
192
|
+
"overflow": "hidden",
|
|
193
|
+
"textOverflow": "ellipsis",
|
|
194
|
+
"whiteSpace": "nowrap"
|
|
195
|
+
},
|
|
196
|
+
"& [part=\"label\"]:empty": {
|
|
197
|
+
"display": "none"
|
|
198
|
+
},
|
|
199
|
+
"& [part=\"mark-slot\"]": {
|
|
200
|
+
"display": "contents"
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
"children": [
|
|
204
|
+
{
|
|
205
|
+
"tagName": "button",
|
|
206
|
+
"attributes": {
|
|
207
|
+
"part": "control",
|
|
208
|
+
"type": "button",
|
|
209
|
+
"role": "${state.checked ? 'radio' : null}",
|
|
210
|
+
"aria-checked": "${state.checked || null}",
|
|
211
|
+
"aria-label": "${state.name}",
|
|
212
|
+
"tabindex": "${state.tabindex || null}",
|
|
213
|
+
"disabled": {
|
|
214
|
+
"$ref": "#/state/disabled"
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
"children": [
|
|
218
|
+
{
|
|
219
|
+
"tagName": "span",
|
|
220
|
+
"attributes": {
|
|
221
|
+
"part": "chip",
|
|
222
|
+
"aria-hidden": "true"
|
|
223
|
+
},
|
|
224
|
+
"children": [
|
|
225
|
+
{
|
|
226
|
+
"tagName": "span",
|
|
227
|
+
"attributes": {
|
|
228
|
+
"part": "mark-slot"
|
|
229
|
+
},
|
|
230
|
+
"$switch": {
|
|
231
|
+
"$ref": "#/state/chosen"
|
|
232
|
+
},
|
|
233
|
+
"cases": {
|
|
234
|
+
"true": {
|
|
235
|
+
"tagName": "jx-icon",
|
|
236
|
+
"$props": {
|
|
237
|
+
"name": "check",
|
|
238
|
+
"weight": "bold"
|
|
239
|
+
},
|
|
240
|
+
"attributes": {
|
|
241
|
+
"part": "mark"
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"tagName": "span",
|
|
250
|
+
"attributes": {
|
|
251
|
+
"part": "label"
|
|
252
|
+
},
|
|
253
|
+
"children": [
|
|
254
|
+
{
|
|
255
|
+
"tagName": "slot"
|
|
256
|
+
}
|
|
257
|
+
]
|
|
258
|
+
}
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://jxsuite.com/schema/v1",
|
|
3
|
+
"$id": "JxSwitch",
|
|
4
|
+
"tagName": "jx-switch",
|
|
5
|
+
"observedAttributes": [
|
|
6
|
+
"checked",
|
|
7
|
+
"disabled",
|
|
8
|
+
"hint",
|
|
9
|
+
"label",
|
|
10
|
+
"labelledby",
|
|
11
|
+
"describedby",
|
|
12
|
+
"name",
|
|
13
|
+
"size"
|
|
14
|
+
],
|
|
15
|
+
"state": {
|
|
16
|
+
"checked": {
|
|
17
|
+
"type": "boolean",
|
|
18
|
+
"default": false,
|
|
19
|
+
"attribute": "checked",
|
|
20
|
+
"description": "Whether the setting is on. Bound to the control BOTH ways, and the two halves do different jobs. The PROPERTY is what keeps tracking: once the reader flips the box the checkedness dirty flag is set and the content attribute stops controlling the live state, so an attribute binding alone would look right until the first click and then silently stop. The ATTRIBUTE is written as well so the control's defaultChecked can never disagree with the element's state — the same shape jx-textfield ships for value. The cost is that defaultChecked is also the form-reset default, so until the element is form-associated (specs/ui.md §3.2) form.reset() moves this switch nowhere. That is the deliberate half of the trade: with no form association the element never hears the reset, so a working reset would move the CONTROL to the authored default and leave the element's checked state behind it, and a control that silently disagrees with its own element is worse than a reset that does nothing."
|
|
21
|
+
},
|
|
22
|
+
"disabled": {
|
|
23
|
+
"type": "boolean",
|
|
24
|
+
"default": false,
|
|
25
|
+
"attribute": "disabled",
|
|
26
|
+
"description": "Cannot be flipped or focused. Disabled, never absent."
|
|
27
|
+
},
|
|
28
|
+
"hint": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"default": "",
|
|
31
|
+
"attribute": "hint",
|
|
32
|
+
"description": "The tooltip on the row: why the setting is off, or what turning it on does. Empty removes the title rather than writing a blank one."
|
|
33
|
+
},
|
|
34
|
+
"label": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"default": "",
|
|
37
|
+
"attribute": "label",
|
|
38
|
+
"description": "The accessible name, forwarded to the control as aria-label. Leave it empty when the slotted text is on screen: the wrapping label is then the name, and a second one would be read twice."
|
|
39
|
+
},
|
|
40
|
+
"labelledby": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"default": "",
|
|
43
|
+
"attribute": "labelledby",
|
|
44
|
+
"description": "Forwarded to the inner control as aria-labelledby, for a visible label the element does not own."
|
|
45
|
+
},
|
|
46
|
+
"describedby": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"default": "",
|
|
49
|
+
"attribute": "describedby",
|
|
50
|
+
"description": "Forwarded to the inner control as aria-describedby, for the help or error sentence on the row."
|
|
51
|
+
},
|
|
52
|
+
"name": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"default": "",
|
|
55
|
+
"attribute": "name",
|
|
56
|
+
"description": "The form field name, forwarded to the control."
|
|
57
|
+
},
|
|
58
|
+
"size": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"default": "md",
|
|
61
|
+
"attribute": "size",
|
|
62
|
+
"description": "sm, md or lg. The track scales with it so a row of controls lines up."
|
|
63
|
+
},
|
|
64
|
+
"tabindex": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"default": "",
|
|
67
|
+
"description": "Forwarded to the inner control as its tabindex, which is what makes a roving caret possible: the focusable node is the input inside, not the host and not the label that wraps it, so a jx-toolbar moving focus writes this rather than reaching into a child'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."
|
|
68
|
+
},
|
|
69
|
+
"onChange": {
|
|
70
|
+
"$prototype": "Function",
|
|
71
|
+
"body": [
|
|
72
|
+
{
|
|
73
|
+
"operator": "=",
|
|
74
|
+
"target": {
|
|
75
|
+
"$ref": "#/state/checked"
|
|
76
|
+
},
|
|
77
|
+
"value": {
|
|
78
|
+
"$ref": "event#/target/checked"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"description": "Mirrors the reader's flip into checked. The native change and input events bubble from the control as they always do, so a host reads e.target.checked exactly as it would from a bare input."
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"attributes": {
|
|
86
|
+
"data-size": "${state.size}",
|
|
87
|
+
"data-checked": "${state.checked ? '' : null}",
|
|
88
|
+
"data-disabled": "${state.disabled ? '' : null}"
|
|
89
|
+
},
|
|
90
|
+
"style": {
|
|
91
|
+
"display": "inline-flex",
|
|
92
|
+
"verticalAlign": "middle",
|
|
93
|
+
"&[hidden]": {
|
|
94
|
+
"display": "none"
|
|
95
|
+
},
|
|
96
|
+
"& > [part=\"control\"]": {
|
|
97
|
+
"display": "inline-flex",
|
|
98
|
+
"alignItems": "center",
|
|
99
|
+
"gap": "var(--jx-space-2)",
|
|
100
|
+
"minHeight": "var(--jx-control-h)",
|
|
101
|
+
"fontFamily": "var(--jx-font-sans)",
|
|
102
|
+
"fontSize": "var(--jx-text-md)",
|
|
103
|
+
"lineHeight": "var(--jx-leading-md)",
|
|
104
|
+
"color": "var(--jx-fg)",
|
|
105
|
+
"cursor": "pointer"
|
|
106
|
+
},
|
|
107
|
+
"&[data-disabled] > [part=\"control\"]": {
|
|
108
|
+
"cursor": "default",
|
|
109
|
+
"color": "var(--jx-fg-muted)"
|
|
110
|
+
},
|
|
111
|
+
"& [part=\"input\"]": {
|
|
112
|
+
"appearance": "none",
|
|
113
|
+
"boxSizing": "border-box",
|
|
114
|
+
"position": "relative",
|
|
115
|
+
"flex": "0 0 auto",
|
|
116
|
+
"width": "28px",
|
|
117
|
+
"height": "16px",
|
|
118
|
+
"margin": "0",
|
|
119
|
+
"padding": "0",
|
|
120
|
+
"border": "1px solid var(--jx-switch-track)",
|
|
121
|
+
"borderRadius": "999px",
|
|
122
|
+
"background": "var(--jx-switch-track)",
|
|
123
|
+
"cursor": "inherit",
|
|
124
|
+
"outline": "none",
|
|
125
|
+
"--jx-switch-travel": "12px",
|
|
126
|
+
"transition": "background var(--jx-dur-1) var(--jx-ease-out), border-color var(--jx-dur-1) var(--jx-ease-out)",
|
|
127
|
+
"::before": {
|
|
128
|
+
"content": "\"\"",
|
|
129
|
+
"position": "absolute",
|
|
130
|
+
"insetBlockStart": "1px",
|
|
131
|
+
"insetInlineStart": "1px",
|
|
132
|
+
"width": "12px",
|
|
133
|
+
"height": "12px",
|
|
134
|
+
"borderRadius": "50%",
|
|
135
|
+
"background": "var(--jx-switch-thumb)",
|
|
136
|
+
"transition": "translate var(--jx-dur-1) var(--jx-ease-out)"
|
|
137
|
+
},
|
|
138
|
+
":checked": {
|
|
139
|
+
"background": "var(--jx-accent-solid)",
|
|
140
|
+
"borderColor": "var(--jx-accent-solid)",
|
|
141
|
+
"::before": {
|
|
142
|
+
"translate": "var(--jx-switch-travel) 0"
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
":focus-visible": {
|
|
146
|
+
"outline": "var(--jx-focus-ring)",
|
|
147
|
+
"outlineOffset": "2px"
|
|
148
|
+
},
|
|
149
|
+
":disabled": {
|
|
150
|
+
"opacity": "0.5",
|
|
151
|
+
"cursor": "default"
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"&:dir(rtl) [part=\"input\"]:checked::before": {
|
|
155
|
+
"translate": "calc(-1 * var(--jx-switch-travel)) 0"
|
|
156
|
+
},
|
|
157
|
+
"&[data-size=\"sm\"] [part=\"input\"]": {
|
|
158
|
+
"width": "22px",
|
|
159
|
+
"height": "12px",
|
|
160
|
+
"--jx-switch-travel": "10px",
|
|
161
|
+
"::before": {
|
|
162
|
+
"width": "8px",
|
|
163
|
+
"height": "8px"
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"&[data-size=\"lg\"] [part=\"input\"]": {
|
|
167
|
+
"width": "34px",
|
|
168
|
+
"height": "20px",
|
|
169
|
+
"--jx-switch-travel": "14px",
|
|
170
|
+
"::before": {
|
|
171
|
+
"width": "16px",
|
|
172
|
+
"height": "16px"
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
"& [part=\"label\"]": {
|
|
176
|
+
"minWidth": "0"
|
|
177
|
+
},
|
|
178
|
+
"& [part=\"label\"]:empty": {
|
|
179
|
+
"display": "none"
|
|
180
|
+
},
|
|
181
|
+
"@(forced-colors: active)": {
|
|
182
|
+
"& [part=\"input\"]": {
|
|
183
|
+
"forcedColorAdjust": "none",
|
|
184
|
+
"background": "ButtonFace",
|
|
185
|
+
"borderColor": "ButtonText",
|
|
186
|
+
"::before": {
|
|
187
|
+
"background": "ButtonText"
|
|
188
|
+
},
|
|
189
|
+
":checked": {
|
|
190
|
+
"background": "Highlight",
|
|
191
|
+
"borderColor": "Highlight",
|
|
192
|
+
"::before": {
|
|
193
|
+
"background": "ButtonFace"
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
":disabled": {
|
|
197
|
+
"borderColor": "GrayText",
|
|
198
|
+
"opacity": "1",
|
|
199
|
+
"::before": {
|
|
200
|
+
"background": "GrayText"
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
"children": [
|
|
207
|
+
{
|
|
208
|
+
"tagName": "label",
|
|
209
|
+
"attributes": {
|
|
210
|
+
"part": "control",
|
|
211
|
+
"title": "${state.hint || null}"
|
|
212
|
+
},
|
|
213
|
+
"children": [
|
|
214
|
+
{
|
|
215
|
+
"tagName": "input",
|
|
216
|
+
"attributes": {
|
|
217
|
+
"part": "input",
|
|
218
|
+
"type": "checkbox",
|
|
219
|
+
"role": "switch",
|
|
220
|
+
"aria-label": "${state.label || null}",
|
|
221
|
+
"aria-labelledby": "${state.labelledby || null}",
|
|
222
|
+
"aria-describedby": "${state.describedby || null}",
|
|
223
|
+
"tabindex": "${state.tabindex || null}",
|
|
224
|
+
"name": "${state.name || null}",
|
|
225
|
+
"disabled": {
|
|
226
|
+
"$ref": "#/state/disabled"
|
|
227
|
+
},
|
|
228
|
+
"checked": {
|
|
229
|
+
"$ref": "#/state/checked"
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
"checked": {
|
|
233
|
+
"$ref": "#/state/checked"
|
|
234
|
+
},
|
|
235
|
+
"onchange": {
|
|
236
|
+
"$ref": "#/state/onChange"
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"tagName": "span",
|
|
241
|
+
"attributes": {
|
|
242
|
+
"part": "label"
|
|
243
|
+
},
|
|
244
|
+
"children": [
|
|
245
|
+
{
|
|
246
|
+
"tagName": "slot"
|
|
247
|
+
}
|
|
248
|
+
]
|
|
249
|
+
}
|
|
250
|
+
]
|
|
251
|
+
}
|
|
252
|
+
]
|
|
253
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://jxsuite.com/schema/v1",
|
|
3
|
+
"$id": "JxTabPanel",
|
|
4
|
+
"tagName": "jx-tab-panel",
|
|
5
|
+
"observedAttributes": ["active", "labelledby"],
|
|
6
|
+
"state": {
|
|
7
|
+
"active": {
|
|
8
|
+
"type": "boolean",
|
|
9
|
+
"default": false,
|
|
10
|
+
"attribute": "active",
|
|
11
|
+
"description": "Whether this panel is the showing one. Every other panel is hidden, not absent, so the ids its tab names stay resolvable."
|
|
12
|
+
},
|
|
13
|
+
"labelledby": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"default": "",
|
|
16
|
+
"attribute": "labelledby",
|
|
17
|
+
"description": "The id of the tab that controls this panel, announced as aria-labelledby. Nothing checks the pairing: mint this id and the tab's aria-controls from one key."
|
|
18
|
+
},
|
|
19
|
+
"notActive": {
|
|
20
|
+
"$expression": {
|
|
21
|
+
"operator": "!",
|
|
22
|
+
"target": {
|
|
23
|
+
"$ref": "#/state/active"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"attributes": {
|
|
29
|
+
"role": "tabpanel",
|
|
30
|
+
"tabindex": "0",
|
|
31
|
+
"aria-labelledby": "${state.labelledby || null}",
|
|
32
|
+
"hidden": {
|
|
33
|
+
"$ref": "#/state/notActive"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"style": {
|
|
37
|
+
"display": "block",
|
|
38
|
+
"&[hidden]": {
|
|
39
|
+
"display": "none"
|
|
40
|
+
},
|
|
41
|
+
"boxSizing": "border-box",
|
|
42
|
+
"padding": "var(--jx-space-3)",
|
|
43
|
+
"fontFamily": "var(--jx-font-sans)",
|
|
44
|
+
"fontSize": "var(--jx-text-md)",
|
|
45
|
+
"lineHeight": "var(--jx-leading-md)",
|
|
46
|
+
"color": "var(--jx-fg)",
|
|
47
|
+
"outline": "none",
|
|
48
|
+
":focus-visible": {
|
|
49
|
+
"outline": "var(--jx-focus-ring)",
|
|
50
|
+
"outlineOffset": "-2px"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"children": [
|
|
54
|
+
{
|
|
55
|
+
"tagName": "slot"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|