@oneli8/react 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 +34 -4
- package/ai-context.json +116 -1
- package/package.json +29 -8
- package/src/atoms/NavigationBadge.js +19 -0
- package/src/foundations/geometry.js +71 -0
- package/src/index.d.ts +214 -0
- package/src/index.js +14 -0
- package/src/molecules/ChoiceChip.js +101 -0
- package/src/molecules/FormMessage.js +33 -0
- package/src/molecules/Link.js +31 -0
- package/src/molecules/NavigationItem.js +55 -0
- package/src/molecules/Select.js +109 -0
- package/src/molecules/SelectionOption.js +4 -1
- package/src/molecules/TextField.js +174 -0
- package/src/molecules/Token.js +49 -0
- package/src/organisms/ChoicePicker.js +114 -0
- package/src/organisms/Combobox.js +122 -0
- package/src/organisms/MultiSelectField.js +138 -0
- package/src/organisms/SegmentedControl.js +114 -0
- package/src/organisms/SelectionPopup.js +73 -0
- package/src/organisms/TabBar.js +68 -0
- package/src/organisms/Tabs.js +123 -0
- package/src/styles/choice-chip.css +216 -0
- package/src/styles/choice-picker.css +100 -0
- package/src/styles/combobox.css +42 -0
- package/src/styles/form-message.css +48 -0
- package/src/styles/gem.css +52 -5
- package/src/styles/link.css +116 -0
- package/src/styles/multi-select-field.css +78 -0
- package/src/styles/navigation-badge.css +37 -0
- package/src/styles/navigation-item.css +155 -0
- package/src/styles/segmented-control.css +115 -0
- package/src/styles/select.css +33 -0
- package/src/styles/selection-indicator.css +13 -4
- package/src/styles/selection-popup.css +92 -0
- package/src/styles/tab-bar.css +47 -0
- package/src/styles/tabs.css +55 -0
- package/src/styles/text-field.css +268 -0
- package/src/styles/token.css +65 -0
- package/styles.css +18 -2
package/README.md
CHANGED
|
@@ -19,11 +19,15 @@ export function Actions() {
|
|
|
19
19
|
|
|
20
20
|
| Tier | Components |
|
|
21
21
|
|---|---|
|
|
22
|
-
| Atom | `Icon`, `SelectionIndicator` |
|
|
23
|
-
| Molecule | `Button`, `IconButton`, `ChoiceItem`, `SelectionOption` |
|
|
24
|
-
| Organism | `RadioGroup`, `CheckboxGroup` |
|
|
22
|
+
| Atom | `Icon`, `SelectionIndicator`, `NavigationBadge` |
|
|
23
|
+
| Molecule | `Button`, `IconButton`, `Link`, `TextField`, `FormMessage`, `Select`, `ChoiceItem`, `SelectionOption`, `ChoiceChip`, `Token` |
|
|
24
|
+
| Organism | `Tabs`, `TabBar`, `SegmentedControl`, `RadioGroup`, `CheckboxGroup`, `SelectionPopup`, `Combobox`, `MultiSelectField`, `ChoicePicker` |
|
|
25
25
|
| Material | Gem, an attribute adapter rather than a tier |
|
|
26
26
|
|
|
27
|
+
Twenty one components, matching `@oneli8/core` one for one. Both packages are
|
|
28
|
+
checked against each other on every build, so the two cannot answer differently
|
|
29
|
+
about a role, a name, a relationship or a state.
|
|
30
|
+
|
|
27
31
|
## The system travels with the package
|
|
28
32
|
|
|
29
33
|
If you need a component OneLi8 does not ship, build it from these foundations
|
|
@@ -48,6 +52,32 @@ Point your agent at them:
|
|
|
48
52
|
Read @oneli8/react/ai-context.json and PRINCIPLES.md before writing any OneLi8 UI.
|
|
49
53
|
```
|
|
50
54
|
|
|
55
|
+
## Why this exists
|
|
56
|
+
|
|
57
|
+
OneLi8 means One Light. It was created by Akshay Dhore, intended for broad human
|
|
58
|
+
benefit and conceived as service to Guruji Shrii Arnav, whose teachings inspire
|
|
59
|
+
it. Service, clarity, harmony, proportion, restraint and evolution guide its
|
|
60
|
+
decisions. `PRINCIPLES.md` ships inside this package and sets them out in full.
|
|
61
|
+
|
|
62
|
+
The practical intention: most design systems hand you components and hope you
|
|
63
|
+
stay inside them. This one hands you the reasoning too, so when you need
|
|
64
|
+
something it does not ship you can build it and have it still belong.
|
|
65
|
+
|
|
66
|
+
## Naming
|
|
67
|
+
|
|
68
|
+
The structure is borrowed from Sanskrit grammar rather than a CSS convention.
|
|
69
|
+
|
|
70
|
+
**A compound naming one thing is one word.** `actionprimary` is not action plus
|
|
71
|
+
primary, it is a single role. `cutedge` is one feature of the Gem material.
|
|
72
|
+
|
|
73
|
+
**A qualifier stays separate from what it qualifies.** In
|
|
74
|
+
`--ol8-material-control-gem--primary-hover-start`, `hover` is a state applied to
|
|
75
|
+
`start`, so it keeps its hyphen. That is why `disabledcontent` is joined and
|
|
76
|
+
`hover-start` is not.
|
|
77
|
+
|
|
78
|
+
Hyphens separate levels of the hierarchy, never words inside a level. The words
|
|
79
|
+
themselves stay readable: no abbreviations and no truncation.
|
|
80
|
+
|
|
51
81
|
## Rules that matter most
|
|
52
82
|
|
|
53
83
|
Reach for a **semantic** token, never a primitive and never a literal.
|
|
@@ -58,7 +88,7 @@ Every dimension sits on the **3px grid**. An exception needs an approval record.
|
|
|
58
88
|
|
|
59
89
|
Icons come from the pool. `OL8_ICONS` is the whole set, an invented name throws.
|
|
60
90
|
A new glyph is a 24px neutral source on the shared **1.8 stroke**, never a
|
|
61
|
-
per
|
|
91
|
+
per size stroke.
|
|
62
92
|
|
|
63
93
|
Margins belong to the parent, never to the component.
|
|
64
94
|
|
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",
|
|
@@ -42,6 +42,14 @@
|
|
|
42
42
|
],
|
|
43
43
|
"constraint": "Composes no other component. Native elements only."
|
|
44
44
|
},
|
|
45
|
+
{
|
|
46
|
+
"tier": "atom",
|
|
47
|
+
"module": "atoms/NavigationBadge.js",
|
|
48
|
+
"exports": [
|
|
49
|
+
"NavigationBadge"
|
|
50
|
+
],
|
|
51
|
+
"constraint": "Composes no other component. Native elements only."
|
|
52
|
+
},
|
|
45
53
|
{
|
|
46
54
|
"tier": "atom",
|
|
47
55
|
"module": "atoms/SelectionIndicator.js",
|
|
@@ -58,6 +66,14 @@
|
|
|
58
66
|
],
|
|
59
67
|
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
60
68
|
},
|
|
69
|
+
{
|
|
70
|
+
"tier": "molecule",
|
|
71
|
+
"module": "molecules/ChoiceChip.js",
|
|
72
|
+
"exports": [
|
|
73
|
+
"ChoiceChip"
|
|
74
|
+
],
|
|
75
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
76
|
+
},
|
|
61
77
|
{
|
|
62
78
|
"tier": "molecule",
|
|
63
79
|
"module": "molecules/ChoiceItem.js",
|
|
@@ -66,6 +82,14 @@
|
|
|
66
82
|
],
|
|
67
83
|
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
68
84
|
},
|
|
85
|
+
{
|
|
86
|
+
"tier": "molecule",
|
|
87
|
+
"module": "molecules/FormMessage.js",
|
|
88
|
+
"exports": [
|
|
89
|
+
"FormMessage"
|
|
90
|
+
],
|
|
91
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
92
|
+
},
|
|
69
93
|
{
|
|
70
94
|
"tier": "molecule",
|
|
71
95
|
"module": "molecules/IconButton.js",
|
|
@@ -74,6 +98,23 @@
|
|
|
74
98
|
],
|
|
75
99
|
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
76
100
|
},
|
|
101
|
+
{
|
|
102
|
+
"tier": "molecule",
|
|
103
|
+
"module": "molecules/Link.js",
|
|
104
|
+
"exports": [
|
|
105
|
+
"Link"
|
|
106
|
+
],
|
|
107
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"tier": "molecule",
|
|
111
|
+
"module": "molecules/Select.js",
|
|
112
|
+
"exports": [
|
|
113
|
+
"OL8_SELECT_NATIVE_POLICIES",
|
|
114
|
+
"Select"
|
|
115
|
+
],
|
|
116
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
117
|
+
},
|
|
77
118
|
{
|
|
78
119
|
"tier": "molecule",
|
|
79
120
|
"module": "molecules/SelectionOption.js",
|
|
@@ -82,6 +123,24 @@
|
|
|
82
123
|
],
|
|
83
124
|
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
84
125
|
},
|
|
126
|
+
{
|
|
127
|
+
"tier": "molecule",
|
|
128
|
+
"module": "molecules/TextField.js",
|
|
129
|
+
"exports": [
|
|
130
|
+
"TextField",
|
|
131
|
+
"countGraphemes",
|
|
132
|
+
"clipToGraphemes"
|
|
133
|
+
],
|
|
134
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"tier": "molecule",
|
|
138
|
+
"module": "molecules/Token.js",
|
|
139
|
+
"exports": [
|
|
140
|
+
"Token"
|
|
141
|
+
],
|
|
142
|
+
"constraint": "Composed of atoms. Reusable and more specialised."
|
|
143
|
+
},
|
|
85
144
|
{
|
|
86
145
|
"tier": "organism",
|
|
87
146
|
"module": "organisms/ChoiceGroup.js",
|
|
@@ -90,6 +149,62 @@
|
|
|
90
149
|
"CheckboxGroup"
|
|
91
150
|
],
|
|
92
151
|
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"tier": "organism",
|
|
155
|
+
"module": "organisms/ChoicePicker.js",
|
|
156
|
+
"exports": [
|
|
157
|
+
"ChoicePicker"
|
|
158
|
+
],
|
|
159
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"tier": "organism",
|
|
163
|
+
"module": "organisms/Combobox.js",
|
|
164
|
+
"exports": [
|
|
165
|
+
"Combobox"
|
|
166
|
+
],
|
|
167
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"tier": "organism",
|
|
171
|
+
"module": "organisms/MultiSelectField.js",
|
|
172
|
+
"exports": [
|
|
173
|
+
"MultiSelectField"
|
|
174
|
+
],
|
|
175
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"tier": "organism",
|
|
179
|
+
"module": "organisms/SegmentedControl.js",
|
|
180
|
+
"exports": [
|
|
181
|
+
"SegmentedControl"
|
|
182
|
+
],
|
|
183
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"tier": "organism",
|
|
187
|
+
"module": "organisms/SelectionPopup.js",
|
|
188
|
+
"exports": [
|
|
189
|
+
"SelectionPopup"
|
|
190
|
+
],
|
|
191
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"tier": "organism",
|
|
195
|
+
"module": "organisms/TabBar.js",
|
|
196
|
+
"exports": [
|
|
197
|
+
"TabBar"
|
|
198
|
+
],
|
|
199
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"tier": "organism",
|
|
203
|
+
"module": "organisms/Tabs.js",
|
|
204
|
+
"exports": [
|
|
205
|
+
"Tabs"
|
|
206
|
+
],
|
|
207
|
+
"constraint": "Composed of atoms, molecules or organisms. May hold application state."
|
|
93
208
|
}
|
|
94
209
|
],
|
|
95
210
|
"buildingWhatIsNotHere": {
|
package/package.json
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oneli8/react",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.6",
|
|
4
4
|
"description": "OneLi8 Design System for React. Components, design tokens, the Gem material, and the design language they follow.",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"design-system",
|
|
8
|
+
"components",
|
|
9
|
+
"design-tokens",
|
|
10
|
+
"accessibility",
|
|
11
|
+
"atomic-design",
|
|
12
|
+
"oneli8"
|
|
13
|
+
],
|
|
6
14
|
"homepage": "https://github.com/Akshay007ad/OneLi8-Design-System#readme",
|
|
7
|
-
"bugs": {
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/Akshay007ad/OneLi8-Design-System/issues"
|
|
17
|
+
},
|
|
8
18
|
"repository": {
|
|
9
19
|
"type": "git",
|
|
10
20
|
"url": "git+https://github.com/Akshay007ad/OneLi8-Design-System.git",
|
|
@@ -14,7 +24,11 @@
|
|
|
14
24
|
"author": "Akshay Dhore",
|
|
15
25
|
"type": "module",
|
|
16
26
|
"exports": {
|
|
17
|
-
".": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./src/index.d.ts",
|
|
29
|
+
"import": "./src/index.js",
|
|
30
|
+
"default": "./src/index.js"
|
|
31
|
+
},
|
|
18
32
|
"./styles.css": "./styles.css",
|
|
19
33
|
"./styles/*.css": "./src/styles/*.css",
|
|
20
34
|
"./ai-context.json": "./ai-context.json",
|
|
@@ -22,7 +36,10 @@
|
|
|
22
36
|
"./package.json": "./package.json"
|
|
23
37
|
},
|
|
24
38
|
"types": "./src/index.d.ts",
|
|
25
|
-
"sideEffects": [
|
|
39
|
+
"sideEffects": [
|
|
40
|
+
"./styles.css",
|
|
41
|
+
"**/*.css"
|
|
42
|
+
],
|
|
26
43
|
"files": [
|
|
27
44
|
"src",
|
|
28
45
|
"styles.css",
|
|
@@ -35,11 +52,15 @@
|
|
|
35
52
|
"NOTICE"
|
|
36
53
|
],
|
|
37
54
|
"dependencies": {
|
|
38
|
-
"@oneli8/tokens": "1.0.0-beta.
|
|
55
|
+
"@oneli8/tokens": "1.0.0-beta.6"
|
|
39
56
|
},
|
|
40
57
|
"peerDependencies": {
|
|
41
58
|
"react": ">=18"
|
|
42
59
|
},
|
|
43
|
-
"engines": {
|
|
44
|
-
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": ">=20"
|
|
62
|
+
},
|
|
63
|
+
"publishConfig": {
|
|
64
|
+
"access": "public"
|
|
65
|
+
}
|
|
45
66
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createElement, forwardRef } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ATOM. Figma 989:484: "Content comes from item.badge; geometry and colors are
|
|
5
|
+
* semantic token controlled." One atom serves all three navigation organisms.
|
|
6
|
+
*
|
|
7
|
+
* The count sits beside a label that already names the destination, so it is
|
|
8
|
+
* not announced twice. A product that needs it announced spells it into the
|
|
9
|
+
* item's own accessible name.
|
|
10
|
+
*/
|
|
11
|
+
export const NavigationBadge = forwardRef(function NavigationBadge({ children, className = '', ...rest }, ref) {
|
|
12
|
+
if (children === undefined || children === null || children === '') {
|
|
13
|
+
throw new Error('[ol8] a navigation badge with nothing to say should not be rendered at all.');
|
|
14
|
+
}
|
|
15
|
+
return createElement('span', {
|
|
16
|
+
...rest, ref, 'aria-hidden': 'true',
|
|
17
|
+
className: `ol8-nav-badge${className ? ` ${className}` : ''}`,
|
|
18
|
+
}, children);
|
|
19
|
+
});
|
|
@@ -28,7 +28,78 @@ export const OL8_SELECTION_STATES = {
|
|
|
28
28
|
|
|
29
29
|
export const OL8_CHOICE_KINDS = OL8_SELECTION_KINDS;
|
|
30
30
|
export const OL8_CHOICE_SIZES = OL8_BUTTON_SIZES;
|
|
31
|
+
export const OL8_LINK_FORMS = ['inline', 'standalone', 'navigation'];
|
|
32
|
+
export const OL8_LINK_SIZES = ['small', 'standard', 'large'];
|
|
33
|
+
export const OL8_LINK_MOTIONS = ['system', 'none'];
|
|
34
|
+
|
|
35
|
+
export const OL8_TEXT_FIELD_SIZES = OL8_BUTTON_SIZES;
|
|
36
|
+
export const OL8_TEXT_FIELD_APPEARANCES = ['outline', 'filled'];
|
|
37
|
+
export const OL8_TEXT_FIELD_MATERIALS = OL8_MATERIALS;
|
|
38
|
+
/** The four tones a message can carry. Pending is not one of them. */
|
|
39
|
+
export const OL8_MESSAGE_TONES = ['critical', 'caution', 'positive', 'informative'];
|
|
40
|
+
/** "Pending is a validation process status, not a fifth message tone." */
|
|
41
|
+
export const OL8_VALIDATION_STATUSES = ['idle', 'pending', 'resolved'];
|
|
42
|
+
/** Soft lets a person overshoot and then correct. Hard is for real technical limits. */
|
|
43
|
+
export const OL8_CHARACTER_LIMIT_BEHAVIORS = ['soft', 'hard'];
|
|
44
|
+
|
|
45
|
+
/** Form Message itself draws all five, because Figma 177:13 enumerates five. */
|
|
46
|
+
export const OL8_FORM_MESSAGE_TONES = [...OL8_MESSAGE_TONES, 'pending'];
|
|
47
|
+
/** Figma pairs one status icon with each tone (Form Message 177:13). */
|
|
48
|
+
export const OL8_FORM_MESSAGE_ICONS = {
|
|
49
|
+
critical: 'critical',
|
|
50
|
+
caution: 'caution',
|
|
51
|
+
positive: 'positive',
|
|
52
|
+
informative: 'informative',
|
|
53
|
+
pending: 'loading',
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const OL8_NAVIGATION_SIZES = OL8_BUTTON_SIZES;
|
|
57
|
+
export const OL8_TABS_HIERARCHIES = ['primary', 'secondary', 'tertiary'];
|
|
58
|
+
export const OL8_TABS_ORIENTATIONS = ['horizontal', 'vertical'];
|
|
59
|
+
export const OL8_TABS_ACTIVATIONS = ['automatic', 'manual'];
|
|
60
|
+
/** "Declare exactly one behavior." */
|
|
61
|
+
export const OL8_SEGMENT_BEHAVIORS = ['single', 'multi', 'momentary'];
|
|
62
|
+
/** "Presentation never changes behavior." */
|
|
63
|
+
export const OL8_SEGMENT_PRESENTATIONS = [
|
|
64
|
+
'inset-fill', 'line-indicator', 'outlined-selection', 'soft-pill', 'icon-only', 'stacked-label',
|
|
65
|
+
];
|
|
66
|
+
export const OL8_TAB_BAR_PRESENTATIONS = ['bottom', 'inline', 'sidebar', 'spatial-rail'];
|
|
67
|
+
|
|
68
|
+
export const OL8_CHIP_SIZES = OL8_BUTTON_SIZES;
|
|
69
|
+
export const OL8_TOKEN_SIZES = OL8_CHIP_SIZES;
|
|
70
|
+
/** Figma draws the last three; `auto` resolves to one of them in code. */
|
|
71
|
+
export const OL8_TOKEN_MARKS = ['auto', 'none', 'check', 'remove'];
|
|
72
|
+
|
|
73
|
+
/** The contract's resolution, stated once so both packages agree. */
|
|
74
|
+
export function resolveTokenMark(mark, { removable = true, selected = false } = {}) {
|
|
75
|
+
if (mark !== 'auto') return mark;
|
|
76
|
+
if (removable) return 'remove';
|
|
77
|
+
return selected ? 'check' : 'none';
|
|
78
|
+
}
|
|
79
|
+
|
|
31
80
|
export const OL8_OPTION_SIZES = ['standard', 'large'];
|
|
81
|
+
export const OL8_POPUP_WIDTHS = ['content', 'anchor', 'wide'];
|
|
82
|
+
export const OL8_POPUP_SIZES = OL8_OPTION_SIZES;
|
|
83
|
+
export const OL8_MULTI_SELECT_SIZES = OL8_BUTTON_SIZES;
|
|
84
|
+
export const OL8_MULTI_SELECT_APPEARANCES = ['outline', 'filled'];
|
|
85
|
+
export const OL8_MULTI_SELECT_MATERIALS = OL8_MATERIALS;
|
|
86
|
+
/** Constrained resolves from a known set; suggestive may also author values. */
|
|
87
|
+
export const OL8_VALUE_POLICIES = ['constrained', 'suggestive'];
|
|
88
|
+
|
|
89
|
+
export const OL8_COMBOBOX_SIZES = OL8_BUTTON_SIZES;
|
|
90
|
+
export const OL8_COMBOBOX_APPEARANCES = ['outline', 'filled'];
|
|
91
|
+
export const OL8_COMBOBOX_MATERIALS = OL8_MATERIALS;
|
|
92
|
+
export const OL8_AUTOCOMPLETE_MODES = ['none', 'list-manual', 'list-automatic'];
|
|
93
|
+
export const OL8_FILTER_SOURCES = ['local', 'remote', 'external'];
|
|
94
|
+
|
|
95
|
+
export const OL8_PICKER_SIZES = OL8_BUTTON_SIZES;
|
|
96
|
+
export const OL8_PICKER_MATERIALS = OL8_MATERIALS;
|
|
97
|
+
export const OL8_COMMIT_BEHAVIORS = ['immediate', 'apply'];
|
|
98
|
+
export const OL8_PICKER_PRESENTATIONS = ['inline', 'popup'];
|
|
99
|
+
/** One treatment across an instance; peers never mix Check and None. */
|
|
100
|
+
export const OL8_PICKER_MARKS = ['check', 'none'];
|
|
101
|
+
|
|
102
|
+
export const OL8_POPUP_STATUSES = ['none', 'loading', 'empty', 'error'];
|
|
32
103
|
export const OL8_AGGREGATE = ['none', 'some', 'all'];
|
|
33
104
|
|
|
34
105
|
/** Compact and Standard take the 18px icon; Comfortable and Large take 24px. */
|
package/src/index.d.ts
CHANGED
|
@@ -15,6 +15,46 @@ export type Ol8Selection =
|
|
|
15
15
|
| 'unchecked' | 'checked' | 'mixed'
|
|
16
16
|
| 'unselected' | 'selected'
|
|
17
17
|
| 'off' | 'on';
|
|
18
|
+
export type Ol8LinkForm = 'inline' | 'standalone' | 'navigation';
|
|
19
|
+
export type Ol8LinkSize = 'small' | 'standard' | 'large';
|
|
20
|
+
export type Ol8LinkMotion = 'system' | 'none';
|
|
21
|
+
export declare const OL8_LINK_FORMS: readonly Ol8LinkForm[];
|
|
22
|
+
export declare const OL8_LINK_SIZES: readonly Ol8LinkSize[];
|
|
23
|
+
export declare const OL8_LINK_MOTIONS: readonly Ol8LinkMotion[];
|
|
24
|
+
|
|
25
|
+
export type Ol8TextFieldSize = 'compact' | 'standard' | 'comfortable' | 'large';
|
|
26
|
+
export type Ol8TextFieldAppearance = 'outline' | 'filled';
|
|
27
|
+
/** Pending is a validation process status, not a fifth message tone. */
|
|
28
|
+
export type Ol8MessageTone = 'critical' | 'caution' | 'positive' | 'informative';
|
|
29
|
+
export type Ol8ValidationStatus = 'idle' | 'pending' | 'resolved';
|
|
30
|
+
export type Ol8CharacterLimitBehavior = 'soft' | 'hard';
|
|
31
|
+
/** Form Message itself draws all five, because Figma 177:13 enumerates five. */
|
|
32
|
+
export type Ol8FormMessageTone = Ol8MessageTone | 'pending';
|
|
33
|
+
export declare const OL8_TEXT_FIELD_SIZES: readonly Ol8TextFieldSize[];
|
|
34
|
+
export declare const OL8_TEXT_FIELD_APPEARANCES: readonly Ol8TextFieldAppearance[];
|
|
35
|
+
export declare const OL8_TEXT_FIELD_MATERIALS: readonly Ol8Material[];
|
|
36
|
+
export declare const OL8_MESSAGE_TONES: readonly Ol8MessageTone[];
|
|
37
|
+
export declare const OL8_VALIDATION_STATUSES: readonly Ol8ValidationStatus[];
|
|
38
|
+
export declare const OL8_CHARACTER_LIMIT_BEHAVIORS: readonly Ol8CharacterLimitBehavior[];
|
|
39
|
+
export declare const OL8_FORM_MESSAGE_TONES: readonly Ol8FormMessageTone[];
|
|
40
|
+
export declare const OL8_FORM_MESSAGE_ICONS: Readonly<Record<Ol8FormMessageTone, string>>;
|
|
41
|
+
|
|
42
|
+
export type Ol8NavigationSize = 'compact' | 'standard' | 'comfortable' | 'large';
|
|
43
|
+
export type Ol8TabsHierarchy = 'primary' | 'secondary' | 'tertiary';
|
|
44
|
+
export type Ol8TabsOrientation = 'horizontal' | 'vertical';
|
|
45
|
+
export type Ol8TabsActivation = 'automatic' | 'manual';
|
|
46
|
+
export type Ol8SegmentBehavior = 'single' | 'multi' | 'momentary';
|
|
47
|
+
export type Ol8SegmentPresentation =
|
|
48
|
+
| 'inset-fill' | 'line-indicator' | 'outlined-selection'
|
|
49
|
+
| 'soft-pill' | 'icon-only' | 'stacked-label';
|
|
50
|
+
export type Ol8TabBarPresentation = 'bottom' | 'inline' | 'sidebar' | 'spatial-rail';
|
|
51
|
+
export declare const OL8_TABS_HIERARCHIES: readonly Ol8TabsHierarchy[];
|
|
52
|
+
export declare const OL8_TABS_ORIENTATIONS: readonly Ol8TabsOrientation[];
|
|
53
|
+
export declare const OL8_TABS_ACTIVATIONS: readonly Ol8TabsActivation[];
|
|
54
|
+
export declare const OL8_SEGMENT_BEHAVIORS: readonly Ol8SegmentBehavior[];
|
|
55
|
+
export declare const OL8_SEGMENT_PRESENTATIONS: readonly Ol8SegmentPresentation[];
|
|
56
|
+
export declare const OL8_TAB_BAR_PRESENTATIONS: readonly Ol8TabBarPresentation[];
|
|
57
|
+
|
|
18
58
|
export type Ol8OptionSize = 'standard' | 'large';
|
|
19
59
|
export type Ol8Aggregate = 'none' | 'some' | 'all';
|
|
20
60
|
|
|
@@ -113,6 +153,62 @@ export interface ChoiceItemProps extends Omit<ComponentPropsWithoutRef<'input'>,
|
|
|
113
153
|
}
|
|
114
154
|
export declare const ChoiceItem: ForwardRefExoticComponent<ChoiceItemProps & RefAttributes<HTMLInputElement>>;
|
|
115
155
|
|
|
156
|
+
/** MOLECULE. States are CSS, never props. Icons are intentionally parked. */
|
|
157
|
+
export interface LinkProps extends Omit<ComponentPropsWithoutRef<'a'>, 'href'> {
|
|
158
|
+
children?: ReactNode;
|
|
159
|
+
href: string;
|
|
160
|
+
form?: Ol8LinkForm;
|
|
161
|
+
size?: Ol8LinkSize;
|
|
162
|
+
/** Navigation only. `true` emits aria-current="page"; a string names the kind. */
|
|
163
|
+
current?: boolean | string;
|
|
164
|
+
motion?: Ol8LinkMotion;
|
|
165
|
+
}
|
|
166
|
+
export declare const Link: ForwardRefExoticComponent<LinkProps & RefAttributes<HTMLAnchorElement>>;
|
|
167
|
+
|
|
168
|
+
/** MOLECULE. Tone maps to semantic message tone; Pending is the validating state. */
|
|
169
|
+
export interface FormMessageProps extends ComponentPropsWithoutRef<'div'> {
|
|
170
|
+
children?: ReactNode;
|
|
171
|
+
tone?: Ol8FormMessageTone;
|
|
172
|
+
/** Figma's Show Icon. */
|
|
173
|
+
icon?: boolean;
|
|
174
|
+
}
|
|
175
|
+
export declare const FormMessage: ForwardRefExoticComponent<FormMessageProps & RefAttributes<HTMLDivElement>>;
|
|
176
|
+
|
|
177
|
+
/** MOLECULE. Conditions are CSS and native state, never props. Gem changes material only. */
|
|
178
|
+
export interface TextFieldProps extends Omit<ComponentPropsWithoutRef<'input'>, 'size' | 'prefix'> {
|
|
179
|
+
/** Required and visible. A placeholder is never the label. */
|
|
180
|
+
label: string;
|
|
181
|
+
/** Default Comfortable, the cross platform size. */
|
|
182
|
+
size?: Ol8TextFieldSize;
|
|
183
|
+
appearance?: Ol8TextFieldAppearance;
|
|
184
|
+
material?: Ol8Material;
|
|
185
|
+
/** False keeps the label as the accessible name without showing it, which needs a documented exception. */
|
|
186
|
+
showLabel?: boolean;
|
|
187
|
+
/** Correction is required. Never set without also exposing a Critical message. */
|
|
188
|
+
invalid?: boolean;
|
|
189
|
+
leadingIcon?: string;
|
|
190
|
+
prefix?: ReactNode;
|
|
191
|
+
suffix?: ReactNode;
|
|
192
|
+
trailingAction?: { icon: string; label: string; onClick?: () => void; pressed?: boolean };
|
|
193
|
+
instruction?: ReactNode;
|
|
194
|
+
message?: ReactNode;
|
|
195
|
+
messageTone?: Ol8MessageTone;
|
|
196
|
+
messageIcon?: boolean;
|
|
197
|
+
/** Pending shows the loader; it never freezes typing. */
|
|
198
|
+
validationStatus?: Ol8ValidationStatus;
|
|
199
|
+
/** Counted in graphemes, so an emoji counts as one. */
|
|
200
|
+
characterLimit?: number;
|
|
201
|
+
/** Soft lets a person overshoot and then correct. Hard is for real technical limits. */
|
|
202
|
+
characterLimitBehavior?: Ol8CharacterLimitBehavior;
|
|
203
|
+
}
|
|
204
|
+
export declare const TextField: ForwardRefExoticComponent<TextFieldProps & RefAttributes<HTMLInputElement>>;
|
|
205
|
+
|
|
206
|
+
/** Counts what a reader would call characters. */
|
|
207
|
+
export declare function countGraphemes(value: unknown): number;
|
|
208
|
+
|
|
209
|
+
/** Keeps the first `limit` graphemes, so a cluster is never cut in half. */
|
|
210
|
+
export declare function clipToGraphemes(value: unknown, limit: number): string;
|
|
211
|
+
|
|
116
212
|
/** MOLECULE. Never focusable; a listbox moves a virtual cursor instead. */
|
|
117
213
|
export interface SelectionOptionProps extends Omit<ComponentPropsWithoutRef<'li'>, 'children'> {
|
|
118
214
|
children?: ReactNode;
|
|
@@ -165,3 +261,121 @@ export interface CheckboxGroupProps extends Ol8GroupShell {
|
|
|
165
261
|
onChange?: (state: Record<string, boolean>) => void;
|
|
166
262
|
}
|
|
167
263
|
export declare function CheckboxGroup(props: CheckboxGroupProps): ReactElement;
|
|
264
|
+
|
|
265
|
+
/** ATOM. One badge serves all three navigation organisms. */
|
|
266
|
+
export interface NavigationBadgeProps extends ComponentPropsWithoutRef<'span'> {
|
|
267
|
+
children: ReactNode;
|
|
268
|
+
}
|
|
269
|
+
export declare const NavigationBadge: ForwardRefExoticComponent<NavigationBadgeProps & RefAttributes<HTMLSpanElement>>;
|
|
270
|
+
|
|
271
|
+
export interface Ol8TabItem {
|
|
272
|
+
/** Required: exactly one panel is paired with it. */
|
|
273
|
+
id: string;
|
|
274
|
+
label?: string;
|
|
275
|
+
icon?: string;
|
|
276
|
+
badge?: string | number;
|
|
277
|
+
disabled?: boolean;
|
|
278
|
+
/** Required when the item shows an icon and no label. */
|
|
279
|
+
ariaLabel?: string;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/** ORGANISM. Emits tablist, tab and tabpanel, and keeps one enabled tab stop. */
|
|
283
|
+
export interface TabsProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onChange'> {
|
|
284
|
+
/** Required. A region nobody can name is a region nobody can reach. */
|
|
285
|
+
label: string;
|
|
286
|
+
items: Ol8TabItem[];
|
|
287
|
+
value?: string;
|
|
288
|
+
defaultValue?: string;
|
|
289
|
+
onChange?: (id: string) => void;
|
|
290
|
+
hierarchy?: Ol8TabsHierarchy;
|
|
291
|
+
size?: Ol8NavigationSize;
|
|
292
|
+
material?: Ol8Material;
|
|
293
|
+
orientation?: Ol8TabsOrientation;
|
|
294
|
+
activation?: Ol8TabsActivation;
|
|
295
|
+
/** Supply it and Tabs renders the owned panel for each item. */
|
|
296
|
+
renderPanel?: (item: Ol8TabItem) => ReactNode;
|
|
297
|
+
}
|
|
298
|
+
export declare const Tabs: ForwardRefExoticComponent<TabsProps & RefAttributes<HTMLDivElement>>;
|
|
299
|
+
|
|
300
|
+
export interface Ol8SegmentItem {
|
|
301
|
+
id: string;
|
|
302
|
+
label?: string;
|
|
303
|
+
icon?: string;
|
|
304
|
+
badge?: string | number;
|
|
305
|
+
disabled?: boolean;
|
|
306
|
+
/** Required when the item shows an icon and no label. */
|
|
307
|
+
ariaLabel?: string;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** ORGANISM. Behaviour is declared, never inferred; presentation never changes it. */
|
|
311
|
+
export interface SegmentedControlProps extends Omit<ComponentPropsWithoutRef<'div'>, 'onChange' | 'defaultValue'> {
|
|
312
|
+
/** Required accessible name. */
|
|
313
|
+
label: string;
|
|
314
|
+
/** Exactly one: single is a radio group, multi is toggle buttons, momentary stores nothing. */
|
|
315
|
+
behavior: Ol8SegmentBehavior;
|
|
316
|
+
items: Ol8SegmentItem[];
|
|
317
|
+
/** One value for single, an array for multi, nothing for momentary. */
|
|
318
|
+
value?: string | string[];
|
|
319
|
+
defaultValue?: string | string[];
|
|
320
|
+
onChange?: (value: string | string[]) => void;
|
|
321
|
+
presentation?: Ol8SegmentPresentation;
|
|
322
|
+
size?: Ol8NavigationSize;
|
|
323
|
+
material?: Ol8Material;
|
|
324
|
+
}
|
|
325
|
+
export declare const SegmentedControl: ForwardRefExoticComponent<SegmentedControlProps & RefAttributes<HTMLDivElement>>;
|
|
326
|
+
|
|
327
|
+
export interface Ol8Destination {
|
|
328
|
+
/** Required. A tab bar navigates, so it uses real links. */
|
|
329
|
+
href: string;
|
|
330
|
+
label?: string;
|
|
331
|
+
icon?: string;
|
|
332
|
+
badge?: string | number;
|
|
333
|
+
/** Required when the destination shows an icon and no label. */
|
|
334
|
+
ariaLabel?: string;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** ORGANISM. Native destination links, one current destination, no disabled pseudo destinations. */
|
|
338
|
+
export interface TabBarProps extends ComponentPropsWithoutRef<'nav'> {
|
|
339
|
+
/** Required navigation name, so a person can tell one landmark from another. */
|
|
340
|
+
label: string;
|
|
341
|
+
items: Ol8Destination[];
|
|
342
|
+
/** The href of the destination a person is on. */
|
|
343
|
+
current?: string;
|
|
344
|
+
/** Routes an ordinary left click while the link stays a real link. */
|
|
345
|
+
onNavigate?: (href: string, event: MouseEvent) => void;
|
|
346
|
+
presentation?: Ol8TabBarPresentation;
|
|
347
|
+
size?: Ol8NavigationSize;
|
|
348
|
+
material?: Ol8Material;
|
|
349
|
+
}
|
|
350
|
+
export declare const TabBar: ForwardRefExoticComponent<TabBarProps & RefAttributes<HTMLElement>>;
|
|
351
|
+
|
|
352
|
+
export type Ol8SelectNativePolicy = 'preferred' | 'required' | 'custom-allowed';
|
|
353
|
+
export declare const OL8_SELECT_NATIVE_POLICIES: readonly Ol8SelectNativePolicy[];
|
|
354
|
+
|
|
355
|
+
export interface Ol8SelectOption {
|
|
356
|
+
value: string;
|
|
357
|
+
label: string;
|
|
358
|
+
disabled?: boolean;
|
|
359
|
+
group?: string;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/** MOLECULE. Native first: a real select, wearing the Text Field geometry Figma reuses. */
|
|
363
|
+
export interface SelectProps extends Omit<ComponentPropsWithoutRef<'select'>, 'size'> {
|
|
364
|
+
/** Required and visible. A placeholder is never the label. */
|
|
365
|
+
label: string;
|
|
366
|
+
options: Ol8SelectOption[];
|
|
367
|
+
size?: Ol8TextFieldSize;
|
|
368
|
+
appearance?: Ol8TextFieldAppearance;
|
|
369
|
+
material?: Ol8Material;
|
|
370
|
+
showLabel?: boolean;
|
|
371
|
+
invalid?: boolean;
|
|
372
|
+
/** Only when an unselected value is valid, or required validation needs a prompt. */
|
|
373
|
+
placeholderOption?: string;
|
|
374
|
+
leadingIcon?: string;
|
|
375
|
+
instruction?: ReactNode;
|
|
376
|
+
message?: ReactNode;
|
|
377
|
+
messageTone?: Ol8MessageTone;
|
|
378
|
+
/** 'custom-allowed' is refused: use Combobox, which implements the full contract. */
|
|
379
|
+
native?: Ol8SelectNativePolicy;
|
|
380
|
+
}
|
|
381
|
+
export declare const Select: ForwardRefExoticComponent<SelectProps & RefAttributes<HTMLSelectElement>>;
|
package/src/index.js
CHANGED
|
@@ -2,8 +2,22 @@ export { Icon } from './atoms/Icon.js';
|
|
|
2
2
|
export { SelectionIndicator } from './atoms/SelectionIndicator.js';
|
|
3
3
|
export { Button } from './molecules/Button.js';
|
|
4
4
|
export { IconButton } from './molecules/IconButton.js';
|
|
5
|
+
export { Link } from './molecules/Link.js';
|
|
5
6
|
export { ChoiceItem } from './molecules/ChoiceItem.js';
|
|
6
7
|
export { SelectionOption } from './molecules/SelectionOption.js';
|
|
8
|
+
export { FormMessage } from './molecules/FormMessage.js';
|
|
9
|
+
export { TextField, countGraphemes, clipToGraphemes } from './molecules/TextField.js';
|
|
10
|
+
export { Select, OL8_SELECT_NATIVE_POLICIES } from './molecules/Select.js';
|
|
11
|
+
export { ChoiceChip } from './molecules/ChoiceChip.js';
|
|
12
|
+
export { Token } from './molecules/Token.js';
|
|
7
13
|
export { RadioGroup, CheckboxGroup } from './organisms/ChoiceGroup.js';
|
|
14
|
+
export { SelectionPopup } from './organisms/SelectionPopup.js';
|
|
15
|
+
export { MultiSelectField } from './organisms/MultiSelectField.js';
|
|
16
|
+
export { ChoicePicker } from './organisms/ChoicePicker.js';
|
|
17
|
+
export { Combobox } from './organisms/Combobox.js';
|
|
18
|
+
export { NavigationBadge } from './atoms/NavigationBadge.js';
|
|
19
|
+
export { Tabs } from './organisms/Tabs.js';
|
|
20
|
+
export { SegmentedControl } from './organisms/SegmentedControl.js';
|
|
21
|
+
export { TabBar } from './organisms/TabBar.js';
|
|
8
22
|
export * from './foundations/geometry.js';
|
|
9
23
|
export { OL8_ICONS, OL8_ICON_VIEWBOX } from './foundations/icons.generated.js';
|