@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,47 @@
1
+ import React, { useMemo } from "react";
2
+ import * as PhosphorIcons from "@phosphor-icons/react";
3
+
4
+ /**
5
+ * Icons component wrapper for Phosphor icons
6
+ * @param {string} name - The name of the Phosphor icon (e.g., "ArrowRight", "User", "House")
7
+ * @param {number|string} size - The size of the icon (default: 24)
8
+ * @param {string} appearance - Optional: "regular" | "bold" | "thin" | "light" | "duotone" | "fill" (default: "regular")
9
+ * @param {object} props - Additional props to pass to the icon component
10
+ */
11
+ export default function Icon({
12
+ name,
13
+ size = 24,
14
+ appearance = "regular",
15
+ ...props
16
+ }) {
17
+ const weightMap = {
18
+ regular: "regular",
19
+ bold: "bold",
20
+ thin: "thin",
21
+ light: "light",
22
+ duotone: "duotone",
23
+ fill: "fill",
24
+ solid: "fill",
25
+ outline: "regular",
26
+ };
27
+
28
+ const weight = weightMap[appearance] || "regular";
29
+ const IconComponent = useMemo(() => {
30
+ if (!name) return null;
31
+ const nameString = typeof name === "string" ? name : String(name);
32
+ const iconName = nameString
33
+ .split(/(?=[A-Z])|[-_\s]/)
34
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
35
+ .join("");
36
+ return PhosphorIcons[iconName] || null;
37
+ }, [name]);
38
+
39
+ if (!IconComponent) {
40
+ if (name) {
41
+ console.warn(`Icon "${name}" not found in Phosphor icons.`);
42
+ }
43
+ return null;
44
+ }
45
+
46
+ return <IconComponent size={size} weight={weight} {...props} />;
47
+ }
@@ -0,0 +1 @@
1
+ export { default } from "./Icon";
@@ -0,0 +1,56 @@
1
+ import React from "react";
2
+ import "./ImageAspect.scss";
3
+
4
+ const BASE_CLASS = "uds-image-aspect";
5
+
6
+ const aspectRatioClassMap = {
7
+ square: "square",
8
+ video: "video",
9
+ "4-3": "4-3",
10
+ "3-2": "3-2",
11
+ "21-9": "21-9",
12
+ portrait: "portrait",
13
+ auto: "auto",
14
+ };
15
+
16
+ /**
17
+ * ImageAspect component for maintaining consistent aspect ratios for images
18
+ * @param {string} ratio - Aspect ratio variant: 'square', 'video', '4-3', '3-2', '21-9', 'portrait', 'auto'
19
+ * @param {string} src - Image source URL
20
+ * @param {string} alt - Alt text for the image
21
+ * @param {string} className - Additional CSS classes
22
+ * @param {object} props - Additional props to pass to the image element
23
+ */
24
+ export default function ImageAspect({
25
+ ratio = "square",
26
+ src,
27
+ alt = "",
28
+ className = "",
29
+ ...props
30
+ }) {
31
+ const classNames = [
32
+ BASE_CLASS,
33
+ aspectRatioClassMap[ratio] &&
34
+ `${BASE_CLASS}--${aspectRatioClassMap[ratio]}`,
35
+ className,
36
+ ]
37
+ .filter(Boolean)
38
+ .join(" ");
39
+
40
+ return (
41
+ <div className={classNames}>
42
+ {src ? (
43
+ <img
44
+ src={src}
45
+ alt={alt}
46
+ className={`${BASE_CLASS}__image`}
47
+ {...props}
48
+ />
49
+ ) : (
50
+ <div className={`${BASE_CLASS}__placeholder`}>
51
+ <span className={`${BASE_CLASS}__placeholder-text`}>Image</span>
52
+ </div>
53
+ )}
54
+ </div>
55
+ );
56
+ }
@@ -0,0 +1,62 @@
1
+ @use "../../styles/typography" as *;
2
+
3
+ .uds-image-aspect {
4
+ position: relative;
5
+ width: 100%;
6
+ overflow: hidden;
7
+ background-color: var(--uds-surface-tertiary);
8
+ border-radius: var(--uds-radius-4);
9
+
10
+ // Aspect ratio variants
11
+ &--square {
12
+ aspect-ratio: var(--uds-aspect-ratio-square, 1 / 1);
13
+ }
14
+
15
+ &--video {
16
+ aspect-ratio: var(--uds-aspect-ratio-video, 16 / 9);
17
+ }
18
+
19
+ &--4-3 {
20
+ aspect-ratio: var(--uds-aspect-ratio-4-3, 4 / 3);
21
+ }
22
+
23
+ &--3-2 {
24
+ aspect-ratio: var(--uds-aspect-ratio-3-2, 3 / 2);
25
+ }
26
+
27
+ &--21-9 {
28
+ aspect-ratio: var(--uds-aspect-ratio-21-9, 21 / 9);
29
+ }
30
+
31
+ &--portrait {
32
+ aspect-ratio: var(--uds-aspect-ratio-portrait, 3 / 4);
33
+ }
34
+
35
+ &--auto {
36
+ aspect-ratio: var(--uds-aspect-ratio-auto, auto);
37
+ }
38
+
39
+ &__image {
40
+ width: 100%;
41
+ height: 100%;
42
+ object-fit: cover;
43
+ object-position: center;
44
+ display: block;
45
+ }
46
+
47
+ &__placeholder {
48
+ width: 100%;
49
+ height: 100%;
50
+ display: flex;
51
+ align-items: center;
52
+ justify-content: center;
53
+ background-color: var(--uds-surface-tertiary);
54
+ border: var(--uds-border-width-1) dashed var(--uds-border-primary);
55
+ color: var(--uds-text-secondary);
56
+ }
57
+
58
+ &__placeholder-text {
59
+ @include uds-body-14;
60
+ color: var(--uds-text-secondary);
61
+ }
62
+ }
@@ -0,0 +1 @@
1
+ export { default } from "./ImageAspect";
@@ -0,0 +1,35 @@
1
+ import React, { useState } from 'react';
2
+ import Input from './Input';
3
+
4
+ /**
5
+ * Figma Code Connect for Input component
6
+ *
7
+ * Simple execution version of input with various configurations
8
+ */
9
+ export default function InputFigma({
10
+ value,
11
+ placeholderText = 'Placeholder',
12
+ type = 'text',
13
+ size = 'default',
14
+ state = 'default',
15
+ placeholder = false,
16
+ disabled = false,
17
+ }) {
18
+ const [internalValue, setInternalValue] = useState(value || '');
19
+
20
+ const handleChange = (e) => {
21
+ setInternalValue(e.target.value);
22
+ };
23
+
24
+ return (
25
+ <Input
26
+ value={placeholder ? '' : (value || internalValue)}
27
+ onChange={handleChange}
28
+ placeholder={placeholder ? placeholderText : undefined}
29
+ type={type}
30
+ size={size.toLowerCase()}
31
+ state={state.toLowerCase()}
32
+ disabled={disabled || state === 'disabled'}
33
+ />
34
+ );
35
+ }
@@ -0,0 +1,68 @@
1
+ import React from "react";
2
+ import "./Input.scss";
3
+
4
+ const BASE_CLASS = "uds-input";
5
+
6
+ const sizeClassMap = {
7
+ compact: "compact",
8
+ default: "default",
9
+ };
10
+
11
+ const stateClassMap = {
12
+ default: "default",
13
+ focused: "focused",
14
+ error: "error",
15
+ disabled: "disabled",
16
+ };
17
+
18
+ /**
19
+ * Input component for single-line text input
20
+ *
21
+ * @param {string} value - The value of the input
22
+ * @param {function} onChange - Callback function when value changes
23
+ * @param {string} placeholder - Placeholder text
24
+ * @param {string} type - Input type: 'text', 'email', 'password', etc. (default: 'text')
25
+ * @param {string} size - Size variant: 'compact' or 'default' (default: 'default')
26
+ * @param {string} state - State variant: 'default', 'focused', 'error', or 'disabled'
27
+ * @param {boolean} disabled - Whether the input is disabled (overrides state)
28
+ * @param {string} id - Unique identifier for the input
29
+ * @param {string} className - Additional CSS classes
30
+ * @param {object} props - Additional props to pass to the input element
31
+ */
32
+ export default function Input({
33
+ value,
34
+ onChange,
35
+ placeholder,
36
+ type = "text",
37
+ size = "default",
38
+ state = "default",
39
+ disabled = false,
40
+ id,
41
+ className = "",
42
+ ...props
43
+ }) {
44
+ const effectiveState = disabled ? "disabled" : state;
45
+
46
+ const classNames = [
47
+ BASE_CLASS,
48
+ sizeClassMap[size] && `${BASE_CLASS}--${sizeClassMap[size]}`,
49
+ stateClassMap[effectiveState] &&
50
+ `${BASE_CLASS}--${stateClassMap[effectiveState]}`,
51
+ className,
52
+ ]
53
+ .filter(Boolean)
54
+ .join(" ");
55
+
56
+ return (
57
+ <input
58
+ id={id}
59
+ type={type}
60
+ className={classNames}
61
+ value={value}
62
+ onChange={onChange}
63
+ placeholder={placeholder}
64
+ disabled={disabled || effectiveState === "disabled"}
65
+ {...props}
66
+ />
67
+ );
68
+ }
@@ -0,0 +1,64 @@
1
+ @use "../../styles/typography" as *;
2
+
3
+ .uds-input {
4
+ @include uds-body-16;
5
+ width: 100%;
6
+ padding: var(--uds-spacing-10) var(--uds-spacing-12);
7
+ border: var(--uds-border-width-1) solid var(--uds-border-primary);
8
+ border-radius: var(--uds-radius-4);
9
+ background-color: var(--uds-surface-primary);
10
+ color: var(--uds-text-primary);
11
+ transition: all var(--uds-animation-duration-200) var(--uds-animation-ease-standard);
12
+ box-sizing: border-box;
13
+ font-family: var(--uds-font-family);
14
+ height: fit-content;
15
+
16
+ &::placeholder {
17
+ color: var(--uds-text-placeholder);
18
+ }
19
+
20
+ // Size variants
21
+ &--compact {
22
+ padding: var(--uds-spacing-8) var(--uds-spacing-10);
23
+ @include uds-body-14;
24
+ }
25
+
26
+ &--default {
27
+ padding: var(--uds-spacing-10) var(--uds-spacing-12);
28
+ @include uds-body-16;
29
+ }
30
+
31
+ // Default state (border color)
32
+ border-color: var(--uds-border-primary);
33
+
34
+ // State: Focused
35
+ &--focused {
36
+ border-color: var(--uds-border-brand-primary);
37
+ }
38
+
39
+ // State: Error
40
+ &--error {
41
+ border-color: var(--uds-text-error, #ef4444);
42
+ }
43
+
44
+ // State: Disabled
45
+ &--disabled,
46
+ &:disabled {
47
+ background-color: var(--uds-surface-tertiary);
48
+ color: var(--uds-text-secondary);
49
+ cursor: not-allowed;
50
+ opacity: 0.6;
51
+ border-color: var(--uds-border-primary);
52
+ }
53
+
54
+ // Focus state (applies to all states except disabled)
55
+ &:focus:not(:disabled) {
56
+ outline: none;
57
+ border-color: var(--uds-border-brand-primary);
58
+ }
59
+
60
+ // Remove default input styling that might interfere
61
+ &:focus-visible {
62
+ outline: none;
63
+ }
64
+ }
@@ -0,0 +1,2 @@
1
+ export { default as Input } from "./Input";
2
+ export { default } from "./Input";
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import './Key.scss';
3
+
4
+ const BASE_CLASS = 'uds-key';
5
+
6
+ const appearanceClassMap = {
7
+ light: 'light',
8
+ dark: 'dark',
9
+ };
10
+
11
+ /**
12
+ * Key component for displaying keyboard key representations
13
+ * @param {string} label - The text or symbol to display on the key (e.g., "Esc", "⌘", "Ctrl")
14
+ * @param {string} appearance - Visual style variant: 'light' or 'dark'
15
+ * @param {string} className - Additional CSS classes
16
+ * @param {object} props - Additional props to pass to the key element
17
+ */
18
+ export default function Key({
19
+ label,
20
+ appearance = 'light',
21
+ className = '',
22
+ ...props
23
+ }) {
24
+ const classNames = [
25
+ BASE_CLASS,
26
+ appearanceClassMap[appearance] && `${BASE_CLASS}--${appearanceClassMap[appearance]}`,
27
+ className,
28
+ ]
29
+ .filter(Boolean)
30
+ .join(' ');
31
+
32
+ return (
33
+ <kbd className={classNames} {...props}>
34
+ {label}
35
+ </kbd>
36
+ );
37
+ }
@@ -0,0 +1,34 @@
1
+ @use "../../styles/typography" as *;
2
+
3
+ .uds-key {
4
+ @include uds-body-14-medium;
5
+ display: inline-flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ min-width: 24px;
9
+ height: 24px;
10
+ padding-inline: var(--uds-padding-8);
11
+ padding-block: var(--uds-padding-4);
12
+ border-radius: var(--uds-radius-4);
13
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
14
+ @include uds-body-12;
15
+ font-size: 12px;
16
+ line-height: 1;
17
+ white-space: nowrap;
18
+ user-select: none;
19
+ box-sizing: border-box;
20
+ transition: all var(--uds-duration-200) var(--uds-ease-standard);
21
+
22
+ // Appearance variants
23
+ &--light {
24
+ background-color: var(--uds-surface-primary);
25
+ border: var(--uds-border-width-1) solid var(--uds-border-primary);
26
+ color: var(--uds-text-secondary);
27
+ }
28
+
29
+ &--dark {
30
+ background-color: #374151; // Dark blue-gray
31
+ border: none;
32
+ color: #FFFFFF;
33
+ }
34
+ }
@@ -0,0 +1 @@
1
+ export { default } from "./Key";