benivo-ui-library 1.9.76 → 1.9.77
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 +22 -0
- package/activityFeed.less +394 -0
- package/benivo-ui-lib.less +14 -0
- package/button.less +35 -9
- package/checkboxGroup.less +198 -0
- package/closeButton.less +70 -0
- package/datePicker.less +446 -96
- package/emptyState.less +151 -0
- package/featuredIcon.less +13 -1
- package/fileCard.less +345 -0
- package/fileTypeIcon.less +12 -0
- package/fileUpload.less +268 -0
- package/flagFeatureIcon.less +41 -0
- package/forms.less +9 -4
- package/illustration.less +62 -0
- package/index.js +1 -1
- package/menu.less +247 -0
- package/miButton.less +149 -0
- package/modal.less +226 -0
- package/optionList.less +102 -0
- package/package.json +7 -3
- package/pageIndicator.less +125 -0
- package/pagination.less +222 -0
- package/phoneNumber.less +16 -0
- package/radiobutton.less +29 -0
- package/select.less +62 -30
- package/tag.less +55 -7
- package/tagsSelect.less +19 -0
- package/textarea.less +1 -1
- package/tileGeometry.less +12 -0
- package/variables.less +20 -3
package/README.md
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
`benivo-ui-library` is a collection of react hooks and components for faster development.
|
|
6
6
|
|
|
7
|
+
Accessibility is tested automatically with jest-axe — run `npm run a11y:audit` and see
|
|
8
|
+
[docs/accessibility-testing.md](docs/accessibility-testing.md) for the enforcement model.
|
|
9
|
+
|
|
7
10
|
# Installation
|
|
8
11
|
|
|
9
12
|
```sh
|
|
@@ -36,3 +39,22 @@ function MyApp() {
|
|
|
36
39
|
);
|
|
37
40
|
}
|
|
38
41
|
```
|
|
42
|
+
|
|
43
|
+
# Publishing
|
|
44
|
+
|
|
45
|
+
Publishing auth comes from the `NPM_TOKEN` environment variable — never from a token
|
|
46
|
+
committed to this repo. Both `.npmrc` files reference it as `${NPM_TOKEN}`, which npm
|
|
47
|
+
expands at run time.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
export NPM_TOKEN=<your granular npm publish token for benivo-ui-library>
|
|
51
|
+
npm run publish:lib
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`publish:lib` runs `check:npm-token` first and stops with a clear message if `NPM_TOKEN`
|
|
55
|
+
is unset, rather than failing part-way through a publish.
|
|
56
|
+
|
|
57
|
+
Use a **granular** npm access token scoped to the `benivo-ui-library` package only, with
|
|
58
|
+
publish rights and an expiry — not a classic automation token on the whole `benivo`
|
|
59
|
+
account. Keep it in your own environment or a CI secret. Do not add it to `.npmrc`,
|
|
60
|
+
`.storybook/.npmrc`, or any other tracked file.
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Activity feed
|
|
3
|
+
//
|
|
4
|
+
// A timeline / message log built from FeedItems, matching the DS "Feed item base"
|
|
5
|
+
// and "Activity feed" (Figma page 253-14231). The container owns spacing and
|
|
6
|
+
// separators; the item owns its anatomy and the connector rail.
|
|
7
|
+
//
|
|
8
|
+
// Colours are tokens only (see scripts/check-tokens.sh): text on --black /
|
|
9
|
+
// --text-400 / --text-600, links and the "new" dot on --brand-700, rail and
|
|
10
|
+
// separators on --border-200, the date band on --bg-100.
|
|
11
|
+
//
|
|
12
|
+
|
|
13
|
+
@feed-bubble-shadow: 0 1px 1px rgba(16, 24, 40, 0.05);
|
|
14
|
+
@feed-gap: 32px; // spacing between items (Figma: 32px in every divider mode)
|
|
15
|
+
|
|
16
|
+
.bnv-feed {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
font-family: @font-family;
|
|
20
|
+
|
|
21
|
+
// ---- spacing per divider style ----
|
|
22
|
+
// none: 32px between items.
|
|
23
|
+
&--divider-none {
|
|
24
|
+
gap: @feed-gap;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// line: a full-width 1px separator sits in a 16px gap either side (~32px total).
|
|
28
|
+
&--divider-line {
|
|
29
|
+
gap: 16px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// connector: the rail is a flex segment inside the item, so the item carries
|
|
33
|
+
// its own bottom spacing (Figma: content pb 32). No container gap.
|
|
34
|
+
&--divider-connector {
|
|
35
|
+
gap: 0;
|
|
36
|
+
|
|
37
|
+
.bnv-feed-item:last-child .bnv-feed-item__body {
|
|
38
|
+
padding-bottom: 0;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// With a 32px container gap, the date's own 12px block margin would make the
|
|
43
|
+
// date↔item spacing 44px, which reads as disconnected. Drop it here so it is a
|
|
44
|
+
// clean 32px, uniform with the item spacing. (Line mode keeps the 12px → 28px.)
|
|
45
|
+
&--divider-none &__date,
|
|
46
|
+
&--divider-connector &__date {
|
|
47
|
+
margin: 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ---- separators ----
|
|
51
|
+
&__separator {
|
|
52
|
+
height: 1px;
|
|
53
|
+
background-color: var(--border-200);
|
|
54
|
+
border: 0;
|
|
55
|
+
flex-shrink: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ---- day / date grouping header ----
|
|
59
|
+
// A pill (bg-100) with a calendar glyph and a bold date. The 12px block
|
|
60
|
+
// padding sits on top of the container gap, matching Figma's date frame.
|
|
61
|
+
&__date {
|
|
62
|
+
display: flex;
|
|
63
|
+
align-items: center;
|
|
64
|
+
gap: 10px;
|
|
65
|
+
box-sizing: border-box;
|
|
66
|
+
width: 100%;
|
|
67
|
+
margin: 12px 0;
|
|
68
|
+
padding: 8px 12px;
|
|
69
|
+
background-color: var(--bg-100);
|
|
70
|
+
border-radius: 0.5rem;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
&__date-icon {
|
|
74
|
+
flex-shrink: 0;
|
|
75
|
+
color: var(--text-600);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
&__date-label {
|
|
79
|
+
font-size: @font-size; // 16px
|
|
80
|
+
line-height: 24px;
|
|
81
|
+
font-weight: @font-weight-semibold;
|
|
82
|
+
color: var(--black);
|
|
83
|
+
white-space: nowrap;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ------------------------------------------------------------------ FeedItem
|
|
88
|
+
.bnv-feed-item {
|
|
89
|
+
--fi-avatar: 48px;
|
|
90
|
+
position: relative;
|
|
91
|
+
display: flex;
|
|
92
|
+
gap: 12px;
|
|
93
|
+
align-items: flex-start;
|
|
94
|
+
box-sizing: border-box;
|
|
95
|
+
font-size: @font-size; // 16px
|
|
96
|
+
line-height: 24px;
|
|
97
|
+
color: var(--text-600);
|
|
98
|
+
|
|
99
|
+
&--sm {
|
|
100
|
+
--fi-avatar: 32px;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ---------- leading column + rail ----------
|
|
104
|
+
&__leading {
|
|
105
|
+
display: flex;
|
|
106
|
+
flex-direction: column;
|
|
107
|
+
align-items: center;
|
|
108
|
+
flex-shrink: 0;
|
|
109
|
+
width: var(--fi-avatar);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&--connector &__leading {
|
|
113
|
+
align-self: stretch;
|
|
114
|
+
gap: 4px;
|
|
115
|
+
padding-bottom: 4px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
&__avatar {
|
|
119
|
+
display: inline-flex;
|
|
120
|
+
flex-shrink: 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Fallback marker when there is no avatar/icon.
|
|
124
|
+
&__marker {
|
|
125
|
+
width: 10px;
|
|
126
|
+
height: 10px;
|
|
127
|
+
margin-top: 7px;
|
|
128
|
+
border-radius: 50%;
|
|
129
|
+
background-color: var(--text-300);
|
|
130
|
+
flex-shrink: 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Decorative timeline rail — grows to fill the column below the avatar.
|
|
134
|
+
&__rail {
|
|
135
|
+
flex: 1 0 0;
|
|
136
|
+
width: 2px;
|
|
137
|
+
min-height: 8px;
|
|
138
|
+
border-radius: 2px;
|
|
139
|
+
background-color: var(--border-200);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ---------- body ----------
|
|
143
|
+
&__body {
|
|
144
|
+
flex: 1 1 0;
|
|
145
|
+
min-width: 0;
|
|
146
|
+
display: flex;
|
|
147
|
+
flex-direction: column;
|
|
148
|
+
gap: 12px;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
&--connector &__body {
|
|
152
|
+
padding-bottom: @feed-gap;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Header + action line sit tight together; 12px separates them from supporting.
|
|
156
|
+
&__text-block {
|
|
157
|
+
display: flex;
|
|
158
|
+
flex-direction: column;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
&__heading {
|
|
162
|
+
display: flex;
|
|
163
|
+
flex-direction: column;
|
|
164
|
+
min-width: 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
&__meta {
|
|
168
|
+
display: flex;
|
|
169
|
+
align-items: baseline;
|
|
170
|
+
flex-wrap: wrap;
|
|
171
|
+
gap: 8px;
|
|
172
|
+
min-width: 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
&__actor {
|
|
176
|
+
font-weight: @font-weight-semibold;
|
|
177
|
+
color: var(--black);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
&__timestamp {
|
|
181
|
+
font-weight: @font-weight-normal;
|
|
182
|
+
color: var(--text-400);
|
|
183
|
+
white-space: nowrap;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// @handle sub-line (messages).
|
|
187
|
+
&__handle {
|
|
188
|
+
font-size: @font-size-sm;
|
|
189
|
+
line-height: 20px;
|
|
190
|
+
color: var(--text-400);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Status pill sits below the action line, left-aligned.
|
|
194
|
+
&__status {
|
|
195
|
+
display: flex;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Edit/delete sit top-right, right of the name. Absolute + centred on the name
|
|
199
|
+
// row (24px) so taller buttons never push the description down.
|
|
200
|
+
&__trailing {
|
|
201
|
+
position: absolute;
|
|
202
|
+
top: 0;
|
|
203
|
+
right: 0;
|
|
204
|
+
height: 24px;
|
|
205
|
+
display: flex;
|
|
206
|
+
align-items: center;
|
|
207
|
+
gap: 8px;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
&__actions {
|
|
211
|
+
display: flex;
|
|
212
|
+
align-items: center;
|
|
213
|
+
gap: 2px;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Row actions use the DS Button (icon-only). It carries its own styling — this
|
|
217
|
+
// class is only a hook for context tweaks if ever needed.
|
|
218
|
+
&__action-btn {
|
|
219
|
+
flex-shrink: 0;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Visually-hidden label (e.g. "Unread") — exposed to assistive tech only.
|
|
223
|
+
&__sr-only {
|
|
224
|
+
position: absolute;
|
|
225
|
+
width: 1px;
|
|
226
|
+
height: 1px;
|
|
227
|
+
margin: -1px;
|
|
228
|
+
padding: 0;
|
|
229
|
+
border: 0;
|
|
230
|
+
overflow: hidden;
|
|
231
|
+
clip: rect(0 0 0 0);
|
|
232
|
+
clip-path: inset(50%);
|
|
233
|
+
white-space: nowrap;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Unread indicator.
|
|
237
|
+
&__new-dot {
|
|
238
|
+
width: 10px;
|
|
239
|
+
height: 10px;
|
|
240
|
+
border-radius: 50%;
|
|
241
|
+
background-color: var(--brand-700);
|
|
242
|
+
flex-shrink: 0;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// ---------- action line ----------
|
|
246
|
+
// Kept uniformly 16px/24px across every variant so the name→description gap is
|
|
247
|
+
// identical whether the item has a file, labels, text or nothing.
|
|
248
|
+
&__action {
|
|
249
|
+
color: var(--text-600);
|
|
250
|
+
|
|
251
|
+
a,
|
|
252
|
+
.bnv-feed-item__link {
|
|
253
|
+
color: var(--brand-700);
|
|
254
|
+
font-weight: @font-weight-medium;
|
|
255
|
+
text-decoration: none;
|
|
256
|
+
|
|
257
|
+
&:hover { text-decoration: underline; }
|
|
258
|
+
|
|
259
|
+
&:focus-visible {
|
|
260
|
+
outline: 2px solid var(--primary);
|
|
261
|
+
outline-offset: 2px;
|
|
262
|
+
border-radius: 0.125rem;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// ---------- supporting: file ----------
|
|
268
|
+
// The file is its own hoverable target — download/delete belong to the document,
|
|
269
|
+
// so they sit on its right and reveal on hover/focus. A "card" outline is drawn
|
|
270
|
+
// just outside the content so nothing shifts when it appears.
|
|
271
|
+
&__file {
|
|
272
|
+
position: relative;
|
|
273
|
+
display: flex;
|
|
274
|
+
gap: 12px;
|
|
275
|
+
align-items: flex-start;
|
|
276
|
+
width: 100%;
|
|
277
|
+
min-width: 0;
|
|
278
|
+
|
|
279
|
+
&::before {
|
|
280
|
+
content: '';
|
|
281
|
+
position: absolute;
|
|
282
|
+
inset: -8px -12px;
|
|
283
|
+
border: 1px solid transparent;
|
|
284
|
+
border-radius: 0.5rem;
|
|
285
|
+
pointer-events: none;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
&:hover::before,
|
|
289
|
+
&:focus-within::before {
|
|
290
|
+
border-color: var(--border-200);
|
|
291
|
+
background-color: var(--white);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
> * { position: relative; } // keep content above the ::before card
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
&__file-icon {
|
|
298
|
+
flex-shrink: 0;
|
|
299
|
+
width: 32px;
|
|
300
|
+
height: 40px;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
&__file-text {
|
|
304
|
+
display: flex;
|
|
305
|
+
flex-direction: column;
|
|
306
|
+
flex: 1 1 auto;
|
|
307
|
+
min-width: 0;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
&__file-name {
|
|
311
|
+
color: var(--black);
|
|
312
|
+
overflow: hidden;
|
|
313
|
+
text-overflow: ellipsis;
|
|
314
|
+
white-space: nowrap;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
&__file-size {
|
|
318
|
+
font-size: @font-size-sm;
|
|
319
|
+
line-height: 20px;
|
|
320
|
+
color: var(--text-600);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Actions on the right of the file row — hidden until hover/focus.
|
|
324
|
+
&__file-actions {
|
|
325
|
+
display: flex;
|
|
326
|
+
align-items: center;
|
|
327
|
+
gap: 2px;
|
|
328
|
+
flex-shrink: 0;
|
|
329
|
+
align-self: center;
|
|
330
|
+
opacity: 0;
|
|
331
|
+
transition: opacity 0.12s ease;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
&__file:hover &__file-actions,
|
|
335
|
+
&__file:focus-within &__file-actions {
|
|
336
|
+
opacity: 1;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Touch devices have no hover — keep the actions visible there.
|
|
340
|
+
@media (hover: none) {
|
|
341
|
+
&__file-actions { opacity: 1; }
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// ---------- supporting: labels ----------
|
|
345
|
+
&__labels {
|
|
346
|
+
display: flex;
|
|
347
|
+
flex-wrap: wrap;
|
|
348
|
+
gap: 4px;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// ---------- supporting: text (message bubble) ----------
|
|
352
|
+
&__bubble {
|
|
353
|
+
box-sizing: border-box;
|
|
354
|
+
width: 100%;
|
|
355
|
+
padding: 12px;
|
|
356
|
+
background-color: var(--white);
|
|
357
|
+
border: 1px solid var(--border-200);
|
|
358
|
+
// Speech-bubble: square top-left, rounded elsewhere.
|
|
359
|
+
border-radius: 0 8px 8px 8px;
|
|
360
|
+
box-shadow: @feed-bubble-shadow;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
&__text {
|
|
364
|
+
color: var(--black);
|
|
365
|
+
white-space: pre-wrap;
|
|
366
|
+
overflow-wrap: anywhere;
|
|
367
|
+
|
|
368
|
+
&.is-clamped {
|
|
369
|
+
display: -webkit-box;
|
|
370
|
+
-webkit-box-orient: vertical;
|
|
371
|
+
-webkit-line-clamp: 4; // overridden inline via clampLines
|
|
372
|
+
overflow: hidden;
|
|
373
|
+
position: relative;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Fade the last visible line while clamped and actually overflowing.
|
|
377
|
+
&.is-clamped.is-overflowing::after {
|
|
378
|
+
content: '';
|
|
379
|
+
position: absolute;
|
|
380
|
+
left: 0;
|
|
381
|
+
right: 0;
|
|
382
|
+
bottom: 0;
|
|
383
|
+
height: 1.4em;
|
|
384
|
+
background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--white));
|
|
385
|
+
pointer-events: none;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// The toggle is the DS Button (text/link). Only position it below the text.
|
|
390
|
+
&__toggle {
|
|
391
|
+
align-self: flex-start;
|
|
392
|
+
margin-top: 8px;
|
|
393
|
+
}
|
|
394
|
+
}
|
package/benivo-ui-lib.less
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
@import '../components/input/input.less';
|
|
2
2
|
@import '../components/tooltip/tooltip.less';
|
|
3
3
|
@import '../components/button/button.less';
|
|
4
|
+
@import '../components/closeButton/closeButton.less';
|
|
4
5
|
@import '../components/spinner/spinner.less';
|
|
5
6
|
@import '../components/fantasyButton/fantasyButton.less';
|
|
7
|
+
@import '../components/miButton/miButton.less';
|
|
6
8
|
@import '../components/checkbox/checkbox.less';
|
|
7
9
|
@import '../components/radiobutton/radiobutton.less';
|
|
10
|
+
@import '../components/checkboxGroup/checkboxGroup.less';
|
|
8
11
|
@import '../components/slider/slider.less';
|
|
9
12
|
@import '../components/progress/progress.less';
|
|
10
13
|
@import '../icons/featuredIcon/featuredIcon.less';
|
|
14
|
+
@import '../icons/flagFeatureIcon/flagFeatureIcon.less';
|
|
11
15
|
@import '../icons/starIcon/starIcon.less';
|
|
12
16
|
@import '../icons/checkIcon/checkIcon.less';
|
|
13
17
|
@import '../components/checkItem/checkItem.less';
|
|
@@ -15,11 +19,16 @@
|
|
|
15
19
|
@import '../icons/folderIcon/folderIcon.less';
|
|
16
20
|
@import '../icons/fileTypeIcon/fileTypeIcon.less';
|
|
17
21
|
@import '../components/badge/badge.less';
|
|
22
|
+
@import '../components/activityFeed/activityFeed.less';
|
|
18
23
|
@import '../components/notificationCard/notificationCard.less';
|
|
19
24
|
@import '../components/alertBanner/alertBanner.less';
|
|
20
25
|
@import '../components/alert/alert.less';
|
|
21
26
|
@import '../icons/pageHeaderIcon/pageHeaderIcon.less';
|
|
22
27
|
@import '../components/breadcrumbs/breadcrumbs.less';
|
|
28
|
+
@import '../components/pageIndicator/pageIndicator.less';
|
|
29
|
+
@import '../components/fileUpload/fileUpload.less';
|
|
30
|
+
@import '../components/pagination/pagination.less';
|
|
31
|
+
@import '../components/shared/optionList.less';
|
|
23
32
|
@import '../components/select/select.less';
|
|
24
33
|
@import '../components/datePicker/datePicker.less';
|
|
25
34
|
@import '../components/navigation/navigation.less';
|
|
@@ -28,6 +37,9 @@
|
|
|
28
37
|
@import '../components/copyInput/copyInput.less';
|
|
29
38
|
@import '../components/currencyInput/currencyInput.less';
|
|
30
39
|
@import '../components/phoneNumber/phoneNumber.less';
|
|
40
|
+
@import '../components/emptyState/emptyState.less';
|
|
41
|
+
@import '../components/emptyState/illustration/illustration.less';
|
|
42
|
+
@import '../components/menu/menu.less';
|
|
31
43
|
@import '../components/heroInput/heroInput.less';
|
|
32
44
|
@import '../components/formSection/formSection.less';
|
|
33
45
|
@import '../components/verificationCode/verificationCode.less';
|
|
@@ -39,6 +51,8 @@
|
|
|
39
51
|
@import '../components/countryFlag/countryFlag.less';
|
|
40
52
|
@import '../components/flag/flag.less';
|
|
41
53
|
@import '../components/textarea/textarea.less';
|
|
54
|
+
@import '../components/modal/modal.less';
|
|
55
|
+
@import '../components/fileCard/fileCard.less';
|
|
42
56
|
@import './forms.less';
|
|
43
57
|
@import './spacing.less';
|
|
44
58
|
@import './typography.less';
|
package/button.less
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
//
|
|
2
2
|
// Buttons
|
|
3
3
|
//
|
|
4
|
+
// WCAG 1.4.3 (BPO-14588, EPApp sheet row 110322 "Update button in the profile page has
|
|
5
|
+
// insufficient contrast ratio"): all eight disabled variants below coloured their label
|
|
6
|
+
// var(--text-400) = #98A2B3. Measured on the profile page's Update button, which opens in its
|
|
7
|
+
// disabled state, that is 2.464:1 against the button's own background - the label is there but
|
|
8
|
+
// cannot be read. SC 1.4.3 does exempt "inactive user interface components", so this is fixed
|
|
9
|
+
// because an unreadable label is a defect either way, not because the criterion forces it.
|
|
10
|
+
// var(--text-500) measures 4.6:1 on --bg-100 and 4.8:1 on --bg-50.
|
|
4
11
|
.client-hub {
|
|
5
12
|
.dropdown .btn {
|
|
6
13
|
&:first-child {
|
|
@@ -344,7 +351,7 @@
|
|
|
344
351
|
opacity: 1;
|
|
345
352
|
background: var(--bg-100);
|
|
346
353
|
border-color: var(--bg-200);
|
|
347
|
-
color: var(--text-
|
|
354
|
+
color: var(--text-500);
|
|
348
355
|
}
|
|
349
356
|
}
|
|
350
357
|
|
|
@@ -372,7 +379,7 @@
|
|
|
372
379
|
opacity: 1;
|
|
373
380
|
background: var(--bg-100);
|
|
374
381
|
border-color: var(--bg-200);
|
|
375
|
-
color: var(--text-
|
|
382
|
+
color: var(--text-500);
|
|
376
383
|
}
|
|
377
384
|
|
|
378
385
|
.bn-spinner div {
|
|
@@ -414,7 +421,7 @@
|
|
|
414
421
|
opacity: 1;
|
|
415
422
|
background: var(--white);
|
|
416
423
|
border-color: var(--bg-200);
|
|
417
|
-
color: var(--text-
|
|
424
|
+
color: var(--text-500);
|
|
418
425
|
}
|
|
419
426
|
|
|
420
427
|
.bn-spinner div {
|
|
@@ -445,7 +452,7 @@
|
|
|
445
452
|
&[disabled] {
|
|
446
453
|
opacity: 1;
|
|
447
454
|
background: transparent;
|
|
448
|
-
color: var(--text-
|
|
455
|
+
color: var(--text-500);
|
|
449
456
|
}
|
|
450
457
|
|
|
451
458
|
.bn-spinner div {
|
|
@@ -477,7 +484,7 @@
|
|
|
477
484
|
&[disabled] {
|
|
478
485
|
opacity: 1;
|
|
479
486
|
background: transparent;
|
|
480
|
-
color: var(--text-
|
|
487
|
+
color: var(--text-500);
|
|
481
488
|
}
|
|
482
489
|
|
|
483
490
|
.bn-spinner div {
|
|
@@ -527,7 +534,7 @@
|
|
|
527
534
|
opacity: 1;
|
|
528
535
|
background: var(--bg-100);
|
|
529
536
|
border-color: var(--bg-200);
|
|
530
|
-
color: var(--text-
|
|
537
|
+
color: var(--text-500);
|
|
531
538
|
}
|
|
532
539
|
}
|
|
533
540
|
|
|
@@ -556,7 +563,7 @@
|
|
|
556
563
|
opacity: 1;
|
|
557
564
|
background: var(--white);
|
|
558
565
|
border-color: var(--bg-200);
|
|
559
|
-
color: var(--text-
|
|
566
|
+
color: var(--text-500);
|
|
560
567
|
}
|
|
561
568
|
|
|
562
569
|
.bn-spinner div {
|
|
@@ -587,7 +594,7 @@
|
|
|
587
594
|
&[disabled] {
|
|
588
595
|
opacity: 1;
|
|
589
596
|
background: transparent;
|
|
590
|
-
color: var(--text-
|
|
597
|
+
color: var(--text-500);
|
|
591
598
|
}
|
|
592
599
|
|
|
593
600
|
.bn-spinner div {
|
|
@@ -632,4 +639,23 @@
|
|
|
632
639
|
&.has-error {
|
|
633
640
|
border-color: var(--error-main) !important;
|
|
634
641
|
}
|
|
635
|
-
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// =====================================================================================
|
|
645
|
+
// SC 1.4.11 (BPO-14588, sheet rows 110087 / 110150): a button "appearing as normal text"
|
|
646
|
+
// in the Aquatic / Desert contrast themes.
|
|
647
|
+
//
|
|
648
|
+
// A contrast theme forces every background to Canvas, so a variant whose whole button-ness
|
|
649
|
+
// is its fill has nothing left. Most variants here also set border-color, which survives -
|
|
650
|
+
// but btn-color-link sets `border: none`, and any button carrying a variant class this
|
|
651
|
+
// stylesheet does not define falls back to the base rule and depends on the consumer having
|
|
652
|
+
// overridden @btn-border. Giving every .btn a ButtonText edge in forced colours costs
|
|
653
|
+
// nothing in normal rendering and makes the shape independent of which variant is in play -
|
|
654
|
+
// which matters most for CMS-authored buttons, whose class list is not in any repo.
|
|
655
|
+
// =====================================================================================
|
|
656
|
+
@media (forced-colors: active) {
|
|
657
|
+
|
|
658
|
+
.btn {
|
|
659
|
+
border: 1px solid ButtonText;
|
|
660
|
+
}
|
|
661
|
+
}
|