@orioncactuscorp/ui 1.2.0 → 1.4.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.
Files changed (120) hide show
  1. package/README.md +56 -27
  2. package/dist/components/Accordion/Accordion.css +1 -1
  3. package/dist/components/Accordion/Accordion.js +39 -38
  4. package/dist/components/Accordion/Accordion.module.scss.js +5 -5
  5. package/dist/components/ActionArea/ActionArea.css +1 -1
  6. package/dist/components/ActionArea/ActionArea.js +101 -71
  7. package/dist/components/ActionArea/ActionAreaLayout.css +1 -0
  8. package/dist/components/ActionArea/ActionAreaLayout.js +145 -0
  9. package/dist/components/ActionArea/ActionAreaLayout.module.scss.js +11 -0
  10. package/dist/components/ActionArea.js +10 -4
  11. package/dist/components/Alert/Alert.css +1 -1
  12. package/dist/components/BackgroundIconButton/BackgroundIconButton.css +1 -1
  13. package/dist/components/BackgroundIconButton/BackgroundIconButton.js +72 -52
  14. package/dist/components/Badge/Badge.css +1 -1
  15. package/dist/components/Badge/Badge.js +69 -25
  16. package/dist/components/Button/Button.css +1 -1
  17. package/dist/components/Button/Button.js +79 -139
  18. package/dist/components/Cell/Cell.css +1 -1
  19. package/dist/components/Cell/Cell.js +98 -88
  20. package/dist/components/CheckMark/CheckMark.css +1 -1
  21. package/dist/components/CheckMark/CheckMark.js +20 -18
  22. package/dist/components/CheckMark/CheckMark.module.scss.js +7 -3
  23. package/dist/components/Checkbox/Checkbox.css +1 -1
  24. package/dist/components/Checkbox/Checkbox.module.scss.js +10 -8
  25. package/dist/components/Field/Field.css +1 -1
  26. package/dist/components/Fieldset/Fieldset.css +1 -1
  27. package/dist/components/IconButton/IconButton.css +1 -1
  28. package/dist/components/IconButton/IconButton.js +48 -29
  29. package/dist/components/Interaction/Interaction.css +1 -1
  30. package/dist/components/Loading/Loading.css +1 -1
  31. package/dist/components/Loading/Loading.js +10 -10
  32. package/dist/components/Menu/Menu.css +1 -1
  33. package/dist/components/Modal/Modal.css +1 -1
  34. package/dist/components/Modal/Modal.js +377 -346
  35. package/dist/components/Modal/useModalDrag.js +654 -614
  36. package/dist/components/Radio/Radio.css +1 -1
  37. package/dist/components/Radio/Radio.module.scss.js +9 -7
  38. package/dist/components/ScrollArea/ScrollArea.css +1 -1
  39. package/dist/components/SectionHeader/SectionHeader.css +1 -1
  40. package/dist/components/Select/Select.css +1 -1
  41. package/dist/components/Select/Select.js +15 -15
  42. package/dist/components/Select/SelectContent.css +1 -1
  43. package/dist/components/Switch/Switch.css +1 -1
  44. package/dist/components/Switch/Switch.module.scss.js +6 -4
  45. package/dist/components/TextArea/TextArea.css +1 -1
  46. package/dist/components/TextArea/TextAreaContent.css +1 -1
  47. package/dist/components/TextButton/TextButton.css +1 -1
  48. package/dist/components/TextInput/TextInput.css +1 -1
  49. package/dist/components/TextInput/TextInputContent.css +1 -1
  50. package/dist/components/Tooltip/Tooltip.css +1 -1
  51. package/dist/components/internal/Pressable.js +90 -0
  52. package/dist/foundations/atomic.css +1 -1
  53. package/dist/foundations/motion.css +1 -1
  54. package/dist/foundations/typo.css +1 -1
  55. package/dist/foundations.css +3 -3
  56. package/dist/index.js +102 -96
  57. package/dist/react/motion.js +109 -106
  58. package/dist/styles.css +32 -31
  59. package/dist/ui/src/components/Accordion/Accordion.d.ts.map +1 -1
  60. package/dist/ui/src/components/ActionArea/ActionArea.d.ts +1 -1
  61. package/dist/ui/src/components/ActionArea/ActionArea.d.ts.map +1 -1
  62. package/dist/ui/src/components/ActionArea/ActionAreaLayout.d.ts +12 -0
  63. package/dist/ui/src/components/ActionArea/ActionAreaLayout.d.ts.map +1 -0
  64. package/dist/ui/src/components/ActionArea/index.d.ts +2 -1
  65. package/dist/ui/src/components/ActionArea/index.d.ts.map +1 -1
  66. package/dist/ui/src/components/ActionArea/types.d.ts +13 -2
  67. package/dist/ui/src/components/ActionArea/types.d.ts.map +1 -1
  68. package/dist/ui/src/components/BackgroundIconButton/BackgroundIconButton.d.ts +1 -1
  69. package/dist/ui/src/components/BackgroundIconButton/BackgroundIconButton.d.ts.map +1 -1
  70. package/dist/ui/src/components/BackgroundIconButton/index.d.ts +1 -1
  71. package/dist/ui/src/components/BackgroundIconButton/index.d.ts.map +1 -1
  72. package/dist/ui/src/components/BackgroundIconButton/types.d.ts +6 -5
  73. package/dist/ui/src/components/BackgroundIconButton/types.d.ts.map +1 -1
  74. package/dist/ui/src/components/Badge/Badge.d.ts +1 -1
  75. package/dist/ui/src/components/Badge/Badge.d.ts.map +1 -1
  76. package/dist/ui/src/components/Badge/types.d.ts +19 -2
  77. package/dist/ui/src/components/Badge/types.d.ts.map +1 -1
  78. package/dist/ui/src/components/Button/Button.d.ts.map +1 -1
  79. package/dist/ui/src/components/Button/types.d.ts +3 -7
  80. package/dist/ui/src/components/Button/types.d.ts.map +1 -1
  81. package/dist/ui/src/components/Cell/Cell.d.ts.map +1 -1
  82. package/dist/ui/src/components/CheckMark/CheckMark.d.ts +1 -1
  83. package/dist/ui/src/components/CheckMark/CheckMark.d.ts.map +1 -1
  84. package/dist/ui/src/components/CheckMark/index.d.ts +1 -1
  85. package/dist/ui/src/components/CheckMark/index.d.ts.map +1 -1
  86. package/dist/ui/src/components/CheckMark/types.d.ts +2 -0
  87. package/dist/ui/src/components/CheckMark/types.d.ts.map +1 -1
  88. package/dist/ui/src/components/IconButton/IconButton.d.ts +1 -1
  89. package/dist/ui/src/components/IconButton/IconButton.d.ts.map +1 -1
  90. package/dist/ui/src/components/IconButton/index.d.ts +1 -1
  91. package/dist/ui/src/components/IconButton/index.d.ts.map +1 -1
  92. package/dist/ui/src/components/IconButton/types.d.ts +6 -5
  93. package/dist/ui/src/components/IconButton/types.d.ts.map +1 -1
  94. package/dist/ui/src/components/Modal/Modal.d.ts.map +1 -1
  95. package/dist/ui/src/components/Modal/contexts.d.ts +1 -0
  96. package/dist/ui/src/components/Modal/contexts.d.ts.map +1 -1
  97. package/dist/ui/src/components/Modal/types.d.ts +7 -6
  98. package/dist/ui/src/components/Modal/types.d.ts.map +1 -1
  99. package/dist/ui/src/components/Modal/useModalDrag.d.ts.map +1 -1
  100. package/dist/ui/src/components/internal/Pressable.d.ts +19 -0
  101. package/dist/ui/src/components/internal/Pressable.d.ts.map +1 -0
  102. package/dist/ui/src/index.d.ts +5 -5
  103. package/dist/ui/src/index.d.ts.map +1 -1
  104. package/dist/ui/src/react/motion/index.d.ts +9 -8
  105. package/dist/ui/src/react/motion/index.d.ts.map +1 -1
  106. package/dist/ui/src/utils/motion.d.ts +15 -14
  107. package/dist/ui/src/utils/motion.d.ts.map +1 -1
  108. package/dist/utils/motion.js +282 -183
  109. package/dist/vscode/oc-ui-vars.css +31 -16
  110. package/package.json +2 -2
  111. package/src/scss/foundations/atomic.scss +12 -10
  112. package/src/scss/foundations/atomic.test.ts +34 -0
  113. package/src/scss/foundations/motion.scss +30 -16
  114. package/src/scss/foundations/typo.scss +1 -1
  115. package/src/scss/index.scss +1 -0
  116. package/src/scss/mixins/_motion.scss +168 -77
  117. package/src/scss/mixins/_motion.test.ts +137 -54
  118. package/src/scss/mixins/_radius.scss +3 -0
  119. package/src/scss/mixins/_radius.test.ts +52 -0
  120. package/src/scss/mixins/_typo.scss +2 -2
