@mezzanine-ui/system 0.15.3 → 1.0.0-alpha.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 (58) hide show
  1. package/_system.scss +46 -7
  2. package/effect/_effect.scss +63 -0
  3. package/effect/_index.scss +1 -0
  4. package/effect/constants.d.ts +1 -0
  5. package/effect/constants.js +3 -0
  6. package/effect/index.d.ts +2 -0
  7. package/effect/index.js +1 -0
  8. package/effect/typings.d.ts +32 -0
  9. package/motion/_motion.scss +47 -11
  10. package/motion/duration.d.ts +1 -1
  11. package/motion/duration.js +6 -5
  12. package/motion/easing.d.ts +1 -1
  13. package/motion/easing.js +3 -4
  14. package/package.json +2 -2
  15. package/palette/_index.scss +3 -1
  16. package/palette/_palette.scss +3 -203
  17. package/palette/_primitives.scss +267 -0
  18. package/palette/_semantic.scss +537 -0
  19. package/palette/constants.d.ts +1 -1
  20. package/palette/constants.js +2 -2
  21. package/palette/index.js +1 -1
  22. package/palette/typings.d.ts +86 -0
  23. package/radius/_index.scss +1 -0
  24. package/radius/_radius.scss +71 -0
  25. package/radius/constants.d.ts +1 -0
  26. package/radius/constants.js +3 -0
  27. package/radius/index.d.ts +3 -0
  28. package/radius/index.js +2 -0
  29. package/radius/radius.d.ts +18 -0
  30. package/radius/radius.js +32 -0
  31. package/size/_size.scss +6 -1
  32. package/size/size.d.ts +2 -0
  33. package/spacing/_index.scss +3 -1
  34. package/spacing/_primitives.scss +137 -0
  35. package/spacing/_semantic.scss +566 -0
  36. package/spacing/_spacing.scss +2 -18
  37. package/spacing/constants.d.ts +1 -0
  38. package/spacing/constants.js +2 -1
  39. package/spacing/index.js +1 -1
  40. package/spacing/toSpacingCssVar.d.ts +1 -0
  41. package/spacing/toSpacingCssVar.js +1 -0
  42. package/spacing/typings.d.ts +81 -0
  43. package/transition/_transition.scss +25 -9
  44. package/typography/SF-Mono/SFMonoMedium.woff +0 -0
  45. package/typography/SF-Mono/SFMonoRegular.woff +0 -0
  46. package/typography/SF-Mono/SFMonoSemibold.woff +0 -0
  47. package/typography/_index.scss +4 -1
  48. package/typography/_primitives.scss +318 -0
  49. package/typography/_semantic.scss +237 -0
  50. package/typography/_sf-mono.scss +34 -0
  51. package/typography/_typography.scss +4 -248
  52. package/typography/_utils.scss +4 -0
  53. package/typography/index.js +1 -0
  54. package/typography/typings.d.ts +9 -1
  55. package/typography/typings.js +4 -0
  56. package/z-index/_z-index.scss +1 -1
  57. package/palette/_constants.scss +0 -267
  58. package/palette/_utils.scss +0 -47
