@robr0/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 (223) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +127 -0
  3. package/charts.d.ts +14 -0
  4. package/charts.js +20 -0
  5. package/components/Accordion/Accordion.css +119 -0
  6. package/components/Accordion/Accordion.d.ts +24 -0
  7. package/components/Accordion/Accordion.js +76 -0
  8. package/components/Alert/Alert.css +252 -0
  9. package/components/Alert/Alert.d.ts +24 -0
  10. package/components/Alert/Alert.js +53 -0
  11. package/components/AlertDialog/AlertDialog.css +131 -0
  12. package/components/AlertDialog/AlertDialog.d.ts +29 -0
  13. package/components/AlertDialog/AlertDialog.js +143 -0
  14. package/components/AppLayout/AppLayout.css +52 -0
  15. package/components/AppLayout/AppLayout.d.ts +27 -0
  16. package/components/AppLayout/AppLayout.js +45 -0
  17. package/components/AppSidebar/AppSidebar.css +434 -0
  18. package/components/AppSidebar/AppSidebar.d.ts +67 -0
  19. package/components/AppSidebar/AppSidebar.js +272 -0
  20. package/components/Avatar/Avatar.css +133 -0
  21. package/components/Avatar/Avatar.d.ts +20 -0
  22. package/components/Avatar/Avatar.js +56 -0
  23. package/components/Avatar/demoAvatars.d.ts +14 -0
  24. package/components/Avatar/demoAvatars.js +16 -0
  25. package/components/Badge/Badge.css +68 -0
  26. package/components/Badge/Badge.d.ts +13 -0
  27. package/components/Badge/Badge.js +15 -0
  28. package/components/Breadcrumb/Breadcrumb.css +92 -0
  29. package/components/Breadcrumb/Breadcrumb.d.ts +19 -0
  30. package/components/Breadcrumb/Breadcrumb.js +39 -0
  31. package/components/Button/Button.css +381 -0
  32. package/components/Button/Button.d.ts +39 -0
  33. package/components/Button/Button.js +71 -0
  34. package/components/ButtonGroup/ButtonGroup.css +39 -0
  35. package/components/ButtonGroup/ButtonGroup.d.ts +13 -0
  36. package/components/ButtonGroup/ButtonGroup.js +37 -0
  37. package/components/Card/Card.css +169 -0
  38. package/components/Card/Card.d.ts +30 -0
  39. package/components/Card/Card.js +90 -0
  40. package/components/Carousel/Carousel.css +112 -0
  41. package/components/Carousel/Carousel.d.ts +25 -0
  42. package/components/Carousel/Carousel.js +126 -0
  43. package/components/Chart/AreaChart.d.ts +36 -0
  44. package/components/Chart/AreaChart.js +99 -0
  45. package/components/Chart/BarChart.d.ts +34 -0
  46. package/components/Chart/BarChart.js +107 -0
  47. package/components/Chart/Chart.css +176 -0
  48. package/components/Chart/LineChart.d.ts +34 -0
  49. package/components/Chart/LineChart.js +90 -0
  50. package/components/Chart/PieChart.d.ts +34 -0
  51. package/components/Chart/PieChart.js +106 -0
  52. package/components/Chart/RadarChart.d.ts +34 -0
  53. package/components/Chart/RadarChart.js +91 -0
  54. package/components/Chart/RadialChart.d.ts +37 -0
  55. package/components/Chart/RadialChart.js +119 -0
  56. package/components/Chart/ScatterChart.d.ts +36 -0
  57. package/components/Chart/ScatterChart.js +109 -0
  58. package/components/Chart/StackedBarChart.d.ts +34 -0
  59. package/components/Chart/StackedBarChart.js +111 -0
  60. package/components/Chart/Treemap.d.ts +33 -0
  61. package/components/Chart/Treemap.js +109 -0
  62. package/components/Checkbox/Checkbox.css +164 -0
  63. package/components/Checkbox/Checkbox.d.ts +45 -0
  64. package/components/Checkbox/Checkbox.js +125 -0
  65. package/components/Chip/Chip.css +195 -0
  66. package/components/Chip/Chip.d.ts +27 -0
  67. package/components/Chip/Chip.js +80 -0
  68. package/components/CircularButton/CircularButton.css +206 -0
  69. package/components/CircularButton/CircularButton.d.ts +30 -0
  70. package/components/CircularButton/CircularButton.js +54 -0
  71. package/components/CodeBlock/CodeBlock.css +180 -0
  72. package/components/CodeBlock/CodeBlock.d.ts +23 -0
  73. package/components/CodeBlock/CodeBlock.js +85 -0
  74. package/components/ColourSwatch/ColourSwatch.css +88 -0
  75. package/components/ColourSwatch/ColourSwatch.d.ts +34 -0
  76. package/components/ColourSwatch/ColourSwatch.js +42 -0
  77. package/components/Combobox/Combobox.css +411 -0
  78. package/components/Combobox/Combobox.d.ts +73 -0
  79. package/components/Combobox/Combobox.js +312 -0
  80. package/components/CommandPalette/CommandPalette.css +310 -0
  81. package/components/CommandPalette/CommandPalette.d.ts +60 -0
  82. package/components/CommandPalette/CommandPalette.js +263 -0
  83. package/components/ContactCard/ContactCard.css +123 -0
  84. package/components/ContactCard/ContactCard.d.ts +23 -0
  85. package/components/ContactCard/ContactCard.js +78 -0
  86. package/components/ContributionGraph/ContributionGraph.css +142 -0
  87. package/components/ContributionGraph/ContributionGraph.d.ts +26 -0
  88. package/components/ContributionGraph/ContributionGraph.js +125 -0
  89. package/components/DateInput/DateInput.css +163 -0
  90. package/components/DateInput/DateInput.d.ts +43 -0
  91. package/components/DateInput/DateInput.js +69 -0
  92. package/components/DatePicker/DatePicker.css +198 -0
  93. package/components/DatePicker/DatePicker.d.ts +22 -0
  94. package/components/DatePicker/DatePicker.js +170 -0
  95. package/components/Dialog/Dialog.css +176 -0
  96. package/components/Dialog/Dialog.d.ts +28 -0
  97. package/components/Dialog/Dialog.js +132 -0
  98. package/components/Divider/Divider.css +100 -0
  99. package/components/Divider/Divider.d.ts +18 -0
  100. package/components/Divider/Divider.js +31 -0
  101. package/components/Drawer/Drawer.css +262 -0
  102. package/components/Drawer/Drawer.d.ts +30 -0
  103. package/components/Drawer/Drawer.js +134 -0
  104. package/components/Dropdown/Dropdown.css +300 -0
  105. package/components/Dropdown/Dropdown.d.ts +48 -0
  106. package/components/Dropdown/Dropdown.js +196 -0
  107. package/components/DropdownMenu/DropdownMenu.css +303 -0
  108. package/components/DropdownMenu/DropdownMenu.d.ts +42 -0
  109. package/components/DropdownMenu/DropdownMenu.js +322 -0
  110. package/components/EmptyState/EmptyState.css +115 -0
  111. package/components/EmptyState/EmptyState.d.ts +27 -0
  112. package/components/EmptyState/EmptyState.js +32 -0
  113. package/components/EntityCard/EntityCard.css +69 -0
  114. package/components/EntityCard/EntityCard.d.ts +18 -0
  115. package/components/EntityCard/EntityCard.js +26 -0
  116. package/components/Figure/Figure.css +61 -0
  117. package/components/Figure/Figure.d.ts +17 -0
  118. package/components/Figure/Figure.js +35 -0
  119. package/components/FileInput/FileInput.css +308 -0
  120. package/components/FileInput/FileInput.d.ts +54 -0
  121. package/components/FileInput/FileInput.js +177 -0
  122. package/components/Input/Input.css +193 -0
  123. package/components/Input/Input.d.ts +40 -0
  124. package/components/Input/Input.js +71 -0
  125. package/components/Instructions/Instructions.css +216 -0
  126. package/components/Instructions/Instructions.d.ts +28 -0
  127. package/components/Instructions/Instructions.js +32 -0
  128. package/components/LinkList/LinkList.css +71 -0
  129. package/components/LinkList/LinkList.d.ts +20 -0
  130. package/components/LinkList/LinkList.js +41 -0
  131. package/components/MotionSwatch/MotionSwatch.css +176 -0
  132. package/components/MotionSwatch/MotionSwatch.d.ts +25 -0
  133. package/components/MotionSwatch/MotionSwatch.js +74 -0
  134. package/components/Nav/Nav.css +51 -0
  135. package/components/Nav/Nav.d.ts +19 -0
  136. package/components/Nav/Nav.js +26 -0
  137. package/components/Pagination/Pagination.css +126 -0
  138. package/components/Pagination/Pagination.d.ts +22 -0
  139. package/components/Pagination/Pagination.js +83 -0
  140. package/components/Popover/Popover.css +99 -0
  141. package/components/Popover/Popover.d.ts +28 -0
  142. package/components/Popover/Popover.js +102 -0
  143. package/components/ProgressBar/ProgressBar.css +60 -0
  144. package/components/ProgressBar/ProgressBar.d.ts +16 -0
  145. package/components/ProgressBar/ProgressBar.js +27 -0
  146. package/components/Quote/Quote.css +79 -0
  147. package/components/Quote/Quote.d.ts +18 -0
  148. package/components/Quote/Quote.js +26 -0
  149. package/components/RadioButton/RadioButton.css +132 -0
  150. package/components/RadioButton/RadioButton.d.ts +43 -0
  151. package/components/RadioButton/RadioButton.js +77 -0
  152. package/components/SectionTitle/SectionTitle.css +37 -0
  153. package/components/SectionTitle/SectionTitle.d.ts +10 -0
  154. package/components/SectionTitle/SectionTitle.js +17 -0
  155. package/components/SegmentedControl/SegmentedControl.css +129 -0
  156. package/components/SegmentedControl/SegmentedControl.d.ts +33 -0
  157. package/components/SegmentedControl/SegmentedControl.js +91 -0
  158. package/components/SelectionCard/SelectionCard.css +251 -0
  159. package/components/SelectionCard/SelectionCard.d.ts +26 -0
  160. package/components/SelectionCard/SelectionCard.js +85 -0
  161. package/components/Skeleton/Skeleton.css +79 -0
  162. package/components/Skeleton/Skeleton.d.ts +16 -0
  163. package/components/Skeleton/Skeleton.js +30 -0
  164. package/components/Slider/Slider.css +86 -0
  165. package/components/Slider/Slider.d.ts +25 -0
  166. package/components/Slider/Slider.js +46 -0
  167. package/components/SpacingSwatch/SpacingSwatch.css +108 -0
  168. package/components/SpacingSwatch/SpacingSwatch.d.ts +20 -0
  169. package/components/SpacingSwatch/SpacingSwatch.js +50 -0
  170. package/components/Spinner/Spinner.css +73 -0
  171. package/components/Spinner/Spinner.d.ts +14 -0
  172. package/components/Spinner/Spinner.js +42 -0
  173. package/components/Stat/Stat.css +78 -0
  174. package/components/Stat/Stat.d.ts +19 -0
  175. package/components/Stat/Stat.js +30 -0
  176. package/components/Table/Table.css +186 -0
  177. package/components/Table/Table.d.ts +45 -0
  178. package/components/Table/Table.js +65 -0
  179. package/components/Tabs/Tabs.css +140 -0
  180. package/components/Tabs/Tabs.d.ts +28 -0
  181. package/components/Tabs/Tabs.js +77 -0
  182. package/components/Textarea/Textarea.css +152 -0
  183. package/components/Textarea/Textarea.d.ts +40 -0
  184. package/components/Textarea/Textarea.js +74 -0
  185. package/components/Timeline/Timeline.css +339 -0
  186. package/components/Timeline/Timeline.d.ts +63 -0
  187. package/components/Timeline/Timeline.js +69 -0
  188. package/components/Toast/Toast.css +342 -0
  189. package/components/Toast/Toast.d.ts +63 -0
  190. package/components/Toast/Toast.js +213 -0
  191. package/components/ToggleGroup/ToggleGroup.css +84 -0
  192. package/components/ToggleGroup/ToggleGroup.d.ts +30 -0
  193. package/components/ToggleGroup/ToggleGroup.js +53 -0
  194. package/components/ToggleSwitch/ToggleSwitch.css +139 -0
  195. package/components/ToggleSwitch/ToggleSwitch.d.ts +23 -0
  196. package/components/ToggleSwitch/ToggleSwitch.js +50 -0
  197. package/components/Tooltip/Tooltip.css +122 -0
  198. package/components/Tooltip/Tooltip.d.ts +21 -0
  199. package/components/Tooltip/Tooltip.js +63 -0
  200. package/components/TypographySwatch/TypographySwatch.css +81 -0
  201. package/components/TypographySwatch/TypographySwatch.d.ts +24 -0
  202. package/components/TypographySwatch/TypographySwatch.js +40 -0
  203. package/components/registry.d.ts +20 -0
  204. package/components/registry.js +7 -0
  205. package/components/registry.json +67 -0
  206. package/components/registry.json.d.ts +70 -0
  207. package/components/registry.json.js +8 -0
  208. package/fonts/MaterialSymbolsRounded-VariableFont_FILL,GRAD,opsz,wght.woff2 +0 -0
  209. package/fonts/material-symbols.css +94 -0
  210. package/index.d.ts +62 -0
  211. package/index.js +123 -0
  212. package/package.json +63 -0
  213. package/tokens/registry.d.ts +22 -0
  214. package/tokens/registry.js +14 -0
  215. package/tokens/registry.json +203 -0
  216. package/tokens/registry.json.d.ts +206 -0
  217. package/tokens/registry.json.js +8 -0
  218. package/tokens/tokens-dark.css +119 -0
  219. package/tokens/tokens-light.css +159 -0
  220. package/tokens/tokens-motion.css +68 -0
  221. package/tokens/tokens-primitives.css +176 -0
  222. package/tokens/tokens-typography.css +116 -0
  223. package/tokens/tokens.css +11 -0