@@ -22,51 +22,51 @@ describe('motion utilities', () => {
22
22
  `);
23
23
 
24
24
  expect(result.css).toContain(
25
- 'background-color calc(var(--oc-motion-duration-feedback) * var(--oc-motion-duration-scale) * var(--oc-motion-pace-quick) * 1) var(--oc-motion-timing-feedback)',
25
+ 'background-color calc(var(--oc-motion-duration-feedback) * var(--oc-motion-duration-factor) * var(--oc-motion-pace-quick) * 1) var(--oc-motion-timing-feedback)',
26
26
  );
27
27
  expect(result.css).toContain(
28
- 'color calc(var(--oc-motion-duration-feedback) * var(--oc-motion-duration-scale) * var(--oc-motion-pace-quick) * 1) var(--oc-motion-timing-feedback)',
28
+ 'color calc(var(--oc-motion-duration-feedback) * var(--oc-motion-duration-factor) * var(--oc-motion-pace-quick) * 1) var(--oc-motion-timing-feedback)',
29
29
  );
30
30
  expect(result.css).toContain(
31
- 'box-shadow calc(var(--oc-motion-duration-feedback) * var(--oc-motion-duration-scale) * var(--oc-motion-pace-quick) * 1) var(--oc-motion-timing-feedback)',
31
+ 'box-shadow calc(var(--oc-motion-duration-feedback) * var(--oc-motion-duration-factor) * var(--oc-motion-pace-quick) * 1) var(--oc-motion-timing-feedback)',
32
32
  );
33
33
  });
34
34
 
35
- it('keeps numeric duration scale separate from pace', () => {
35
+ it('keeps numeric duration factor separate from pace', () => {
36
36
  const result = compileMotion(`
37
37
  .target {
38
- transition: oc-motion(opacity, feedback, $pace: slow, $duration-scale: 0.9);
38
+ transition: oc-motion(opacity, feedback, $pace: slow, $duration-factor: 0.9);
39
39
  }
40
40
  `);
41
41
 
42
42
  expect(result.css).toContain(
43
- 'opacity calc(var(--oc-motion-duration-feedback) * var(--oc-motion-duration-scale) * var(--oc-motion-pace-slow) * 0.9) var(--oc-motion-timing-feedback)',
43
+ 'opacity calc(var(--oc-motion-duration-feedback) * var(--oc-motion-duration-factor) * var(--oc-motion-pace-slow) * 0.9) var(--oc-motion-timing-feedback)',
44
44
  );
45
45
  });
46
46
 
47
- it('scales transform amplitude through motion scale tokens', () => {
47
+ it('scales transform amplitude through motion scale factor tokens', () => {
48
48
  const result = compileMotion(`
49
49
  .feedback {
50
50
  transform: scale(oc-motion-scale(0.95, feedback));
51
51
  }
52
52
 
53
- .reveal {
54
- transform: scale(oc-motion-scale(var(--local-scale), reveal));
53
+ .surface {
54
+ transform: scale(oc-motion-scale(var(--local-scale), surface));
55
55
  }
56
56
  `);
57
57
 
58
58
  expect(result.css).toContain(
59
- 'transform: scale(max(0, 1 + (0.95 - 1) * var(--oc-motion-scale-feedback)))',
59
+ 'transform: scale(max(0, 1 + (0.95 - 1) * var(--oc-motion-scale-factor-feedback)))',
60
60
  );
61
61
  expect(result.css).toContain(
62
- 'transform: scale(max(0, 1 + (var(--local-scale) - 1) * var(--oc-motion-scale-reveal)))',
62
+ 'transform: scale(max(0, 1 + (var(--local-scale) - 1) * var(--oc-motion-scale-factor-spatial)))',
63
63
  );
64
64
  });
65
65
 
66
- it('scales transform distance through motion distance tokens', () => {
66
+ it('scales transform distance through motion distance factor tokens', () => {
67
67
  const result = compileMotion(`
68
- .reveal {
69
- transform: translateY(oc-motion-distance(-1rem, reveal));
68
+ .sheet {
69
+ transform: translateY(oc-motion-distance(-1rem, sheet));
70
70
  }
71
71
 
72
72
  .reject {
@@ -75,10 +75,10 @@ describe('motion utilities', () => {
75
75
  `);
76
76
 
77
77
  expect(result.css).toContain(
78
- 'transform: translateY(calc(-1rem * var(--oc-motion-distance-scale-reveal)))',
78
+ 'transform: translateY(calc(-1rem * var(--oc-motion-distance-factor-spatial)))',
79
79
  );
80
80
  expect(result.css).toContain(
81
- 'transform: translateX(calc(var(--local-distance) * var(--oc-motion-distance-scale-reject)))',
81
+ 'transform: translateX(calc(var(--local-distance) * var(--oc-motion-distance-factor-reject)))',
82
82
  );
83
83
  });
84
84
 
@@ -90,31 +90,80 @@ describe('motion utilities', () => {
90
90
  `);
91
91
 
92
92
  expect(result.css).toContain(
93
- 'opacity calc(var(--local-feedback-time) * var(--oc-motion-duration-scale) * var(--oc-motion-pace-normal) * 1) var(--oc-motion-timing-feedback)',
93
+ 'opacity calc(var(--local-feedback-time) * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) var(--oc-motion-timing-feedback)',
94
94
  );
95
95
  expect(result.css).toContain(
96
- 'transition-duration: calc(var(--local-feedback-time) * var(--oc-motion-duration-scale-reduced) * var(--oc-motion-pace-normal) * 1);',
96
+ 'transition-duration: calc(var(--local-feedback-time) * var(--oc-motion-duration-factor-reduced) * var(--oc-motion-pace-normal) * 1);',
97
97
  );
98
98
  expect(result.css).toContain(
99
99
  'transition-timing-function: var(--oc-motion-timing-feedback);',
100
100
  );
101
101
  });
102
102
 
103
- it('uses smooth opacity and snappy transform for reveal motion', () => {
103
+ it('uses smooth opacity and snappy transform for disclosure motion', () => {
104
104
  const result = compileMotion(`
105
105
  .target {
106
- transition: oc-motion((opacity, transform), reveal);
106
+ transition: oc-motion((opacity, transform), disclosure);
107
107
  }
108
108
  `);
109
109
 
110
110
  expect(result.css).toContain(
111
- 'transition: opacity calc(0.561s * var(--oc-motion-duration-scale) * var(--oc-motion-pace-normal) * 1) linear(',
111
+ 'transition: opacity calc(0.374s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
112
112
  );
113
113
  expect(result.css).toContain(
114
- ', transform calc(0.58s * var(--oc-motion-duration-scale) * var(--oc-motion-pace-normal) * 1) linear(',
114
+ ', transform calc(0.382s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
115
115
  );
116
116
  });
117
117
 
118
+ it('uses role-specific profiles for disclosure, surface, sheet, and expand motion', () => {
119
+ const result = compileMotion(`
120
+ .disclosure {
121
+ transition: oc-motion((opacity, transform), disclosure, $phase: enter);
122
+ }
123
+
124
+ .surface {
125
+ transition: oc-motion(transform, surface, $phase: enter);
126
+ }
127
+
128
+ .sheet {
129
+ transition: oc-motion(transform, sheet, $phase: release);
130
+ }
131
+
132
+ .expand {
133
+ transition: oc-motion(opacity, expand, $phase: exit);
134
+ }
135
+ `);
136
+
137
+ expect(result.css).toContain(
138
+ '.disclosure {\n transition: opacity calc(0.374s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
139
+ );
140
+ expect(result.css).toContain(
141
+ ', transform calc(0.382s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
142
+ );
143
+ expect(result.css).toContain(
144
+ '.surface {\n transition: transform calc(0.486s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
145
+ );
146
+ expect(result.css).toContain(
147
+ '.sheet {\n transition: transform calc(0.617s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
148
+ );
149
+ expect(result.css).toContain(
150
+ '.expand {\n transition: opacity calc(0.449s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
151
+ );
152
+ });
153
+
154
+ it('keeps disclosure exit on the token accelerate easing path', () => {
155
+ const result = compileMotion(`
156
+ .exit {
157
+ transition: oc-motion((opacity, transform), disclosure, $phase: exit);
158
+ }
159
+ `);
160
+
161
+ expect(result.css).toContain(
162
+ '.exit {\n transition: opacity calc(var(--oc-motion-duration-disclosure-exit) * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) var(--oc-motion-timing-disclosure-exit), transform calc(var(--oc-motion-duration-disclosure-exit) * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) var(--oc-motion-timing-disclosure-exit);',
163
+ );
164
+ expect(result.css).not.toContain('linear(');
165
+ });
166
+
118
167
  it('uses spring timing for reject feedback motion', () => {
119
168
  const result = compileMotion(`
120
169
  .target {
@@ -128,86 +177,98 @@ describe('motion utilities', () => {
128
177
 
129
178
  expect(result.css).toContain('.target {\n transition: transform calc(');
130
179
  expect(result.css).toContain(
131
- ' * var(--oc-motion-duration-scale) * var(--oc-motion-pace-normal) * 1) linear(',
180
+ ' * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
132
181
  );
133
182
  expect(result.css).toContain(
134
- '.exit {\n transition: transform calc(var(--oc-motion-duration-reject) * var(--oc-motion-duration-scale) * var(--oc-motion-pace-normal) * 1) var(--oc-motion-timing-reject);',
183
+ '.exit {\n transition: transform calc(var(--oc-motion-duration-reject) * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) var(--oc-motion-timing-reject);',
135
184
  );
136
185
  });
137
186
 
138
- it('uses snappy spring timing for feedback settle motion', () => {
187
+ it('uses snappy spring timing for gesture release motion', () => {
139
188
  const result = compileMotion(`
140
189
  .target {
141
- transition: oc-motion(transform, feedback, $phase: settle);
190
+ transition: oc-motion(transform, gesture, $phase: release);
142
191
  }
143
192
  `);
144
193
 
194
+ expect(result.css).toContain('.target {\n transition: transform calc(');
145
195
  expect(result.css).toContain(
146
- 'transform calc(0.326s * var(--oc-motion-duration-scale) * var(--oc-motion-pace-normal) * 1) linear(',
196
+ ' * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
197
+ );
198
+ expect(result.css).not.toContain(
199
+ 'var(--oc-motion-duration-gesture-release)',
147
200
  );
148
- expect(result.css).not.toContain('var(--oc-motion-duration-feedback)');
149
201
  });
150
202
 
151
- it('keeps gesture settle on the token easing path', () => {
203
+ it('applies runtime duration factor and pace tokens to spring-backed motion duration', () => {
152
204
  const result = compileMotion(`
153
205
  .target {
154
- transition: oc-motion(transform, gesture, $phase: settle);
206
+ transition: oc-motion(transform, surface, $pace: slow, $duration-factor: 0.9);
155
207
  }
156
208
  `);
157
209
 
158
210
  expect(result.css).toContain(
159
- 'transform calc(var(--oc-motion-duration-gesture-settle) * var(--oc-motion-duration-scale) * var(--oc-motion-pace-normal) * 1) var(--oc-motion-timing-gesture-settle)',
211
+ 'transform calc(0.486s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-slow) * 0.9) linear(',
160
212
  );
161
- expect(result.css).not.toContain('linear(');
162
213
  });
163
214
 
164
- it('applies runtime duration scale and pace tokens to spring-backed motion duration', () => {
215
+ it('uses smooth spring for surface exit motion', () => {
165
216
  const result = compileMotion(`
166
217
  .target {
167
- transition: oc-motion(transform, reveal, $pace: slow, $duration-scale: 0.9);
218
+ transition: oc-motion((opacity, transform), surface, $phase: exit);
168
219
  }
169
220
  `);
170
221
 
171
222
  expect(result.css).toContain(
172
- 'transform calc(0.58s * var(--oc-motion-duration-scale) * var(--oc-motion-pace-slow) * 0.9) linear(',
223
+ 'opacity calc(0.449s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
224
+ );
225
+ expect(result.css).toContain(
226
+ ', transform calc(0.449s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
173
227
  );
174
228
  });
175
229
 
176
- it('uses smooth spring for reveal exit motion', () => {
230
+ it('allows spring-backed motion to override extra bounce', () => {
177
231
  const result = compileMotion(`
178
- .target {
179
- transition: oc-motion((opacity, transform), reveal, $phase: exit);
232
+ .default {
233
+ transition: oc-motion(transform, disclosure, $phase: enter);
234
+ }
235
+
236
+ .low {
237
+ transition: oc-motion(transform, disclosure, $phase: enter, $extra-bounce: 0);
238
+ }
239
+
240
+ .high {
241
+ transition: oc-motion(transform, disclosure, $phase: enter, $extra-bounce: 0.18);
180
242
  }
181
243
  `);
182
244
 
183
245
  expect(result.css).toContain(
184
- 'opacity calc(0.233s * var(--oc-motion-duration-scale) * var(--oc-motion-pace-normal) * 1) linear(',
185
- );
186
- expect(result.css).toContain(
187
- ', transform calc(0.233s * var(--oc-motion-duration-scale) * var(--oc-motion-pace-normal) * 1) linear(',
246
+ '.default {\n transition: transform calc(0.382s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
188
247
  );
248
+ expect(result.css).toContain('.low {\n transition: transform calc(');
249
+ expect(result.css).toContain('.high {\n transition: transform calc(');
189
250
  });
190
251
 
191
252
  it('emits reduced motion policy from the mixin', () => {
192
253
  const result = compileMotion(`
193
254
  .target {
194
- @include oc-motion((opacity, transform), reveal);
255
+ @include oc-motion((opacity, transform), surface);
195
256
  }
196
257
  `);
197
258
 
198
259
  expect(result.css).toContain(
199
- 'transition: opacity calc(0.561s * var(--oc-motion-duration-scale) * var(--oc-motion-pace-normal) * 1) linear(',
260
+ 'transition: opacity calc(0.486s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
200
261
  );
201
262
  expect(result.css).toContain(
202
- ', transform calc(0.58s * var(--oc-motion-duration-scale) * var(--oc-motion-pace-normal) * 1) linear(',
263
+ ', transform calc(0.486s * var(--oc-motion-duration-factor) * var(--oc-motion-pace-normal) * 1) linear(',
203
264
  );
204
265
  expect(result.css).toContain('@media (prefers-reduced-motion: reduce)');
205
266
  expect(result.css).toContain('transition-property: opacity;');
206
267
  expect(result.css).toContain(
207
- 'transition-duration: calc(var(--oc-motion-duration-reveal) * var(--oc-motion-duration-scale-reduced) * var(--oc-motion-pace-normal) * 1);',
268
+ 'transition-duration: calc(var(--oc-motion-duration-surface) * var(--oc-motion-duration-factor-reduced) * var(--oc-motion-pace-normal) * 1);',
208
269
  );
209
270
  expect(result.css).toContain(
210
- 'transition-timing-function: var(--oc-motion-timing-reveal);',
271
+ 'transition-timing-function: var(--oc-motion-timing-surface);',
211
272
  );
212
273
  expect(result.css).toContain('transform: none;');
213
274
  });
@@ -224,7 +285,7 @@ describe('motion utilities', () => {
224
285
  );
225
286
 
226
287
  expect(reducedCss).toContain(
227
- 'transition-duration: calc(var(--oc-motion-duration-move) * var(--oc-motion-duration-scale-preserve) * var(--oc-motion-pace-normal) * 1);',
288
+ 'transition-duration: calc(var(--oc-motion-duration-move) * var(--oc-motion-duration-factor-preserve) * var(--oc-motion-pace-normal) * 1);',
228
289
  );
229
290
  expect(reducedCss).toContain(
230
291
  'transition-timing-function: var(--oc-motion-timing-move);',
@@ -268,14 +329,14 @@ describe('motion utilities', () => {
268
329
  ).toThrow('Unknown oc-motion pace: 0.85. Use quick, normal, or slow.');
269
330
  });
270
331
 
271
- it('rejects negative duration scale values', () => {
332
+ it('rejects negative duration factor values', () => {
272
333
  expect(() =>
273
334
  compileMotion(`
274
335
  .target {
275
- transition: oc-motion(opacity, feedback, $duration-scale: -0.1);
336
+ transition: oc-motion(opacity, feedback, $duration-factor: -0.1);
276
337
  }
277
338
  `),
278
- ).toThrow('oc-motion $duration-scale must be greater than or equal to 0.');
339
+ ).toThrow('oc-motion $duration-factor must be greater than or equal to 0.');
279
340
  });
280
341
 
281
342
  it('rejects unit scale values', () => {
@@ -302,11 +363,11 @@ describe('motion utilities', () => {
302
363
  expect(() =>
303
364
  compileMotion(`
304
365
  .target {
305
- transition: oc-motion(opacity, reveal, $phase: leave);
366
+ transition: oc-motion(opacity, disclosure, $phase: leave);
306
367
  }
307
368
  `),
308
369
  ).toThrow(
309
- 'Unknown oc-motion phase: leave. Use change, enter, exit, settle, or loop.',
370
+ 'Unknown oc-motion phase: leave. Use change, enter, exit, release, or loop.',
310
371
  );
311
372
  });
312
373
 
@@ -314,7 +375,7 @@ describe('motion utilities', () => {
314
375
  expect(() =>
315
376
  compileMotion(`
316
377
  .target {
317
- transition: oc-motion(opacity, reveal, $duration-token: var(--local-reveal-time));
378
+ transition: oc-motion(opacity, surface, $duration-token: var(--local-surface-time));
318
379
  }
319
380
  `),
320
381
  ).toThrow(
@@ -322,6 +383,28 @@ describe('motion utilities', () => {
322
383
  );
323
384
  });
324
385
 
386
+ it('rejects extra bounce overrides for non-spring motion', () => {
387
+ expect(() =>
388
+ compileMotion(`
389
+ .target {
390
+ transition: oc-motion(opacity, feedback, $extra-bounce: 0.1);
391
+ }
392
+ `),
393
+ ).toThrow(
394
+ 'oc-motion $extra-bounce is only supported for spring-backed motion.',
395
+ );
396
+ });
397
+
398
+ it('rejects unit extra bounce values', () => {
399
+ expect(() =>
400
+ compileMotion(`
401
+ .target {
402
+ transition: oc-motion(transform, surface, $extra-bounce: 10%);
403
+ }
404
+ `),
405
+ ).toThrow('oc-motion $extra-bounce must be a unitless number.');
406
+ });
407
+
325
408
  it('rejects unknown reduced policies', () => {
326
409
  expect(() =>
327
410
  compileMotion(`
@@ -0,0 +1,3 @@
1
+ @function oc-radius($radius, $factor-token: var(--oc-atomic-radius-factor)) {
2
+ @return max(0px, calc(#{$radius} * #{$factor-token}));
3
+ }
@@ -0,0 +1,52 @@
1
+ import { compileString } from 'sass';
2
+ import { describe, expect, it } from 'vitest';
3
+
4
+ describe('radius utilities', () => {
5
+ const compileRadius = (scss: string) =>
6
+ compileString(
7
+ `
8
+ @use 'mixins/radius' as *;
9
+
10
+ ${scss}
11
+ `,
12
+ {
13
+ loadPaths: ['src/scss'],
14
+ },
15
+ );
16
+
17
+ it('applies the atomic radius factor to length values', () => {
18
+ const result = compileRadius(`
19
+ .target {
20
+ border-radius: oc-radius(0.5rem);
21
+ }
22
+ `);
23
+
24
+ expect(result.css).toContain(
25
+ 'border-radius: max(0px, 0.5rem * var(--oc-atomic-radius-factor));',
26
+ );
27
+ });
28
+
29
+ it('keeps em radius values relative while applying the radius factor', () => {
30
+ const result = compileRadius(`
31
+ .target {
32
+ --local-radius: #{oc-radius(0.4em)};
33
+ }
34
+ `);
35
+
36
+ expect(result.css).toContain(
37
+ '--local-radius: max(0px, 0.4em * var(--oc-atomic-radius-factor));',
38
+ );
39
+ });
40
+
41
+ it('accepts a custom factor token', () => {
42
+ const result = compileRadius(`
43
+ .target {
44
+ border-radius: oc-radius(12px, var(--local-radius-factor));
45
+ }
46
+ `);
47
+
48
+ expect(result.css).toContain(
49
+ 'border-radius: max(0px, 12px * var(--local-radius-factor));',
50
+ );
51
+ });
52
+ });
@@ -4,8 +4,8 @@
4
4
  @use './utils' as *;
5
5
 
6
6
  @mixin typo($variant, $weight: normal) {
7
- font-size: calc(var(--oc-typo-size-#{$variant}) * var(--oc-typo-scale, 1));
8
- line-height: calc(var(--oc-typo-height-#{$variant}) * var(--oc-typo-scale, 1));
7
+ font-size: calc(var(--oc-typo-size-#{$variant}) * var(--oc-typo-size-factor, 1));
8
+ line-height: calc(var(--oc-typo-height-#{$variant}) * var(--oc-typo-size-factor, 1));
9
9
  letter-spacing: var(--oc-typo-spacing-#{$variant});
10
10
 
11
11
  @if $weight == normal {