@teseor/css 1.1.0 → 1.2.1

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 (236) hide show
  1. package/dist/compiled.css +1967 -1877
  2. package/dist/index.css +2015 -1925
  3. package/package.json +1 -1
  4. package/src/00-config/tokens/_variables.scss +39 -25
  5. package/src/00-config/tokens/colors/index.scss +22 -21
  6. package/src/00-config/tokens/shadows/index.scss +3 -3
  7. package/src/03-layout/cluster/cluster-visual.png +0 -0
  8. package/src/03-layout/cluster/cluster.visual.spec.ts +15 -0
  9. package/src/03-layout/sidebar/sidebar-visual.png +0 -0
  10. package/src/03-layout/sidebar/sidebar.docs.json +62 -0
  11. package/src/03-layout/sidebar/sidebar.visual.spec.ts +14 -0
  12. package/src/03-layout/sidebar-nav/sidebar-nav.api.json +29 -80
  13. package/src/04-components/actions/button/button-visual.png +0 -0
  14. package/src/04-components/{button → actions/button}/button.api.json +30 -56
  15. package/src/04-components/{button → actions/button}/button.docs.json +75 -0
  16. package/src/04-components/{button → actions/button}/button.visual.spec.ts +1 -1
  17. package/src/04-components/{button → actions/button}/index.scss +28 -18
  18. package/src/04-components/actions/button-group/button-group-visual.png +0 -0
  19. package/src/04-components/{button-group → actions/button-group}/button-group.api.json +5 -1
  20. package/src/04-components/{button-group → actions/button-group}/button-group.visual.spec.ts +3 -2
  21. package/src/04-components/{button-group → actions/button-group}/index.scss +1 -1
  22. package/src/04-components/{avatar → data-display/avatar}/avatar.api.json +5 -0
  23. package/src/04-components/{avatar → data-display/avatar}/avatar.visual.spec.ts +1 -1
  24. package/src/04-components/{avatar → data-display/avatar}/index.scss +1 -1
  25. package/src/04-components/{badge → data-display/badge}/badge.visual.spec.ts +1 -1
  26. package/src/04-components/{badge → data-display/badge}/index.scss +13 -10
  27. package/src/04-components/{card → data-display/card}/card.visual.spec.ts +1 -1
  28. package/src/04-components/{card → data-display/card}/index.scss +1 -1
  29. package/src/04-components/data-display/data-list/data-list-visual.png +0 -0
  30. package/src/04-components/{data-list → data-display/data-list}/data-list.api.json +16 -1
  31. package/src/04-components/{data-list → data-display/data-list}/data-list.visual.spec.ts +3 -2
  32. package/src/04-components/{data-list → data-display/data-list}/index.scss +4 -3
  33. package/src/04-components/data-display/icon/icon-visual.png +0 -0
  34. package/src/04-components/{icon → data-display/icon}/icon.api.json +7 -6
  35. package/src/04-components/{icon → data-display/icon}/icon.docs.json +86 -22
  36. package/src/04-components/{icon → data-display/icon}/icon.visual.spec.ts +1 -1
  37. package/src/04-components/{icon → data-display/icon}/index.scss +7 -20
  38. package/src/04-components/{status → data-display/status}/index.scss +1 -1
  39. package/src/04-components/{status → data-display/status}/status.api.json +14 -1
  40. package/src/04-components/{status → data-display/status}/status.visual.spec.ts +1 -1
  41. package/src/04-components/{table → data-display/table}/index.scss +1 -1
  42. package/src/04-components/{table → data-display/table}/table.api.json +8 -1
  43. package/src/04-components/{table → data-display/table}/table.visual.spec.ts +1 -1
  44. package/src/04-components/{tag → data-display/tag}/index.scss +1 -1
  45. package/src/04-components/{tag → data-display/tag}/tag.api.json +4 -0
  46. package/src/04-components/{tag → data-display/tag}/tag.visual.spec.ts +1 -1
  47. package/src/04-components/{accordion → disclosure/accordion}/accordion.api.json +5 -1
  48. package/src/04-components/{accordion → disclosure/accordion}/accordion.visual.spec.ts +1 -1
  49. package/src/04-components/{accordion → disclosure/accordion}/index.scss +1 -1
  50. package/src/04-components/disclosure/{disclosure.api.json → disclosure/disclosure.api.json} +13 -1
  51. package/src/04-components/disclosure/{disclosure.visual.spec.ts → disclosure/disclosure.visual.spec.ts} +1 -1
  52. package/src/04-components/disclosure/{index.scss → disclosure/index.scss} +1 -1
  53. package/src/04-components/{alert → feedback/alert}/alert.api.json +6 -0
  54. package/src/04-components/{alert → feedback/alert}/alert.visual.spec.ts +1 -1
  55. package/src/04-components/{alert → feedback/alert}/index.scss +11 -16
  56. package/src/04-components/{progress → feedback/progress}/index.scss +1 -1
  57. package/src/04-components/{progress → feedback/progress}/progress.api.json +20 -1
  58. package/src/04-components/{progress → feedback/progress}/progress.visual.spec.ts +1 -1
  59. package/src/04-components/{skeleton → feedback/skeleton}/index.scss +1 -1
  60. package/src/04-components/{skeleton → feedback/skeleton}/skeleton.api.json +8 -1
  61. package/src/04-components/{skeleton → feedback/skeleton}/skeleton.visual.spec.ts +1 -1
  62. package/src/04-components/{spinner → feedback/spinner}/index.scss +1 -1
  63. package/src/04-components/{spinner → feedback/spinner}/spinner.visual.spec.ts +1 -1
  64. package/src/04-components/{toast → feedback/toast}/index.scss +1 -1
  65. package/src/04-components/{toast → feedback/toast}/toast.api.json +22 -1
  66. package/src/04-components/{toast → feedback/toast}/toast.visual.spec.ts +1 -1
  67. package/src/04-components/forms/checkbox/checkbox-visual.png +0 -0
  68. package/src/04-components/{checkbox → forms/checkbox}/checkbox.api.json +1 -1
  69. package/src/04-components/{checkbox → forms/checkbox}/checkbox.visual.spec.ts +1 -1
  70. package/src/04-components/{checkbox → forms/checkbox}/index.scss +1 -1
  71. package/src/04-components/forms/field/field.api.json +19 -0
  72. package/src/04-components/{field → forms/field}/field.visual.spec.ts +1 -1
  73. package/src/04-components/{field → forms/field}/index.scss +1 -1
  74. package/src/04-components/forms/form-error/form-error-visual.png +0 -0
  75. package/src/04-components/{form-error → forms/form-error}/form-error.api.json +3 -0
  76. package/src/04-components/{form-error → forms/form-error}/form-error.visual.spec.ts +1 -1
  77. package/src/04-components/{form-error → forms/form-error}/index.scss +1 -1
  78. package/src/04-components/{form-helper → forms/form-helper}/form-helper.visual.spec.ts +1 -1
  79. package/src/04-components/{form-helper → forms/form-helper}/index.scss +1 -1
  80. package/src/04-components/{input → forms/input}/index.scss +1 -1
  81. package/src/04-components/forms/input/input-visual.png +0 -0
  82. package/src/04-components/{input → forms/input}/input.api.json +31 -0
  83. package/src/04-components/{input → forms/input}/input.visual.spec.ts +1 -1
  84. package/src/04-components/{label → forms/label}/index.scss +1 -1
  85. package/src/04-components/{label → forms/label}/label.api.json +4 -0
  86. package/src/04-components/{label → forms/label}/label.visual.spec.ts +1 -1
  87. package/src/04-components/{radio → forms/radio}/index.scss +1 -1
  88. package/src/04-components/forms/radio/radio-visual.png +0 -0
  89. package/src/04-components/{radio → forms/radio}/radio.api.json +1 -1
  90. package/src/04-components/{radio → forms/radio}/radio.visual.spec.ts +1 -1
  91. package/src/04-components/{select → forms/select}/index.scss +1 -1
  92. package/src/04-components/{select → forms/select}/select.api.json +3 -0
  93. package/src/04-components/{select → forms/select}/select.visual.spec.ts +1 -1
  94. package/src/04-components/{textarea → forms/textarea}/index.scss +1 -1
  95. package/src/04-components/{textarea → forms/textarea}/textarea.api.json +3 -0
  96. package/src/04-components/{textarea → forms/textarea}/textarea.visual.spec.ts +1 -1
  97. package/src/04-components/{toggle → forms/toggle}/index.scss +1 -1
  98. package/src/04-components/{toggle → forms/toggle}/toggle.api.json +5 -0
  99. package/src/04-components/{toggle → forms/toggle}/toggle.visual.spec.ts +1 -1
  100. package/src/04-components/index.scss +42 -41
  101. package/src/04-components/{divider → layout/divider}/divider.api.json +3 -0
  102. package/src/04-components/{divider → layout/divider}/divider.visual.spec.ts +1 -1
  103. package/src/04-components/{divider → layout/divider}/index.scss +1 -1
  104. package/src/04-components/{breadcrumb → navigation/breadcrumb}/breadcrumb.api.json +5 -0
  105. package/src/04-components/{breadcrumb → navigation/breadcrumb}/breadcrumb.visual.spec.ts +1 -1
  106. package/src/04-components/{breadcrumb → navigation/breadcrumb}/index.scss +1 -1
  107. package/src/04-components/{menu → navigation/menu}/index.scss +1 -1
  108. package/src/04-components/{menu → navigation/menu}/menu.api.json +24 -0
  109. package/src/04-components/{menu → navigation/menu}/menu.visual.spec.ts +1 -1
  110. package/src/04-components/navigation/nav/index.scss +142 -0
  111. package/src/04-components/navigation/nav/nav-visual.png +0 -0
  112. package/src/04-components/navigation/nav/nav.api.json +55 -0
  113. package/src/04-components/navigation/nav/nav.docs.json +242 -0
  114. package/src/04-components/navigation/nav/nav.visual.spec.ts +14 -0
  115. package/src/04-components/{pagination → navigation/pagination}/index.scss +1 -1
  116. package/src/04-components/{pagination → navigation/pagination}/pagination.api.json +22 -1
  117. package/src/04-components/{pagination → navigation/pagination}/pagination.visual.spec.ts +1 -1
  118. package/src/04-components/{tabs → navigation/tabs}/index.scss +1 -1
  119. package/src/04-components/{tabs → navigation/tabs}/tabs.api.json +17 -0
  120. package/src/04-components/{tabs → navigation/tabs}/tabs.visual.spec.ts +1 -1
  121. package/src/04-components/{dialog → overlays/dialog}/dialog.api.json +12 -1
  122. package/src/04-components/{dialog → overlays/dialog}/dialog.visual.spec.ts +1 -1
  123. package/src/04-components/{dialog → overlays/dialog}/index.scss +1 -1
  124. package/src/04-components/{drawer → overlays/drawer}/drawer.api.json +17 -1
  125. package/src/04-components/{drawer → overlays/drawer}/drawer.visual.spec.ts +1 -1
  126. package/src/04-components/{drawer → overlays/drawer}/index.scss +1 -1
  127. package/src/04-components/{modal → overlays/modal}/index.scss +1 -1
  128. package/src/04-components/{modal → overlays/modal}/modal.api.json +12 -1
  129. package/src/04-components/{modal → overlays/modal}/modal.visual.spec.ts +1 -1
  130. package/src/04-components/{overlay → overlays/overlay}/index.scss +1 -1
  131. package/src/04-components/{overlay → overlays/overlay}/overlay.api.json +14 -1
  132. package/src/04-components/{overlay → overlays/overlay}/overlay.visual.spec.ts +1 -1
  133. package/src/04-components/{popover → overlays/popover}/index.scss +1 -1
  134. package/src/04-components/{popover → overlays/popover}/popover.api.json +9 -1
  135. package/src/04-components/{popover → overlays/popover}/popover.visual.spec.ts +1 -1
  136. package/src/04-components/{tooltip → overlays/tooltip}/index.scss +1 -1
  137. package/src/04-components/{tooltip → overlays/tooltip}/tooltip.api.json +11 -1
  138. package/src/04-components/{tooltip → overlays/tooltip}/tooltip.visual.spec.ts +1 -1
  139. package/src/04-components/{code → typography/code}/code.api.json +6 -1
  140. package/src/04-components/{code → typography/code}/code.visual.spec.ts +1 -1
  141. package/src/04-components/{code → typography/code}/index.scss +1 -1
  142. package/src/04-components/{heading → typography/heading}/heading.visual.spec.ts +1 -1
  143. package/src/04-components/{heading → typography/heading}/index.scss +1 -1
  144. package/src/04-components/{link → typography/link}/index.scss +1 -1
  145. package/src/04-components/typography/link/link-visual.png +0 -0
  146. package/src/04-components/{link → typography/link}/link.api.json +6 -0
  147. package/src/04-components/{link → typography/link}/link.visual.spec.ts +1 -1
  148. package/src/99-debug/grid-overlay.scss +9 -8
  149. package/src/testing/page-setup.ts +25 -9
  150. package/src/testing/sidebar-toggles.spec.ts +103 -0
  151. package/src/04-components/button/button-visual.png +0 -0
  152. package/src/04-components/button-group/button-group-visual.png +0 -0
  153. package/src/04-components/checkbox/checkbox-visual.png +0 -0
  154. package/src/04-components/data-list/data-list-visual.png +0 -0
  155. package/src/04-components/field/field.api.json +0 -11
  156. package/src/04-components/form-error/form-error-visual.png +0 -0
  157. package/src/04-components/icon/icon-visual.png +0 -0
  158. package/src/04-components/input/input-visual.png +0 -0
  159. package/src/04-components/link/link-visual.png +0 -0
  160. package/src/04-components/radio/radio-visual.png +0 -0
  161. /package/src/04-components/{button-group → actions/button-group}/button-group.docs.json +0 -0
  162. /package/src/04-components/{avatar → data-display/avatar}/avatar-visual.png +0 -0
  163. /package/src/04-components/{avatar → data-display/avatar}/avatar.docs.json +0 -0
  164. /package/src/04-components/{badge → data-display/badge}/badge-visual.png +0 -0
  165. /package/src/04-components/{badge → data-display/badge}/badge.api.json +0 -0
  166. /package/src/04-components/{badge → data-display/badge}/badge.docs.json +0 -0
  167. /package/src/04-components/{card → data-display/card}/card-visual.png +0 -0
  168. /package/src/04-components/{card → data-display/card}/card.api.json +0 -0
  169. /package/src/04-components/{card → data-display/card}/card.docs.json +0 -0
  170. /package/src/04-components/{data-list → data-display/data-list}/data-list.docs.json +0 -0
  171. /package/src/04-components/{status → data-display/status}/status-visual.png +0 -0
  172. /package/src/04-components/{status → data-display/status}/status.docs.json +0 -0
  173. /package/src/04-components/{table → data-display/table}/table-visual.png +0 -0
  174. /package/src/04-components/{table → data-display/table}/table.docs.json +0 -0
  175. /package/src/04-components/{tag → data-display/tag}/tag-visual.png +0 -0
  176. /package/src/04-components/{tag → data-display/tag}/tag.docs.json +0 -0
  177. /package/src/04-components/{accordion → disclosure/accordion}/accordion-visual.png +0 -0
  178. /package/src/04-components/{accordion → disclosure/accordion}/accordion.docs.json +0 -0
  179. /package/src/04-components/disclosure/{disclosure-visual.png → disclosure/disclosure-visual.png} +0 -0
  180. /package/src/04-components/disclosure/{disclosure.docs.json → disclosure/disclosure.docs.json} +0 -0
  181. /package/src/04-components/{alert → feedback/alert}/alert-visual.png +0 -0
  182. /package/src/04-components/{alert → feedback/alert}/alert.docs.json +0 -0
  183. /package/src/04-components/{progress → feedback/progress}/progress-visual.png +0 -0
  184. /package/src/04-components/{progress → feedback/progress}/progress.docs.json +0 -0
  185. /package/src/04-components/{skeleton → feedback/skeleton}/skeleton-visual.png +0 -0
  186. /package/src/04-components/{skeleton → feedback/skeleton}/skeleton.docs.json +0 -0
  187. /package/src/04-components/{spinner → feedback/spinner}/spinner-visual.png +0 -0
  188. /package/src/04-components/{spinner → feedback/spinner}/spinner.api.json +0 -0
  189. /package/src/04-components/{spinner → feedback/spinner}/spinner.docs.json +0 -0
  190. /package/src/04-components/{toast → feedback/toast}/toast-visual.png +0 -0
  191. /package/src/04-components/{toast → feedback/toast}/toast.docs.json +0 -0
  192. /package/src/04-components/{checkbox → forms/checkbox}/checkbox.docs.json +0 -0
  193. /package/src/04-components/{field → forms/field}/field-visual.png +0 -0
  194. /package/src/04-components/{field → forms/field}/field.docs.json +0 -0
  195. /package/src/04-components/{form-error → forms/form-error}/form-error.docs.json +0 -0
  196. /package/src/04-components/{form-helper → forms/form-helper}/form-helper-visual.png +0 -0
  197. /package/src/04-components/{form-helper → forms/form-helper}/form-helper.api.json +0 -0
  198. /package/src/04-components/{form-helper → forms/form-helper}/form-helper.docs.json +0 -0
  199. /package/src/04-components/{input → forms/input}/input.docs.json +0 -0
  200. /package/src/04-components/{label → forms/label}/label-visual.png +0 -0
  201. /package/src/04-components/{label → forms/label}/label.docs.json +0 -0
  202. /package/src/04-components/{radio → forms/radio}/radio.docs.json +0 -0
  203. /package/src/04-components/{select → forms/select}/select-visual.png +0 -0
  204. /package/src/04-components/{select → forms/select}/select.docs.json +0 -0
  205. /package/src/04-components/{textarea → forms/textarea}/textarea-visual.png +0 -0
  206. /package/src/04-components/{textarea → forms/textarea}/textarea.docs.json +0 -0
  207. /package/src/04-components/{toggle → forms/toggle}/toggle-visual.png +0 -0
  208. /package/src/04-components/{toggle → forms/toggle}/toggle.docs.json +0 -0
  209. /package/src/04-components/{divider → layout/divider}/divider-visual.png +0 -0
  210. /package/src/04-components/{divider → layout/divider}/divider.docs.json +0 -0
  211. /package/src/04-components/{breadcrumb → navigation/breadcrumb}/breadcrumb-visual.png +0 -0
  212. /package/src/04-components/{breadcrumb → navigation/breadcrumb}/breadcrumb.docs.json +0 -0
  213. /package/src/04-components/{menu → navigation/menu}/menu-visual.png +0 -0
  214. /package/src/04-components/{menu → navigation/menu}/menu.docs.json +0 -0
  215. /package/src/04-components/{pagination → navigation/pagination}/pagination-visual.png +0 -0
  216. /package/src/04-components/{pagination → navigation/pagination}/pagination.docs.json +0 -0
  217. /package/src/04-components/{tabs → navigation/tabs}/tabs-visual.png +0 -0
  218. /package/src/04-components/{tabs → navigation/tabs}/tabs.docs.json +0 -0
  219. /package/src/04-components/{dialog → overlays/dialog}/dialog-visual.png +0 -0
  220. /package/src/04-components/{dialog → overlays/dialog}/dialog.docs.json +0 -0
  221. /package/src/04-components/{drawer → overlays/drawer}/drawer-visual.png +0 -0
  222. /package/src/04-components/{drawer → overlays/drawer}/drawer.docs.json +0 -0
  223. /package/src/04-components/{modal → overlays/modal}/modal-visual.png +0 -0
  224. /package/src/04-components/{modal → overlays/modal}/modal.docs.json +0 -0
  225. /package/src/04-components/{overlay → overlays/overlay}/overlay-visual.png +0 -0
  226. /package/src/04-components/{overlay → overlays/overlay}/overlay.docs.json +0 -0
  227. /package/src/04-components/{popover → overlays/popover}/popover-visual.png +0 -0
  228. /package/src/04-components/{popover → overlays/popover}/popover.docs.json +0 -0
  229. /package/src/04-components/{tooltip → overlays/tooltip}/tooltip-visual.png +0 -0
  230. /package/src/04-components/{tooltip → overlays/tooltip}/tooltip.docs.json +0 -0
  231. /package/src/04-components/{code → typography/code}/code-visual.png +0 -0
  232. /package/src/04-components/{code → typography/code}/code.docs.json +0 -0
  233. /package/src/04-components/{heading → typography/heading}/heading-visual.png +0 -0
  234. /package/src/04-components/{heading → typography/heading}/heading.api.json +0 -0
  235. /package/src/04-components/{heading → typography/heading}/heading.docs.json +0 -0
  236. /package/src/04-components/{link → typography/link}/link.docs.json +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teseor/css",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "CSS library - reset, primitives, components, utilities",