@@ -0,0 +1,566 @@
1
+ @use '../utils/list';
2
+ @use '../utils/map';
3
+ @use './primitives' as primitive;
4
+
5
+ $prefix: mzn-spacing;
6
+
7
+ // 定義所有情境類型
8
+ $semantic-contexts: (size, gap, padding);
9
+
10
+ // 定義 size 的子分類
11
+ $size-categories: (element, container);
12
+
13
+ // 定義 padding 的子分類
14
+ $padding-categories: (horizontal, vertical);
15
+
16
+ // 定義各個分類下的 tones
17
+ $element-tones: (
18
+ hairline,
19
+ micro,
20
+ tiny,
21
+ tight,
22
+ compact,
23
+ slim,
24
+ narrow,
25
+ base,
26
+ base-fixed,
27
+ gentle,
28
+ relaxed,
29
+ airy,
30
+ roomy,
31
+ loose,
32
+ extra-wide,
33
+ extra-wide-condense,
34
+ expansive,
35
+ extra,
36
+ max
37
+ );
38
+
39
+ $container-tones: (
40
+ collapsed,
41
+ compressed,
42
+ tiny,
43
+ snug,
44
+ tight,
45
+ slim,
46
+ narrow,
47
+ compact,
48
+ standard,
49
+ balanced,
50
+ broad,
51
+ wide,
52
+ expanded,
53
+ max
54
+ );
55
+
56
+ $horizontal-tones: (
57
+ none,
58
+ micro,
59
+ tiny,
60
+ tiny-fixed,
61
+ tight,
62
+ tight-fixed,
63
+ base,
64
+ base-fixed,
65
+ calm,
66
+ comfort,
67
+ comfort-fixed,
68
+ roomy,
69
+ spacious,
70
+ open,
71
+ relaxed,
72
+ airy,
73
+ breath,
74
+ wide,
75
+ max,
76
+ ultra
77
+ );
78
+
79
+ $vertical-tones: (
80
+ none,
81
+ micro,
82
+ tiny,
83
+ tight,
84
+ base,
85
+ calm,
86
+ comfort,
87
+ roomy,
88
+ spacious,
89
+ generous,
90
+ relaxed
91
+ );
92
+
93
+ $semantic-spacings: (
94
+ size: (
95
+ element: (
96
+ hairline: (
97
+ default: primitive.variable(1),
98
+ compact: primitive.variable(1),
99
+ ),
100
+ micro: (
101
+ default: primitive.variable(3),
102
+ compact: primitive.variable(3),
103
+ ),
104
+ tiny: (
105
+ default: primitive.variable(4),
106
+ compact: primitive.variable(4),
107
+ ),
108
+ tight: (
109
+ default: primitive.variable(6),
110
+ compact: primitive.variable(6),
111
+ ),
112
+ compact: (
113
+ default: primitive.variable(8),
114
+ compact: primitive.variable(6),
115
+ ),
116
+ slim: (
117
+ default: primitive.variable(12),
118
+ compact: primitive.variable(8),
119
+ ),
120
+ narrow: (
121
+ default: primitive.variable(14),
122
+ compact: primitive.variable(12),
123
+ ),
124
+ base: (
125
+ default: primitive.variable(16),
126
+ compact: primitive.variable(12),
127
+ ),
128
+ base-fixed: (
129
+ default: primitive.variable(16),
130
+ compact: primitive.variable(16),
131
+ ),
132
+ gentle: (
133
+ default: primitive.variable(20),
134
+ compact: primitive.variable(18),
135
+ ),
136
+ relaxed: (
137
+ default: primitive.variable(24),
138
+ compact: primitive.variable(20),
139
+ ),
140
+ airy: (
141
+ default: primitive.variable(28),
142
+ compact: primitive.variable(24),
143
+ ),
144
+ roomy: (
145
+ default: primitive.variable(32),
146
+ compact: primitive.variable(28),
147
+ ),
148
+ loose: (
149
+ default: primitive.variable(36),
150
+ compact: primitive.variable(32),
151
+ ),
152
+ extra-wide: (
153
+ default: primitive.variable(40),
154
+ compact: primitive.variable(36),
155
+ ),
156
+ extra-wide-condense: (
157
+ default: primitive.variable(40),
158
+ compact: primitive.variable(24),
159
+ ),
160
+ expansive: (
161
+ default: primitive.variable(60),
162
+ compact: primitive.variable(24),
163
+ ),
164
+ extra: (
165
+ default: primitive.variable(64),
166
+ compact: primitive.variable(48),
167
+ ),
168
+ max: (
169
+ default: primitive.variable(80),
170
+ compact: primitive.variable(64),
171
+ ),
172
+ ),
173
+ container: (
174
+ collapsed: (
175
+ default: primitive.variable(52),
176
+ compact: primitive.variable(52),
177
+ ),
178
+ compressed: (
179
+ default: primitive.variable(70),
180
+ compact: primitive.variable(70),
181
+ ),
182
+ tiny: (
183
+ default: primitive.variable(80),
184
+ compact: primitive.variable(80),
185
+ ),
186
+ snug: (
187
+ default: primitive.variable(140),
188
+ compact: primitive.variable(140),
189
+ ),
190
+ tight: (
191
+ default: primitive.variable(160),
192
+ compact: primitive.variable(160),
193
+ ),
194
+ slim: (
195
+ default: primitive.variable(240),
196
+ compact: primitive.variable(240),
197
+ ),
198
+ narrow: (
199
+ default: primitive.variable(320),
200
+ compact: primitive.variable(320),
201
+ ),
202
+ compact: (
203
+ default: primitive.variable(360),
204
+ compact: primitive.variable(360),
205
+ ),
206
+ standard: (
207
+ default: primitive.variable(400),
208
+ compact: primitive.variable(400),
209
+ ),
210
+ balanced: (
211
+ default: primitive.variable(480),
212
+ compact: primitive.variable(480),
213
+ ),
214
+ broad: (
215
+ default: primitive.variable(560),
216
+ compact: primitive.variable(560),
217
+ ),
218
+ wide: (
219
+ default: primitive.variable(640),
220
+ compact: primitive.variable(640),
221
+ ),
222
+ expanded: (
223
+ default: primitive.variable(720),
224
+ compact: primitive.variable(720),
225
+ ),
226
+ max: (
227
+ default: primitive.variable(960),
228
+ compact: primitive.variable(960),
229
+ ),
230
+ ),
231
+ ),
232
+ gap: (
233
+ none: (
234
+ default: primitive.variable(0),
235
+ compact: primitive.variable(0),
236
+ ),
237
+ tiny: (
238
+ default: primitive.variable(2),
239
+ compact: primitive.variable(2),
240
+ ),
241
+ tight: (
242
+ default: primitive.variable(4),
243
+ compact: primitive.variable(2),
244
+ ),
245
+ tight-fixed: (
246
+ default: primitive.variable(4),
247
+ compact: primitive.variable(4),
248
+ ),
249
+ slim: (
250
+ default: primitive.variable(6),
251
+ compact: primitive.variable(4),
252
+ ),
253
+ base: (
254
+ default: primitive.variable(8),
255
+ compact: primitive.variable(6),
256
+ ),
257
+ calm: (
258
+ default: primitive.variable(12),
259
+ compact: primitive.variable(10),
260
+ ),
261
+ comfort: (
262
+ default: primitive.variable(16),
263
+ compact: primitive.variable(14),
264
+ ),
265
+ roomy: (
266
+ default: primitive.variable(20),
267
+ compact: primitive.variable(16),
268
+ ),
269
+ spacious: (
270
+ default: primitive.variable(24),
271
+ compact: primitive.variable(20),
272
+ ),
273
+ loose: (
274
+ default: primitive.variable(40),
275
+ compact: primitive.variable(36),
276
+ ),
277
+ ),
278
+ padding: (
279
+ horizontal: (
280
+ none: (
281
+ default: primitive.variable(0),
282
+ compact: primitive.variable(0),
283
+ ),
284
+ micro: (
285
+ default: primitive.variable(2),
286
+ compact: primitive.variable(2),
287
+ ),
288
+ tiny: (
289
+ default: primitive.variable(4),
290
+ compact: primitive.variable(2),
291
+ ),
292
+ tiny-fixed: (
293
+ default: primitive.variable(4),
294
+ compact: primitive.variable(4),
295
+ ),
296
+ tight: (
297
+ default: primitive.variable(6),
298
+ compact: primitive.variable(4),
299
+ ),
300
+ tight-fixed: (
301
+ default: primitive.variable(6),
302
+ compact: primitive.variable(6),
303
+ ),
304
+ base: (
305
+ default: primitive.variable(8),
306
+ compact: primitive.variable(4),
307
+ ),
308
+ base-fixed: (
309
+ default: primitive.variable(8),
310
+ compact: primitive.variable(8),
311
+ ),
312
+ cozy: (
313
+ default: primitive.variable(10),
314
+ compact: primitive.variable(8),
315
+ ),
316
+ comfort: (
317
+ default: primitive.variable(12),
318
+ compact: primitive.variable(10),
319
+ ),
320
+ comfort-fixed: (
321
+ default: primitive.variable(12),
322
+ compact: primitive.variable(12),
323
+ ),
324
+ roomy: (
325
+ default: primitive.variable(14),
326
+ compact: primitive.variable(12),
327
+ ),
328
+ spacious: (
329
+ default: primitive.variable(16),
330
+ compact: primitive.variable(14),
331
+ ),
332
+ open: (
333
+ default: primitive.variable(20),
334
+ compact: primitive.variable(16),
335
+ ),
336
+ relaxed: (
337
+ default: primitive.variable(24),
338
+ compact: primitive.variable(20),
339
+ ),
340
+ airy: (
341
+ default: primitive.variable(28),
342
+ compact: primitive.variable(24),
343
+ ),
344
+ breath: (
345
+ default: primitive.variable(32),
346
+ compact: primitive.variable(28),
347
+ ),
348
+ wide: (
349
+ default: primitive.variable(40),
350
+ compact: primitive.variable(36),
351
+ ),
352
+ max: (
353
+ default: primitive.variable(48),
354
+ compact: primitive.variable(40),
355
+ ),
356
+ ultra: (
357
+ default: primitive.variable(64),
358
+ compact: primitive.variable(56),
359
+ ),
360
+ ),
361
+ vertical: (
362
+ none: (
363
+ default: primitive.variable(0),
364
+ compact: primitive.variable(0),
365
+ ),
366
+ micro: (
367
+ default: primitive.variable(2),
368
+ compact: primitive.variable(2),
369
+ ),
370
+ tiny: (
371
+ default: primitive.variable(4),
372
+ compact: primitive.variable(2),
373
+ ),
374
+ tight: (
375
+ default: primitive.variable(6),
376
+ compact: primitive.variable(4),
377
+ ),
378
+ base: (
379
+ default: primitive.variable(8),
380
+ compact: primitive.variable(4),
381
+ ),
382
+ calm: (
383
+ default: primitive.variable(10),
384
+ compact: primitive.variable(6),
385
+ ),
386
+ comfort: (
387
+ default: primitive.variable(12),
388
+ compact: primitive.variable(8),
389
+ ),
390
+ roomy: (
391
+ default: primitive.variable(14),
392
+ compact: primitive.variable(10),
393
+ ),
394
+ spacious: (
395
+ default: primitive.variable(16),
396
+ compact: primitive.variable(12),
397
+ ),
398
+ generous: (
399
+ default: primitive.variable(20),
400
+ compact: primitive.variable(14),
401
+ ),
402
+ relaxed: (
403
+ default: primitive.variable(24),
404
+ compact: primitive.variable(16),
405
+ ),
406
+ ),
407
+ ),
408
+ );
409
+
410
+ // 驗證 context 是否有效
411
+ @function is-valid-context($context) {
412
+ @return list.index($semantic-contexts, $context) != null;
413
+ }
414
+
415
+ // 驗證 category 是否對該 context 有效
416
+ @function is-valid-category($context, $category) {
417
+ @if $context == size {
418
+ @return list.index($size-categories, $category) != null;
419
+ } @else if $context == padding {
420
+ @return list.index($padding-categories, $category) != null;
421
+ }
422
+
423
+ // gap 沒有 category
424
+ @return false;
425
+ }
426
+
427
+ // 驗證 tone 是否對該 context/category 有效
428
+ @function is-valid-tone($context, $category, $tone, $spacings: $semantic-spacings) {
429
+ @if not is-valid-context($context) {
430
+ @return false;
431
+ }
432
+
433
+ $context-map: map.get($spacings, $context);
434
+
435
+ @if not $context-map {
436
+ @return false;
437
+ }
438
+
439
+ // gap 沒有 category,直接檢查 tone
440
+ @if $context == gap {
441
+ @return map.has-key($context-map, $tone);
442
+ }
443
+
444
+ // size 和 padding 需要先檢查 category
445
+ @if not $category {
446
+ @return false;
447
+ }
448
+
449
+ $category-map: map.get($context-map, $category);
450
+
451
+ @if not $category-map {
452
+ @return false;
453
+ }
454
+
455
+ @return map.has-key($category-map, $tone);
456
+ }
457
+
458
+ // 取得特定 context 的所有 categories(僅適用於 size 和 padding)
459
+ @function get-context-categories($context) {
460
+ @if $context == size {
461
+ @return $size-categories;
462
+ } @else if $context == padding {
463
+ @return $padding-categories;
464
+ }
465
+
466
+ @return ();
467
+ }
468
+
469
+ // 取得特定 context/category 的所有 tones
470
+ @function get-tones($context, $category: null) {
471
+ @if $context == gap {
472
+ @return map.keys(map.get($semantic-spacings, gap));
473
+ }
474
+
475
+ @if $context == size and $category == element {
476
+ @return $element-tones;
477
+ } @else if $context == size and $category == container {
478
+ @return $container-tones;
479
+ } @else if $context == padding and $category == horizontal {
480
+ @return $horizontal-tones;
481
+ } @else if $context == padding and $category == vertical {
482
+ @return $vertical-tones;
483
+ }
484
+
485
+ @return ();
486
+ }
487
+
488
+ // 取得 CSS 變數名稱
489
+ // size: --mzn-spacing-size-element-base
490
+ // gap: --mzn-spacing-gap-base
491
+ // padding: --mzn-spacing-padding-horizontal-base
492
+ @function get-var-name($context, $category, $tone: null) {
493
+ // gap 沒有 category,tone 在第二個參數
494
+ @if $context == gap {
495
+ @return --#{$prefix}-#{$context}-#{$category};
496
+ }
497
+
498
+ // size 和 padding 有 category
499
+ @return --#{$prefix}-#{$context}-#{$category}-#{$tone};
500
+ }
501
+
502
+ // 使用 CSS 變數引用 spacing
503
+ @function variable($context, $category, $tone: null) {
504
+ @if not is-valid-context($context) {
505
+ @error 'Invalid context "#{$context}". Valid contexts are: #{$semantic-contexts}';
506
+ }
507
+
508
+ @return var(#{get-var-name($context, $category, $tone)});
509
+ }
510
+
511
+ // 檢查 spacing 值是否已定義
512
+ @function is-spacing-defined($value) {
513
+ @return $value != null;
514
+ }
515
+
516
+ // 生成所有 semantic spacing CSS 變數
517
+ // mode: 'default' 或 'compact'
518
+ @mixin variables($mode: default, $spacings: ()) {
519
+ @include primitive.variables();
520
+
521
+ $spacings: map.deep-merge($semantic-spacings, $spacings);
522
+
523
+ @each $context, $context-value in $spacings {
524
+ @if not is-valid-context($context) {
525
+ @error 'Invalid context "#{$context}" in semantic spacings map. Valid contexts are: #{$semantic-contexts}';
526
+ }
527
+
528
+ @if $context == gap {
529
+ @each $tone, $modes in $context-value {
530
+ @if not is-valid-tone($context, null, $tone, $spacings) {
531
+ $valid-tones: get-tones($context);
532
+
533
+ @error 'Invalid tone "#{$tone}" for context "#{$context}". Valid tones are: #{$valid-tones}';
534
+ }
535
+
536
+ $spacing: map.get($modes, $mode);
537
+
538
+ @if is-spacing-defined($spacing) {
539
+ #{get-var-name($context, $tone)}: #{$spacing};
540
+ }
541
+ }
542
+ } @else {
543
+ @each $category, $category-value in $context-value {
544
+ @if not is-valid-category($context, $category) {
545
+ $valid-categories: get-context-categories($context);
546
+
547
+ @error 'Invalid category "#{$category}" for context "#{$context}". Valid categories are: #{$valid-categories}';
548
+ }
549
+
550
+ @each $tone, $modes in $category-value {
551
+ @if not is-valid-tone($context, $category, $tone, $spacings) {
552
+ $valid-tones: get-tones($context, $category);
553
+
554
+ @error 'Invalid tone "#{$tone}" for context "#{$context}" and category "#{$category}". Valid tones are: #{$valid-tones}';
555
+ }
556
+
557
+ $spacing: map.get($modes, $mode);
558
+
559
+ @if is-spacing-defined($spacing) {
560
+ #{get-var-name($context, $category, $tone)}: #{$spacing};
561
+ }
562
+ }
563
+ }
564
+ }
565
+ }
566
+ }
@@ -1,20 +1,4 @@
1
- @use 'sass:list';
2
- @use '../typography/utils' as utils-typography;
3
-
4
- $prefix: mzn-spacing;
5
- // The spacing level starts from 1.
6
- $default-levels: (4px, 8px, 12px, 16px, 24px, 32px, 40px, 48px, 64px, 96px, 160px);
7
-
8
- @mixin variables($levels: $default-levels) {
9
- // Use `index` as level since list of sass starts with 1.
10
- @for $level from 1 through list.length($levels) {
11
- $size: list.nth($levels, $level);
12
- $size: utils-typography.px-to-rem($size);
13
-
14
- --#{$prefix}-#{$level}: #{$size};
15
- }
16
- }
17
-
1
+ /* @deprecated */
18
2
  @function level($level) {
19
- @return var(--#{$prefix}-#{$level});
3
+ @return 0;
20
4
  }
@@ -1 +1,2 @@
1
1
  export declare const spacingPrefix = "mzn-spacing";
2
+ export declare const spacingPrimitivePrefix = "mzn-spacing-primitive";
@@ -1,3 +1,4 @@
1
1
  const spacingPrefix = 'mzn-spacing';
2
+ const spacingPrimitivePrefix = `${spacingPrefix}-primitive`;
2
3
 
3
- export { spacingPrefix };
4
+ export { spacingPrefix, spacingPrimitivePrefix };
package/spacing/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { spacingPrefix } from './constants.js';
1
+ export { spacingPrefix, spacingPrimitivePrefix } from './constants.js';
2
2
  export { toSpacingCssVar } from './toSpacingCssVar.js';
@@ -1,2 +1,3 @@
1
1
  import { SpacingLevel } from './typings';
2
+ /** @deprecated */
2
3
  export declare function toSpacingCssVar(level: SpacingLevel): string;
@@ -1,6 +1,7 @@
1
1
  import { spacingPrefix } from './constants.js';
2
2
  import { toCssVar } from '../css/toCssVar.js';
3
3
 
4
+ /** @deprecated */
4
5
  function toSpacingCssVar(level) {
5
6
  return toCssVar(`${spacingPrefix}-${level}`);
6
7
  }
@@ -1 +1,82 @@
1
+ /** @deprecated */
1
2
  export type SpacingLevel = number;
3
+ /**
4
+ * Spacing primitive scales - 間距原始級距(對應 px 值)
5
+ */
6
+ export type SpacingScale = 0 | 1 | 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 24 | 28 | 32 | 36 | 40 | 48 | 52 | 56 | 60 | 64 | 80 | 160 | 240 | 320 | 360 | 400 | 480 | 560 | 640 | 720 | 960 | 1140;
7
+ /**
8
+ * Spacing primitives configuration
9
+ */
10
+ export type SpacingPrimitives = Partial<Record<SpacingScale, string | number>>;
11
+ /**
12
+ * Spacing semantic contexts - 語意化間距的使用情境
13
+ */
14
+ export type SpacingContext = 'size' | 'gap' | 'padding';
15
+ /**
16
+ * Spacing mode - 間距模式
17
+ */
18
+ export type SpacingMode = 'default' | 'compact';
19
+ /**
20
+ * Size categories - 尺寸分類
21
+ */
22
+ export type SizeCategory = 'element' | 'container';
23
+ /**
24
+ * Padding categories - 內邊距分類
25
+ */
26
+ export type PaddingCategory = 'horizontal' | 'vertical';
27
+ /**
28
+ * Element size tones - 元素尺寸調性
29
+ */
30
+ export type ElementTone = 'hairline' | 'tiny' | 'tight' | 'compact' | 'slim' | 'narrow' | 'base' | 'base-fixed' | 'gentle' | 'relaxed' | 'airy' | 'roomy' | 'loose' | 'extra-wide' | 'extra-wide-condense' | 'expansive' | 'extra' | 'max';
31
+ /**
32
+ * Container size tones - 容器尺寸調性
33
+ */
34
+ export type ContainerTone = 'collapsed' | 'tiny' | 'tight' | 'slim' | 'narrow' | 'compact' | 'standard' | 'balanced' | 'broad' | 'wide' | 'expanded' | 'max';
35
+ /**
36
+ * Gap tones - 間隙調性
37
+ */
38
+ export type GapTone = 'none' | 'micro' | 'tiny' | 'tight' | 'compact' | 'base' | 'base-fixed' | 'comfortable' | 'roomy' | 'spacious' | 'relaxed' | 'airy' | 'generous' | 'breath' | 'wide';
39
+ /**
40
+ * Horizontal padding tones - 水平內邊距調性
41
+ */
42
+ export type HorizontalPaddingTone = 'none' | 'micro' | 'tiny' | 'tiny-fixed' | 'tight' | 'tight-fixed' | 'base' | 'base-fixed' | 'calm' | 'comfort' | 'comfort-fixed' | 'roomy' | 'spacious' | 'relaxed' | 'airy' | 'breath' | 'wide' | 'max';
43
+ /**
44
+ * Vertical padding tones - 垂直內邊距調性
45
+ */
46
+ export type VerticalPaddingTone = 'none' | 'micro' | 'tiny' | 'tight' | 'base' | 'calm' | 'comfort' | 'roomy' | 'spacious' | 'generous' | 'relaxed';
47
+ /**
48
+ * Category 與對應 Tone 的映射型別
49
+ */
50
+ export type SpacingToneMap = {
51
+ size: {
52
+ element: ElementTone;
53
+ container: ContainerTone;
54
+ };
55
+ gap: GapTone;
56
+ padding: {
57
+ horizontal: HorizontalPaddingTone;
58
+ vertical: VerticalPaddingTone;
59
+ };
60
+ };
61
+ /**
62
+ * 取得特定 context 的 tone 型別
63
+ * @example
64
+ * type GapT = SpacingToneFor<'gap'>; // GapTone
65
+ */
66
+ export type SpacingToneFor<C extends SpacingContext> = SpacingToneMap[C] extends infer T ? T extends {
67
+ element: any;
68
+ } ? never : T : never;
69
+ /**
70
+ * 取得特定 context + category 的 tone 型別
71
+ * @example
72
+ * type EleTone = SpacingCategoryToneFor<'size', 'element'>; // ElementTone
73
+ */
74
+ export type SpacingCategoryToneFor<C extends SpacingContext, Cat extends C extends 'size' ? SizeCategory : C extends 'padding' ? PaddingCategory : never> = C extends 'size' ? Cat extends SizeCategory ? SpacingToneMap['size'][Cat] : never : C extends 'padding' ? Cat extends PaddingCategory ? SpacingToneMap['padding'][Cat] : never : never;
75
+ /**
76
+ * Semantic spacing 完整型別 - context + category + tone 組合
77
+ * @example
78
+ * const spacing1: SemanticSpacing = 'size-element-base';
79
+ * const spacing2: SemanticSpacing = 'gap-comfortable';
80
+ * const spacing3: SemanticSpacing = 'padding-horizontal-calm';
81
+ */
82
+ export type SemanticSpacing = `size-element-${ElementTone}` | `size-container-${ContainerTone}` | `gap-${GapTone}` | `padding-horizontal-${HorizontalPaddingTone}` | `padding-vertical-${VerticalPaddingTone}`;