@orioncactuscorp/ui 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -26
- package/dist/components/Accordion/Accordion.css +1 -1
- package/dist/components/Accordion/Accordion.js +39 -38
- package/dist/components/Accordion/Accordion.module.scss.js +5 -5
- package/dist/components/ActionArea/ActionArea.css +1 -1
- package/dist/components/ActionArea/ActionArea.js +101 -71
- package/dist/components/Alert/Alert.css +1 -1
- package/dist/components/BackgroundIconButton/BackgroundIconButton.css +1 -1
- package/dist/components/Badge/Badge.css +1 -1
- package/dist/components/Badge/Badge.js +69 -25
- package/dist/components/Button/Button.css +1 -1
- package/dist/components/Button/Button.js +27 -27
- package/dist/components/Cell/Cell.css +1 -1
- package/dist/components/Cell/Cell.js +98 -88
- package/dist/components/CheckMark/CheckMark.css +1 -1
- package/dist/components/CheckMark/CheckMark.js +20 -18
- package/dist/components/CheckMark/CheckMark.module.scss.js +7 -3
- package/dist/components/Checkbox/Checkbox.css +1 -1
- package/dist/components/Checkbox/Checkbox.module.scss.js +10 -8
- package/dist/components/Field/Field.css +1 -1
- package/dist/components/Fieldset/Fieldset.css +1 -1
- package/dist/components/IconButton/IconButton.css +1 -1
- package/dist/components/Interaction/Interaction.css +1 -1
- package/dist/components/Loading/Loading.css +1 -1
- package/dist/components/Menu/Menu.css +1 -1
- package/dist/components/Modal/Modal.css +1 -1
- package/dist/components/Modal/Modal.js +377 -346
- package/dist/components/Modal/useModalDrag.js +654 -614
- package/dist/components/Radio/Radio.css +1 -1
- package/dist/components/Radio/Radio.module.scss.js +9 -7
- package/dist/components/ScrollArea/ScrollArea.css +1 -1
- package/dist/components/SectionHeader/SectionHeader.css +1 -1
- package/dist/components/Select/Select.css +1 -1
- package/dist/components/Select/Select.js +15 -15
- package/dist/components/Select/SelectContent.css +1 -1
- package/dist/components/Switch/Switch.css +1 -1
- package/dist/components/Switch/Switch.module.scss.js +6 -4
- package/dist/components/TextArea/TextArea.css +1 -1
- package/dist/components/TextArea/TextAreaContent.css +1 -1
- package/dist/components/TextButton/TextButton.css +1 -1
- package/dist/components/TextInput/TextInput.css +1 -1
- package/dist/components/TextInput/TextInputContent.css +1 -1
- package/dist/components/Tooltip/Tooltip.css +1 -1
- package/dist/foundations/atomic.css +1 -1
- package/dist/foundations/motion.css +1 -1
- package/dist/foundations/typo.css +1 -1
- package/dist/foundations.css +3 -3
- package/dist/react/motion.js +109 -106
- package/dist/styles.css +31 -31
- package/dist/ui/src/components/Accordion/Accordion.d.ts.map +1 -1
- package/dist/ui/src/components/ActionArea/ActionArea.d.ts +1 -1
- package/dist/ui/src/components/ActionArea/ActionArea.d.ts.map +1 -1
- package/dist/ui/src/components/ActionArea/index.d.ts +1 -1
- package/dist/ui/src/components/ActionArea/index.d.ts.map +1 -1
- package/dist/ui/src/components/ActionArea/types.d.ts +2 -2
- package/dist/ui/src/components/ActionArea/types.d.ts.map +1 -1
- package/dist/ui/src/components/Badge/Badge.d.ts +1 -1
- package/dist/ui/src/components/Badge/Badge.d.ts.map +1 -1
- package/dist/ui/src/components/Badge/types.d.ts +19 -2
- package/dist/ui/src/components/Badge/types.d.ts.map +1 -1
- package/dist/ui/src/components/Button/Button.d.ts.map +1 -1
- package/dist/ui/src/components/Cell/Cell.d.ts.map +1 -1
- package/dist/ui/src/components/CheckMark/CheckMark.d.ts +1 -1
- package/dist/ui/src/components/CheckMark/CheckMark.d.ts.map +1 -1
- package/dist/ui/src/components/CheckMark/index.d.ts +1 -1
- package/dist/ui/src/components/CheckMark/index.d.ts.map +1 -1
- package/dist/ui/src/components/CheckMark/types.d.ts +2 -0
- package/dist/ui/src/components/CheckMark/types.d.ts.map +1 -1
- package/dist/ui/src/components/Modal/Modal.d.ts.map +1 -1
- package/dist/ui/src/components/Modal/contexts.d.ts +1 -0
- package/dist/ui/src/components/Modal/contexts.d.ts.map +1 -1
- package/dist/ui/src/components/Modal/types.d.ts +5 -4
- package/dist/ui/src/components/Modal/types.d.ts.map +1 -1
- package/dist/ui/src/components/Modal/useModalDrag.d.ts.map +1 -1
- package/dist/ui/src/index.d.ts +4 -4
- package/dist/ui/src/index.d.ts.map +1 -1
- package/dist/ui/src/react/motion/index.d.ts +9 -8
- package/dist/ui/src/react/motion/index.d.ts.map +1 -1
- package/dist/ui/src/utils/motion.d.ts +15 -14
- package/dist/ui/src/utils/motion.d.ts.map +1 -1
- package/dist/utils/motion.js +282 -183
- package/dist/vscode/oc-ui-vars.css +31 -16
- package/package.json +2 -2
- package/src/scss/foundations/atomic.scss +12 -10
- package/src/scss/foundations/atomic.test.ts +34 -0
- package/src/scss/foundations/motion.scss +30 -16
- package/src/scss/foundations/typo.scss +1 -1
- package/src/scss/index.scss +1 -0
- package/src/scss/mixins/_element.scss +67 -7
- package/src/scss/mixins/_element.test.ts +94 -7
- package/src/scss/mixins/_motion.scss +168 -77
- package/src/scss/mixins/_motion.test.ts +137 -54
- package/src/scss/mixins/_radius.scss +3 -0
- package/src/scss/mixins/_radius.test.ts +52 -0
- package/src/scss/mixins/_typo.scss +2 -2
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
:root {
|
|
5
5
|
--oc-atomic-blur-compact: initial;
|
|
6
6
|
--oc-atomic-blur-normal: initial;
|
|
7
|
+
--oc-atomic-radius-factor: initial;
|
|
7
8
|
--oc-atomic-radius-huge: initial;
|
|
8
9
|
--oc-atomic-radius-large: initial;
|
|
9
10
|
--oc-atomic-radius-max: initial;
|
|
@@ -291,34 +292,48 @@
|
|
|
291
292
|
--oc-color-theme-status-cautionary: initial;
|
|
292
293
|
--oc-color-theme-status-negative: initial;
|
|
293
294
|
--oc-color-theme-status-positive: initial;
|
|
294
|
-
--oc-motion-distance-
|
|
295
|
-
--oc-motion-distance-
|
|
296
|
-
--oc-motion-distance-
|
|
295
|
+
--oc-motion-distance-factor: initial;
|
|
296
|
+
--oc-motion-distance-factor-reject: initial;
|
|
297
|
+
--oc-motion-distance-factor-spatial: initial;
|
|
297
298
|
--oc-motion-duration-ambient: initial;
|
|
299
|
+
--oc-motion-duration-disclosure: initial;
|
|
300
|
+
--oc-motion-duration-disclosure-exit: initial;
|
|
301
|
+
--oc-motion-duration-expand: initial;
|
|
302
|
+
--oc-motion-duration-expand-exit: initial;
|
|
303
|
+
--oc-motion-duration-factor: initial;
|
|
304
|
+
--oc-motion-duration-factor-preserve: initial;
|
|
305
|
+
--oc-motion-duration-factor-reduced: initial;
|
|
298
306
|
--oc-motion-duration-feedback: initial;
|
|
299
307
|
--oc-motion-duration-gesture: initial;
|
|
300
|
-
--oc-motion-duration-gesture-
|
|
308
|
+
--oc-motion-duration-gesture-release: initial;
|
|
301
309
|
--oc-motion-duration-move: initial;
|
|
302
310
|
--oc-motion-duration-reject: initial;
|
|
303
|
-
--oc-motion-duration-
|
|
304
|
-
--oc-motion-duration-
|
|
305
|
-
--oc-motion-duration-
|
|
306
|
-
--oc-motion-duration-
|
|
307
|
-
--oc-motion-duration-
|
|
311
|
+
--oc-motion-duration-sheet: initial;
|
|
312
|
+
--oc-motion-duration-sheet-exit: initial;
|
|
313
|
+
--oc-motion-duration-sheet-release: initial;
|
|
314
|
+
--oc-motion-duration-surface: initial;
|
|
315
|
+
--oc-motion-duration-surface-exit: initial;
|
|
308
316
|
--oc-motion-pace-normal: initial;
|
|
309
317
|
--oc-motion-pace-quick: initial;
|
|
310
318
|
--oc-motion-pace-slow: initial;
|
|
311
|
-
--oc-motion-scale: initial;
|
|
312
|
-
--oc-motion-scale-feedback: initial;
|
|
313
|
-
--oc-motion-scale-
|
|
319
|
+
--oc-motion-scale-factor: initial;
|
|
320
|
+
--oc-motion-scale-factor-feedback: initial;
|
|
321
|
+
--oc-motion-scale-factor-spatial: initial;
|
|
314
322
|
--oc-motion-timing-ambient: initial;
|
|
323
|
+
--oc-motion-timing-disclosure: initial;
|
|
324
|
+
--oc-motion-timing-disclosure-exit: initial;
|
|
325
|
+
--oc-motion-timing-expand: initial;
|
|
326
|
+
--oc-motion-timing-expand-exit: initial;
|
|
315
327
|
--oc-motion-timing-feedback: initial;
|
|
316
328
|
--oc-motion-timing-gesture: initial;
|
|
317
|
-
--oc-motion-timing-gesture-
|
|
329
|
+
--oc-motion-timing-gesture-release: initial;
|
|
318
330
|
--oc-motion-timing-move: initial;
|
|
319
331
|
--oc-motion-timing-reject: initial;
|
|
320
|
-
--oc-motion-timing-
|
|
321
|
-
--oc-motion-timing-
|
|
332
|
+
--oc-motion-timing-sheet: initial;
|
|
333
|
+
--oc-motion-timing-sheet-exit: initial;
|
|
334
|
+
--oc-motion-timing-sheet-release: initial;
|
|
335
|
+
--oc-motion-timing-surface: initial;
|
|
336
|
+
--oc-motion-timing-surface-exit: initial;
|
|
322
337
|
--oc-space-item-gap-huge: initial;
|
|
323
338
|
--oc-space-item-gap-large: initial;
|
|
324
339
|
--oc-space-item-gap-medium: initial;
|
|
@@ -373,7 +388,6 @@
|
|
|
373
388
|
--oc-typo-height-title1: initial;
|
|
374
389
|
--oc-typo-height-title2: initial;
|
|
375
390
|
--oc-typo-height-title3: initial;
|
|
376
|
-
--oc-typo-scale: initial;
|
|
377
391
|
--oc-typo-size-body1: initial;
|
|
378
392
|
--oc-typo-size-body1reading: initial;
|
|
379
393
|
--oc-typo-size-body2: initial;
|
|
@@ -382,6 +396,7 @@
|
|
|
382
396
|
--oc-typo-size-display1: initial;
|
|
383
397
|
--oc-typo-size-display2: initial;
|
|
384
398
|
--oc-typo-size-display3: initial;
|
|
399
|
+
--oc-typo-size-factor: initial;
|
|
385
400
|
--oc-typo-size-heading1: initial;
|
|
386
401
|
--oc-typo-size-heading2: initial;
|
|
387
402
|
--oc-typo-size-headline1: initial;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orioncactuscorp/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "orioncactus UI foundations and core primitives",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"vitest": "^3.2.4"
|
|
120
120
|
},
|
|
121
121
|
"dependencies": {
|
|
122
|
-
"@orioncactuscorp/icons": "^1.
|
|
122
|
+
"@orioncactuscorp/icons": "^1.3.0",
|
|
123
123
|
"@base-ui-components/react": "^1.0.0-rc.0"
|
|
124
124
|
}
|
|
125
125
|
}
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
@use '../mixins/breakpoint' as *;
|
|
2
2
|
@use '../mixins/color' as *;
|
|
3
|
+
@use '../mixins/radius' as *;
|
|
3
4
|
@use '../mixins/utils' as *;
|
|
4
5
|
|
|
5
6
|
:root {
|
|
6
|
-
--oc-atomic-radius-
|
|
7
|
-
--oc-atomic-radius-
|
|
8
|
-
--oc-atomic-radius-
|
|
9
|
-
--oc-atomic-radius-
|
|
10
|
-
--oc-atomic-radius-
|
|
11
|
-
--oc-atomic-radius-
|
|
12
|
-
--oc-atomic-radius-
|
|
13
|
-
--oc-atomic-radius-
|
|
14
|
-
--oc-atomic-radius-
|
|
15
|
-
--oc-atomic-radius-
|
|
7
|
+
--oc-atomic-radius-factor: 1;
|
|
8
|
+
--oc-atomic-radius-max: #{oc-radius(10000px)};
|
|
9
|
+
--oc-atomic-radius-huge: #{oc-radius(fluidClamp(toRem(24), $breakpoint-md, from, toRem(64)))};
|
|
10
|
+
--oc-atomic-radius-xlarge: #{oc-radius(fluidClamp(toRem(12), $breakpoint-md, from, toRem(32)))};
|
|
11
|
+
--oc-atomic-radius-large: #{oc-radius(fluidClamp(toRem(12), $breakpoint-md, from, toRem(24)))};
|
|
12
|
+
--oc-atomic-radius-medium: #{oc-radius(fluidClamp(toRem(12), $breakpoint-md, from, toRem(16)))};
|
|
13
|
+
--oc-atomic-radius-small: #{oc-radius(fluidClamp(toRem(10), $breakpoint-md, from, toRem(12)))};
|
|
14
|
+
--oc-atomic-radius-xsmall: #{oc-radius(fluidClamp(toRem(8), $breakpoint-md, from, toRem(10)))};
|
|
15
|
+
--oc-atomic-radius-mini: #{oc-radius(fluidClamp(toRem(6), $breakpoint-md, from, toRem(8)))};
|
|
16
|
+
--oc-atomic-radius-tiny: #{oc-radius(fluidClamp(toRem(4), $breakpoint-md, from, toRem(6)))};
|
|
17
|
+
--oc-atomic-radius-micro: #{oc-radius(toRem(4))};
|
|
16
18
|
|
|
17
19
|
--oc-atomic-width-content: 35em;
|
|
18
20
|
--oc-atomic-width-section-large: 60rem;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { compileString } from 'sass';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
|
|
4
|
+
describe('atomic foundation', () => {
|
|
5
|
+
const compileAtomic = () =>
|
|
6
|
+
compileString("@use 'foundations/atomic' as *;", {
|
|
7
|
+
loadPaths: ['src/scss'],
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('exposes a global atomic radius factor', () => {
|
|
11
|
+
const result = compileAtomic();
|
|
12
|
+
|
|
13
|
+
expect(result.css).toContain('--oc-atomic-radius-factor: 1;');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('applies the radius factor to max and fixed radius tokens', () => {
|
|
17
|
+
const result = compileAtomic();
|
|
18
|
+
|
|
19
|
+
expect(result.css).toContain(
|
|
20
|
+
'--oc-atomic-radius-max: max(0px, 10000px * var(--oc-atomic-radius-factor));',
|
|
21
|
+
);
|
|
22
|
+
expect(result.css).toContain(
|
|
23
|
+
'--oc-atomic-radius-micro: max(0px, 0.25rem * var(--oc-atomic-radius-factor));',
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('applies the radius factor to fluid radius tokens', () => {
|
|
28
|
+
const result = compileAtomic();
|
|
29
|
+
|
|
30
|
+
expect(result.css).toContain(
|
|
31
|
+
'--oc-atomic-radius-medium: max(0px, clamp(0.75rem, 12 / 768 * 100vw, 1rem) * var(--oc-atomic-radius-factor));',
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
@use '../spring' as *;
|
|
2
2
|
|
|
3
3
|
:root {
|
|
4
|
-
--oc-motion-duration-
|
|
5
|
-
--oc-motion-duration-
|
|
6
|
-
--oc-motion-duration-
|
|
7
|
-
--oc-motion-scale: 1;
|
|
8
|
-
--oc-motion-scale-feedback: var(--oc-motion-scale);
|
|
9
|
-
--oc-motion-scale-
|
|
10
|
-
--oc-motion-distance-
|
|
11
|
-
--oc-motion-distance-
|
|
12
|
-
--oc-motion-distance-
|
|
4
|
+
--oc-motion-duration-factor: 1;
|
|
5
|
+
--oc-motion-duration-factor-reduced: 0.75;
|
|
6
|
+
--oc-motion-duration-factor-preserve: 1;
|
|
7
|
+
--oc-motion-scale-factor: 1;
|
|
8
|
+
--oc-motion-scale-factor-feedback: var(--oc-motion-scale-factor);
|
|
9
|
+
--oc-motion-scale-factor-spatial: var(--oc-motion-scale-factor);
|
|
10
|
+
--oc-motion-distance-factor: 1;
|
|
11
|
+
--oc-motion-distance-factor-reject: var(--oc-motion-distance-factor);
|
|
12
|
+
--oc-motion-distance-factor-spatial: var(--oc-motion-distance-factor);
|
|
13
13
|
|
|
14
14
|
/* Pace tokens are unitless duration multipliers. */
|
|
15
15
|
--oc-motion-pace-quick: 0.75;
|
|
@@ -17,19 +17,33 @@
|
|
|
17
17
|
--oc-motion-pace-slow: 1.35;
|
|
18
18
|
--oc-motion-duration-feedback: 0.2s;
|
|
19
19
|
--oc-motion-duration-reject: #{oc-spring-settle-duration(0.32s, smooth)};
|
|
20
|
-
--oc-motion-duration-
|
|
21
|
-
--oc-motion-duration-
|
|
20
|
+
--oc-motion-duration-disclosure: 0.2s;
|
|
21
|
+
--oc-motion-duration-disclosure-exit: 0.14s;
|
|
22
|
+
--oc-motion-duration-surface: 0.26s;
|
|
23
|
+
--oc-motion-duration-surface-exit: 0.24s;
|
|
24
|
+
--oc-motion-duration-sheet: 0.26s;
|
|
25
|
+
--oc-motion-duration-sheet-exit: 0.33s;
|
|
26
|
+
--oc-motion-duration-sheet-release: 0.33s;
|
|
27
|
+
--oc-motion-duration-expand: 0.3s;
|
|
28
|
+
--oc-motion-duration-expand-exit: 0.24s;
|
|
22
29
|
--oc-motion-duration-move: 0.3s;
|
|
23
30
|
--oc-motion-duration-gesture: 0.2s;
|
|
24
|
-
--oc-motion-duration-gesture-
|
|
31
|
+
--oc-motion-duration-gesture-release: 0.52s;
|
|
25
32
|
--oc-motion-duration-ambient: 1.2s;
|
|
26
33
|
--oc-motion-timing-feedback: ease;
|
|
27
34
|
--oc-motion-timing-reject: #{oc-spring-timing(0.32s, smooth, $samples: 64)};
|
|
28
|
-
--oc-motion-timing-
|
|
29
|
-
--oc-motion-timing-
|
|
35
|
+
--oc-motion-timing-disclosure: ease;
|
|
36
|
+
--oc-motion-timing-disclosure-exit: cubic-bezier(0.8, 0, 1, 1);
|
|
37
|
+
--oc-motion-timing-surface: ease;
|
|
38
|
+
--oc-motion-timing-surface-exit: ease-in;
|
|
39
|
+
--oc-motion-timing-sheet: ease;
|
|
40
|
+
--oc-motion-timing-sheet-exit: ease-in;
|
|
41
|
+
--oc-motion-timing-sheet-release: ease;
|
|
42
|
+
--oc-motion-timing-expand: ease;
|
|
43
|
+
--oc-motion-timing-expand-exit: ease-in;
|
|
30
44
|
--oc-motion-timing-move: cubic-bezier(0.32, 0.72, 0, 1);
|
|
31
45
|
--oc-motion-timing-gesture: ease;
|
|
32
|
-
--oc-motion-timing-gesture-
|
|
46
|
+
--oc-motion-timing-gesture-release: cubic-bezier(0.32, 0.72, 0, 1);
|
|
33
47
|
--oc-motion-timing-ambient: linear;
|
|
34
48
|
--oc-spring-smooth-timing: #{oc-spring-timing(0.5s, smooth, $samples: 64)};
|
|
35
49
|
--oc-spring-smooth-duration-scale: #{oc-spring-duration-scale(0.5s, smooth)};
|
|
@@ -41,6 +55,6 @@
|
|
|
41
55
|
|
|
42
56
|
@media (prefers-reduced-motion: reduce) {
|
|
43
57
|
:root {
|
|
44
|
-
--oc-motion-duration-
|
|
58
|
+
--oc-motion-duration-factor: var(--oc-motion-duration-factor-reduced);
|
|
45
59
|
}
|
|
46
60
|
}
|
|
@@ -364,7 +364,7 @@ $oc-typo-responsive-segments: (
|
|
|
364
364
|
*/
|
|
365
365
|
:root {
|
|
366
366
|
--oc-typo-font-family: #{$oc-typo-font-family};
|
|
367
|
-
--oc-typo-
|
|
367
|
+
--oc-typo-size-factor: 1;
|
|
368
368
|
|
|
369
369
|
@include oc-emit-responsive-tokens('typo-size', $oc-typo-size-stops, $oc-typo-responsive-segments, $oc-responsive-typo-stops, '$oc-responsive-typo-stops');
|
|
370
370
|
@include oc-emit-responsive-tokens('typo-height', $oc-typo-height-stops, $oc-typo-responsive-segments, $oc-responsive-typo-stops, '$oc-responsive-typo-stops');
|
package/src/scss/index.scss
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
@use 'sass:list';
|
|
2
|
+
@use 'sass:math';
|
|
3
|
+
@use 'sass:meta';
|
|
1
4
|
@use './motion' as *;
|
|
2
5
|
|
|
3
6
|
@mixin element-button {
|
|
@@ -25,28 +28,85 @@
|
|
|
25
28
|
user-select: none;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
@
|
|
31
|
+
@function _oc-border-is-half-px($width) {
|
|
32
|
+
@if meta.type-of($width) != 'number' or math.unit($width) != 'px' {
|
|
33
|
+
@return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
$pixels: math.div($width, 1px);
|
|
37
|
+
|
|
38
|
+
@return $pixels == math.floor($pixels) + 0.5;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@function _oc-border-webkit-base-spread($width) {
|
|
42
|
+
$pixels: math.floor(math.div($width, 1px));
|
|
43
|
+
|
|
44
|
+
@if $pixels < 1 {
|
|
45
|
+
@return 1px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@return $pixels * 1px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@function _oc-border-webkit-device-spread($width, $dppx) {
|
|
52
|
+
$pixels: math.div($width, 1px);
|
|
53
|
+
$device-pixels: math.ceil($pixels * $dppx);
|
|
54
|
+
$spread: math.div($device-pixels, $dppx);
|
|
55
|
+
$precision: math.pow(10, 4);
|
|
56
|
+
|
|
57
|
+
@return math.div(math.floor($spread * $precision), $precision) * 1px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@function _oc-border-args($args) {
|
|
61
|
+
$count: list.length($args);
|
|
62
|
+
|
|
63
|
+
@if $count == 0 {
|
|
64
|
+
@return (1px, currentColor);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@if $count == 1 {
|
|
68
|
+
$value: list.nth($args, 1);
|
|
69
|
+
|
|
70
|
+
@if meta.type-of($value) == 'number' {
|
|
71
|
+
@return ($value, currentColor);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@return (1px, $value);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@if $count == 2 {
|
|
78
|
+
@return (list.nth($args, 1), list.nth($args, 2));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@error 'oc-border accepts zero, one, or two arguments.';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@mixin oc-border($args...) {
|
|
85
|
+
$resolved: _oc-border-args($args);
|
|
86
|
+
$width: list.nth($resolved, 1);
|
|
87
|
+
$color: list.nth($resolved, 2);
|
|
88
|
+
|
|
29
89
|
box-shadow: inset 0 0 0 $width $color;
|
|
30
90
|
|
|
31
|
-
@if $width
|
|
32
|
-
/* stylelint-disable block-no-redundant-nested-style-rules -- WebKit rounds
|
|
91
|
+
@if _oc-border-is-half-px($width) {
|
|
92
|
+
/* stylelint-disable block-no-redundant-nested-style-rules, media-feature-range-notation -- WebKit rounds fractional inset strokes differently by DPR; nested selectors keep the correction scoped. */
|
|
33
93
|
@supports (-webkit-backdrop-filter: none) {
|
|
34
94
|
& {
|
|
35
|
-
box-shadow: inset 0 0 0
|
|
95
|
+
box-shadow: inset 0 0 0 _oc-border-webkit-base-spread($width) $color;
|
|
36
96
|
}
|
|
37
97
|
|
|
38
98
|
@media only screen and (resolution: 2dppx) {
|
|
39
99
|
& {
|
|
40
|
-
box-shadow: inset 0 0 0
|
|
100
|
+
box-shadow: inset 0 0 0 _oc-border-webkit-device-spread($width, 2) $color;
|
|
41
101
|
}
|
|
42
102
|
}
|
|
43
103
|
|
|
44
104
|
@media only screen and (resolution: 3dppx) {
|
|
45
105
|
& {
|
|
46
|
-
box-shadow: inset 0 0 0
|
|
106
|
+
box-shadow: inset 0 0 0 _oc-border-webkit-device-spread($width, 3) $color;
|
|
47
107
|
}
|
|
48
108
|
}
|
|
49
109
|
}
|
|
50
|
-
/* stylelint-enable block-no-redundant-nested-style-rules */
|
|
110
|
+
/* stylelint-enable block-no-redundant-nested-style-rules, media-feature-range-notation */
|
|
51
111
|
}
|
|
52
112
|
}
|
|
@@ -1,14 +1,48 @@
|
|
|
1
1
|
import { compileString } from 'sass';
|
|
2
2
|
import { describe, expect, it } from 'vitest';
|
|
3
3
|
|
|
4
|
-
describe('
|
|
5
|
-
it('emits a
|
|
4
|
+
describe('oc-border mixin', () => {
|
|
5
|
+
it('emits a 1px currentColor inset border by default', () => {
|
|
6
6
|
const result = compileString(
|
|
7
7
|
`
|
|
8
8
|
@use 'element' as *;
|
|
9
9
|
|
|
10
10
|
.target {
|
|
11
|
-
@include
|
|
11
|
+
@include oc-border;
|
|
12
|
+
}
|
|
13
|
+
`,
|
|
14
|
+
{
|
|
15
|
+
loadPaths: ['src/scss/mixins'],
|
|
16
|
+
},
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
expect(result.css).toContain('box-shadow: inset 0 0 0 1px currentColor;');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('treats a single non-number argument as the border color', () => {
|
|
23
|
+
const result = compileString(
|
|
24
|
+
`
|
|
25
|
+
@use 'element' as *;
|
|
26
|
+
|
|
27
|
+
.target {
|
|
28
|
+
@include oc-border(black);
|
|
29
|
+
}
|
|
30
|
+
`,
|
|
31
|
+
{
|
|
32
|
+
loadPaths: ['src/scss/mixins'],
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
expect(result.css).toContain('box-shadow: inset 0 0 0 1px black;');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('emits a direct inset border for integer widths', () => {
|
|
40
|
+
const result = compileString(
|
|
41
|
+
`
|
|
42
|
+
@use 'element' as *;
|
|
43
|
+
|
|
44
|
+
.target {
|
|
45
|
+
@include oc-border(2px, var(--stroke));
|
|
12
46
|
}
|
|
13
47
|
`,
|
|
14
48
|
{
|
|
@@ -20,13 +54,13 @@ describe('inset-stroke mixin', () => {
|
|
|
20
54
|
expect(result.css).not.toContain('@supports');
|
|
21
55
|
});
|
|
22
56
|
|
|
23
|
-
it('adds WebKit DPR correction for 1.5px
|
|
57
|
+
it('adds WebKit DPR correction for 1.5px borders', () => {
|
|
24
58
|
const result = compileString(
|
|
25
59
|
`
|
|
26
60
|
@use 'element' as *;
|
|
27
61
|
|
|
28
62
|
.target {
|
|
29
|
-
@include
|
|
63
|
+
@include oc-border(1.5px);
|
|
30
64
|
}
|
|
31
65
|
`,
|
|
32
66
|
{
|
|
@@ -34,11 +68,64 @@ describe('inset-stroke mixin', () => {
|
|
|
34
68
|
},
|
|
35
69
|
);
|
|
36
70
|
|
|
37
|
-
expect(result.css).toContain('box-shadow: inset 0 0 0 1.5px
|
|
71
|
+
expect(result.css).toContain('box-shadow: inset 0 0 0 1.5px currentColor;');
|
|
38
72
|
expect(result.css).toContain('@supports (-webkit-backdrop-filter: none)');
|
|
73
|
+
expect(result.css).toContain('box-shadow: inset 0 0 0 1px currentColor;');
|
|
74
|
+
expect(result.css).toContain('@media only screen and (resolution: 2dppx)');
|
|
39
75
|
expect(result.css).toContain('@media only screen and (resolution: 3dppx)');
|
|
40
76
|
expect(result.css).toContain(
|
|
41
|
-
'box-shadow: inset 0 0 0 1.6666px
|
|
77
|
+
'box-shadow: inset 0 0 0 1.6666px currentColor;',
|
|
42
78
|
);
|
|
43
79
|
});
|
|
80
|
+
|
|
81
|
+
it('generalizes WebKit DPR correction for half-pixel borders', () => {
|
|
82
|
+
const result = compileString(
|
|
83
|
+
`
|
|
84
|
+
@use 'element' as *;
|
|
85
|
+
|
|
86
|
+
.two {
|
|
87
|
+
@include oc-border(2.5px, var(--stroke));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.three {
|
|
91
|
+
@include oc-border(3.5px, var(--stroke));
|
|
92
|
+
}
|
|
93
|
+
`,
|
|
94
|
+
{
|
|
95
|
+
loadPaths: ['src/scss/mixins'],
|
|
96
|
+
},
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
expect(result.css).toContain('box-shadow: inset 0 0 0 2px var(--stroke);');
|
|
100
|
+
expect(result.css).toContain(
|
|
101
|
+
'box-shadow: inset 0 0 0 2.5px var(--stroke);',
|
|
102
|
+
);
|
|
103
|
+
expect(result.css).toContain(
|
|
104
|
+
'box-shadow: inset 0 0 0 2.6666px var(--stroke);',
|
|
105
|
+
);
|
|
106
|
+
expect(result.css).toContain('box-shadow: inset 0 0 0 3px var(--stroke);');
|
|
107
|
+
expect(result.css).toContain(
|
|
108
|
+
'box-shadow: inset 0 0 0 3.5px var(--stroke);',
|
|
109
|
+
);
|
|
110
|
+
expect(result.css).toContain(
|
|
111
|
+
'box-shadow: inset 0 0 0 3.6666px var(--stroke);',
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('does not expose the removed inset-stroke mixin', () => {
|
|
116
|
+
expect(() =>
|
|
117
|
+
compileString(
|
|
118
|
+
`
|
|
119
|
+
@use 'element' as *;
|
|
120
|
+
|
|
121
|
+
.target {
|
|
122
|
+
@include inset-stroke(1px);
|
|
123
|
+
}
|
|
124
|
+
`,
|
|
125
|
+
{
|
|
126
|
+
loadPaths: ['src/scss/mixins'],
|
|
127
|
+
},
|
|
128
|
+
),
|
|
129
|
+
).toThrow('Undefined mixin');
|
|
130
|
+
});
|
|
44
131
|
});
|