5
5
  "license": "MIT",
6
6
  "author": "letanure",
@@ -1,3 +1,5 @@
1
+ @use 'sass:map';
2
+
1
3
  // SCSS Variables - Source of truth for fallback values
2
4
  // These are the computed values that CSS custom properties resolve to.
3
5
  // Import this file in components that need standalone fallbacks.
@@ -23,6 +25,20 @@ $space-4: $unit * 4;
23
25
  $space-6: $unit * 6;
24
26
  $space-8: $unit * 8;
25
27
 
28
+ // T-shirt sizes map for looping
29
+ $sizes: (
30
+ xs: $unit, // 8px
31
+ sm: $unit * 1.5, // 12px
32
+ md: $unit * 2, // 16px
33
+ lg: $unit * 2.5, // 20px
34
+ xl: $unit * 3 // 24px
35
+ );
36
+
37
+ // Helper function to get size value
38
+ @function size($name) {
39
+ @return map.get($sizes, $name);
40
+ }
41
+
26
42
  // Typography - Font families
27
43
  $font-sans: "Noto Sans", system-ui, -apple-system, sans-serif;
28
44
  $font-mono: "Noto Sans Mono", ui-monospace, "Cascadia Code", monospace;
@@ -76,31 +92,29 @@ $border-width-sm: $unit * 0.125; // 1px
76
92
  $border-width-md: $unit * 0.25; // 2px
