@mich8060/chg-design-system 0.1.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 (260) hide show
  1. package/.github/workflows/figma-sync.yml +30 -0
  2. package/ARCHITECTURE_FIX.md +241 -0
  3. package/LICENSE +21 -0
  4. package/README.lib.md +103 -0
  5. package/README.md +177 -0
  6. package/figma.config.json +9 -0
  7. package/package.json +67 -0
  8. package/package.lib.json +49 -0
  9. package/public/data/figma-variables.json +40026 -0
  10. package/public/favicon.ico +0 -0
  11. package/public/index.html +46 -0
  12. package/public/logo192.png +0 -0
  13. package/public/logo512.png +0 -0
  14. package/public/manifest.json +25 -0
  15. package/public/robots.txt +3 -0
  16. package/public/styles/tokens.css +1994 -0
  17. package/scripts/index.js +896 -0
  18. package/scripts/publish-lib.js +150 -0
  19. package/scripts/validate.js +94 -0
  20. package/src/App.css +457 -0
  21. package/src/App.css.map +1 -0
  22. package/src/App.js +161 -0
  23. package/src/App.scss +548 -0
  24. package/src/App.test.js +8 -0
  25. package/src/assets/images/.gitkeep +0 -0
  26. package/src/assets/images/doctors/Avatar-1.png +0 -0
  27. package/src/assets/images/doctors/Avatar-10.png +0 -0
  28. package/src/assets/images/doctors/Avatar-11.png +0 -0
  29. package/src/assets/images/doctors/Avatar-12.png +0 -0
  30. package/src/assets/images/doctors/Avatar-13.png +0 -0
  31. package/src/assets/images/doctors/Avatar-14.png +0 -0
  32. package/src/assets/images/doctors/Avatar-15.png +0 -0
  33. package/src/assets/images/doctors/Avatar-16.png +0 -0
  34. package/src/assets/images/doctors/Avatar-17.png +0 -0
  35. package/src/assets/images/doctors/Avatar-18.png +0 -0
  36. package/src/assets/images/doctors/Avatar-19.png +0 -0
  37. package/src/assets/images/doctors/Avatar-2.png +0 -0
  38. package/src/assets/images/doctors/Avatar-20.png +0 -0
  39. package/src/assets/images/doctors/Avatar-21.png +0 -0
  40. package/src/assets/images/doctors/Avatar-3.png +0 -0
  41. package/src/assets/images/doctors/Avatar-4.png +0 -0
  42. package/src/assets/images/doctors/Avatar-5.png +0 -0
  43. package/src/assets/images/doctors/Avatar-6.png +0 -0
  44. package/src/assets/images/doctors/Avatar-7.png +0 -0
  45. package/src/assets/images/doctors/Avatar-8.png +0 -0
  46. package/src/assets/images/doctors/Avatar-9.png +0 -0
  47. package/src/assets/images/doctors/Avatar.png +0 -0
  48. package/src/assets/images/doctors/index.js +141 -0
  49. package/src/data/figma-variables.json +90305 -0
  50. package/src/index.js +20 -0
  51. package/src/index.scss +10 -0
  52. package/src/pages/AccordionDemo.jsx +206 -0
  53. package/src/pages/AccordionDemo.scss +34 -0
  54. package/src/pages/ActionMenuDemo.jsx +957 -0
  55. package/src/pages/ActionMenuDemo.scss +34 -0
  56. package/src/pages/AvatarDemo.jsx +328 -0
  57. package/src/pages/AvatarDemo.scss +40 -0
  58. package/src/pages/BadgeDemo.jsx +254 -0
  59. package/src/pages/BadgeDemo.scss +40 -0
  60. package/src/pages/BorderRadiusDemo.jsx +112 -0
  61. package/src/pages/BorderRadiusDemo.scss +50 -0
  62. package/src/pages/BrandingDemo.jsx +117 -0
  63. package/src/pages/BreadcrumbDemo.jsx +172 -0
  64. package/src/pages/ButtonDemo.jsx +708 -0
  65. package/src/pages/ButtonDemo.scss +34 -0
  66. package/src/pages/CheckboxDemo.jsx +194 -0
  67. package/src/pages/ChipDemo.jsx +359 -0
  68. package/src/pages/ChipDemo.scss +40 -0
  69. package/src/pages/ColorsDemo.jsx +566 -0
  70. package/src/pages/ColorsDemo.scss +243 -0
  71. package/src/pages/ComponentsUsage.jsx +401 -0
  72. package/src/pages/DatepickerDemo.jsx +223 -0
  73. package/src/pages/DividerDemo.jsx +337 -0
  74. package/src/pages/DotStatusDemo.jsx +223 -0
  75. package/src/pages/DropdownDemo.jsx +229 -0
  76. package/src/pages/FieldDemo.jsx +253 -0
  77. package/src/pages/FigmaVariablesDemo.jsx +426 -0
  78. package/src/pages/FigmaVariablesDemo.scss +316 -0
  79. package/src/pages/FileUploadDemo.jsx +186 -0
  80. package/src/pages/FlexDemo.jsx +144 -0
  81. package/src/pages/FlexDemo.scss +119 -0
  82. package/src/pages/FontInstallation.jsx +252 -0
  83. package/src/pages/FontInstallation.scss +40 -0
  84. package/src/pages/Home.jsx +3156 -0
  85. package/src/pages/IconDemo.jsx +1680 -0
  86. package/src/pages/ImageAspectDemo.jsx +152 -0
  87. package/src/pages/InputDemo.jsx +245 -0
  88. package/src/pages/Installation.jsx +257 -0
  89. package/src/pages/Installation.scss +40 -0
  90. package/src/pages/KeyDemo.jsx +184 -0
  91. package/src/pages/MenuDemo.jsx +139 -0
  92. package/src/pages/MicroCalendarDemo.jsx +165 -0
  93. package/src/pages/PaginationDemo.jsx +176 -0
  94. package/src/pages/PillToggleDemo.jsx +212 -0
  95. package/src/pages/ProgressCircleDemo.jsx +206 -0
  96. package/src/pages/ProgressIndicatorDemo.jsx +227 -0
  97. package/src/pages/RadioDemo.jsx +282 -0
  98. package/src/pages/ShadowsDemo.jsx +118 -0
  99. package/src/pages/ShadowsDemo.scss +93 -0
  100. package/src/pages/SliderDemo.jsx +226 -0
  101. package/src/pages/SpacingDemo.jsx +160 -0
  102. package/src/pages/SpacingDemo.scss +107 -0
  103. package/src/pages/StatusDemo.jsx +196 -0
  104. package/src/pages/StepsDemo.jsx +308 -0
  105. package/src/pages/TableDemo.jsx +376 -0
  106. package/src/pages/TabsDemo.jsx +221 -0
  107. package/src/pages/ToastDemo.jsx +195 -0
  108. package/src/pages/ToggleDemo.jsx +187 -0
  109. package/src/pages/TokensDemo.jsx +637 -0
  110. package/src/pages/TokensDemo.scss +270 -0
  111. package/src/pages/TokensUsage.jsx +220 -0
  112. package/src/pages/TooltipDemo.jsx +170 -0
  113. package/src/pages/TypographyDemo.jsx +229 -0
  114. package/src/pages/TypographyDemo.scss +105 -0
  115. package/src/pages/UtilitiesDemo.jsx +381 -0
  116. package/src/pages/UtilitiesDemo.scss +214 -0
  117. package/src/reportWebVitals.js +13 -0
  118. package/src/setupTests.js +5 -0
  119. package/src/styles/_typography.scss +932 -0
  120. package/src/styles/_utilities.scss +3635 -0
  121. package/src/styles/_variables.scss +887 -0
  122. package/src/styles/prism-custom.css +206 -0
  123. package/src/styles/prism-custom.css.map +1 -0
  124. package/src/styles/prism-custom.scss +205 -0
  125. package/src/styles/tokens.css +4416 -0
  126. package/src/styles/tokens.css.map +1 -0
  127. package/src/styles/tokens.scss +1456 -0
  128. package/src/ui/Accordion/Accordion.jsx +70 -0
  129. package/src/ui/Accordion/Accordion.scss +82 -0
  130. package/src/ui/Accordion/index.js +1 -0
  131. package/src/ui/ActionMenu/ActionMenu.jsx +383 -0
  132. package/src/ui/ActionMenu/ActionMenu.scss +198 -0
  133. package/src/ui/ActionMenu/index.js +1 -0
  134. package/src/ui/Avatar/Avatar.jsx +49 -0
  135. package/src/ui/Avatar/Avatar.scss +82 -0
  136. package/src/ui/Avatar/index.js +1 -0
  137. package/src/ui/Badge/Badge.jsx +64 -0
  138. package/src/ui/Badge/Badge.scss +84 -0
  139. package/src/ui/Badge/index.js +1 -0
  140. package/src/ui/Branding/Branding.jsx +65 -0
  141. package/src/ui/Branding/Branding.scss +116 -0
  142. package/src/ui/Branding/index.js +1 -0
  143. package/src/ui/Breadcrumb/Breadcrumb.jsx +162 -0
  144. package/src/ui/Breadcrumb/Breadcrumb.scss +46 -0
  145. package/src/ui/Breadcrumb/index.js +2 -0
  146. package/src/ui/Button/Button.figma.tsx +49 -0
  147. package/src/ui/Button/Button.jsx +135 -0
  148. package/src/ui/Button/Button.scss +188 -0
  149. package/src/ui/Button/index.js +1 -0
  150. package/src/ui/Card/Card.jsx +25 -0
  151. package/src/ui/Card/Card.scss +47 -0
  152. package/src/ui/Card/index.js +1 -0
  153. package/src/ui/Checkbox/Checkbox.jsx +70 -0
  154. package/src/ui/Checkbox/Checkbox.scss +96 -0
  155. package/src/ui/Checkbox/index.js +1 -0
  156. package/src/ui/Chip/Chip.jsx +104 -0
  157. package/src/ui/Chip/Chip.scss +118 -0
  158. package/src/ui/Chip/index.js +1 -0
  159. package/src/ui/CopyButton/CopyButton.jsx +102 -0
  160. package/src/ui/CopyButton/CopyButton.scss +56 -0
  161. package/src/ui/CopyButton/index.js +1 -0
  162. package/src/ui/Datepicker/Datepicker.jsx +326 -0
  163. package/src/ui/Datepicker/Datepicker.scss +187 -0
  164. package/src/ui/Datepicker/index.js +2 -0
  165. package/src/ui/Divider/Divider.jsx +89 -0
  166. package/src/ui/Divider/Divider.scss +112 -0
  167. package/src/ui/Divider/index.js +1 -0
  168. package/src/ui/DotStatus/DotStatus.jsx +64 -0
  169. package/src/ui/DotStatus/DotStatus.scss +87 -0
  170. package/src/ui/DotStatus/index.js +1 -0
  171. package/src/ui/Dropdown/Dropdown.jsx +200 -0
  172. package/src/ui/Dropdown/Dropdown.scss +156 -0
  173. package/src/ui/Dropdown/index.js +1 -0
  174. package/src/ui/Field/Field.jsx +89 -0
  175. package/src/ui/Field/Field.scss +119 -0
  176. package/src/ui/Field/index.js +1 -0
  177. package/src/ui/FileUpload/FileUpload.figma.tsx +28 -0
  178. package/src/ui/FileUpload/FileUpload.jsx +153 -0
  179. package/src/ui/FileUpload/FileUpload.scss +78 -0
  180. package/src/ui/FileUpload/index.js +2 -0
  181. package/src/ui/Flex/Flex.jsx +42 -0
  182. package/src/ui/Flex/Flex.scss +119 -0
  183. package/src/ui/Flex/index.js +1 -0
  184. package/src/ui/Icon/Icon.figma.tsx +22 -0
  185. package/src/ui/Icon/Icon.jsx +47 -0
  186. package/src/ui/Icon/index.js +1 -0
  187. package/src/ui/ImageAspect/ImageAspect.jsx +56 -0
  188. package/src/ui/ImageAspect/ImageAspect.scss +62 -0
  189. package/src/ui/ImageAspect/index.js +1 -0
  190. package/src/ui/Input/Input.figma.tsx +35 -0
  191. package/src/ui/Input/Input.jsx +68 -0
  192. package/src/ui/Input/Input.scss +64 -0
  193. package/src/ui/Input/index.js +2 -0
  194. package/src/ui/Key/Key.jsx +37 -0
  195. package/src/ui/Key/Key.scss +34 -0
  196. package/src/ui/Key/index.js +1 -0
  197. package/src/ui/Menu/Menu.jsx +389 -0
  198. package/src/ui/Menu/Menu.scss +382 -0
  199. package/src/ui/Menu/index.js +1 -0
  200. package/src/ui/MicroCalendar/MicroCalendar.jsx +392 -0
  201. package/src/ui/MicroCalendar/MicroCalendar.scss +277 -0
  202. package/src/ui/MicroCalendar/index.js +1 -0
  203. package/src/ui/Pagination/Pagination.jsx +237 -0
  204. package/src/ui/Pagination/Pagination.scss +182 -0
  205. package/src/ui/Pagination/index.js +1 -0
  206. package/src/ui/PillToggle/PillToggle.jsx +56 -0
  207. package/src/ui/PillToggle/PillToggle.scss +84 -0
  208. package/src/ui/PillToggle/index.js +1 -0
  209. package/src/ui/Playground/Playground.jsx +524 -0
  210. package/src/ui/Playground/Playground.scss +310 -0
  211. package/src/ui/Playground/index.js +2 -0
  212. package/src/ui/ProgressCircle/ProgressCircle.jsx +147 -0
  213. package/src/ui/ProgressCircle/ProgressCircle.scss +143 -0
  214. package/src/ui/ProgressCircle/index.js +1 -0
  215. package/src/ui/ProgressIndicator/ProgressIndicator.jsx +92 -0
  216. package/src/ui/ProgressIndicator/ProgressIndicator.scss +133 -0
  217. package/src/ui/ProgressIndicator/index.js +1 -0
  218. package/src/ui/Radio/Radio.jsx +57 -0
  219. package/src/ui/Radio/Radio.scss +84 -0
  220. package/src/ui/Radio/index.js +1 -0
  221. package/src/ui/Slider/Slider.jsx +283 -0
  222. package/src/ui/Slider/Slider.scss +156 -0
  223. package/src/ui/Slider/index.js +1 -0
  224. package/src/ui/Status/Status.jsx +66 -0
  225. package/src/ui/Status/Status.scss +90 -0
  226. package/src/ui/Status/index.js +1 -0
  227. package/src/ui/Steps/Steps.jsx +201 -0
  228. package/src/ui/Steps/Steps.scss +240 -0
  229. package/src/ui/Steps/index.js +1 -0
  230. package/src/ui/Table/Table.jsx +143 -0
  231. package/src/ui/Table/Table.scss +90 -0
  232. package/src/ui/Table/index.js +1 -0
  233. package/src/ui/Tabs/TabItem.jsx +86 -0
  234. package/src/ui/Tabs/Tabs.figma.tsx +30 -0
  235. package/src/ui/Tabs/Tabs.jsx +318 -0
  236. package/src/ui/Tabs/Tabs.scss +164 -0
  237. package/src/ui/Tabs/Untitled +1 -0
  238. package/src/ui/Tabs/index.js +3 -0
  239. package/src/ui/Tag/Tag.figma.tsx +29 -0
  240. package/src/ui/Tag/Tag.jsx +93 -0
  241. package/src/ui/Tag/Tag.scss +229 -0
  242. package/src/ui/Tag/index.js +2 -0
  243. package/src/ui/Textarea/Textarea.figma.tsx +35 -0
  244. package/src/ui/Textarea/Textarea.jsx +68 -0
  245. package/src/ui/Textarea/Textarea.scss +69 -0
  246. package/src/ui/Textarea/index.js +2 -0
  247. package/src/ui/Toast/Toast.jsx +75 -0
  248. package/src/ui/Toast/Toast.scss +132 -0
  249. package/src/ui/Toast/index.js +2 -0
  250. package/src/ui/Toggle/Toggle.jsx +73 -0
  251. package/src/ui/Toggle/Toggle.scss +139 -0
  252. package/src/ui/Toggle/index.js +1 -0
  253. package/src/ui/Tooltip/Tooltip.figma.tsx +24 -0
  254. package/src/ui/Tooltip/Tooltip.jsx +123 -0
  255. package/src/ui/Tooltip/Tooltip.scss +80 -0
  256. package/src/ui/Tooltip/index.js +2 -0
  257. package/src/ui/index.js +63 -0
  258. package/src/utils/formatDate.js +27 -0
  259. package/src/utils/headerVariants.js +69 -0
  260. package/vite.config.lib.js +55 -0
