@oneli8/core 1.0.0-beta.4 → 1.0.0-beta.6
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/README.md +51 -13
- package/ai-context.json +168 -1
- package/package.json +18 -3
- package/src/atoms/index.d.ts +1 -0
- package/src/atoms/index.js +1 -0
- package/src/atoms/navigation-badge/index.d.ts +1 -0
- package/src/atoms/navigation-badge/index.js +1 -0
- package/src/atoms/navigation-badge/navigation-badge.css +35 -0
- package/src/atoms/navigation-badge/navigation-badge.d.ts +5 -0
- package/src/atoms/navigation-badge/navigation-badge.js +21 -0
- package/src/atoms/selection-indicator/selection-indicator.css +13 -4
- package/src/materials/gem/gem.css +52 -5
- package/src/molecules/choice-chip/choice-chip.css +214 -0
- package/src/molecules/choice-chip/choice-chip.d.ts +27 -0
- package/src/molecules/choice-chip/choice-chip.js +170 -0
- package/src/molecules/choice-chip/index.d.ts +2 -0
- package/src/molecules/choice-chip/index.js +10 -0
- package/src/molecules/form-message/form-message.css +46 -0
- package/src/molecules/form-message/form-message.d.ts +23 -0
- package/src/molecules/form-message/form-message.js +73 -0
- package/src/molecules/form-message/index.d.ts +1 -0
- package/src/molecules/form-message/index.js +1 -0
- package/src/molecules/index.d.ts +6 -0
- package/src/molecules/index.js +6 -0
- package/src/molecules/link/index.d.ts +1 -0
- package/src/molecules/link/index.js +1 -0
- package/src/molecules/link/link.css +114 -0
- package/src/molecules/link/link.d.ts +27 -0
- package/src/molecules/link/link.js +76 -0
- package/src/molecules/navigation-item/index.js +1 -0
- package/src/molecules/navigation-item/navigation-item.css +153 -0
- package/src/molecules/navigation-item/navigation-item.js +95 -0
- package/src/molecules/select/index.js +1 -0
- package/src/molecules/select/select.css +31 -0
- package/src/molecules/select/select.js +127 -0
- package/src/molecules/selection-option/selection-option.js +4 -4
- package/src/molecules/text-field/index.d.ts +1 -0
- package/src/molecules/text-field/index.js +5 -0
- package/src/molecules/text-field/text-field.css +266 -0
- package/src/molecules/text-field/text-field.d.ts +69 -0
- package/src/molecules/text-field/text-field.js +234 -0
- package/src/molecules/token/index.d.ts +2 -0
- package/src/molecules/token/index.js +1 -0
- package/src/molecules/token/token.css +63 -0
- package/src/molecules/token/token.d.ts +35 -0
- package/src/molecules/token/token.js +83 -0
- package/src/organisms/choice-picker/choice-picker.css +98 -0
- package/src/organisms/choice-picker/choice-picker.d.ts +62 -0
- package/src/organisms/choice-picker/choice-picker.js +201 -0
- package/src/organisms/choice-picker/index.d.ts +1 -0
- package/src/organisms/choice-picker/index.js +1 -0
- package/src/organisms/combobox/combobox.css +40 -0
- package/src/organisms/combobox/combobox.js +309 -0
- package/src/organisms/combobox/index.js +5 -0
- package/src/organisms/index.d.ts +7 -0
- package/src/organisms/index.js +7 -0
- package/src/organisms/multi-select-field/index.d.ts +1 -0
- package/src/organisms/multi-select-field/index.js +1 -0
- package/src/organisms/multi-select-field/multi-select-field.css +76 -0
- package/src/organisms/multi-select-field/multi-select-field.d.ts +64 -0
- package/src/organisms/multi-select-field/multi-select-field.js +317 -0
- package/src/organisms/navigation-keys.js +58 -0
- package/src/organisms/segmented-control/index.d.ts +1 -0
- package/src/organisms/segmented-control/index.js +1 -0
- package/src/organisms/segmented-control/segmented-control.css +113 -0
- package/src/organisms/segmented-control/segmented-control.d.ts +43 -0
- package/src/organisms/segmented-control/segmented-control.js +163 -0
- package/src/organisms/selection-popup/index.js +1 -0
- package/src/organisms/selection-popup/selection-popup.css +90 -0
- package/src/organisms/selection-popup/selection-popup.js +100 -0
- package/src/organisms/tab-bar/index.d.ts +1 -0
- package/src/organisms/tab-bar/index.js +1 -0
- package/src/organisms/tab-bar/tab-bar.css +45 -0
- package/src/organisms/tab-bar/tab-bar.d.ts +37 -0
- package/src/organisms/tab-bar/tab-bar.js +104 -0
- package/src/organisms/tabs/index.d.ts +1 -0
- package/src/organisms/tabs/index.js +1 -0
- package/src/organisms/tabs/tabs.css +53 -0
- package/src/organisms/tabs/tabs.d.ts +48 -0
- package/src/organisms/tabs/tabs.js +152 -0
- package/styles.css +18 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @oneli8/core
|
|
2
2
|
|
|
3
|
-
OneLi8 Design System
|
|
3
|
+
OneLi8 Design System, framework agnostic components.
|
|
4
4
|
|
|
5
5
|
Every component is two functions: `renderX(...)` returns an HTML **string**, and
|
|
6
6
|
`hydrateX(root)` enforces the runtime contract on markup that already exists.
|
|
@@ -26,26 +26,64 @@ hydrateButtons();
|
|
|
26
26
|
|
|
27
27
|
| Tier | Component |
|
|
28
28
|
|---|---|
|
|
29
|
-
| Atom | `Icon`, `Selection Indicator` (checkbox, radio, switch) |
|
|
30
|
-
| Molecule | `Button`, `Icon Button`, `Choice Item`, `Selection Option` |
|
|
31
|
-
| Organism | `Choice Group`
|
|
32
|
-
| Material | `Gem
|
|
29
|
+
| Atom | `Icon`, `Selection Indicator` (checkbox, radio, switch), `Navigation Badge` |
|
|
30
|
+
| Molecule | `Button`, `Icon Button`, `Link`, `Text Field`, `Form Message`, `Select`, `Choice Item`, `Selection Option`, `Choice Chip`, `Token` |
|
|
31
|
+
| Organism | `Tabs`, `Tab Bar`, `Segmented Control`, `Choice Group`, `Selection Popup`, `Combobox`, `Multi-select Field`, `Choice Picker` |
|
|
32
|
+
| Material | `Gem`, an attribute adapter, not a tier |
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
Twenty one components, every one of them drawn from a component set in the
|
|
35
|
+
Figma file rather than invented here. Anything not listed is not exported.
|
|
36
|
+
Tokens exist for families whose implementations are not in this release; a token
|
|
37
|
+
is not a promise of a component.
|
|
38
|
+
|
|
39
|
+
## Why this exists
|
|
40
|
+
|
|
41
|
+
OneLi8 means One Light. It was created by Akshay Dhore, intended for broad human
|
|
42
|
+
benefit and conceived as service to Guruji Shrii Arnav, whose teachings inspire
|
|
43
|
+
it. Service, clarity, harmony, proportion, restraint and evolution guide its
|
|
44
|
+
decisions. `PRINCIPLES.md` ships inside this package and sets them out in full.
|
|
45
|
+
|
|
46
|
+
The practical intention: most design systems hand you components and hope you
|
|
47
|
+
stay inside them. This one hands you the reasoning too, so when you need
|
|
48
|
+
something it does not ship you can build it and have it still belong.
|
|
49
|
+
|
|
50
|
+
## Naming
|
|
51
|
+
|
|
52
|
+
The structure is borrowed from Sanskrit grammar rather than a CSS convention.
|
|
53
|
+
|
|
54
|
+
**A compound naming one thing is one word.** `actionprimary` is not action plus
|
|
55
|
+
primary, it is a single role. `cutedge` is one feature of the Gem material.
|
|
56
|
+
|
|
57
|
+
**A qualifier stays separate from what it qualifies.** In
|
|
58
|
+
`--ol8-material-control-gem--primary-hover-start`, `hover` is a state applied to
|
|
59
|
+
`start`, so it keeps its hyphen. That is why `disabledcontent` is joined and
|
|
60
|
+
`hover-start` is not.
|
|
61
|
+
|
|
62
|
+
Hyphens separate levels of the hierarchy, never words inside a level. The words
|
|
63
|
+
themselves stay readable: no abbreviations and no truncation.
|
|
36
64
|
|
|
37
65
|
## Rendering and hydration
|
|
38
66
|
|
|
39
67
|
`render*` covers everything expressible in markup. `hydrate*` exists only for
|
|
40
68
|
what markup genuinely cannot express:
|
|
41
69
|
|
|
42
|
-
- `indeterminate` on a checkbox is a JavaScript
|
|
70
|
+
- `indeterminate` on a checkbox is a JavaScript only property, so Mixed needs
|
|
43
71
|
hydration and every other state does not.
|
|
44
72
|
- A `<button>` without an explicit `type` submits its form. Hydration pins it.
|
|
45
73
|
- Links cannot be natively disabled, so they get `aria-disabled` and their
|
|
46
74
|
activation is swallowed.
|
|
47
|
-
|
|
48
|
-
|
|
75
|
+
- Tabs and Segmented Control move one tab stop across their items with the
|
|
76
|
+
arrow keys, which is a roving focus model markup cannot describe.
|
|
77
|
+
- Combobox keeps real focus on its input and carries the active option as a
|
|
78
|
+
virtual cursor, so the cursor has to be moved in script.
|
|
79
|
+
- Multi-select Field walks its committed values with the arrow keys and takes
|
|
80
|
+
two presses to remove one, so a stray Backspace cannot drop a value.
|
|
81
|
+
- Choice Picker in Apply mode commits on Enter and restores on Escape, and
|
|
82
|
+
leaves a composing input method alone.
|
|
83
|
+
|
|
84
|
+
Fifteen `hydrate*` functions ship, one per family that needs one. Hydration is
|
|
85
|
+
idempotent, running it twice changes nothing, and a page that never calls it
|
|
86
|
+
still renders and still reads correctly.
|
|
49
87
|
|
|
50
88
|
## Styles
|
|
51
89
|
|
|
@@ -57,7 +95,7 @@ import '@oneli8/tokens/css';
|
|
|
57
95
|
import '@oneli8/core/styles/button.css';
|
|
58
96
|
```
|
|
59
97
|
|
|
60
|
-
Tokens must always come first
|
|
98
|
+
Tokens must always come first, every component rule reads them.
|
|
61
99
|
|
|
62
100
|
## Accessibility is enforced, not suggested
|
|
63
101
|
|
|
@@ -66,11 +104,11 @@ Tokens must always come first — every component rule reads them.
|
|
|
66
104
|
Primary and Secondary only. These are errors rather than review comments on
|
|
67
105
|
purpose.
|
|
68
106
|
|
|
69
|
-
Test Gem against its real backdrop.
|
|
107
|
+
Test Gem against its real backdrop. Content close to white content alone does not guarantee
|
|
70
108
|
readable contrast.
|
|
71
109
|
|
|
72
110
|
## Licence
|
|
73
111
|
|
|
74
|
-
Apache
|
|
112
|
+
Apache 2.0. Created by Akshay Dhore. See `LICENSE` and `NOTICE`; preserve the
|
|
75
113
|
attribution notices when redistributing. This does not require a visible badge
|
|
76
114
|
in your product, and implies no OneLi8 endorsement.
|
package/ai-context.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "GENERATED by packages/sync/src/build-package-context.mjs — do not edit.",
|
|
3
3
|
"system": "OneLi8",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.6",
|
|
5
5
|
"meaning": "OneLi8 means One Light.",
|
|
6
6
|
"foundations": {
|
|
7
7
|
"package": "@oneli8/tokens",
|
|
@@ -46,6 +46,14 @@
|
|
|
46
46
|
],
|
|
47
47
|
"constraint": "Composes no other component. Native elements only."
|
|
48
48
|
},
|
|
49
|
+
{
|
|
50
|
+
"tier": "atom",
|
|
51
|
+
"module": "atoms/navigation-badge/navigation-badge.js",
|
|
52
|
+
"exports": [
|
|
53
|
+
"renderNavigationBadge"
|
|
54
|
+
],
|
|
55
|
+
"constraint": "Composes no other component. Native elements only."
|
|
56
|
+
},
|
|
49
57
|
{
|
|
50
58
|
"tier": "atom",
|
|
51
59
|
"module": "atoms/selection-indicator/selection-indicator.js",
|
|
@@ -72,6 +80,17 @@
|
|
|
72
80
|
],
|
|
73
81
|
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
74
82
|
},
|
|
83
|
+
{
|
|
84
|
+
"tier": "molecule",
|
|
85
|
+
"module": "molecules/choice-chip/choice-chip.js",
|
|
86
|
+
"exports": [
|
|
87
|
+
"OL8_CHIP_SIZES",
|
|
88
|
+
"renderChoiceChip",
|
|
89
|
+
"hydrateChoiceChips",
|
|
90
|
+
"syncChip"
|
|
91
|
+
],
|
|
92
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
93
|
+
},
|
|
75
94
|
{
|
|
76
95
|
"tier": "molecule",
|
|
77
96
|
"module": "molecules/choice-item/choice-item.js",
|
|
@@ -87,6 +106,17 @@
|
|
|
87
106
|
],
|
|
88
107
|
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
89
108
|
},
|
|
109
|
+
{
|
|
110
|
+
"tier": "molecule",
|
|
111
|
+
"module": "molecules/form-message/form-message.js",
|
|
112
|
+
"exports": [
|
|
113
|
+
"OL8_FORM_MESSAGE_TONES",
|
|
114
|
+
"OL8_FORM_MESSAGE_ICONS",
|
|
115
|
+
"renderFormMessage",
|
|
116
|
+
"hydrateFormMessages"
|
|
117
|
+
],
|
|
118
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
119
|
+
},
|
|
90
120
|
{
|
|
91
121
|
"tier": "molecule",
|
|
92
122
|
"module": "molecules/icon-button/icon-button.js",
|
|
@@ -100,6 +130,30 @@
|
|
|
100
130
|
],
|
|
101
131
|
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
102
132
|
},
|
|
133
|
+
{
|
|
134
|
+
"tier": "molecule",
|
|
135
|
+
"module": "molecules/link/link.js",
|
|
136
|
+
"exports": [
|
|
137
|
+
"OL8_LINK_FORMS",
|
|
138
|
+
"OL8_LINK_SIZES",
|
|
139
|
+
"OL8_LINK_MOTIONS",
|
|
140
|
+
"renderLink",
|
|
141
|
+
"hydrateLinks"
|
|
142
|
+
],
|
|
143
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"tier": "molecule",
|
|
147
|
+
"module": "molecules/select/select.js",
|
|
148
|
+
"exports": [
|
|
149
|
+
"OL8_SELECT_SIZES",
|
|
150
|
+
"OL8_SELECT_APPEARANCES",
|
|
151
|
+
"OL8_SELECT_MATERIALS",
|
|
152
|
+
"OL8_SELECT_NATIVE_POLICIES",
|
|
153
|
+
"renderSelect"
|
|
154
|
+
],
|
|
155
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
156
|
+
},
|
|
103
157
|
{
|
|
104
158
|
"tier": "molecule",
|
|
105
159
|
"module": "molecules/selection-option/selection-option.js",
|
|
@@ -111,6 +165,34 @@
|
|
|
111
165
|
],
|
|
112
166
|
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
113
167
|
},
|
|
168
|
+
{
|
|
169
|
+
"tier": "molecule",
|
|
170
|
+
"module": "molecules/text-field/text-field.js",
|
|
171
|
+
"exports": [
|
|
172
|
+
"OL8_TEXT_FIELD_SIZES",
|
|
173
|
+
"OL8_TEXT_FIELD_APPEARANCES",
|
|
174
|
+
"OL8_TEXT_FIELD_MATERIALS",
|
|
175
|
+
"OL8_MESSAGE_TONES",
|
|
176
|
+
"OL8_VALIDATION_STATUSES",
|
|
177
|
+
"OL8_CHARACTER_LIMIT_BEHAVIORS",
|
|
178
|
+
"renderTextField",
|
|
179
|
+
"hydrateTextFields",
|
|
180
|
+
"countGraphemes",
|
|
181
|
+
"clipToGraphemes"
|
|
182
|
+
],
|
|
183
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"tier": "molecule",
|
|
187
|
+
"module": "molecules/token/token.js",
|
|
188
|
+
"exports": [
|
|
189
|
+
"OL8_TOKEN_SIZES",
|
|
190
|
+
"OL8_TOKEN_MARKS",
|
|
191
|
+
"resolveTokenMark",
|
|
192
|
+
"renderToken"
|
|
193
|
+
],
|
|
194
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
195
|
+
},
|
|
114
196
|
{
|
|
115
197
|
"tier": "organism",
|
|
116
198
|
"module": "organisms/choice-group/choice-group.js",
|
|
@@ -122,6 +204,91 @@
|
|
|
122
204
|
"hydrateChoiceGroups"
|
|
123
205
|
],
|
|
124
206
|
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"tier": "organism",
|
|
210
|
+
"module": "organisms/choice-picker/choice-picker.js",
|
|
211
|
+
"exports": [
|
|
212
|
+
"OL8_PICKER_SIZES",
|
|
213
|
+
"OL8_PICKER_MATERIALS",
|
|
214
|
+
"OL8_COMMIT_BEHAVIORS",
|
|
215
|
+
"OL8_PICKER_PRESENTATIONS",
|
|
216
|
+
"OL8_PICKER_MARKS",
|
|
217
|
+
"renderChoicePicker",
|
|
218
|
+
"hydrateChoicePickers"
|
|
219
|
+
],
|
|
220
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"tier": "organism",
|
|
224
|
+
"module": "organisms/combobox/combobox.js",
|
|
225
|
+
"exports": [
|
|
226
|
+
"OL8_COMBOBOX_SIZES",
|
|
227
|
+
"OL8_COMBOBOX_APPEARANCES",
|
|
228
|
+
"OL8_COMBOBOX_MATERIALS",
|
|
229
|
+
"OL8_AUTOCOMPLETE_MODES",
|
|
230
|
+
"OL8_FILTER_SOURCES",
|
|
231
|
+
"renderCombobox",
|
|
232
|
+
"hydrateComboboxes"
|
|
233
|
+
],
|
|
234
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"tier": "organism",
|
|
238
|
+
"module": "organisms/multi-select-field/multi-select-field.js",
|
|
239
|
+
"exports": [
|
|
240
|
+
"OL8_MULTI_SELECT_SIZES",
|
|
241
|
+
"OL8_MULTI_SELECT_APPEARANCES",
|
|
242
|
+
"OL8_MULTI_SELECT_MATERIALS",
|
|
243
|
+
"renderMultiSelectField",
|
|
244
|
+
"hydrateMultiSelectFields"
|
|
245
|
+
],
|
|
246
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"tier": "organism",
|
|
250
|
+
"module": "organisms/segmented-control/segmented-control.js",
|
|
251
|
+
"exports": [
|
|
252
|
+
"OL8_SEGMENT_BEHAVIORS",
|
|
253
|
+
"OL8_SEGMENT_PRESENTATIONS",
|
|
254
|
+
"renderSegmentedControl",
|
|
255
|
+
"hydrateSegmentedControls"
|
|
256
|
+
],
|
|
257
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"tier": "organism",
|
|
261
|
+
"module": "organisms/selection-popup/selection-popup.js",
|
|
262
|
+
"exports": [
|
|
263
|
+
"OL8_POPUP_WIDTHS",
|
|
264
|
+
"OL8_POPUP_SIZES",
|
|
265
|
+
"OL8_POPUP_STATUSES",
|
|
266
|
+
"renderSelectionPopup"
|
|
267
|
+
],
|
|
268
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"tier": "organism",
|
|
272
|
+
"module": "organisms/tab-bar/tab-bar.js",
|
|
273
|
+
"exports": [
|
|
274
|
+
"OL8_TAB_BAR_PRESENTATIONS",
|
|
275
|
+
"renderTabBar",
|
|
276
|
+
"hydrateTabBars"
|
|
277
|
+
],
|
|
278
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
"tier": "organism",
|
|
282
|
+
"module": "organisms/tabs/tabs.js",
|
|
283
|
+
"exports": [
|
|
284
|
+
"OL8_TABS_HIERARCHIES",
|
|
285
|
+
"OL8_TABS_ORIENTATIONS",
|
|
286
|
+
"OL8_TABS_ACTIVATIONS",
|
|
287
|
+
"renderTabs",
|
|
288
|
+
"renderTabPanel",
|
|
289
|
+
"hydrateTabs"
|
|
290
|
+
],
|
|
291
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
125
292
|
}
|
|
126
293
|
],
|
|
127
294
|
"buildingWhatIsNotHere": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oneli8/core",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.6",
|
|
4
4
|
"description": "OneLi8 Design System, framework agnostic. renderX returns an HTML string, hydrateX wires existing DOM. Ships the design language and the rules it follows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"design-system",
|
|
@@ -46,12 +46,27 @@
|
|
|
46
46
|
},
|
|
47
47
|
"./styles.css": "./styles.css",
|
|
48
48
|
"./styles/icon.css": "./src/atoms/icon/icon.css",
|
|
49
|
+
"./styles/navigation-badge.css": "./src/atoms/navigation-badge/navigation-badge.css",
|
|
49
50
|
"./styles/selection-indicator.css": "./src/atoms/selection-indicator/selection-indicator.css",
|
|
50
51
|
"./styles/button.css": "./src/molecules/button/button.css",
|
|
51
|
-
"./styles/
|
|
52
|
+
"./styles/choice-chip.css": "./src/molecules/choice-chip/choice-chip.css",
|
|
52
53
|
"./styles/choice-item.css": "./src/molecules/choice-item/choice-item.css",
|
|
54
|
+
"./styles/form-message.css": "./src/molecules/form-message/form-message.css",
|
|
55
|
+
"./styles/icon-button.css": "./src/molecules/icon-button/icon-button.css",
|
|
56
|
+
"./styles/link.css": "./src/molecules/link/link.css",
|
|
57
|
+
"./styles/navigation-item.css": "./src/molecules/navigation-item/navigation-item.css",
|
|
58
|
+
"./styles/select.css": "./src/molecules/select/select.css",
|
|
53
59
|
"./styles/selection-option.css": "./src/molecules/selection-option/selection-option.css",
|
|
60
|
+
"./styles/text-field.css": "./src/molecules/text-field/text-field.css",
|
|
61
|
+
"./styles/token.css": "./src/molecules/token/token.css",
|
|
54
62
|
"./styles/choice-group.css": "./src/organisms/choice-group/choice-group.css",
|
|
63
|
+
"./styles/choice-picker.css": "./src/organisms/choice-picker/choice-picker.css",
|
|
64
|
+
"./styles/combobox.css": "./src/organisms/combobox/combobox.css",
|
|
65
|
+
"./styles/multi-select-field.css": "./src/organisms/multi-select-field/multi-select-field.css",
|
|
66
|
+
"./styles/segmented-control.css": "./src/organisms/segmented-control/segmented-control.css",
|
|
67
|
+
"./styles/selection-popup.css": "./src/organisms/selection-popup/selection-popup.css",
|
|
68
|
+
"./styles/tab-bar.css": "./src/organisms/tab-bar/tab-bar.css",
|
|
69
|
+
"./styles/tabs.css": "./src/organisms/tabs/tabs.css",
|
|
55
70
|
"./styles/gem.css": "./src/materials/gem/gem.css",
|
|
56
71
|
"./package.json": "./package.json",
|
|
57
72
|
"./ai-context.json": "./ai-context.json",
|
|
@@ -74,7 +89,7 @@
|
|
|
74
89
|
"NOTICE"
|
|
75
90
|
],
|
|
76
91
|
"dependencies": {
|
|
77
|
-
"@oneli8/tokens": "1.0.0-beta.
|
|
92
|
+
"@oneli8/tokens": "1.0.0-beta.6"
|
|
78
93
|
},
|
|
79
94
|
"engines": {
|
|
80
95
|
"node": ">=20"
|
package/src/atoms/index.d.ts
CHANGED
package/src/atoms/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './navigation-badge.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { renderNavigationBadge } from './navigation-badge.js';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Oneli8 · Navigation Badge (ATOM)
|
|
3
|
+
* Figma: Atom / Navigation Badge 989:484 — a full radius pill at the standard
|
|
4
|
+
* indicator height, padded by the related inline step, whose surface and
|
|
5
|
+
* content are the only things that change when the item is selected or gem.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.ol8-nav-badge {
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
block-size: var(--ol8-size-indicator-standard);
|
|
13
|
+
padding-inline: var(--ol8-spacing-inline-related);
|
|
14
|
+
border-radius: var(--ol8-shape-radius-full);
|
|
15
|
+
background: var(--ol8-color-navigation-badge-surface-default);
|
|
16
|
+
color: var(--ol8-color-navigation-badge-content-default);
|
|
17
|
+
font-family: var(--ol8-font-family-functional);
|
|
18
|
+
font-size: var(--ol8-font-size-012);
|
|
19
|
+
font-weight: var(--ol8-font-weight-semibold);
|
|
20
|
+
line-height: var(--ol8-font-line-018);
|
|
21
|
+
font-variant-numeric: tabular-nums;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* Selection and material reach the badge through the item that owns it. */
|
|
25
|
+
[data-ol8-selected="true"] > * > .ol8-nav-badge,
|
|
26
|
+
[aria-selected="true"] > * > .ol8-nav-badge,
|
|
27
|
+
[aria-current] > * > .ol8-nav-badge {
|
|
28
|
+
background: var(--ol8-color-navigation-badge-surface-selected);
|
|
29
|
+
color: var(--ol8-color-navigation-badge-content-selected);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
[data-ol8-material="gem"] .ol8-nav-badge {
|
|
33
|
+
background: var(--ol8-color-navigation-badge-surface-gem);
|
|
34
|
+
color: var(--ol8-color-navigation-badge-content-gem);
|
|
35
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Navigation Badge (ATOM). Figma 989:484. One atom serves all three navigation organisms. */
|
|
2
|
+
export interface Ol8NavigationBadgeOptions { className?: string }
|
|
3
|
+
|
|
4
|
+
/** @throws when there is nothing to say. */
|
|
5
|
+
export declare function renderNavigationBadge(label: string | number, options?: Ol8NavigationBadgeOptions): string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Oneli8 · Navigation Badge — headless behavior.
|
|
3
|
+
*
|
|
4
|
+
* Figma (989:484): "Canonical optional navigation badge. Content comes from
|
|
5
|
+
* item.badge; geometry and colors are semantic token controlled."
|
|
6
|
+
*
|
|
7
|
+
* One atom serves Tabs, Segmented Control and Tab Bar. None of them owns a
|
|
8
|
+
* private copy of it.
|
|
9
|
+
*/
|
|
10
|
+
export function renderNavigationBadge(label, options = {}) {
|
|
11
|
+
const { className } = options;
|
|
12
|
+
const text = String(label ?? '');
|
|
13
|
+
if (text === '') throw new Error('[ol8] a navigation badge with nothing to say should not be rendered at all.');
|
|
14
|
+
|
|
15
|
+
// The count is decoration beside a label that already names the destination,
|
|
16
|
+
// so the badge is not announced twice. A product that needs it announced
|
|
17
|
+
// spells it into the item's own accessible name.
|
|
18
|
+
return `<span class="ol8-nav-badge${className ? ` ${className}` : ''}" aria-hidden="true">${escapeText(text)}</span>`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function escapeText(v) { return String(v).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); }
|
|
@@ -71,12 +71,21 @@
|
|
|
71
71
|
--_ink: var(--ol8-color-icon-disabled);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
/* The check glyph
|
|
75
|
-
|
|
74
|
+
/* The check glyph does NOT scale with the box, for the same reason the Mixed
|
|
75
|
+
bar below does not. Figma's `Icon / Selection / Check` is a governed two size
|
|
76
|
+
master rather than an Icon Frame instance: Size=Small (18) and Size=Standard
|
|
77
|
+
(24) both carry the same 10.2 x 6.9 artwork at the same 1.8 stroke, centred
|
|
78
|
+
in their box. So the source keeps its 24 unit box at both sizes and the
|
|
79
|
+
smaller box simply lets the empty margin overflow. The artwork is well
|
|
80
|
+
inside 18, so nothing is clipped.
|
|
81
|
+
|
|
82
|
+
This previously scaled with the box, which drew the compact check a quarter
|
|
83
|
+
smaller than Figma at a 1.35 stroke, off the 1.8 system. */
|
|
76
84
|
.ol8-selection--checkbox > .ol8-selection__mark > svg {
|
|
77
85
|
display: block;
|
|
78
|
-
inline-size: var(--
|
|
79
|
-
block-size: var(--
|
|
86
|
+
inline-size: var(--ol8-size-icon-standard);
|
|
87
|
+
block-size: var(--ol8-size-icon-standard);
|
|
88
|
+
overflow: visible;
|
|
80
89
|
}
|
|
81
90
|
|
|
82
91
|
/* The Mixed bar does NOT scale. Both the 18px and 24px masters carry the same
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
34
|
.ol8-btn[data-ol8-material="gem"],
|
|
35
|
-
.ol8-icon-btn[data-ol8-material="gem"] > .ol8-icon-btn__surface
|
|
35
|
+
.ol8-icon-btn[data-ol8-material="gem"] > .ol8-icon-btn__surface,
|
|
36
|
+
.ol8-field[data-ol8-material="gem"] > .ol8-field__control-stack > .ol8-field__control {
|
|
36
37
|
position: relative;
|
|
37
38
|
isolation: isolate;
|
|
38
39
|
--_rim: var(--ol8-material-control-gem-rim-default);
|
|
@@ -41,7 +42,8 @@
|
|
|
41
42
|
/* The regular opaque background stays underneath on purpose — it is what
|
|
42
43
|
shows through when the gem layer is suppressed for Reduced Transparency. */
|
|
43
44
|
.ol8-btn[data-ol8-material="gem"]::before,
|
|
44
|
-
.ol8-icon-btn[data-ol8-material="gem"] > .ol8-icon-btn__surface::before
|
|
45
|
+
.ol8-icon-btn[data-ol8-material="gem"] > .ol8-icon-btn__surface::before,
|
|
46
|
+
.ol8-field[data-ol8-material="gem"] .ol8-field__control::before {
|
|
45
47
|
content: "";
|
|
46
48
|
position: absolute;
|
|
47
49
|
inset: 0;
|
|
@@ -58,7 +60,8 @@
|
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
.ol8-btn[data-ol8-material="gem"]::after,
|
|
61
|
-
.ol8-icon-btn[data-ol8-material="gem"] > .ol8-icon-btn__surface::after
|
|
63
|
+
.ol8-icon-btn[data-ol8-material="gem"] > .ol8-icon-btn__surface::after,
|
|
64
|
+
.ol8-field[data-ol8-material="gem"] .ol8-field__control::after {
|
|
62
65
|
content: "";
|
|
63
66
|
position: absolute;
|
|
64
67
|
inset: 0;
|
|
@@ -143,9 +146,48 @@
|
|
|
143
146
|
--_g3: var(--ol8-material-control-gem-secondary-loadinglow);
|
|
144
147
|
}
|
|
145
148
|
|
|
149
|
+
/* ---- Text Field · the same Secondary body, per Figma 211:36 and 215:226 ---
|
|
150
|
+
Outline follows the Cut Edge, Filled sits on the Stabilized Face and follows
|
|
151
|
+
the Inner Thin Cut. Hover moves Filled onto the Cut Edge. Invalid keeps the
|
|
152
|
+
critical boundary, because a material must never hide a validation result. */
|
|
153
|
+
.ol8-field[data-ol8-material="gem"] .ol8-field__control {
|
|
154
|
+
--_g1: var(--ol8-material-control-gem-secondary-high);
|
|
155
|
+
--_g2: var(--ol8-material-control-gem-secondary-mid);
|
|
156
|
+
--_g3: var(--ol8-material-control-gem-secondary-low);
|
|
157
|
+
--_surface: transparent;
|
|
158
|
+
--_border: var(--ol8-material-gem-color-cutedge-high);
|
|
159
|
+
}
|
|
160
|
+
.ol8-field[data-ol8-material="gem"]:hover:not([data-ol8-disabled]) .ol8-field__control {
|
|
161
|
+
--_g1: var(--ol8-material-control-gem-secondary-hoverhigh);
|
|
162
|
+
--_g2: var(--ol8-material-control-gem-secondary-hovermid);
|
|
163
|
+
--_g3: var(--ol8-material-control-gem-secondary-hoverlow);
|
|
164
|
+
--_rim: var(--ol8-material-control-gem-rim-hover);
|
|
165
|
+
--_border: var(--ol8-material-gem-color-cutedge-high);
|
|
166
|
+
}
|
|
167
|
+
.ol8-field[data-ol8-material="gem"][data-ol8-appearance="filled"] .ol8-field__control {
|
|
168
|
+
--_surface: var(--ol8-material-gem-color-quiet-stabilizedface);
|
|
169
|
+
--_border: var(--ol8-material-gem-color-innerthincut-high);
|
|
170
|
+
}
|
|
171
|
+
.ol8-field[data-ol8-material="gem"][data-ol8-readonly][data-ol8-appearance="filled"] .ol8-field__control {
|
|
172
|
+
--_border: var(--ol8-material-gem-color-innerthincut-high);
|
|
173
|
+
}
|
|
174
|
+
.ol8-field[data-ol8-material="gem"]:has(.ol8-field__input[aria-invalid="true"]) .ol8-field__control,
|
|
175
|
+
.ol8-field[data-ol8-material="gem"][data-ol8-status="invalid"] .ol8-field__control {
|
|
176
|
+
--_border: var(--ol8-color-feedbackcritical-inlinecontent);
|
|
177
|
+
}
|
|
178
|
+
/* Disabled resolves to the opaque equivalent, which is the same answer Reduced
|
|
179
|
+
Transparency gives. */
|
|
180
|
+
.ol8-field[data-ol8-material="gem"][data-ol8-disabled] .ol8-field__control {
|
|
181
|
+
--_surface: var(--ol8-material-gem-color-quiet-opaqueequivalent);
|
|
182
|
+
--_border: var(--ol8-color-border-disabled);
|
|
183
|
+
}
|
|
184
|
+
.ol8-field[data-ol8-material="gem"][data-ol8-disabled] .ol8-field__control::before,
|
|
185
|
+
.ol8-field[data-ol8-material="gem"][data-ol8-disabled] .ol8-field__control::after { display: none; }
|
|
186
|
+
|
|
146
187
|
/* Content must sit above the ::before body. */
|
|
147
188
|
.ol8-btn[data-ol8-material="gem"] > *,
|
|
148
|
-
.ol8-icon-btn[data-ol8-material="gem"] .ol8-icon
|
|
189
|
+
.ol8-icon-btn[data-ol8-material="gem"] .ol8-icon,
|
|
190
|
+
.ol8-field[data-ol8-material="gem"] .ol8-field__control > * { position: relative; z-index: 0; }
|
|
149
191
|
|
|
150
192
|
/* ---- Disabled inherits the regular opaque treatment ------------------ */
|
|
151
193
|
.ol8-btn[data-ol8-material="gem"]:disabled::before,
|
|
@@ -160,7 +202,12 @@
|
|
|
160
202
|
.ol8-btn[data-ol8-material="gem"]::before,
|
|
161
203
|
.ol8-btn[data-ol8-material="gem"]::after,
|
|
162
204
|
.ol8-icon-btn[data-ol8-material="gem"] > .ol8-icon-btn__surface::before,
|
|
163
|
-
.ol8-icon-btn[data-ol8-material="gem"] > .ol8-icon-btn__surface::after
|
|
205
|
+
.ol8-icon-btn[data-ol8-material="gem"] > .ol8-icon-btn__surface::after,
|
|
206
|
+
.ol8-field[data-ol8-material="gem"] .ol8-field__control::before,
|
|
207
|
+
.ol8-field[data-ol8-material="gem"] .ol8-field__control::after { display: none; }
|
|
208
|
+
.ol8-field[data-ol8-material="gem"] .ol8-field__control {
|
|
209
|
+
--_surface: var(--ol8-material-gem-color-quiet-opaqueequivalent);
|
|
210
|
+
}
|
|
164
211
|
.ol8-btn--secondary[data-ol8-material="gem"] {
|
|
165
212
|
--_bw: var(--ol8-component-button-secondaryboundary);
|
|
166
213
|
--_bd: var(--ol8-color-actionsecondary-contentdefault);
|