77
93
  $border-width-lg: $unit * 0.5; // 4px
78
94
 
79
- // Color primitives
80
- $hue-primary: 220;
81
- $hue-success: 142;
82
- $hue-warning: 38;
83
- $hue-danger: 0;
84
-
85
- $color-neutral-50: hsl($hue-primary 10% 98%);
86
- $color-neutral-100: hsl($hue-primary 10% 96%);
87
- $color-neutral-200: hsl($hue-primary 10% 90%);
88
- $color-neutral-300: hsl($hue-primary 10% 80%);
89
- $color-neutral-400: hsl($hue-primary 10% 60%);
90
- $color-neutral-500: hsl($hue-primary 10% 45%);
91
- $color-neutral-600: hsl($hue-primary 10% 35%);
92
- $color-neutral-700: hsl($hue-primary 10% 25%);
93
- $color-neutral-800: hsl($hue-primary 10% 15%);
94
- $color-neutral-900: hsl($hue-primary 10% 10%);
95
-
96
- $color-primary-light: hsl($hue-primary 85% 65%);
97
- $color-primary: hsl($hue-primary 85% 50%);
98
- $color-primary-dark: hsl($hue-primary 85% 40%);
99
-
100
- $color-success: hsl($hue-success 70% 45%);
101
- $color-warning: hsl($hue-warning 90% 50%);
102
- $color-danger: hsl($hue-danger 70% 50%);
103
- $color-danger-dark: hsl($hue-danger 70% 40%);
95
+ // Base colors - OKLCH for perceptual uniformity
96
+ // These are fallback values; CSS custom properties take precedence
97
+ $color-primary: oklch(55% 0.22 250);
98
+ $color-success: oklch(60% 0.18 145);
99
+ $color-warning: oklch(75% 0.18 70);
100
+ $color-danger: oklch(60% 0.22 25);
101
+ $color-neutral: oklch(50% 0.02 250);
102
+
103
+ // Neutral scale - approximated from color-mix in oklch
104
+ $color-neutral-50: hsl(220 10% 98%);
105
+ $color-neutral-100: hsl(220 10% 96%);
106
+ $color-neutral-200: hsl(220 10% 90%);
107
+ $color-neutral-300: hsl(220 10% 80%);
108
+ $color-neutral-400: hsl(220 10% 60%);
109
+ $color-neutral-500: hsl(220 10% 45%);
110
+ $color-neutral-600: hsl(220 10% 35%);
111
+ $color-neutral-700: hsl(220 10% 25%);
112
+ $color-neutral-800: hsl(220 10% 15%);
113
+ $color-neutral-900: hsl(220 10% 10%);
114
+
115
+ // Primary shades - fallbacks (CSS uses color-mix)
116
+ $color-primary-light: oklch(75% 0.15 250);
117
+ $color-primary-dark: oklch(40% 0.18 250);
104
118
 