@@ -0,0 +1,381 @@
1
+ import React, { useState, useEffect } from "react";
2
+ import Breadcrumb from "../ui/Breadcrumb/Breadcrumb";
3
+ import Tabs from "../ui/Tabs/Tabs";
4
+ import { formatLastUpdated } from "../utils/formatDate";
5
+ import Flex from "../ui/Flex/Flex";
6
+ import Divider from "../ui/Divider/Divider";
7
+ import CopyButton from "../ui/CopyButton/CopyButton";
8
+ import Prism from "prismjs";
9
+ import "../styles/prism-custom.css";
10
+ import "prismjs/components/prism-markup";
11
+ import "./UtilitiesDemo.scss";
12
+
13
+ const UTILITY_CATEGORIES = [
14
+ { id: "layout", label: "Layout" },
15
+ { id: "flexbox-grid", label: "Flexbox & Grid" },
16
+ { id: "spacing", label: "Spacing" },
17
+ { id: "sizing", label: "Sizing" },
18
+ { id: "typography", label: "Typography" },
19
+ { id: "backgrounds", label: "Backgrounds" },
20
+ { id: "borders-effects", label: "Borders & Effects" },
21
+ { id: "transforms-animation", label: "Transforms & Animation" },
22
+ { id: "interactivity", label: "Interactivity & Accessibility" },
23
+ { id: "variants", label: "Variants" },
24
+ ];
25
+
26
+ const UTILITY_EXAMPLES = {
27
+ layout: [
28
+ { class: "block", description: "Display block" },
29
+ { class: "inline", description: "Display inline" },
30
+ { class: "flex", description: "Display flex" },
31
+ { class: "grid", description: "Display grid" },
32
+ { class: "hidden", description: "Display none" },
33
+ { class: "relative", description: "Position relative" },
34
+ { class: "absolute", description: "Position absolute" },
35
+ { class: "fixed", description: "Position fixed" },
36
+ { class: "sticky", description: "Position sticky" },
37
+ { class: "overflow-hidden", description: "Hide overflow" },
38
+ { class: "overflow-auto", description: "Auto overflow" },
39
+ { class: "z-modal", description: "Modal z-index" },
40
+ ],
41
+ "flexbox-grid": [
42
+ { class: "flex-row", description: "Flex direction row" },
43
+ { class: "flex-col", description: "Flex direction column" },
44
+ { class: "flex-wrap", description: "Flex wrap" },
45
+ { class: "items-center", description: "Align items center" },
46
+ { class: "justify-between", description: "Justify space-between" },
47
+ { class: "gap-4", description: "Gap 4px" },
48
+ { class: "gap-8", description: "Gap 8px" },
49
+ { class: "grid-cols-3", description: "Grid 3 columns" },
50
+ { class: "grid-rows-2", description: "Grid 2 rows" },
51
+ ],
52
+ spacing: [
53
+ { class: "p-4", description: "Padding 4px all sides" },
54
+ { class: "px-8", description: "Padding 8px horizontal" },
55
+ { class: "py-12", description: "Padding 12px vertical" },
56
+ { class: "pt-16", description: "Padding-top 16px" },
57
+ { class: "m-8", description: "Margin 8px all sides" },
58
+ { class: "mx-auto", description: "Margin horizontal auto" },
59
+ { class: "my-16", description: "Margin 16px vertical" },
60
+ { class: "mt-24", description: "Margin-top 24px" },
61
+ { class: "space-x-4", description: "Space between children horizontal" },
62
+ { class: "space-y-8", description: "Space between children vertical" },
63
+ ],
64
+ sizing: [
65
+ { class: "w-full", description: "Width 100%" },
66
+ { class: "w-auto", description: "Width auto" },
67
+ { class: "h-screen", description: "Height 100vh" },
68
+ { class: "h-full", description: "Height 100%" },
69
+ { class: "min-w-0", description: "Min-width 0" },
70
+ { class: "max-w-full", description: "Max-width 100%" },
71
+ { class: "size-24", description: "Width & height 24px" },
72
+ { class: "aspect-square", description: "Aspect ratio 1:1" },
73
+ ],
74
+ typography: [
75
+ { class: "text-16", description: "Font size 16px" },
76
+ { class: "text-24", description: "Font size 24px" },
77
+ { class: "font-semibold", description: "Font weight semibold" },
78
+ { class: "font-bold", description: "Font weight bold" },
79
+ { class: "leading-16", description: "Line height 16px" },
80
+ { class: "uppercase", description: "Text transform uppercase" },
81
+ { class: "italic", description: "Font style italic" },
82
+ { class: "underline", description: "Text underline" },
83
+ { class: "truncate", description: "Truncate text with ellipsis" },
84
+ { class: "line-clamp-2", description: "Clamp to 2 lines" },
85
+ ],
86
+ backgrounds: [
87
+ { class: "bg-primary", description: "Background primary" },
88
+ { class: "bg-secondary", description: "Background secondary" },
89
+ { class: "bg-brand-primary", description: "Background brand primary" },
90
+ { class: "bg-cover", description: "Background size cover" },
91
+ { class: "bg-center", description: "Background position center" },
92
+ ],
93
+ "borders-effects": [
94
+ { class: "border", description: "Border width 1px" },
95
+ { class: "border-2", description: "Border width 2px" },
96
+ { class: "border-primary", description: "Border color primary" },
97
+ { class: "rounded-8", description: "Border radius 8px" },
98
+ { class: "rounded-full", description: "Border radius full" },
99
+ { class: "shadow-md", description: "Box shadow medium" },
100
+ { class: "shadow-lg", description: "Box shadow large" },
101
+ { class: "opacity-50", description: "Opacity 50%" },
102
+ { class: "blur-sm", description: "Blur filter small" },
103
+ ],
104
+ "transforms-animation": [
105
+ { class: "scale-105", description: "Scale 105%" },
106
+ { class: "rotate-45", description: "Rotate 45deg" },
107
+ { class: "translate-x-4", description: "Translate X 4px" },
108
+ { class: "transition", description: "Transition all" },
109
+ { class: "duration-300", description: "Transition duration 300ms" },
110
+ { class: "ease-in-out", description: "Ease in-out timing" },
111
+ ],
112
+ interactivity: [
113
+ { class: "cursor-pointer", description: "Cursor pointer" },
114
+ { class: "cursor-not-allowed", description: "Cursor not-allowed" },
115
+ { class: "select-none", description: "User select none" },
116
+ { class: "sr-only", description: "Screen reader only" },
117
+ { class: "focus-visible:ring", description: "Focus visible ring" },
118
+ ],
119
+ variants: [
120
+ { class: "hover:bg-secondary", description: "Hover background" },
121
+ { class: "hover:opacity-75", description: "Hover opacity" },
122
+ { class: "focus:ring", description: "Focus ring" },
123
+ { class: "active:scale-95", description: "Active scale" },
124
+ { class: "disabled:opacity-50", description: "Disabled opacity" },
125
+ { class: "dark:bg-primary", description: "Dark mode background" },
126
+ ],
127
+ };
128
+
129
+ const gettingStartedCode = `<div class="flex items-center gap-4 p-8 rounded-8 shadow-md">
130
+ <span class="text-16 font-semibold">Hello World</span>
131
+ </div>`;
132
+
133
+ export default function UtilitiesDemo() {
134
+ const [activeTab, setActiveTab] = useState(0);
135
+
136
+ useEffect(() => {
137
+ Prism.highlightAll();
138
+ }, []);
139
+
140
+ const UtilityExample = ({ utilityClass, description }) => {
141
+ const [copied, setCopied] = useState(false);
142
+
143
+ const handleCopy = () => {
144
+ navigator.clipboard.writeText(utilityClass);
145
+ setCopied(true);
146
+ setTimeout(() => setCopied(false), 2000);
147
+ };
148
+
149
+ return (
150
+ <div className="utility-example">
151
+ <div className="utility-example__preview">
152
+ <div className={`utility-example__demo ${utilityClass}`}>
153
+ {utilityClass.includes("text") && <span>Sample Text</span>}
154
+ {utilityClass.includes("bg") && !utilityClass.includes("text") && (
155
+ <span style={{ padding: "8px" }}>Background</span>
156
+ )}
157
+ {utilityClass.includes("border") && (
158
+ <div style={{ padding: "16px", minHeight: "40px" }}>Border</div>
159
+ )}
160
+ {utilityClass.includes("rounded") && (
161
+ <div style={{ padding: "16px", minHeight: "40px" }}>Rounded</div>
162
+ )}
163
+ {utilityClass.includes("shadow") && (
164
+ <div style={{ padding: "16px", minHeight: "40px" }}>Shadow</div>
165
+ )}
166
+ {utilityClass.includes("p-") && !utilityClass.includes("px") && !utilityClass.includes("py") && !utilityClass.includes("pt") && !utilityClass.includes("pr") && !utilityClass.includes("pb") && !utilityClass.includes("pl") && (
167
+ <div style={{ background: "var(--uds-surface-secondary)", borderRadius: "4px" }}>
168
+ Padding
169
+ </div>
170
+ )}
171
+ {(utilityClass.includes("px-") || utilityClass.includes("py-") || utilityClass.includes("pt-") || utilityClass.includes("pr-") || utilityClass.includes("pb-") || utilityClass.includes("pl-")) && (
172
+ <div style={{ background: "var(--uds-surface-secondary)", borderRadius: "4px" }}>
173
+ Padding
174
+ </div>
175
+ )}
176
+ {utilityClass.includes("m-") && !utilityClass.includes("mx") && !utilityClass.includes("my") && !utilityClass.includes("mt") && !utilityClass.includes("mr") && !utilityClass.includes("mb") && !utilityClass.includes("ml") && (
177
+ <div style={{ background: "var(--uds-surface-secondary)", borderRadius: "4px" }}>
178
+ Margin
179
+ </div>
180
+ )}
181
+ {(utilityClass.includes("mx-") || utilityClass.includes("my-") || utilityClass.includes("mt-") || utilityClass.includes("mr-") || utilityClass.includes("mb-") || utilityClass.includes("ml-")) && (
182
+ <div style={{ background: "var(--uds-surface-secondary)", borderRadius: "4px" }}>
183
+ Margin
184
+ </div>
185
+ )}
186
+ {utilityClass.includes("space-") && (
187
+ <div style={{ display: "flex", gap: utilityClass.includes("x") ? "0" : "0", flexDirection: utilityClass.includes("x") ? "row" : "column" }}>
188
+ <div style={{ padding: "8px", background: "var(--uds-surface-secondary)", borderRadius: "4px" }}>1</div>
189
+ <div style={{ padding: "8px", background: "var(--uds-surface-secondary)", borderRadius: "4px" }}>2</div>
190
+ <div style={{ padding: "8px", background: "var(--uds-surface-secondary)", borderRadius: "4px" }}>3</div>
191
+ </div>
192
+ )}
193
+ {utilityClass.includes("flex") && (
194
+ <div style={{ display: "flex", gap: "8px" }}>
195
+ <div style={{ padding: "8px", background: "var(--uds-surface-secondary)" }}>1</div>
196
+ <div style={{ padding: "8px", background: "var(--uds-surface-secondary)" }}>2</div>
197
+ <div style={{ padding: "8px", background: "var(--uds-surface-secondary)" }}>3</div>
198
+ </div>
199
+ )}
200
+ {utilityClass.includes("grid") && (
201
+ <div style={{ display: "grid", gap: "8px", gridTemplateColumns: "repeat(3, 1fr)" }}>
202
+ <div style={{ padding: "8px", background: "var(--uds-surface-secondary)" }}>1</div>
203
+ <div style={{ padding: "8px", background: "var(--uds-surface-secondary)" }}>2</div>
204
+ <div style={{ padding: "8px", background: "var(--uds-surface-secondary)" }}>3</div>
205
+ </div>
206
+ )}
207
+ {!utilityClass.includes("text") &&
208
+ !utilityClass.includes("bg") &&
209
+ !utilityClass.includes("border") &&
210
+ !utilityClass.includes("rounded") &&
211
+ !utilityClass.includes("shadow") &&
212
+ !utilityClass.includes("p-") &&
213
+ !utilityClass.includes("m-") &&
214
+ !utilityClass.includes("flex") &&
215
+ !utilityClass.includes("grid") && (
216
+ <span>Example</span>
217
+ )}
218
+ </div>
219
+ </div>
220
+ <div className="utility-example__info">
221
+ <div className="utility-example__code">
222
+ <code>{utilityClass}</code>
223
+ <button
224
+ className="utility-example__copy"
225
+ onClick={handleCopy}
226
+ aria-label="Copy class name"
227
+ >
228
+ {copied ? "✓ Copied" : "Copy"}
229
+ </button>
230
+ </div>
231
+ <p className="utility-example__description">{description}</p>
232
+ </div>
233
+ </div>
234
+ );
235
+ };
236
+
237
+ return (
238
+ <section className="page utilities-demo">
239
+ <header className="page__header">
240
+ <div className="page__header-container">
241
+ <Breadcrumb />
242
+ <div className="page__header-info">
243
+ <div className="page__header-content">
244
+ <h1 className="page__header-title">Utility Classes</h1>
245
+ <p className="page__header-description">
246
+ Tailwind-inspired utility classes using design tokens. These utilities provide
247
+ quick access to common CSS patterns while maintaining consistency with your design
248
+ system. All utilities use design tokens, so they automatically respect theme and
249
+ brand settings.
250
+ </p>
251
+ </div>
252
+ <div className="page__header-metadata">
253
+ <div className="page__metadata-row">
254
+ <p className="page__metadata-label">Author</p>
255
+ <a
256
+ href="https://chgit.slack.com/team/U06V9C0K06S"
257
+ className="page__metadata-link"
258
+ target="_blank"
259
+ rel="noopener noreferrer"
260
+ >
261
+ @Michael-Stevens
262
+ </a>
263
+ </div>
264
+ <div className="page__metadata-row">
265
+ <p className="page__metadata-label">Last updated</p>
266
+ <p className="page__metadata-value">{formatLastUpdated()}</p>
267
+ </div>
268
+ <div className="page__metadata-row">
269
+ <p className="page__metadata-label">Version</p>
270
+ <Flex direction="row" gap="8" alignItems="center">
271
+ <p className="page__metadata-value">1.0.0</p>
272
+ <span className="page__version-badge">BETA</span>
273
+ </Flex>
274
+ </div>
275
+ </div>
276
+ </div>
277
+ </div>
278
+ </header>
279
+
280
+ <main className="page__content">
281
+ <div className="utilities-demo__intro">
282
+ <h2>Getting Started</h2>
283
+ <p>
284
+ Utility classes are included in <code>tokens.css</code> and are available
285
+ throughout your application. Simply add the class names to your HTML elements:
286
+ </p>
287
+ <div className="utilities-demo__code-block-wrapper">
288
+ <CopyButton textToCopy={gettingStartedCode} />
289
+ <pre className="utilities-demo__code-block">
290
+ <code className="language-markup">{gettingStartedCode}</code>
291
+ </pre>
292
+ </div>
293
+ </div>
294
+
295
+ <Divider variant="solid" />
296
+
297
+ <div className="page__tabs-container">
298
+ <Tabs
299
+ tabs={UTILITY_CATEGORIES.map((cat) => ({
300
+ id: cat.id,
301
+ label: cat.label,
302
+ }))}
303
+ activeTab={activeTab}
304
+ onTabChange={(index, tab) => {
305
+ setActiveTab(index);
306
+ }}
307
+ scrollable={true}
308
+ />
309
+ </div>
310
+
311
+ <div className="utilities-demo__content">
312
+ {UTILITY_CATEGORIES.map((category, index) => (
313
+ <div
314
+ key={category.id}
315
+ className={`utilities-demo__category ${
316
+ activeTab === index ? "utilities-demo__category--active" : ""
317
+ }`}
318
+ >
319
+ <h2 className="utilities-demo__category-title">{category.label}</h2>
320
+ <p className="utilities-demo__category-description">
321
+ {category.id === "layout" &&
322
+ "Display, positioning, overflow, and z-index utilities for layout control."}
323
+ {category.id === "flexbox-grid" &&
324
+ "Flexbox and grid utilities for creating flexible layouts."}
325
+ {category.id === "spacing" &&
326
+ "Padding, margin, and space-between utilities using spacing tokens."}
327
+ {category.id === "sizing" &&
328
+ "Width, height, and aspect ratio utilities using sizing tokens."}
329
+ {category.id === "typography" &&
330
+ "Font size, weight, line height, and text styling utilities."}
331
+ {category.id === "backgrounds" &&
332
+ "Background color, gradient, and positioning utilities."}
333
+ {category.id === "borders-effects" &&
334
+ "Border, radius, shadow, opacity, and blur utilities."}
335
+ {category.id === "transforms-animation" &&
336
+ "Transform and transition utilities for animations."}
337
+ {category.id === "interactivity" &&
338
+ "Cursor, pointer events, selection, and accessibility utilities."}
339
+ {category.id === "variants" &&
340
+ "Hover, focus, active, disabled, and responsive variant utilities."}
341
+ </p>
342
+ <div className="utilities-demo__grid">
343
+ {UTILITY_EXAMPLES[category.id]?.map((example) => (
344
+ <UtilityExample
345
+ key={example.class}
346
+ utilityClass={example.class}
347
+ description={example.description}
348
+ />
349
+ ))}
350
+ </div>
351
+ </div>
352
+ ))}
353
+ </div>
354
+
355
+ <Divider variant="solid" />
356
+
357
+ <div className="utilities-demo__notes">
358
+ <h2>Notes</h2>
359
+ <ul>
360
+ <li>
361
+ All utilities use design tokens (e.g., <code>var(--uds-spacing-8)</code>), so they
362
+ automatically respect your theme and brand settings.
363
+ </li>
364
+ <li>
365
+ Utility classes follow a consistent naming pattern similar to Tailwind CSS for
366
+ familiarity.
367
+ </li>
368
+ <li>
369
+ Variants like <code>hover:</code>, <code>focus:</code>, and <code>dark:</code> can
370
+ be combined with other utilities.
371
+ </li>
372
+ <li>
373
+ For a complete list of available utilities, see{" "}
374
+ <code>src/styles/_utilities.scss</code>.
375
+ </li>
376
+ </ul>
377
+ </div>
378
+ </main>
379
+ </section>
380
+ );
381
+ }
@@ -0,0 +1,214 @@
1
+ .utilities-demo {
2
+ &__intro {
3
+ margin: 0 auto;
4
+ max-width: 960px;
5
+ width: 100%;
6
+ padding: var(--uds-spacing-48) var(--uds-spacing-48) 0;
7
+ margin-bottom: var(--uds-spacing-24);
8
+
9
+ h2 {
10
+ font-size: var(--uds-font-size-24);
11
+ font-weight: var(--uds-font-weight-semibold);
12
+ margin-bottom: var(--uds-spacing-12);
13
+ color: var(--uds-text-primary);
14
+ }
15
+
16
+ p {
17
+ margin-bottom: var(--uds-spacing-16);
18
+ color: var(--uds-text-secondary);
19
+ line-height: var(--uds-line-20);
20
+ }
21
+ }
22
+
23
+ &__code-block-wrapper {
24
+ position: relative;
25
+ margin: var(--uds-spacing-16) 0;
26
+ }
27
+
28
+ &__code-block {
29
+ background: var(--uds-code-bg);
30
+ border: 1px solid var(--uds-border-primary);
31
+ border-radius: var(--uds-radius-8);
32
+ padding: var(--uds-spacing-16);
33
+ overflow-x: auto;
34
+ margin: 0;
35
+ max-width: 100%;
36
+ word-break: break-word;
37
+
38
+ code[class*="language-"] {
39
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
40
+ font-size: var(--uds-font-size-14);
41
+ line-height: var(--uds-line-20);
42
+ white-space: pre;
43
+ word-wrap: normal;
44
+ display: block;
45
+ overflow-x: auto;
46
+ background: transparent;
47
+ }
48
+ }
49
+
50
+ &__code-block-wrapper:hover .copy-button {
51
+ opacity: 1;
52
+ pointer-events: auto;
53
+ }
54
+
55
+ &__content {
56
+ margin: 0 auto;
57
+ max-width: 960px;
58
+ width: 100%;
59
+ padding: 0 var(--uds-spacing-48);
60
+ margin-top: var(--uds-spacing-24);
61
+ }
62
+
63
+ &__category {
64
+ display: none;
65
+
66
+ &--active {
67
+ display: block;
68
+ }
69
+
70
+ &-title {
71
+ font-size: var(--uds-font-size-24);
72
+ font-weight: var(--uds-font-weight-semibold);
73
+ margin-bottom: var(--uds-spacing-8);
74
+ color: var(--uds-text-primary);
75
+ }
76
+
77
+ &-description {
78
+ margin-bottom: var(--uds-spacing-24);
79
+ color: var(--uds-text-secondary);
80
+ line-height: var(--uds-line-20);
81
+ }
82
+ }
83
+
84
+ &__grid {
85
+ display: grid;
86
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
87
+ gap: var(--uds-spacing-16);
88
+ margin-bottom: var(--uds-spacing-32);
89
+ max-width: 100%;
90
+
91
+ @media (max-width: 768px) {
92
+ grid-template-columns: 1fr;
93
+ }
94
+ }
95
+
96
+ &__notes {
97
+ margin: var(--uds-spacing-32) auto 0;
98
+ max-width: 960px;
99
+ width: 100%;
100
+ padding: 0 var(--uds-spacing-48) var(--uds-spacing-48);
101
+
102
+ h2 {
103
+ font-size: var(--uds-font-size-24);
104
+ font-weight: var(--uds-font-weight-semibold);
105
+ margin-bottom: var(--uds-spacing-16);
106
+ color: var(--uds-text-primary);
107
+ }
108
+
109
+ ul {
110
+ list-style: disc;
111
+ padding-left: var(--uds-spacing-24);
112
+ color: var(--uds-text-secondary);
113
+ line-height: var(--uds-line-24);
114
+
115
+ li {
116
+ margin-bottom: var(--uds-spacing-8);
117
+
118
+ code {
119
+ background: var(--uds-surface-secondary);
120
+ padding: 2px 6px;
121
+ border-radius: var(--uds-radius-4);
122
+ font-size: var(--uds-font-size-14);
123
+ color: var(--uds-text-brand-primary);
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
129
+
130
+ .utility-example {
131
+ border: 1px solid var(--uds-border-primary);
132
+ border-radius: var(--uds-radius-8);
133
+ overflow: hidden;
134
+ background: var(--uds-surface-primary);
135
+ transition: box-shadow 0.2s ease;
136
+ max-width: 100%;
137
+ min-width: 0; // Prevents grid items from overflowing
138
+
139
+ &:hover {
140
+ box-shadow: 0 4px 6px -1px var(--uds-shadow-10), 0 2px 4px -2px var(--uds-shadow-10);
141
+ }
142
+
143
+ &__preview {
144
+ padding: var(--uds-spacing-16);
145
+ background: var(--uds-surface-secondary);
146
+ border-bottom: 1px solid var(--uds-border-primary);
147
+ min-height: 80px;
148
+ display: flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ }
152
+
153
+ &__demo {
154
+ width: 100%;
155
+ display: flex;
156
+ align-items: center;
157
+ justify-content: center;
158
+ color: var(--uds-text-primary);
159
+ }
160
+
161
+ &__info {
162
+ padding: var(--uds-spacing-12);
163
+ }
164
+
165
+ &__code {
166
+ display: flex;
167
+ align-items: center;
168
+ justify-content: space-between;
169
+ margin-bottom: var(--uds-spacing-8);
170
+ gap: var(--uds-spacing-8);
171
+ min-width: 0; // Allows flex item to shrink
172
+
173
+ code {
174
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
175
+ font-size: var(--uds-font-size-14);
176
+ color: var(--uds-text-brand-primary);
177
+ background: var(--uds-surface-secondary);
178
+ padding: var(--uds-spacing-4) var(--uds-spacing-8);
179
+ border-radius: var(--uds-radius-4);
180
+ flex: 1;
181
+ min-width: 0; // Allows text to truncate
182
+ overflow: hidden;
183
+ text-overflow: ellipsis;
184
+ white-space: nowrap;
185
+ }
186
+ }
187
+
188
+ &__copy {
189
+ background: var(--uds-surface-brand-primary);
190
+ color: var(--uds-text-on-brand);
191
+ border: none;
192
+ padding: var(--uds-spacing-4) var(--uds-spacing-8);
193
+ border-radius: var(--uds-radius-4);
194
+ font-size: var(--uds-font-size-12);
195
+ font-weight: var(--uds-font-weight-medium);
196
+ cursor: pointer;
197
+ transition: opacity 0.2s ease;
198
+
199
+ &:hover {
200
+ opacity: 0.9;
201
+ }
202
+
203
+ &:active {
204
+ opacity: 0.8;
205
+ }
206
+ }
207
+
208
+ &__description {
209
+ font-size: var(--uds-font-size-14);
210
+ color: var(--uds-text-secondary);
211
+ line-height: var(--uds-line-20);
212
+ margin: 0;
213
+ }
214
+ }
@@ -0,0 +1,13 @@
1
+ const reportWebVitals = (onPerfEntry) => {
2
+ if (onPerfEntry && onPerfEntry instanceof Function) {
3
+ import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4
+ getCLS(onPerfEntry);
5
+ getFID(onPerfEntry);
6
+ getFCP(onPerfEntry);
7
+ getLCP(onPerfEntry);
8
+ getTTFB(onPerfEntry);
9
+ });
10
+ }
11
+ };
12
+
13
+ export default reportWebVitals;
@@ -0,0 +1,5 @@
1
+ // jest-dom adds custom jest matchers for asserting on DOM nodes.
2
+ // allows you to do things like:
3
+ // expect(element).toHaveTextContent(/react/i)
4
+ // learn more: https://github.com/testing-library/jest-dom
5
+ import "@testing-library/jest-dom";