@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.
- package/components/jx-accordion-item.json +281 -0
- package/components/jx-accordion.json +33 -0
- package/components/jx-action-button.json +268 -34
- package/components/jx-action-group.json +131 -0
- package/components/jx-button.json +141 -26
- package/components/jx-checkbox.json +222 -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 +551 -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 +6 -13
- 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 +331 -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 +645 -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 +719 -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,296 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://jxsuite.com/schema/v1",
|
|
3
|
+
"$id": "JxTab",
|
|
4
|
+
"tagName": "jx-tab",
|
|
5
|
+
"observedAttributes": ["value", "label", "selected", "panel", "closable", "dirty"],
|
|
6
|
+
"$elements": [
|
|
7
|
+
{
|
|
8
|
+
"$ref": "./jx-icon.json"
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
"state": {
|
|
12
|
+
"value": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"default": "",
|
|
15
|
+
"attribute": "value",
|
|
16
|
+
"description": "What the tab stands for: the detail of the events it dispatches, and what the strip's selected is compared against."
|
|
17
|
+
},
|
|
18
|
+
"label": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"default": "",
|
|
21
|
+
"attribute": "label",
|
|
22
|
+
"description": "The words on the tab, and its accessible name — written to aria-label as well as drawn, because a tab naming itself from its content would swallow the close button's own name and announce the label twice. That is also what makes the slots safe: aria-label wins over name-from-content, so nothing a consumer slots in — a marker, a pill, a pin — ever joins the tab's name, and each slotted control keeps announcing its own. The corollary is that label is REQUIRED once anything is slotted: with none there is no aria-label, name-from-content comes back, and a tab whose only content is a pin button is announced \"Pin\". Write it as an ATTRIBUTE: the runtime does not reflect a property write back to an attribute, so a host that sets el.label breaks every getAttribute(\"label\") selector aimed at the strip while looking correct. A count belongs in this string, not in a badge of its own."
|
|
23
|
+
},
|
|
24
|
+
"selected": {
|
|
25
|
+
"type": "boolean",
|
|
26
|
+
"default": false,
|
|
27
|
+
"attribute": "selected",
|
|
28
|
+
"description": "Whether this is the current tab. The strip writes it — jx-tabs is the single writer of every child's selected — so a host moves the selection by writing the strip's selected, never a tab's."
|
|
29
|
+
},
|
|
30
|
+
"panel": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"default": "",
|
|
33
|
+
"attribute": "panel",
|
|
34
|
+
"description": "The id of the jx-tab-panel this tab controls, announced as aria-controls. Nothing checks the pairing: both ids live in the consumer's document, so mint the tab's id and this one from one key."
|
|
35
|
+
},
|
|
36
|
+
"closable": {
|
|
37
|
+
"type": "boolean",
|
|
38
|
+
"default": false,
|
|
39
|
+
"attribute": "closable",
|
|
40
|
+
"description": "Draws a close button on the tab, which dispatches close with this tab's value. It is a real button: Enter and Space on it close, Delete on the focused tab is the same path, and its target is 24px square though it draws 16. It carries its own name, and the tab carries its own, so neither is heard twice."
|
|
41
|
+
},
|
|
42
|
+
"dirty": {
|
|
43
|
+
"type": "boolean",
|
|
44
|
+
"default": false,
|
|
45
|
+
"attribute": "dirty",
|
|
46
|
+
"description": "Marks the tab as holding unsaved work. Purely visual, and hidden from assistive technology: a reader is told about unsaved work by the page, not by a dot."
|
|
47
|
+
},
|
|
48
|
+
"onClick": {
|
|
49
|
+
"$prototype": "Function",
|
|
50
|
+
"body": [
|
|
51
|
+
{
|
|
52
|
+
"dispatchEvent": "select",
|
|
53
|
+
"detail": {
|
|
54
|
+
"$ref": "#/state/value"
|
|
55
|
+
},
|
|
56
|
+
"bubbles": true
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
"emits": [
|
|
60
|
+
{
|
|
61
|
+
"name": "select",
|
|
62
|
+
"description": "The tab was activated; detail is its value. The strip listens for it and answers with change."
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"description": "Activation dispatches select, which the tablist turns into its own selection and one change. A click that started on the close button never reaches here."
|
|
66
|
+
},
|
|
67
|
+
"onClose": {
|
|
68
|
+
"$prototype": "Function",
|
|
69
|
+
"body": [
|
|
70
|
+
{
|
|
71
|
+
"stopPropagation": true
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"dispatchEvent": "close",
|
|
75
|
+
"detail": {
|
|
76
|
+
"$ref": "#/state/value"
|
|
77
|
+
},
|
|
78
|
+
"bubbles": true
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"emits": [
|
|
82
|
+
{
|
|
83
|
+
"name": "close",
|
|
84
|
+
"description": "The tab was asked to close; detail is its value. Closing is the host's to do."
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
"description": "The click stops at the close button, so closing a tab does not also select it."
|
|
88
|
+
},
|
|
89
|
+
"onActions": {
|
|
90
|
+
"$prototype": "Function",
|
|
91
|
+
"body": [
|
|
92
|
+
{
|
|
93
|
+
"stopPropagation": true
|
|
94
|
+
}
|
|
95
|
+
],
|
|
96
|
+
"description": "A click inside the actions slot stops there, so activating a control a consumer put on the tab never ALSO selects the tab — the same judgement onClose makes for the close button, which is the one such control the element ships itself. It stops at the CONTAINER rather than at the host: stopPropagation halts an event at the node it is called on and every node after it, never the other listeners on that node or the ones already run below it, so the slotted control's own handler has fired (it is the target) and only the tab's onclick is cut off. Nothing is stopped for icon or status: those hold marks rather than controls, and a click on a mark is a click on the tab."
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"attributes": {
|
|
100
|
+
"role": "tab",
|
|
101
|
+
"tabindex": "-1",
|
|
102
|
+
"aria-label": "${state.label || null}",
|
|
103
|
+
"aria-selected": "${state.selected ? 'true' : 'false'}",
|
|
104
|
+
"aria-controls": "${state.panel || null}"
|
|
105
|
+
},
|
|
106
|
+
"onclick": {
|
|
107
|
+
"$ref": "#/state/onClick"
|
|
108
|
+
},
|
|
109
|
+
"style": {
|
|
110
|
+
"display": "inline-flex",
|
|
111
|
+
"&[hidden]": {
|
|
112
|
+
"display": "none"
|
|
113
|
+
},
|
|
114
|
+
"alignItems": "center",
|
|
115
|
+
"gap": "var(--jx-space-2)",
|
|
116
|
+
"boxSizing": "border-box",
|
|
117
|
+
"minHeight": "var(--jx-control-h)",
|
|
118
|
+
"maxWidth": "220px",
|
|
119
|
+
"padding": "var(--jx-space-1) var(--jx-space-3)",
|
|
120
|
+
"marginBlockEnd": "-1px",
|
|
121
|
+
"borderBlockEnd": "2px solid transparent",
|
|
122
|
+
"color": "inherit",
|
|
123
|
+
"cursor": "default",
|
|
124
|
+
"userSelect": "none",
|
|
125
|
+
"whiteSpace": "nowrap",
|
|
126
|
+
"outline": "none",
|
|
127
|
+
":hover": {
|
|
128
|
+
"background": "var(--jx-hover-bg)",
|
|
129
|
+
"color": "var(--jx-fg)"
|
|
130
|
+
},
|
|
131
|
+
":focus-visible": {
|
|
132
|
+
"outline": "var(--jx-focus-ring)",
|
|
133
|
+
"outlineOffset": "-2px"
|
|
134
|
+
},
|
|
135
|
+
"&[aria-selected=\"true\"]": {
|
|
136
|
+
"color": "var(--jx-fg)",
|
|
137
|
+
"borderBlockEndColor": "var(--jx-accent-solid)"
|
|
138
|
+
},
|
|
139
|
+
"& > [part=\"label\"]": {
|
|
140
|
+
"overflow": "hidden",
|
|
141
|
+
"textOverflow": "ellipsis",
|
|
142
|
+
"whiteSpace": "nowrap"
|
|
143
|
+
},
|
|
144
|
+
"& [part=\"icon\"], & [part=\"status\"], & [part=\"actions\"]": {
|
|
145
|
+
"$description": "The three consumer zones, and they generate no box of their own. display: contents is what makes an EMPTY one cost nothing: as ordinary flex items three unused containers would each take the tab's gap, which is dead space on every tab that slotted nothing — the same measurement (8px of trailing gap, the label visibly off-centre) that gave [part=\"dirty-slot\"] its own contents. It is also what puts slotted content in the TAB's flex row rather than one box deeper, so a marker, a pill and a pin line up with the label, the dot and the close button on one gap rather than on two.",
|
|
146
|
+
"display": "contents"
|
|
147
|
+
},
|
|
148
|
+
"& [part=\"dirty-slot\"], & [part=\"close-slot\"]": {
|
|
149
|
+
"display": "contents"
|
|
150
|
+
},
|
|
151
|
+
"& [part=\"dirty\"]": {
|
|
152
|
+
"display": "inline-block",
|
|
153
|
+
"width": "6px",
|
|
154
|
+
"height": "6px",
|
|
155
|
+
"borderRadius": "50%",
|
|
156
|
+
"background": "var(--jx-accent-solid)"
|
|
157
|
+
},
|
|
158
|
+
"& [part=\"close\"]": {
|
|
159
|
+
"appearance": "none",
|
|
160
|
+
"font": "inherit",
|
|
161
|
+
"display": "inline-flex",
|
|
162
|
+
"alignItems": "center",
|
|
163
|
+
"justifyContent": "center",
|
|
164
|
+
"position": "relative",
|
|
165
|
+
"width": "16px",
|
|
166
|
+
"height": "16px",
|
|
167
|
+
"padding": "0",
|
|
168
|
+
"border": "0",
|
|
169
|
+
"borderRadius": "var(--jx-radius-xs)",
|
|
170
|
+
"background": "transparent",
|
|
171
|
+
"color": "var(--jx-fg-muted)",
|
|
172
|
+
"cursor": "pointer",
|
|
173
|
+
"::before": {
|
|
174
|
+
"content": "\"\"",
|
|
175
|
+
"position": "absolute",
|
|
176
|
+
"insetBlock": "-4px",
|
|
177
|
+
"insetInline": "-4px"
|
|
178
|
+
},
|
|
179
|
+
":hover": {
|
|
180
|
+
"background": "var(--jx-hover-bg)",
|
|
181
|
+
"color": "var(--jx-fg)"
|
|
182
|
+
},
|
|
183
|
+
":focus-visible": {
|
|
184
|
+
"outline": "var(--jx-focus-ring)",
|
|
185
|
+
"outlineOffset": "1px"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"children": [
|
|
190
|
+
{
|
|
191
|
+
"tagName": "span",
|
|
192
|
+
"attributes": {
|
|
193
|
+
"part": "icon"
|
|
194
|
+
},
|
|
195
|
+
"children": [
|
|
196
|
+
{
|
|
197
|
+
"tagName": "slot",
|
|
198
|
+
"attributes": {
|
|
199
|
+
"name": "icon"
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"tagName": "span",
|
|
206
|
+
"attributes": {
|
|
207
|
+
"part": "label"
|
|
208
|
+
},
|
|
209
|
+
"textContent": "${state.label}"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"tagName": "span",
|
|
213
|
+
"attributes": {
|
|
214
|
+
"part": "status"
|
|
215
|
+
},
|
|
216
|
+
"children": [
|
|
217
|
+
{
|
|
218
|
+
"tagName": "slot",
|
|
219
|
+
"attributes": {
|
|
220
|
+
"name": "status"
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"tagName": "span",
|
|
227
|
+
"attributes": {
|
|
228
|
+
"part": "actions"
|
|
229
|
+
},
|
|
230
|
+
"onclick": {
|
|
231
|
+
"$ref": "#/state/onActions"
|
|
232
|
+
},
|
|
233
|
+
"children": [
|
|
234
|
+
{
|
|
235
|
+
"tagName": "slot",
|
|
236
|
+
"attributes": {
|
|
237
|
+
"name": "actions"
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"tagName": "span",
|
|
244
|
+
"attributes": {
|
|
245
|
+
"part": "dirty-slot"
|
|
246
|
+
},
|
|
247
|
+
"$switch": {
|
|
248
|
+
"$ref": "#/state/dirty"
|
|
249
|
+
},
|
|
250
|
+
"cases": {
|
|
251
|
+
"true": {
|
|
252
|
+
"tagName": "span",
|
|
253
|
+
"attributes": {
|
|
254
|
+
"part": "dirty",
|
|
255
|
+
"aria-hidden": "true"
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"tagName": "span",
|
|
262
|
+
"attributes": {
|
|
263
|
+
"part": "close-slot"
|
|
264
|
+
},
|
|
265
|
+
"$switch": {
|
|
266
|
+
"$ref": "#/state/closable"
|
|
267
|
+
},
|
|
268
|
+
"cases": {
|
|
269
|
+
"true": {
|
|
270
|
+
"tagName": "button",
|
|
271
|
+
"attributes": {
|
|
272
|
+
"part": "close",
|
|
273
|
+
"type": "button",
|
|
274
|
+
"aria-label": "Close ${state.label}",
|
|
275
|
+
"tabindex": "${state.selected ? '0' : '-1'}"
|
|
276
|
+
},
|
|
277
|
+
"onclick": {
|
|
278
|
+
"$ref": "#/state/onClose"
|
|
279
|
+
},
|
|
280
|
+
"children": [
|
|
281
|
+
{
|
|
282
|
+
"tagName": "jx-icon",
|
|
283
|
+
"$props": {
|
|
284
|
+
"name": "x",
|
|
285
|
+
"weight": "bold"
|
|
286
|
+
},
|
|
287
|
+
"attributes": {
|
|
288
|
+
"part": "close-icon"
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
]
|
|
296
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://jxsuite.com/schema/v1",
|
|
3
|
+
"$id": "JxTabs",
|
|
4
|
+
"tagName": "jx-tabs",
|
|
5
|
+
"observedAttributes": ["selected", "label", "activation", "orientation"],
|
|
6
|
+
"state": {
|
|
7
|
+
"selected": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"default": "",
|
|
10
|
+
"attribute": "selected",
|
|
11
|
+
"description": "The value of the tab whose panel is showing. The strip is the one writer of its children's selected state, so a host owns this and nothing else."
|
|
12
|
+
},
|
|
13
|
+
"label": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"default": "Tabs",
|
|
16
|
+
"attribute": "label",
|
|
17
|
+
"description": "The accessible name of the strip. A tablist is named by nothing else — it takes no name from its tabs — and no lint can say so, because a bound role switches the naming rules off. Name every strip."
|
|
18
|
+
},
|
|
19
|
+
"activation": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"default": "auto",
|
|
22
|
+
"attribute": "activation",
|
|
23
|
+
"description": "auto selects a tab as the caret lands on it; manual moves the caret alone and waits for Enter or Space. auto is right for a strip whose panels are already built, manual for one whose panels cost something to show."
|
|
24
|
+
},
|
|
25
|
+
"orientation": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"default": "horizontal",
|
|
28
|
+
"attribute": "orientation",
|
|
29
|
+
"description": "horizontal or vertical. It chooses which arrow keys move the caret, and which edge carries both the strip's rule and the selected tab's mark on it — a tab cannot see the strip's orientation from its own sheet, so the strip draws that mark."
|
|
30
|
+
},
|
|
31
|
+
"applySelection": {
|
|
32
|
+
"$prototype": "Function",
|
|
33
|
+
"$src": "jx-ui:/behaviors/tabs.ts",
|
|
34
|
+
"$export": "applySelection",
|
|
35
|
+
"parameters": ["scope"],
|
|
36
|
+
"description": "Writes the selection onto the tabs and returns it. Idempotent: it runs inside a render effect."
|
|
37
|
+
},
|
|
38
|
+
"sync": "${state.applySelection(state)}",
|
|
39
|
+
"onKeydown": {
|
|
40
|
+
"$prototype": "Function",
|
|
41
|
+
"$src": "jx-ui:/behaviors/tabs.ts",
|
|
42
|
+
"$export": "onTabsKeydown",
|
|
43
|
+
"description": "The tab keyboard contract: the arrows of the strip's orientation move the caret with wrap, Home and End go to the ends, Enter and Space activate under manual activation, and Delete closes a closable tab."
|
|
44
|
+
},
|
|
45
|
+
"onSelect": {
|
|
46
|
+
"$prototype": "Function",
|
|
47
|
+
"$src": "jx-ui:/behaviors/tabs.ts",
|
|
48
|
+
"$export": "onTabsSelect",
|
|
49
|
+
"description": "A tab was activated: selected is written first, then change is dispatched, so a listener reading e.target.selected sees the new value.",
|
|
50
|
+
"emits": [
|
|
51
|
+
{
|
|
52
|
+
"name": "change",
|
|
53
|
+
"description": "The selection moved; detail is the newly selected tab's value."
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"onReady": {
|
|
58
|
+
"$prototype": "Function",
|
|
59
|
+
"$src": "jx-ui:/behaviors/tabs.ts",
|
|
60
|
+
"$export": "onTabsMount",
|
|
61
|
+
"description": "Gives the strip its first sight of itself and syncs the tabs. Not optional: applyAttributes runs before distributeSlots, so no tab exists when the root's bindings first evaluate."
|
|
62
|
+
},
|
|
63
|
+
"onMount": {
|
|
64
|
+
"$prototype": "Function",
|
|
65
|
+
"body": [
|
|
66
|
+
{
|
|
67
|
+
"dispatchEvent": "jx-ready",
|
|
68
|
+
"bubbles": true
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"description": "Announces that the strip has rendered and taken its slotted tabs, which is how onReady reaches the element itself."
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"attributes": {
|
|
75
|
+
"role": "tablist",
|
|
76
|
+
"aria-label": "${state.label}",
|
|
77
|
+
"aria-orientation": "${state.orientation}",
|
|
78
|
+
"tabindex": "-1",
|
|
79
|
+
"data-selection": "${state.sync}"
|
|
80
|
+
},
|
|
81
|
+
"onkeydown": {
|
|
82
|
+
"$ref": "#/state/onKeydown"
|
|
83
|
+
},
|
|
84
|
+
"onselect": {
|
|
85
|
+
"$ref": "#/state/onSelect"
|
|
86
|
+
},
|
|
87
|
+
"onjx-ready": {
|
|
88
|
+
"$ref": "#/state/onReady"
|
|
89
|
+
},
|
|
90
|
+
"style": {
|
|
91
|
+
"display": "flex",
|
|
92
|
+
"&[hidden]": {
|
|
93
|
+
"display": "none"
|
|
94
|
+
},
|
|
95
|
+
"boxSizing": "border-box",
|
|
96
|
+
"alignItems": "stretch",
|
|
97
|
+
"gap": "var(--jx-space-1)",
|
|
98
|
+
"fontFamily": "var(--jx-font-sans)",
|
|
99
|
+
"fontSize": "var(--jx-text-md)",
|
|
100
|
+
"lineHeight": "var(--jx-leading-md)",
|
|
101
|
+
"color": "var(--jx-fg-dim)",
|
|
102
|
+
"borderBlockEnd": "1px solid var(--jx-border)",
|
|
103
|
+
"outline": "none",
|
|
104
|
+
"&[aria-orientation=\"vertical\"]": {
|
|
105
|
+
"flexDirection": "column",
|
|
106
|
+
"borderBlockEnd": "0",
|
|
107
|
+
"borderInlineEnd": "1px solid var(--jx-border)",
|
|
108
|
+
"& > jx-tab": {
|
|
109
|
+
"marginBlockEnd": "0",
|
|
110
|
+
"marginInlineEnd": "-1px",
|
|
111
|
+
"borderBlockEnd": "0",
|
|
112
|
+
"borderInlineEnd": "2px solid transparent"
|
|
113
|
+
},
|
|
114
|
+
"& > jx-tab[aria-selected=\"true\"]": {
|
|
115
|
+
"borderInlineEndColor": "var(--jx-accent-solid)"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
"children": [
|
|
120
|
+
{
|
|
121
|
+
"tagName": "slot"
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
}
|