105
119
  // Semantic colors (light theme defaults)
106
120
  $color-text: $color-neutral-900;
@@ -1,25 +1,26 @@
1
1
  :root {
2
- --ui-hue-primary: 220;
3
- --ui-hue-success: 142;
4
- --ui-hue-warning: 38;
5
- --ui-hue-danger: 0;
2
+ // Base colors - override these to customize the design system
3
+ --ui-color-primary: oklch(55% 0.22 250);
4
+ --ui-color-success: oklch(60% 0.18 145);
5
+ --ui-color-warning: oklch(75% 0.18 70);
6
+ --ui-color-danger: oklch(60% 0.22 25);
7
+ --ui-color-neutral: oklch(50% 0.02 250);
6
8
 
7
- --ui-color-neutral-50: hsl(var(--ui-hue-primary) 10% 98%);
8
- --ui-color-neutral-100: hsl(var(--ui-hue-primary) 10% 96%);
9
- --ui-color-neutral-200: hsl(var(--ui-hue-primary) 10% 90%);
10
- --ui-color-neutral-300: hsl(var(--ui-hue-primary) 10% 80%);
11
- --ui-color-neutral-400: hsl(var(--ui-hue-primary) 10% 60%);
12
- --ui-color-neutral-500: hsl(var(--ui-hue-primary) 10% 45%);
13
- --ui-color-neutral-600: hsl(var(--ui-hue-primary) 10% 35%);
14
- --ui-color-neutral-700: hsl(var(--ui-hue-primary) 10% 25%);
15
- --ui-color-neutral-800: hsl(var(--ui-hue-primary) 10% 15%);
16
- --ui-color-neutral-900: hsl(var(--ui-hue-primary) 10% 10%);
9
+ // Primary shades - auto-generated via color-mix
10
+ --ui-color-primary-light: color-mix(in oklch, var(--ui-color-primary) 50%, white);
11
+ --ui-color-primary-dark: color-mix(in oklch, var(--ui-color-primary) 75%, black);
12
+ --ui-color-primary-subtle: color-mix(in oklch, var(--ui-color-primary) 12%, white);
13
+ --ui-color-primary-hover: color-mix(in oklch, var(--ui-color-primary) 85%, black);
17
14
 
18
- --ui-color-primary-light: hsl(var(--ui-hue-primary) 85% 65%);
19
- --ui-color-primary: hsl(var(--ui-hue-primary) 85% 50%);
20
- --ui-color-primary-dark: hsl(var(--ui-hue-primary) 85% 40%);
21
-
22
- --ui-color-success: hsl(var(--ui-hue-success) 70% 45%);
23
- --ui-color-warning: hsl(var(--ui-hue-warning) 90% 50%);
24
- --ui-color-danger: hsl(var(--ui-hue-danger) 70% 50%);
15
+ // Neutral scale - auto-generated via color-mix
16
+ --ui-color-neutral-50: color-mix(in oklch, var(--ui-color-neutral) 3%, white);
17
+ --ui-color-neutral-100: color-mix(in oklch, var(--ui-color-neutral) 6%, white);
18
+ --ui-color-neutral-200: color-mix(in oklch, var(--ui-color-neutral) 12%, white);
19
+ --ui-color-neutral-300: color-mix(in oklch, var(--ui-color-neutral) 25%, white);
20
+ --ui-color-neutral-400: color-mix(in oklch, var(--ui-color-neutral) 50%, white);
21
+ --ui-color-neutral-500: var(--ui-color-neutral);
22
+ --ui-color-neutral-600: color-mix(in oklch, var(--ui-color-neutral) 85%, black);
23
+ --ui-color-neutral-700: color-mix(in oklch, var(--ui-color-neutral) 70%, black);
24
+ --ui-color-neutral-800: color-mix(in oklch, var(--ui-color-neutral) 50%, black);
25
+ --ui-color-neutral-900: color-mix(in oklch, var(--ui-color-neutral) 35%, black);
25
26
  }