@@ -0,0 +1,80 @@
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
+ import "react";
3
+ import "./Chip.css";
4
+ import "../../fonts/material-symbols.css";
5
+ const Chip = ({
6
+ label,
7
+ icon,
8
+ selected,
9
+ disabled = false,
10
+ size = "default",
11
+ onClick,
12
+ onRemove,
13
+ removeLabel = "Remove",
14
+ className = ""
15
+ }) => {
16
+ const baseClass = "ds-chip";
17
+ const classes = [
18
+ baseClass,
19
+ `${baseClass}--${size}`,
20
+ selected && `${baseClass}--selected`,
21
+ disabled && `${baseClass}--disabled`,
22
+ onClick && !onRemove && `${baseClass}--clickable`,
23
+ onRemove && `${baseClass}--removable`,
24
+ className
25
+ ].filter(Boolean).join(" ");
26
+ const renderIcon = (iconProp) => {
27
+ if (typeof iconProp === "string") {
28
+ return /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon material-symbols-rounded`, "aria-hidden": "true", children: iconProp });
29
+ }
30
+ return /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon`, "aria-hidden": "true", children: iconProp });
31
+ };
32
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
33
+ icon && renderIcon(icon),
34
+ /* @__PURE__ */ jsx("span", { className: `${baseClass}__label`, children: label })
35
+ ] });
36
+ const ariaPressed = typeof selected === "boolean" ? selected : void 0;
37
+ if (onRemove) {
38
+ return /* @__PURE__ */ jsxs("span", { className: classes, children: [
39
+ onClick ? /* @__PURE__ */ jsx(
40
+ "button",
41
+ {
42
+ type: "button",
43
+ className: `${baseClass}__main`,
44
+ onClick,
45
+ disabled,
46
+ "aria-pressed": ariaPressed,
47
+ children: content
48
+ }
49
+ ) : content,
50
+ /* @__PURE__ */ jsx(
51
+ "button",
52
+ {
53
+ type: "button",
54
+ className: `${baseClass}__remove`,
55
+ onClick: onRemove,
56
+ disabled,
57
+ "aria-label": removeLabel,
58
+ children: /* @__PURE__ */ jsx("span", { className: "material-symbols-rounded", "aria-hidden": "true", children: "close" })
59
+ }
60
+ )
61
+ ] });
62
+ }
63
+ if (onClick) {
64
+ return /* @__PURE__ */ jsx(
65
+ "button",
66
+ {
67
+ type: "button",
68
+ className: classes,
69
+ onClick,
70
+ disabled,
71
+ "aria-pressed": ariaPressed,
72
+ children: content
73
+ }
74
+ );
75
+ }
76
+ return /* @__PURE__ */ jsx("span", { className: classes, children: content });
77
+ };
78
+ export {
79
+ Chip
80
+ };
@@ -0,0 +1,206 @@
1
+ /* ============================================
2
+ CIRCULAR BUTTON (ICON BUTTON)
3
+ Round button with a single icon
4
+ ============================================ */
5
+
6
+ .ds-circular-button {
7
+ /* Layout */
8
+ display: inline-flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+
12
+ /* Size — default */
13
+ width: 40px;
14
+ height: 40px;
15
+
16
+ /* Shape */
17
+ border-radius: var(--radius-full); /* 999px — perfect circle */
18
+
19
+ /* Transitions */
20
+ transition: background-color var(--motion-duration-base) var(--motion-ease-standard), border-color var(--motion-duration-base) var(--motion-ease-standard), opacity var(--motion-duration-base) var(--motion-ease-standard);
21
+
22
+ /* Reset */
23
+ cursor: pointer;
24
+ border: none;
25
+ padding: 0;
26
+ text-decoration: none;
27
+ color: inherit;
28
+ }
29
+
30
+ /* ============================================
31
+ SIZE — DEFAULT
32
+ ============================================ */
33
+
34
+ .ds-circular-button--default {
35
+ width: 40px;
36
+ height: 40px;
37
+ }
38
+
39
+ /* ============================================
40
+ SIZE — COMPACT
41
+ ============================================ */
42
+
43
+ .ds-circular-button--compact {
44
+ width: 32px;
45
+ height: 32px;
46
+ }
47
+
48
+ .ds-circular-button--compact .ds-circular-button__icon {
49
+ --icon-size: var(--icon-size-sm);
50
+ }
51
+
52
+ /* ============================================
53
+ ICON
54
+ ============================================ */
55
+
56
+ .ds-circular-button__icon {
57
+ flex-shrink: 0;
58
+ --icon-size: var(--icon-size-md);
59
+ line-height: 1;
60
+ }
61
+
62
+ /* ============================================
63
+ PRIMARY VARIANT (SOLID)
64
+ ============================================ */
65
+
66
+ .ds-circular-button--primary {
67
+ background-color: var(--color-action-primary-bg);
68
+ border: none;
69
+ }
70
+
71
+ .ds-circular-button--primary .ds-circular-button__icon {
72
+ color: var(--color-action-primary-text);
73
+ }
74
+
75
+ .ds-circular-button--primary.ds-circular-button--hover {
76
+ background-color: var(--color-action-primary-bg-hover);
77
+ }
78
+
79
+ .ds-circular-button--primary.ds-circular-button--hover .ds-circular-button__icon {
80
+ color: var(--color-action-primary-text-active);
81
+ }
82
+
83
+ .ds-circular-button--primary.ds-circular-button--active {
84
+ background-color: var(--color-action-primary-bg-active);
85
+ }
86
+
87
+ .ds-circular-button--primary.ds-circular-button--active .ds-circular-button__icon {
88
+ color: var(--color-action-primary-text-active);
89
+ }
90
+
91
+ .ds-circular-button--primary.ds-circular-button--disabled {
92
+ opacity: 0.4;
93
+ cursor: not-allowed;
94
+ }
95
+
96
+ /* Interactive hover/active */
97
+ .ds-circular-button--primary:not(.ds-circular-button--disabled):hover {
98
+ background-color: var(--color-action-primary-bg-hover);
99
+ }
100
+
101
+ .ds-circular-button--primary:not(.ds-circular-button--disabled):hover .ds-circular-button__icon {
102
+ color: var(--color-action-primary-text-active);
103
+ }
104
+
105
+ .ds-circular-button--primary:not(.ds-circular-button--disabled):active {
106
+ background-color: var(--color-action-primary-bg-active);
107
+ }
108
+
109
+ .ds-circular-button--primary:not(.ds-circular-button--disabled):active .ds-circular-button__icon {
110
+ color: var(--color-action-primary-text-active);
111
+ }
112
+
113
+ /* ============================================
114
+ SECONDARY VARIANT (OUTLINED)
115
+ ============================================ */
116
+
117
+ .ds-circular-button--secondary {
118
+ border: var(--border-xs) solid var(--color-action-primary-border);
119
+ background-color: transparent;
120
+ }
121
+
122
+ .ds-circular-button--secondary .ds-circular-button__icon {
123
+ color: var(--color-action-icon-default);
124
+ }
125
+
126
+ .ds-circular-button--secondary.ds-circular-button--hover {
127
+ background-color: var(--color-action-primary-bg-hover);
128
+ }
129
+
130
+ .ds-circular-button--secondary.ds-circular-button--hover .ds-circular-button__icon {
131
+ color: var(--color-action-icon-active);
132
+ }
133
+
134
+ .ds-circular-button--secondary.ds-circular-button--active {
135
+ background-color: var(--color-action-primary-bg-active);
136
+ }
137
+
138
+ .ds-circular-button--secondary.ds-circular-button--active .ds-circular-button__icon {
139
+ color: var(--color-action-icon-active);
140
+ }
141
+
142
+ .ds-circular-button--secondary.ds-circular-button--disabled {
143
+ opacity: 0.4;
144
+ cursor: not-allowed;
145
+ }
146
+
147
+ /* Interactive hover/active */
148
+ .ds-circular-button--secondary:not(.ds-circular-button--disabled):hover {
149
+ background-color: var(--color-action-primary-bg-hover);
150
+ }
151
+
152
+ .ds-circular-button--secondary:not(.ds-circular-button--disabled):hover .ds-circular-button__icon {
153
+ color: var(--color-action-icon-active);
154
+ }
155
+
156
+ .ds-circular-button--secondary:not(.ds-circular-button--disabled):active {
157
+ background-color: var(--color-action-primary-bg-active);
158
+ }
159
+
160
+ .ds-circular-button--secondary:not(.ds-circular-button--disabled):active .ds-circular-button__icon {
161
+ color: var(--color-action-icon-active);
162
+ }
163
+
164
+ /* ============================================
165
+ TERTIARY VARIANT (PASSIVE / GHOST)
166
+ ============================================ */
167
+
168
+ .ds-circular-button--tertiary {
169
+ background-color: var(--color-action-passive-bg);
170
+ border: none;
171
+ }
172
+
173
+ .ds-circular-button--tertiary .ds-circular-button__icon {
174
+ color: var(--color-icon-primary);
175
+ }
176
+
177
+ .ds-circular-button--tertiary.ds-circular-button--hover {
178
+ background-color: var(--color-action-passive-bg-hover);
179
+ }
180
+
181
+ .ds-circular-button--tertiary.ds-circular-button--active {
182
+ background-color: var(--color-action-passive-bg-active);
183
+ }
184
+
185
+ .ds-circular-button--tertiary.ds-circular-button--disabled {
186
+ opacity: 0.4;
187
+ cursor: not-allowed;
188
+ }
189
+
190
+ /* Interactive hover/active */
191
+ .ds-circular-button--tertiary:not(.ds-circular-button--disabled):hover {
192
+ background-color: var(--color-action-passive-bg-hover);
193
+ }
194
+
195
+ .ds-circular-button--tertiary:not(.ds-circular-button--disabled):active {
196
+ background-color: var(--color-action-passive-bg-active);
197
+ }
198
+
199
+ /* ============================================
200
+ FOCUS
201
+ ============================================ */
202
+
203
+ .ds-circular-button:focus-visible {
204
+ outline: 2px solid var(--color-action-primary-bg);
205
+ outline-offset: 2px;
206
+ }
@@ -0,0 +1,30 @@
1
+ export interface CircularButtonProps {
2
+ /** Material Symbol icon name */
3
+ icon: string;
4
+ /** Button priority/variant */
5
+ priority?: 'primary' | 'secondary' | 'tertiary';
6
+ /** Button state */
7
+ state?: 'default' | 'hover' | 'active' | 'disabled';
8
+ /** Button size */
9
+ size?: 'default' | 'compact';
10
+ /** Accessible label */
11
+ ariaLabel: string;
12
+ /** Optional click handler */
13
+ onClick?: () => void;
14
+ /** Optional href — renders as <a> instead of <button> */
15
+ href?: string;
16
+ /** Optional target attribute for links */
17
+ target?: string;
18
+ /** Optional rel attribute for links */
19
+ rel?: string;
20
+ /** Id of an element describing this button — set automatically by Tooltip */
21
+ 'aria-describedby'?: string;
22
+ /** Additional CSS classes */
23
+ className?: string;
24
+ }
25
+ /**
26
+ * Circular icon button component.
27
+ * A round button containing a single icon, available in
28
+ * primary and secondary variants with default and compact sizes.
29
+ */
30
+ export declare const CircularButton: ({ icon, priority, state, size, ariaLabel, onClick, href, target, rel, "aria-describedby": ariaDescribedby, className, }: CircularButtonProps) => import("react").JSX.Element;
@@ -0,0 +1,54 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import "./CircularButton.css";
3
+ import "../../fonts/material-symbols.css";
4
+ const CircularButton = ({
5
+ icon,
6
+ priority = "primary",
7
+ state = "default",
8
+ size = "default",
9
+ ariaLabel,
10
+ onClick,
11
+ href,
12
+ target,
13
+ rel,
14
+ "aria-describedby": ariaDescribedby,
15
+ className = ""
16
+ }) => {
17
+ const baseClass = "ds-circular-button";
18
+ const variantClass = `${baseClass}--${priority}`;
19
+ const stateClass = `${baseClass}--${state}`;
20
+ const sizeClass = `${baseClass}--${size}`;
21
+ const classes = [baseClass, variantClass, stateClass, sizeClass, className].filter(Boolean).join(" ");
22
+ const isDisabled = state === "disabled";
23
+ const children = /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon material-symbols-rounded`, "aria-hidden": "true", children: icon });
24
+ if (href && !isDisabled) {
25
+ return /* @__PURE__ */ jsx(
26
+ "a",
27
+ {
28
+ className: classes,
29
+ href,
30
+ target,
31
+ rel,
32
+ onClick,
33
+ "aria-label": ariaLabel,
34
+ "aria-describedby": ariaDescribedby,
35
+ children
36
+ }
37
+ );
38
+ }
39
+ return /* @__PURE__ */ jsx(
40
+ "button",
41
+ {
42
+ type: "button",
43
+ className: classes,
44
+ onClick,
45
+ disabled: isDisabled,
46
+ "aria-label": ariaLabel,
47
+ "aria-describedby": ariaDescribedby,
48
+ children
49
+ }
50
+ );
51
+ };
52
+ export {
53
+ CircularButton
54
+ };
@@ -0,0 +1,180 @@
1
+ /* ============================================
2
+ CODE BLOCK COMPONENT
3
+ Monospace code with an optional header row
4
+ (filename, language) and a copy button.
5
+ Note: the system typeface is Nunito Sans;
6
+ code is the one sanctioned monospace context.
7
+ ============================================ */
8
+
9
+ .ds-code-block {
10
+ display: flex;
11
+ flex-direction: column;
12
+ width: 100%;
13
+ border: var(--border-xs) solid var(--color-bg-container-border);
14
+ border-radius: var(--radius-md);
15
+ background-color: var(--color-bg-container-primary);
16
+ overflow: hidden;
17
+ max-height: var(--ds-code-block-max-height, none);
18
+ }
19
+
20
+ /* ============================================
21
+ HEADER
22
+ ============================================ */
23
+
24
+ .ds-code-block__header {
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: space-between;
28
+ gap: var(--gap-sm);
29
+ padding: var(--padding-xs) var(--padding-sm) var(--padding-xs) var(--padding-md);
30
+ border-bottom: var(--border-xs) solid var(--color-bg-container-border);
31
+ flex-shrink: 0;
32
+ transition: border-bottom-color var(--motion-duration-slow) var(--motion-ease-standard);
33
+ }
34
+
35
+ /* Collapsed: keep the header's height but hide its divider so it
36
+ doesn't double up with the root border */
37
+ .ds-code-block--collapsed .ds-code-block__header {
38
+ border-bottom-color: transparent;
39
+ }
40
+
41
+ .ds-code-block__meta {
42
+ display: flex;
43
+ align-items: center;
44
+ gap: var(--gap-sm);
45
+ min-width: 0;
46
+ }
47
+
48
+ .ds-code-block__toggle {
49
+ display: inline-flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ margin: 0;
53
+ padding: var(--padding-xxxs);
54
+ border: none;
55
+ border-radius: var(--radius-full);
56
+ background: none;
57
+ color: var(--color-icon-primary);
58
+ cursor: pointer;
59
+ flex-shrink: 0;
60
+ transition: background-color var(--motion-duration-base) var(--motion-ease-standard);
61
+ }
62
+
63
+ .ds-code-block__toggle .material-symbols-rounded {
64
+ --icon-size: var(--icon-size-sm);
65
+ line-height: 1;
66
+ transition: transform var(--motion-duration-slow) var(--motion-ease-standard);
67
+ }
68
+
69
+ .ds-code-block--collapsed .ds-code-block__toggle .material-symbols-rounded {
70
+ transform: rotate(-90deg);
71
+ }
72
+
73
+ .ds-code-block__toggle:hover {
74
+ background-color: var(--color-action-passive-bg-hover);
75
+ }
76
+
77
+ .ds-code-block__toggle:focus-visible {
78
+ outline: 2px solid var(--color-action-primary-bg);
79
+ outline-offset: 2px;
80
+ }
81
+
82
+ .ds-code-block__filename {
83
+ font-family: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, monospace;
84
+ font-size: var(--font-paragraph-sm-size);
85
+ line-height: var(--font-paragraph-sm-line-height);
86
+ color: var(--color-text-secondary);
87
+ overflow: hidden;
88
+ text-overflow: ellipsis;
89
+ white-space: nowrap;
90
+ }
91
+
92
+ .ds-code-block__language {
93
+ font-family: var(--font-paragraph-sm-family);
94
+ font-size: var(--font-paragraph-sm-size);
95
+ font-weight: var(--font-paragraph-sm-em-weight);
96
+ line-height: var(--font-paragraph-sm-line-height);
97
+ text-transform: uppercase;
98
+ letter-spacing: 0.08em;
99
+ color: var(--color-text-tertiary);
100
+ flex-shrink: 0;
101
+ }
102
+
103
+ /* ============================================
104
+ COPY BUTTON
105
+ ============================================ */
106
+
107
+ .ds-code-block__copy {
108
+ display: inline-flex;
109
+ align-items: center;
110
+ gap: var(--gap-xs);
111
+ margin: 0;
112
+ padding: var(--padding-xxxs) var(--padding-sm);
113
+ border: none;
114
+ border-radius: var(--radius-full);
115
+ background: none;
116
+ font-family: var(--font-paragraph-sm-em-family);
117
+ font-size: var(--font-paragraph-sm-em-size);
118
+ font-weight: var(--font-paragraph-sm-em-weight);
119
+ line-height: var(--font-paragraph-sm-em-line-height);
120
+ color: var(--color-text-secondary);
121
+ cursor: pointer;
122
+ flex-shrink: 0;
123
+ transition: background-color var(--motion-duration-base) var(--motion-ease-standard), color var(--motion-duration-base) var(--motion-ease-standard);
124
+ }
125
+
126
+ .ds-code-block__copy .material-symbols-rounded {
127
+ --icon-size: var(--icon-size-sm);
128
+ line-height: 1;
129
+ }
130
+
131
+ .ds-code-block__copy:hover {
132
+ background-color: var(--color-action-passive-bg-hover);
133
+ }
134
+
135
+ .ds-code-block__copy:focus-visible {
136
+ outline: 2px solid var(--color-action-primary-bg);
137
+ outline-offset: 2px;
138
+ }
139
+
140
+ /* ============================================
141
+ CODE AREA
142
+ ============================================ */
143
+
144
+ /* Same collapse technique as Accordion: animate the grid track
145
+ between 0fr and 1fr so height animates without measuring */
146
+ .ds-code-block__panel {
147
+ display: grid;
148
+ grid-template-rows: 1fr;
149
+ transition: grid-template-rows var(--motion-duration-slow) var(--motion-ease-standard);
150
+ min-height: 0;
151
+ }
152
+
153
+ .ds-code-block--collapsed .ds-code-block__panel {
154
+ grid-template-rows: 0fr;
155
+ }
156
+
157
+ .ds-code-block__panel-inner {
158
+ display: flex;
159
+ flex-direction: column;
160
+ min-height: 0;
161
+ overflow: hidden;
162
+ }
163
+
164
+ .ds-code-block__pre {
165
+ margin: 0;
166
+ padding: var(--padding-md);
167
+ overflow: auto;
168
+ /* Allow the pre to shrink below its content height so a
169
+ max-height on the root scrolls here, not past the header */
170
+ flex: 1 1 auto;
171
+ min-height: 0;
172
+ }
173
+
174
+ .ds-code-block__code {
175
+ font-family: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, monospace;
176
+ font-size: var(--font-paragraph-sm-size);
177
+ line-height: var(--font-paragraph-sm-line-height);
178
+ color: var(--color-text-primary);
179
+ white-space: pre;
180
+ }
@@ -0,0 +1,23 @@
1
+ export interface CodeBlockProps {
2
+ /** The code to display, as a plain string */
3
+ code: string;
4
+ /** Language tag shown in the header, e.g. "tsx", "css" */
5
+ language?: string;
6
+ /** Filename shown in the header, e.g. "tokens-light.css" */
7
+ filename?: string;
8
+ /** Show the copy-to-clipboard button */
9
+ showCopy?: boolean;
10
+ /** Max height of the block; code scrolls vertically inside while the header stays pinned. Numbers are px. */
11
+ maxHeight?: number | string;
12
+ /** Show a chevron beside the filename that collapses/expands the code area */
13
+ collapsible?: boolean;
14
+ /** Start collapsed (only applies when collapsible) */
15
+ defaultCollapsed?: boolean;
16
+ /** Additional CSS classes */
17
+ className?: string;
18
+ }
19
+ /**
20
+ * CodeBlock component — monospace code with an optional header row
21
+ * (filename, language tag) and a copy-to-clipboard button.
22
+ */
23
+ export declare const CodeBlock: ({ code, language, filename, showCopy, maxHeight, collapsible, defaultCollapsed, className, }: CodeBlockProps) => import("react").JSX.Element;
@@ -0,0 +1,85 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useState, useId } from "react";
3
+ import "./CodeBlock.css";
4
+ import "../../fonts/material-symbols.css";
5
+ const CodeBlock = ({
6
+ code,
7
+ language,
8
+ filename,
9
+ showCopy = true,
10
+ maxHeight,
11
+ collapsible = false,
12
+ defaultCollapsed = false,
13
+ className = ""
14
+ }) => {
15
+ const baseClass = "ds-code-block";
16
+ const [copied, setCopied] = useState(false);
17
+ const [collapsed, setCollapsed] = useState(collapsible && defaultCollapsed);
18
+ const panelId = useId();
19
+ const classes = [
20
+ baseClass,
21
+ collapsed ? `${baseClass}--collapsed` : "",
22
+ className
23
+ ].filter(Boolean).join(" ");
24
+ const style = maxHeight !== void 0 ? {
25
+ "--ds-code-block-max-height": typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight
26
+ } : void 0;
27
+ const hasHeader = Boolean(filename || language || showCopy || collapsible);
28
+ const copy = () => {
29
+ const fallback = () => {
30
+ const textarea = document.createElement("textarea");
31
+ textarea.value = code;
32
+ textarea.setAttribute("readonly", "");
33
+ textarea.style.position = "absolute";
34
+ textarea.style.left = "-9999px";
35
+ document.body.appendChild(textarea);
36
+ textarea.select();
37
+ document.execCommand("copy");
38
+ document.body.removeChild(textarea);
39
+ };
40
+ if (navigator.clipboard?.writeText) {
41
+ navigator.clipboard.writeText(code).catch(fallback);
42
+ } else {
43
+ fallback();
44
+ }
45
+ setCopied(true);
46
+ window.setTimeout(() => setCopied(false), 2e3);
47
+ };
48
+ return /* @__PURE__ */ jsxs("div", { className: classes, style, children: [
49
+ hasHeader && /* @__PURE__ */ jsxs("div", { className: `${baseClass}__header`, children: [
50
+ /* @__PURE__ */ jsxs("div", { className: `${baseClass}__meta`, children: [
51
+ collapsible && /* @__PURE__ */ jsx(
52
+ "button",
53
+ {
54
+ type: "button",
55
+ className: `${baseClass}__toggle`,
56
+ onClick: () => setCollapsed((c) => !c),
57
+ "aria-expanded": !collapsed,
58
+ "aria-controls": panelId,
59
+ "aria-label": collapsed ? "Expand code" : "Collapse code",
60
+ children: /* @__PURE__ */ jsx("span", { className: "material-symbols-rounded", "aria-hidden": "true", children: "expand_more" })
61
+ }
62
+ ),
63
+ filename && /* @__PURE__ */ jsx("code", { className: `${baseClass}__filename`, children: filename }),
64
+ language && /* @__PURE__ */ jsx("span", { className: `${baseClass}__language`, children: language })
65
+ ] }),
66
+ showCopy && /* @__PURE__ */ jsxs(
67
+ "button",
68
+ {
69
+ type: "button",
70
+ className: `${baseClass}__copy`,
71
+ onClick: copy,
72
+ "aria-label": copied ? "Copied" : "Copy code",
73
+ children: [
74
+ /* @__PURE__ */ jsx("span", { className: "material-symbols-rounded", "aria-hidden": "true", children: copied ? "check" : "content_copy" }),
75
+ copied ? "Copied" : "Copy"
76
+ ]
77
+ }
78
+ )
79
+ ] }),
80
+ /* @__PURE__ */ jsx("div", { id: panelId, className: `${baseClass}__panel`, "aria-hidden": collapsed || void 0, children: /* @__PURE__ */ jsx("div", { className: `${baseClass}__panel-inner`, children: /* @__PURE__ */ jsx("pre", { className: `${baseClass}__pre`, children: /* @__PURE__ */ jsx("code", { className: `${baseClass}__code`, children: code }) }) }) })
81
+ ] });
82
+ };
83
+ export {
84
+ CodeBlock
85
+ };