@oneli8/react 1.0.0-beta.10
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/AGENTS.md +16 -0
- package/LICENSE +202 -0
- package/NOTICE +8 -0
- package/PRINCIPLES.md +48 -0
- package/README.md +136 -0
- package/ai-context.json +264 -0
- package/package.json +66 -0
- package/skills/oneli8-figma-to-code/SKILL.md +25 -0
- package/skills/oneli8-icons/SKILL.md +36 -0
- package/skills/oneli8-ui/SKILL.md +52 -0
- package/src/atoms/Icon.js +34 -0
- package/src/atoms/NavigationBadge.js +19 -0
- package/src/atoms/SelectionIndicator.js +43 -0
- package/src/foundations/geometry.js +143 -0
- package/src/foundations/icons.generated.d.ts +48 -0
- package/src/foundations/icons.generated.js +562 -0
- package/src/index.d.ts +381 -0
- package/src/index.js +23 -0
- package/src/molecules/Button.js +50 -0
- package/src/molecules/ChoiceChip.js +101 -0
- package/src/molecules/ChoiceItem.js +55 -0
- package/src/molecules/FormMessage.js +33 -0
- package/src/molecules/IconButton.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 +44 -0
- package/src/molecules/TextField.js +174 -0
- package/src/molecules/Token.js +49 -0
- package/src/organisms/ChoiceGroup.js +78 -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/button.css +195 -0
- package/src/styles/choice-chip.css +216 -0
- package/src/styles/choice-group.css +95 -0
- package/src/styles/choice-item.css +267 -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 +376 -0
- package/src/styles/icon-button.css +224 -0
- package/src/styles/icon.css +56 -0
- 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 +162 -0
- package/src/styles/selection-option.css +123 -0
- 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 +29 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/* GENERATED from packages/core/src/molecules/choice-item/choice-item.css by packages/sync/src/build-styles.mjs — do not edit.
|
|
2
|
+
Edit the source in packages/core/src and re-run `npm run sync:styles`. */
|
|
3
|
+
/**
|
|
4
|
+
* Oneli8 · Choice Item (MOLECULE)
|
|
5
|
+
* Figma: Documentation / Molecule / Choice Item
|
|
6
|
+
* Checkbox 252:301 (24 variants) · Radio 331:1309 (16) · Switch 825:1591 (16)
|
|
7
|
+
*
|
|
8
|
+
* From the Figma description (252:301):
|
|
9
|
+
* "Selection maps Unchecked/Checked/Mixed to checked/indeterminate;
|
|
10
|
+
* Availability maps enabled/disabled ... The indicator is a shared
|
|
11
|
+
* selection atom, not local artwork. Native input, name/value, required,
|
|
12
|
+
* reset, form submission, and onCheckedChange live in code."
|
|
13
|
+
*
|
|
14
|
+
* So the molecule is: a real <input>, the selection-indicator atom, a label,
|
|
15
|
+
* an optional description — and NOTHING that duplicates native behaviour.
|
|
16
|
+
*
|
|
17
|
+
* ANATOMY (Figma 266:257 / 252:74 / 252:77)
|
|
18
|
+
* <label class=ol8-choice> the whole row is the target
|
|
19
|
+
* input visually hidden, still focusable
|
|
20
|
+
* __surface hover / pressed / gem wash, bleeds 9px inline
|
|
21
|
+
* __indicator slot: indicator wide, label-line tall
|
|
22
|
+
* __content label + optional description
|
|
23
|
+
*
|
|
24
|
+
* ROW GEOMETRY — every size resolves to the same 48px minimum row:
|
|
25
|
+
* size gap indicator slot h label padding-block
|
|
26
|
+
* compact 6 18 18 Body/Small 15
|
|
27
|
+
* standard 9 18 24 Body/Medium 12
|
|
28
|
+
* comfortable 9 24 24 Body/Medium 12
|
|
29
|
+
* large 9 24 30 Body/Large 9
|
|
30
|
+
* padding-block is derived: (48 - slot height) / 2.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
.ol8-choice {
|
|
34
|
+
--_gap: var(--ol8-component-choice-gap-standard);
|
|
35
|
+
--_slot-h: var(--ol8-font-line-024);
|
|
36
|
+
--_pad: calc((var(--ol8-component-choice-rowminimum) - var(--_slot-h)) / 2);
|
|
37
|
+
--_label-size: var(--ol8-font-size-016);
|
|
38
|
+
--_label-line: var(--ol8-font-line-024);
|
|
39
|
+
--_indicator: var(--ol8-size-icon-small);
|
|
40
|
+
/* The hover / pressed / focus wash bleeds outside the text column. */
|
|
41
|
+
--_bleed: var(--ol8-dimension-scale-009);
|
|
42
|
+
|
|
43
|
+
box-sizing: border-box;
|
|
44
|
+
position: relative;
|
|
45
|
+
display: flex;
|
|
46
|
+
align-items: flex-start;
|
|
47
|
+
gap: var(--_gap);
|
|
48
|
+
min-block-size: var(--ol8-component-choice-rowminimum);
|
|
49
|
+
padding-block: var(--_pad);
|
|
50
|
+
font-family: var(--ol8-font-family-functional);
|
|
51
|
+
font-variation-settings: "ARRR" var(--ol8-font-axis-arrr-baseline);
|
|
52
|
+
cursor: pointer;
|
|
53
|
+
}
|
|
54
|
+
.ol8-choice[data-ol8-availability="disabled"] { cursor: not-allowed; }
|
|
55
|
+
|
|
56
|
+
/* ---- Size ------------------------------------------------------------ */
|
|
57
|
+
.ol8-choice[data-ol8-size="compact"] {
|
|
58
|
+
--_gap: var(--ol8-component-choice-gap-compact);
|
|
59
|
+
--_slot-h: var(--ol8-font-line-018);
|
|
60
|
+
--_label-size: var(--ol8-font-size-012);
|
|
61
|
+
--_label-line: var(--ol8-font-line-018);
|
|
62
|
+
--_indicator: var(--ol8-size-icon-small);
|
|
63
|
+
}
|
|
64
|
+
.ol8-choice[data-ol8-size="standard"] {
|
|
65
|
+
--_slot-h: var(--ol8-font-line-024);
|
|
66
|
+
--_label-size: var(--ol8-font-size-016);
|
|
67
|
+
--_label-line: var(--ol8-font-line-024);
|
|
68
|
+
--_indicator: var(--ol8-size-icon-small);
|
|
69
|
+
}
|
|
70
|
+
.ol8-choice[data-ol8-size="comfortable"] {
|
|
71
|
+
--_slot-h: var(--ol8-font-line-024);
|
|
72
|
+
--_label-size: var(--ol8-font-size-016);
|
|
73
|
+
--_label-line: var(--ol8-font-line-024);
|
|
74
|
+
--_indicator: var(--ol8-size-icon-standard);
|
|
75
|
+
}
|
|
76
|
+
.ol8-choice[data-ol8-size="large"] {
|
|
77
|
+
--_slot-h: var(--ol8-font-line-030);
|
|
78
|
+
--_label-size: var(--ol8-font-size-021);
|
|
79
|
+
--_label-line: var(--ol8-font-line-030);
|
|
80
|
+
--_indicator: var(--ol8-size-icon-standard);
|
|
81
|
+
}
|
|
82
|
+
/* Compact's label carries the Body/Small tracking. */
|
|
83
|
+
.ol8-choice[data-ol8-size="compact"] .ol8-choice__label { letter-spacing: 1px; }
|
|
84
|
+
|
|
85
|
+
/* ---- The native input owns everything semantic ----------------------- */
|
|
86
|
+
.ol8-choice__input {
|
|
87
|
+
position: absolute;
|
|
88
|
+
inline-size: 1px;
|
|
89
|
+
block-size: 1px;
|
|
90
|
+
opacity: 0;
|
|
91
|
+
pointer-events: none;
|
|
92
|
+
/* No margin reset needed — it is absolutely positioned, so margin cannot
|
|
93
|
+
affect layout. The structure lint would reject one regardless. */
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* ---- Wash: hover, pressed, focus, gem -------------------------------- */
|
|
97
|
+
.ol8-choice__surface {
|
|
98
|
+
position: absolute;
|
|
99
|
+
inset-block: 0;
|
|
100
|
+
inset-inline: calc(-1 * var(--_bleed));
|
|
101
|
+
border-radius: var(--ol8-shape-radius-medium);
|
|
102
|
+
pointer-events: none;
|
|
103
|
+
}
|
|
104
|
+
.ol8-choice:hover:not([data-ol8-availability="disabled"]) > .ol8-choice__surface,
|
|
105
|
+
.ol8-choice:active:not([data-ol8-availability="disabled"]) > .ol8-choice__surface {
|
|
106
|
+
background: var(--ol8-color-selection-surface);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* Two nested rings, both visible — outer 3px, inner 3px at a 2px inset.
|
|
110
|
+
This is the same two-tone ring the Icon Button focus tokens describe. */
|
|
111
|
+
.ol8-choice:has(> .ol8-choice__input:focus-visible) > .ol8-choice__surface {
|
|
112
|
+
border: var(--ol8-focus-ring-outerwidth) solid var(--ol8-color-focus-outer);
|
|
113
|
+
}
|
|
114
|
+
.ol8-choice:has(> .ol8-choice__input:focus-visible) > .ol8-choice__surface::after {
|
|
115
|
+
content: "";
|
|
116
|
+
position: absolute;
|
|
117
|
+
inset: 2px;
|
|
118
|
+
border: var(--ol8-focus-ring-innerwidth) solid var(--ol8-color-focus-inner);
|
|
119
|
+
border-radius: 7px;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* ---- Indicator slot -------------------------------------------------- */
|
|
123
|
+
.ol8-choice__indicator {
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
justify-content: center;
|
|
127
|
+
position: relative;
|
|
128
|
+
flex: none;
|
|
129
|
+
inline-size: var(--_indicator);
|
|
130
|
+
block-size: var(--_slot-h);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* Invalid draws an extra boundary over the indicator, same shape. */
|
|
134
|
+
.ol8-choice[data-ol8-invalid="true"] .ol8-choice__indicator::after {
|
|
135
|
+
content: "";
|
|
136
|
+
position: absolute;
|
|
137
|
+
inline-size: var(--_indicator);
|
|
138
|
+
block-size: var(--_indicator);
|
|
139
|
+
border: var(--ol8-component-checkbox-boundary) solid var(--ol8-color-feedbackcritical-inlinecontent);
|
|
140
|
+
border-radius: var(--ol8-component-checkbox-radius-compact);
|
|
141
|
+
pointer-events: none;
|
|
142
|
+
}
|
|
143
|
+
.ol8-choice[data-ol8-size="comfortable"][data-ol8-invalid="true"] .ol8-choice__indicator::after,
|
|
144
|
+
.ol8-choice[data-ol8-size="large"][data-ol8-invalid="true"] .ol8-choice__indicator::after {
|
|
145
|
+
border-radius: var(--ol8-component-checkbox-radius-comfortable);
|
|
146
|
+
}
|
|
147
|
+
.ol8-choice--radio[data-ol8-invalid="true"] .ol8-choice__indicator::after {
|
|
148
|
+
border-radius: var(--ol8-shape-radius-full);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* ---- Content --------------------------------------------------------- */
|
|
152
|
+
.ol8-choice__content {
|
|
153
|
+
display: flex;
|
|
154
|
+
flex-direction: column;
|
|
155
|
+
gap: var(--ol8-dimension-scale-003);
|
|
156
|
+
flex: 1 0 0;
|
|
157
|
+
min-inline-size: 0;
|
|
158
|
+
position: relative;
|
|
159
|
+
}
|
|
160
|
+
.ol8-choice__label {
|
|
161
|
+
font-size: var(--_label-size);
|
|
162
|
+
line-height: var(--_label-line);
|
|
163
|
+
font-weight: var(--ol8-font-weight-regular);
|
|
164
|
+
color: var(--ol8-color-text-primary);
|
|
165
|
+
overflow-wrap: break-word;
|
|
166
|
+
}
|
|
167
|
+
.ol8-choice__description {
|
|
168
|
+
font-size: var(--ol8-font-size-012);
|
|
169
|
+
line-height: var(--ol8-font-line-018);
|
|
170
|
+
letter-spacing: 0.12px;
|
|
171
|
+
color: var(--ol8-color-text-secondary);
|
|
172
|
+
overflow-wrap: break-word;
|
|
173
|
+
}
|
|
174
|
+
.ol8-choice[data-ol8-availability="disabled"] .ol8-choice__label,
|
|
175
|
+
.ol8-choice[data-ol8-availability="disabled"] .ol8-choice__description {
|
|
176
|
+
color: var(--ol8-color-text-disabled);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* ---- Gem material ----------------------------------------------------
|
|
180
|
+
"Gem is one Boolean material adapter over the same anatomy; Regular
|
|
181
|
+
remains the default." A wash on the row, not a different component. */
|
|
182
|
+
.ol8-choice[data-ol8-material="gem"] > .ol8-choice__surface {
|
|
183
|
+
background: var(--ol8-material-gem-color-quiet-environmentalface);
|
|
184
|
+
border: 1px solid var(--ol8-material-gem-color-cutedge-high);
|
|
185
|
+
border-radius: var(--ol8-shape-radius-standard);
|
|
186
|
+
inset-inline: 0;
|
|
187
|
+
}
|
|
188
|
+
/* The quiet face is clear glass — near-white at 0.18/0.27, not a dark tint —
|
|
189
|
+
so it cannot guarantee what sits behind it at all. Content on it therefore
|
|
190
|
+
takes the stable near-white gem ink rather than body text, and carries its
|
|
191
|
+
own halo, which is the only thing standing between the label and whatever
|
|
192
|
+
the environment happens to be. Unlike the gem text field, the label and
|
|
193
|
+
description here really are on the face: .ol8-choice__surface spans the row
|
|
194
|
+
beneath them. Disabled is excluded — it resolves to the opaque equivalent,
|
|
195
|
+
where the regular disabled ink applies and no halo is wanted. */
|
|
196
|
+
/* ONE GLOW, TWO SYNTAXES.
|
|
197
|
+
Content on Gem means ALL content — glyphs and control geometry alike. Text
|
|
198
|
+
takes the halo through text-shadow; an SVG stroke cannot, so the indicator
|
|
199
|
+
takes the identical halo through chained drop-shadow filters. Both are built
|
|
200
|
+
from the same two tokens and the same four repetitions, which is what makes
|
|
201
|
+
the label's glow and the checkbox's glow read as one field rather than two
|
|
202
|
+
near-misses. Change the radius or the colour and both follow. */
|
|
203
|
+
.ol8-choice[data-ol8-material="gem"] {
|
|
204
|
+
--_gem-glow: 0 0 var(--ol8-material-gem-blur-contentglow)
|
|
205
|
+
var(--ol8-material-gem-color-quiet-contentglow);
|
|
206
|
+
/* Control geometry takes one stack FEWER than text, on purpose. WCAG 1.4.11
|
|
207
|
+
asks 3:1 of a graphical object where 1.4.3 asks 4.5:1 of text, so the
|
|
208
|
+
boundary does not need the fourth repetition — and leaving it off is what
|
|
209
|
+
keeps the indicator blended into the glass instead of ringed. Measured at
|
|
210
|
+
3px: text in four stacks is 5.06:1, the boundary in three is 3.75:1. */
|
|
211
|
+
--_gem-glow-filter:
|
|
212
|
+
drop-shadow(var(--_gem-glow)) drop-shadow(var(--_gem-glow))
|
|
213
|
+
drop-shadow(var(--_gem-glow));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* DISABLED ON GEM IS ONE GREY, SHARED.
|
|
217
|
+
color.text.disabled is dark in the Light appearance, so a disabled row on
|
|
218
|
+
glass whose enabled content is near-white ended up with a dark label beside
|
|
219
|
+
a dark box — it read broken rather than unavailable. On Gem, disabled text
|
|
220
|
+
and disabled control geometry take the SAME whitish grey, and neither takes
|
|
221
|
+
the halo: the absence of the glow is part of how unavailable reads.
|
|
222
|
+
Disabled content is exempt from 1.4.3, which excludes inactive controls. */
|
|
223
|
+
.ol8-choice[data-ol8-material="gem"][data-ol8-availability="disabled"] .ol8-choice__label,
|
|
224
|
+
.ol8-choice[data-ol8-material="gem"][data-ol8-availability="disabled"] .ol8-choice__description {
|
|
225
|
+
color: var(--ol8-material-gem-color-quiet-contentdisabled);
|
|
226
|
+
text-shadow: none;
|
|
227
|
+
}
|
|
228
|
+
.ol8-choice[data-ol8-material="gem"][data-ol8-availability="disabled"] .ol8-selection {
|
|
229
|
+
--_edge: var(--ol8-material-gem-color-quiet-contentdisabled);
|
|
230
|
+
--_ink: var(--ol8-material-gem-color-quiet-contentdisabled);
|
|
231
|
+
filter: none;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* The unselected control boundary is content, not chrome. It was
|
|
235
|
+
color.border.strong, which is dark in the Light appearance and left the
|
|
236
|
+
checkbox reading as a dark hole in a surface whose text had gone near-white.
|
|
237
|
+
On Gem it takes the same ink as the label. Selected and mixed are untouched:
|
|
238
|
+
those fill with the primary action family and carry their own white mark,
|
|
239
|
+
which already reads on glass. */
|
|
240
|
+
.ol8-choice[data-ol8-material="gem"]:not([data-ol8-availability="disabled"]) .ol8-selection {
|
|
241
|
+
--_edge: var(--ol8-material-gem-color-quiet-content);
|
|
242
|
+
filter: var(--_gem-glow-filter);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/* Any iconography sitting on the face takes the token that already exists for
|
|
246
|
+
exactly this and is already stable across appearances. */
|
|
247
|
+
.ol8-choice[data-ol8-material="gem"]:not([data-ol8-availability="disabled"]) .ol8-icon {
|
|
248
|
+
color: var(--ol8-color-icon-on-gem);
|
|
249
|
+
filter: var(--_gem-glow-filter);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.ol8-choice[data-ol8-material="gem"]:not([data-ol8-availability="disabled"]) .ol8-choice__label,
|
|
253
|
+
.ol8-choice[data-ol8-material="gem"]:not([data-ol8-availability="disabled"]) .ol8-choice__description {
|
|
254
|
+
color: var(--ol8-material-gem-color-quiet-content);
|
|
255
|
+
/* Stacked three times on purpose. A single shadow at this radius reaches
|
|
256
|
+
only 1.71:1 against near-white ink on a bright plate, and widening the
|
|
257
|
+
radius makes it WEAKER because blur spreads a fixed alpha budget over more
|
|
258
|
+
area. Repeating the same shadow accumulates alpha instead of spreading it:
|
|
259
|
+
1 - (1 - a)^4. Measured in proof/gem-halo-contrast.html. */
|
|
260
|
+
text-shadow: var(--_gem-glow), var(--_gem-glow),
|
|
261
|
+
var(--_gem-glow), var(--_gem-glow);
|
|
262
|
+
}
|
|
263
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
264
|
+
.ol8-choice[data-ol8-material="gem"] > .ol8-choice__surface {
|
|
265
|
+
background: var(--ol8-material-gem-color-quiet-opaqueequivalent);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* GENERATED from packages/core/src/organisms/choice-picker/choice-picker.css by packages/sync/src/build-styles.mjs — do not edit.
|
|
2
|
+
Edit the source in packages/core/src and re-run `npm run sync:styles`. */
|
|
3
|
+
/**
|
|
4
|
+
* Oneli8 · Choice Picker (ORGANISM)
|
|
5
|
+
* Figma: Organism / Choice Picker / Soft Hexagon 906:2898 (16 variants)
|
|
6
|
+
*
|
|
7
|
+
* Three parts stacked twelve apart: a search field, a wrapping matrix of chips,
|
|
8
|
+
* and in Apply mode a commitment line. The search field is the canonical Text
|
|
9
|
+
* Field owner and the chips are the canonical Choice Chip owner, so neither is
|
|
10
|
+
* restyled here.
|
|
11
|
+
*
|
|
12
|
+
* Read from all four sizes in Figma: the root gap, the matrix gap and the
|
|
13
|
+
* commitment typography do NOT scale with the picker size. They are twelve,
|
|
14
|
+
* six, and 12/18 at Compact, Standard, Comfortable and Large alike. Only the
|
|
15
|
+
* search field and the chips take the size.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
.ol8-picker {
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
gap: var(--ol8-spacing-stack-related);
|
|
22
|
+
inline-size: 100%;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* "The matrix wraps with 6px gaps and preserves source/reading order; it is not
|
|
26
|
+
a masonry layout." A plain wrapping flex row is exactly that. */
|
|
27
|
+
.ol8-picker__matrix {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-wrap: wrap;
|
|
30
|
+
gap: var(--ol8-component-choice-chip-gap);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* Figma: HORIZONTAL, space between, 24 tall, both texts secondary at 12/18. */
|
|
34
|
+
.ol8-picker__commitment {
|
|
35
|
+
display: flex;
|
|
36
|
+
align-items: flex-start;
|
|
37
|
+
justify-content: space-between;
|
|
38
|
+
gap: var(--ol8-spacing-inline-standard);
|
|
39
|
+
min-block-size: var(--ol8-size-icon-standard);
|
|
40
|
+
font-size: var(--ol8-font-size-012);
|
|
41
|
+
line-height: var(--ol8-font-line-018);
|
|
42
|
+
color: var(--ol8-color-text-secondary);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.ol8-picker__summary {
|
|
46
|
+
font-family: var(--ol8-font-family-functional);
|
|
47
|
+
color: inherit;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Clear all and the apply hint are text weight actions rather than Button
|
|
51
|
+
instances. The contract asks for Clear all to be quiet, and Figma's row is
|
|
52
|
+
twenty four tall, which a Button's protected forty eight target would break.
|
|
53
|
+
They are still real buttons, so they are reachable and announced. */
|
|
54
|
+
.ol8-picker__apply,
|
|
55
|
+
.ol8-picker__clear {
|
|
56
|
+
padding: 0;
|
|
57
|
+
border: 0;
|
|
58
|
+
background: none;
|
|
59
|
+
font-family: var(--ol8-font-family-functional);
|
|
60
|
+
font-size: inherit;
|
|
61
|
+
line-height: inherit;
|
|
62
|
+
color: var(--ol8-color-actionquiet-contentdefault);
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
}
|
|
65
|
+
.ol8-picker__apply:hover,
|
|
66
|
+
.ol8-picker__clear:hover {
|
|
67
|
+
color: var(--ol8-color-actionquiet-contenthover);
|
|
68
|
+
text-decoration: underline;
|
|
69
|
+
}
|
|
70
|
+
.ol8-picker__apply:focus-visible,
|
|
71
|
+
.ol8-picker__clear:focus-visible {
|
|
72
|
+
outline: var(--ol8-focus-ring-innerwidth) solid var(--ol8-color-focus-inner);
|
|
73
|
+
outline-offset: var(--ol8-focus-ring-offset);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.ol8-picker[data-ol8-availability="disabled"] .ol8-picker__apply,
|
|
77
|
+
.ol8-picker[data-ol8-availability="disabled"] .ol8-picker__clear {
|
|
78
|
+
color: var(--ol8-color-actionquiet-contentdisabled);
|
|
79
|
+
cursor: not-allowed;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* The search label stays associated while the composition hides it. */
|
|
83
|
+
.ol8-picker__label-row--hidden {
|
|
84
|
+
position: absolute;
|
|
85
|
+
inline-size: 1px;
|
|
86
|
+
block-size: 1px;
|
|
87
|
+
overflow: hidden;
|
|
88
|
+
clip-path: inset(50%);
|
|
89
|
+
white-space: nowrap;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Retrieval and result counts are announced rather than only drawn. */
|
|
93
|
+
.ol8-picker__status {
|
|
94
|
+
position: absolute;
|
|
95
|
+
inline-size: 1px;
|
|
96
|
+
block-size: 1px;
|
|
97
|
+
overflow: hidden;
|
|
98
|
+
clip-path: inset(50%);
|
|
99
|
+
white-space: nowrap;
|
|
100
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/* GENERATED from packages/core/src/organisms/combobox/combobox.css by packages/sync/src/build-styles.mjs — do not edit.
|
|
2
|
+
Edit the source in packages/core/src and re-run `npm run sync:styles`. */
|
|
3
|
+
/**
|
|
4
|
+
* Oneli8 · Combobox (ORGANISM)
|
|
5
|
+
* Figma: Organism / Combobox 883:2159 — "Reuses approved Text Field, Selection
|
|
6
|
+
* Popup and governed icon atoms."
|
|
7
|
+
*
|
|
8
|
+
* So the field geometry is the field's, the popup is the popup's, and this
|
|
9
|
+
* file adds only what belongs to the combination: where the popup sits, and
|
|
10
|
+
* the two marks at the trailing edge.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
.ol8-combobox { position: relative; }
|
|
14
|
+
|
|
15
|
+
/* "Closed control to popup block gap" is a token, so the popup sits where the
|
|
16
|
+
design says rather than wherever absolute positioning lands it. */
|
|
17
|
+
.ol8-combobox__popup {
|
|
18
|
+
position: absolute;
|
|
19
|
+
z-index: 1;
|
|
20
|
+
inset-inline: 0;
|
|
21
|
+
inset-block-start: calc(100% + var(--ol8-component-selectionpopup-gap));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.ol8-combobox__disclosure {
|
|
25
|
+
flex: none;
|
|
26
|
+
display: inline-flex;
|
|
27
|
+
color: var(--ol8-color-icon-secondary);
|
|
28
|
+
cursor: pointer;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.ol8-combobox__clear {
|
|
32
|
+
flex: none;
|
|
33
|
+
display: inline-flex;
|
|
34
|
+
border: 0;
|
|
35
|
+
padding: 0;
|
|
36
|
+
background: none;
|
|
37
|
+
color: var(--ol8-color-icon-secondary);
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
}
|
|
40
|
+
.ol8-combobox__clear:disabled { color: var(--ol8-color-icon-disabled); cursor: not-allowed; }
|
|
41
|
+
|
|
42
|
+
.ol8-combobox[data-ol8-disabled] .ol8-combobox__disclosure { color: var(--ol8-color-icon-disabled); cursor: not-allowed; }
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/* GENERATED from packages/core/src/molecules/form-message/form-message.css by packages/sync/src/build-styles.mjs — do not edit.
|
|
2
|
+
Edit the source in packages/core/src and re-run `npm run sync:styles`. */
|
|
3
|
+
/**
|
|
4
|
+
* Oneli8 · Form Message (MOLECULE)
|
|
5
|
+
* Figma: Form Message 177:13, five tones.
|
|
6
|
+
*
|
|
7
|
+
* Anatomy read from Figma: a horizontal row, gap Component / Text Field / Gap /
|
|
8
|
+
* Status, items centred, one Small status icon beside twelve over eighteen
|
|
9
|
+
* regular text. Tone changes exactly one thing, the inline content colour,
|
|
10
|
+
* which both the icon stroke and the text take.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
.ol8-form-message {
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
gap: var(--ol8-component-textfield-gap-status);
|
|
17
|
+
color: var(--_tone);
|
|
18
|
+
font-family: var(--ol8-font-family-functional);
|
|
19
|
+
font-size: var(--ol8-font-size-012);
|
|
20
|
+
font-weight: var(--ol8-font-weight-regular);
|
|
21
|
+
line-height: var(--ol8-font-line-018);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.ol8-form-message__icon { flex: none; color: var(--_tone); }
|
|
25
|
+
|
|
26
|
+
/* ---- Tone ------------------------------------------------------------- */
|
|
27
|
+
.ol8-form-message[data-ol8-tone="critical"] { --_tone: var(--ol8-color-feedbackcritical-inlinecontent); }
|
|
28
|
+
.ol8-form-message[data-ol8-tone="caution"] { --_tone: var(--ol8-color-feedbackcaution-inlinecontent); }
|
|
29
|
+
.ol8-form-message[data-ol8-tone="positive"] { --_tone: var(--ol8-color-feedbackpositive-inlinecontent); }
|
|
30
|
+
.ol8-form-message[data-ol8-tone="informative"] { --_tone: var(--ol8-color-feedbackinformative-inlinecontent); }
|
|
31
|
+
|
|
32
|
+
/* Pending reads as informative text, and Figma gives its loading mark the
|
|
33
|
+
primary icon colour rather than a feedback colour, because nothing has been
|
|
34
|
+
decided yet. */
|
|
35
|
+
.ol8-form-message[data-ol8-tone="pending"] {
|
|
36
|
+
--_tone: var(--ol8-color-feedbackinformative-inlinecontent);
|
|
37
|
+
}
|
|
38
|
+
.ol8-form-message[data-ol8-tone="pending"] .ol8-form-message__icon {
|
|
39
|
+
color: var(--ol8-color-icon-primary);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Same treatment the Button gives its busy mark: rotation is opt in and motion
|
|
43
|
+
guarded, and Reduced Motion keeps the static mark. */
|
|
44
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
45
|
+
.ol8-form-message[data-ol8-tone="pending"] .ol8-form-message__icon > svg {
|
|
46
|
+
animation: ol8-spin 900ms linear infinite;
|
|
47
|
+
}
|
|
48
|
+
}
|