@@ -1,5 +1,5 @@
1
1
  :root {
2
- --shadow-sm: 0 1px 2px hsl(var(--ui-hue-primary) 10% 20% / 0.05);
3
- --shadow-md: 0 4px 6px hsl(var(--ui-hue-primary) 10% 20% / 0.1);
4
- --shadow-lg: 0 10px 15px hsl(var(--ui-hue-primary) 10% 20% / 0.15);
2
+ --shadow-sm: 0 1px 2px hsl(var(--ui-hue-primary, 220) 10% 20% / 0.05);
3
+ --shadow-md: 0 4px 6px hsl(var(--ui-hue-primary, 220) 10% 20% / 0.1);
4
+ --shadow-lg: 0 10px 15px hsl(var(--ui-hue-primary, 220) 10% 20% / 0.15);
5
5
  }
@@ -0,0 +1,15 @@
1
+ import { resolve } from 'node:path';
2
+ import { expect, test } from '@playwright/test';
3
+ import { saveForLostPixel, setupVisualTestFromDocs } from '../../testing';
4
+
5
+ const DOCS_PATH = resolve(__dirname, 'cluster.docs.json');
6
+
7
+ test.describe('cluster visual regression', () => {
8
+ test('all variations', async ({ page }) => {
9
+ await setupVisualTestFromDocs(page, DOCS_PATH);
10
+ // skip validateGridRhythm: cluster is a layout primitive that
11
+ // controls gap/alignment, not child height
12
+ await saveForLostPixel(page, 'cluster');
13
+ await expect(page.locator('body')).toHaveScreenshot('cluster.visual.png');
14
+ });
15
+ });
@@ -0,0 +1,62 @@
1
+ {
2
+ "id": "sidebar",
3
+ "type": "primitive",
4
+ "title": "Sidebar",
5
+ "description": "Fixed-position sidebar for app layouts with adjustable widths and positioning.",
6
+ "api": "./sidebar.api.json",
7
+ "sections": [
8
+ {
9
+ "title": "Basic",
10
+ "description": "Default sidebar positioned on the start side. Use inside an app-shell layout.",
11
+ "examples": [
12
+ {
13
+ "code": "<aside class=\"ui-sidebar\">\n <p>Sidebar content</p>\n</aside>"
14
+ }
15
+ ]
16
+ },
17
+ {
18
+ "title": "Widths",
19
+ "description": "Three width options via size modifiers.",
20
+ "examples": [
21
+ {
22
+ "layout": "stack",
23
+ "items": [
24
+ {
25
+ "tag": "div",
26
+ "class": "ui-cluster",
27
+ "children": [
28
+ { "tag": "code", "text": "--sm" },
29
+ { "tag": "span", "text": "192px (24 units)" }
30
+ ]
31
+ },
32
+ {
33
+ "tag": "div",
34
+ "class": "ui-cluster",
35
+ "children": [
36
+ { "tag": "code", "text": "--md" },
37
+ { "tag": "span", "text": "240px (30 units, default)" }
38
+ ]
39
+ },
40
+ {
41
+ "tag": "div",
42
+ "class": "ui-cluster",
43
+ "children": [
44
+ { "tag": "code", "text": "--lg" },
45
+ { "tag": "span", "text": "320px (40 units)" }
46
+ ]
47
+ }
48
+ ]
49
+ }
50
+ ]
51
+ },
52
+ {
53
+ "title": "End Position",
54
+ "description": "Position sidebar on the end side with --end modifier.",
55
+ "examples": [
56
+ {
57
+ "code": "<aside class=\"ui-sidebar ui-sidebar--end\">\n <p>End sidebar</p>\n</aside>"
58
+ }
59
+ ]
60
+ }
61
+ ]
62
+ }
@@ -0,0 +1,14 @@
1
+ import { resolve } from 'node:path';
2
+ import { expect, test } from '@playwright/test';
3
+ import { saveForLostPixel, setupVisualTestFromDocs, validateGridRhythm } from '../../testing';
4
+
5
+ const DOCS_PATH = resolve(__dirname, 'sidebar.docs.json');
6
+
7
+ test.describe('sidebar visual regression', () => {
8
+ test('all variations', async ({ page }) => {
9
+ await setupVisualTestFromDocs(page, DOCS_PATH);
10
+ await validateGridRhythm(page, 'sidebar');
11
+ await saveForLostPixel(page, 'sidebar');
12
+ await expect(page.locator('body')).toHaveScreenshot('sidebar.visual.png');
13
+ });
14
+ });
@@ -1,115 +1,64 @@
1
1
  {
2
2
  "name": "sidebar-nav",
3
- "baseClass": "sidebar-nav",
4
3
  "element": "nav",
5
- "description": "Navigation component for sidebars with support for groups, nested items, icons, and badges",
6
4
  "modifiers": {
7
5
  "collapsed": {
8
- "type": "boolean",
9
- "description": "Icon-only mode, hides labels and badges"
6
+ "type": "boolean"
10
7
  }
11
8
  },
12
9
  "elements": {
13
- "header": {
14
- "element": "div",
15
- "description": "Sticky header section"
16
- },
17
- "content": {
18
- "element": "div",
19
- "description": "Scrollable content area"
20
- },
21
- "footer": {
22
- "element": "div",
23
- "description": "Sticky footer section"
24
- },
25
- "group": {
26
- "element": "div",
27
- "description": "Navigation group container"
28
- },
29
- "group-label": {
30
- "element": "span",
31
- "description": "Group section heading"
32
- },
33
- "group-items": {
34
- "element": "ul",
35
- "description": "List of nav items in a group"
36
- },
37
- "subgroup-label": {
38
- "element": "span",
39
- "description": "Nested subgroup heading"
40
- },
10
+ "header": {},
11
+ "content": {},
12
+ "footer": {},
13
+ "group": {},
14
+ "group-label": {},
15
+ "group-items": {},
16
+ "subgroup-label": {},
41
17
  "item": {
42
- "element": "a",
43
- "description": "Navigation link",
44
18
  "modifiers": {
45
19
  "active": {
46
- "type": "boolean",
47
- "description": "Current/active page state"
20
+ "type": "boolean"
48
21
  },
49
22
  "disabled": {
50
- "type": "boolean",
51
- "description": "Non-interactive item"
23
+ "type": "boolean"
52
24
  },
53
25
  "nested": {
54
- "type": "boolean",
55
- "description": "Indented nested item"
26
+ "type": "boolean"
56
27
  }
57
28
  }
58
29
  },
59
- "icon": {
60
- "element": "span",
61
- "description": "Icon container"
62
- },
63
- "label": {
64
- "element": "span",
65
- "description": "Text label"
66
- },
67
- "badge": {
68
- "element": "span",
69
- "description": "Badge or count indicator"
70
- }
71
- },
72
- "accessibility": {
73
- "role": "navigation",
74
- "aria-label": "Required - descriptive label for the navigation",
75
- "aria-current": "Use 'page' on active item link",
76
- "keyboard": "Tab navigation between focusable items"
30
+ "icon": {},
31
+ "label": {},
32
+ "badge": {}
77
33
  },
78
- "customization": [
34
+ "cssVars": [
79
35
  {
80
- "token": "--ui-sidebar-nav-width",
81
- "default": "calc(var(--ui-unit) * 30)",
82
- "description": "Default sidebar width"
36
+ "name": "--ui-sidebar-nav-width",
37
+ "default": "calc(var(--ui-unit) * 30)"
83
38
  },
84
39
  {
85
- "token": "--ui-sidebar-nav-width-collapsed",
86
- "default": "var(--ui-row-3)",
87
- "description": "Width in collapsed/icon-only mode"
40
+ "name": "--ui-sidebar-nav-width-collapsed",
41
+ "default": "var(--ui-row-3)"
88
42
  },
89
43
  {
90
- "token": "--ui-sidebar-nav-bg",
91
- "default": "var(--ui-color-bg-subtle)",
92
- "description": "Background color"
44
+ "name": "--ui-sidebar-nav-bg",
45
+ "default": "var(--ui-color-bg-subtle)"
93
46
  },
94
47
  {
95
- "token": "--ui-sidebar-nav-item-height",
96
- "default": "var(--ui-row-2)",
97
- "description": "Nav item height"
48
+ "name": "--ui-sidebar-nav-item-height",
49
+ "default": "var(--ui-row-2)"
98
50
  },
99
51
  {
100
- "token": "--ui-sidebar-nav-item-hover-bg",
101
- "default": "var(--ui-color-bg-muted)",
102
- "description": "Item hover background"
52
+ "name": "--ui-sidebar-nav-item-hover-bg",
53
+ "default": "var(--ui-color-bg-muted)"
103
54
  },
104
55
  {
105
- "token": "--ui-sidebar-nav-item-active-bg",
106
- "default": "var(--ui-color-primary-subtle)",
107
- "description": "Active item background"
56
+ "name": "--ui-sidebar-nav-item-active-bg",
57
+ "default": "var(--ui-color-primary-subtle)"
108
58
  },
109
59
  {
110
- "token": "--ui-sidebar-nav-item-active-color",
111
- "default": "var(--ui-color-primary)",
112
- "description": "Active item text color"
60
+ "name": "--ui-sidebar-nav-item-active-color",
61
+ "default": "var(--ui-color-primary)"
113
62
  }
114
63
  ]
115
64
  }
@@ -3,7 +3,7 @@
3
3
  "element": "button",
4
4
  "modifiers": {
5
5
  "size": {
6
- "values": ["sm", "lg"]
6
+ "values": ["sm", "md", "lg"]
7
7
  },
8
8
  "variant": {
9
9
  "values": ["secondary", "ghost", "outline", "danger", "link"]
@@ -21,7 +21,24 @@
21
21
  "type": "boolean"
22
22
  }
23
23
  },
24
+ "elements": {
25
+ "icon": {
26
+ "modifiers": {
27
+ "start": {
28
+ "type": "boolean"
29
+ },
30
+ "end": {
31
+ "type": "boolean"
32
+ }
33
+ }
34
+ }
35
+ },
24
36
  "cssVars": [
37
+ {
38
+ "name": "--ui-button-accent",
39
+ "description": "Primary accent color. All shades auto-generated via color-mix.",
40
+ "default": "var(--ui-color-primary)"
41
+ },
25
42
  {
26
43
  "name": "--ui-button-height",
27
44
  "default": "var(--ui-row-2)"
@@ -42,29 +59,29 @@
42
59
  "name": "--ui-button-radius",
43
60
  "default": "var(--ui-radius-md)"
44
61
  },
45
- {
46
- "name": "--ui-button-bg",
47
- "default": "var(--ui-color-primary)"
48
- },
49
- {
50
- "name": "--ui-button-bg-hover",
51
- "default": "var(--ui-color-primary-dark)"
52
- },
53
62
  {
54
63
  "name": "--ui-button-text",
55
64
  "default": "var(--ui-color-text-inverse)"
56
65
  },
57
66
  {
58
67
  "name": "--ui-button-height-sm",
59
- "default": "var(--row)"
68
+ "default": "calc(var(--row) * 1.5)"
60
69
  },
61
70
  {
62
71
  "name": "--ui-button-font-size-sm",
63
72
  "default": "var(--ui-font-size-xs)"
64
73
  },
74
+ {
75
+ "name": "--ui-button-height-md",
76
+ "default": "var(--ui-row-2)"
77
+ },
78
+ {
79
+ "name": "--ui-button-font-size-md",
80
+ "default": "var(--ui-font-size-sm)"
81
+ },
65
82
  {
66
83
  "name": "--ui-button-height-lg",
67
- "default": "var(--row)"
84
+ "default": "calc(var(--row) * 2.5)"
68
85
  },
69
86
  {
70
87
  "name": "--ui-button-padding-x-lg",
@@ -87,52 +104,9 @@
87
104
  "default": "var(--ui-color-text)"
88
105
  },
89
106
  {
90
- "name": "--ui-button-ghost-bg",
91
- "default": "transparent"
92
- },
93
- {
94
- "name": "--ui-button-ghost-bg-hover",
95
- "default": "var(--ui-color-bg-subtle)"
96
- },
97
- {
98
- "name": "--ui-button-ghost-text",
99
- "default": "var(--ui-color-primary)"
100
- },
101
- {
102
- "name": "--ui-button-outline-bg",
103
- "default": "transparent"
104
- },
105
- {
106
- "name": "--ui-button-outline-bg-hover",
107
- "default": "var(--ui-color-primary)"
108
- },
109
- {
110
- "name": "--ui-button-outline-text",
111
- "default": "var(--ui-color-primary)"
112
- },
113
- {
114
- "name": "--ui-button-outline-text-hover",
115
- "default": "var(--ui-color-text-inverse)"
116
- },
117
- {
118
- "name": "--ui-button-outline-border",
119
- "default": "var(--ui-border-width-sm)"
120
- },
121
- {
122
- "name": "--ui-button-danger-bg",
107
+ "name": "--ui-color-danger",
108
+ "description": "Used by --danger variant as accent color",
123
109
  "default": "var(--ui-color-danger)"
124
- },
125
- {
126
- "name": "--ui-button-danger-bg-hover",
127
- "default": "#{t.$color-danger-dark}"
128
- },
129
- {
130
- "name": "--ui-button-link-text",
131
- "default": "var(--ui-color-primary)"
132
- },
133
- {
134
- "name": "--ui-button-link-text-hover",
135
- "default": "var(--ui-color-primary-dark)"
136
110
  }
137
111
  ]
138
112
  }
@@ -22,6 +22,81 @@
22
22
  }
23
23
  },
24
24
  "sections": [
25
+ {
26
+ "title": "Variants",
27
+ "description": "Button styles for different purposes and emphasis levels.",
28
+ "examples": [
29
+ {
30
+ "layout": "cluster",
31
+ "items": [
32
+ { "tag": "button", "class": "ui-button", "text": "Primary" },
33
+ { "tag": "button", "class": "ui-button ui-button--secondary", "text": "Secondary" },
34
+ { "tag": "button", "class": "ui-button ui-button--outline", "text": "Outline" },
35
+ { "tag": "button", "class": "ui-button ui-button--ghost", "text": "Ghost" },
36
+ { "tag": "button", "class": "ui-button ui-button--danger", "text": "Danger" },
37
+ { "tag": "button", "class": "ui-button ui-button--link", "text": "Link" }
38
+ ]
39
+ }
40
+ ]
41
+ },
42
+ {
43
+ "title": "Sizes",
44
+ "description": "Small for dense UIs, default for most cases, large for prominent CTAs.",
45
+ "examples": [
46
+ {
47
+ "layout": "cluster",
48
+ "items": [
49
+ { "tag": "button", "class": "ui-button ui-button--sm", "text": "Small" },
50
+ { "tag": "button", "class": "ui-button ui-button--md", "text": "Medium" },
51
+ { "tag": "button", "class": "ui-button ui-button--lg", "text": "Large" }
52
+ ]
53
+ }
54
+ ]
55
+ },
56
+ {
57
+ "title": "Radius",
58
+ "description": "Override border radius. Use radius-full for pill-shaped buttons.",
59
+ "examples": [
60
+ {
61
+ "layout": "cluster",
62
+ "items": [
63
+ { "tag": "button", "class": "ui-button ui-button--radius-none", "text": "None" },
64
+ { "tag": "button", "class": "ui-button ui-button--radius-sm", "text": "Small" },
65
+ { "tag": "button", "class": "ui-button", "text": "Default" },
66
+ { "tag": "button", "class": "ui-button ui-button--radius-lg", "text": "Large" },
67
+ { "tag": "button", "class": "ui-button ui-button--radius-full", "text": "Full" }
68
+ ]
69
+ }
70
+ ]
71
+ },
72
+ {
73
+ "title": "Block",
74
+ "description": "Full width button for mobile or form submit.",
75
+ "examples": [
76
+ {
77
+ "items": [
78
+ { "tag": "button", "class": "ui-button ui-button--block", "text": "Block Button" }
79
+ ]
80
+ }
81
+ ]
82
+ },
83
+ {
84
+ "title": "Loading",
85
+ "description": "Shows spinner animation. Button becomes non-interactive.",
86
+ "examples": [
87
+ {
88
+ "layout": "cluster",
89
+ "items": [
90
+ { "tag": "button", "class": "ui-button ui-button--loading", "text": "Loading" },
91
+ {
92
+ "tag": "button",
93
+ "class": "ui-button ui-button--secondary ui-button--loading",
94
+ "text": "Loading"
95
+ }
96
+ ]
97
+ }
98
+ ]
99
+ },
25
100
  {
26
101
  "title": "Icon Button",
27
102
  "description": "Square icon-only buttons. Use with SVG icons from Lucide or similar sets.",
@@ -1,6 +1,6 @@
1
1
  import { resolve } from 'node:path';
2
2
  import { expect, test } from '@playwright/test';
3
- import { saveForLostPixel, setupVisualTestFromDocs, validateGridRhythm } from '../../testing';
3
+ import { saveForLostPixel, setupVisualTestFromDocs, validateGridRhythm } from '../../../testing';
4
4
 
5
5
  const DOCS_PATH = resolve(__dirname, 'button.docs.json');
6
6