@rebasepro/ui 0.24.0 → 0.24.1-canary.g19596ef

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 (241) hide show
  1. package/dist/components/Alert.d.ts +6 -0
  2. package/dist/components/Alert.es.js +82 -0
  3. package/dist/components/Alert.es.js.map +1 -0
  4. package/dist/components/Autocomplete.es.js +53 -0
  5. package/dist/components/Autocomplete.es.js.map +1 -0
  6. package/dist/components/Avatar.d.ts +3 -1
  7. package/dist/components/Avatar.es.js +37 -0
  8. package/dist/components/Avatar.es.js.map +1 -0
  9. package/dist/components/Badge.es.js +27 -0
  10. package/dist/components/Badge.es.js.map +1 -0
  11. package/dist/components/BooleanSwitch.es.js +75 -0
  12. package/dist/components/BooleanSwitch.es.js.map +1 -0
  13. package/dist/components/BooleanSwitchWithLabel.es.js +55 -0
  14. package/dist/components/BooleanSwitchWithLabel.es.js.map +1 -0
  15. package/dist/components/Button.es.js +58 -0
  16. package/dist/components/Button.es.js.map +1 -0
  17. package/dist/components/Card.es.js +26 -0
  18. package/dist/components/Card.es.js.map +1 -0
  19. package/dist/components/CenteredView.es.js +23 -0
  20. package/dist/components/CenteredView.es.js.map +1 -0
  21. package/dist/components/Checkbox.es.js +62 -0
  22. package/dist/components/Checkbox.es.js.map +1 -0
  23. package/dist/components/Chip.es.js +72 -0
  24. package/dist/components/Chip.es.js.map +1 -0
  25. package/dist/components/CircularProgress.es.js +28 -0
  26. package/dist/components/CircularProgress.es.js.map +1 -0
  27. package/dist/components/CircularProgressCenter.es.js +30 -0
  28. package/dist/components/CircularProgressCenter.es.js.map +1 -0
  29. package/dist/components/Collapse.es.js +57 -0
  30. package/dist/components/Collapse.es.js.map +1 -0
  31. package/dist/components/ColorPicker.es.js +89 -0
  32. package/dist/components/ColorPicker.es.js.map +1 -0
  33. package/dist/components/Container.es.js +31 -0
  34. package/dist/components/Container.es.js.map +1 -0
  35. package/dist/components/DateTimeField.d.ts +11 -1
  36. package/dist/components/DateTimeField.es.js +253 -0
  37. package/dist/components/DateTimeField.es.js.map +1 -0
  38. package/dist/components/DebouncedTextField.es.js +93 -0
  39. package/dist/components/DebouncedTextField.es.js.map +1 -0
  40. package/dist/components/Dialog.es.js +98 -0
  41. package/dist/components/Dialog.es.js.map +1 -0
  42. package/dist/components/DialogActions.es.js +15 -0
  43. package/dist/components/DialogActions.es.js.map +1 -0
  44. package/dist/components/DialogContent.es.js +18 -0
  45. package/dist/components/DialogContent.es.js.map +1 -0
  46. package/dist/components/DialogTitle.es.js +26 -0
  47. package/dist/components/DialogTitle.es.js.map +1 -0
  48. package/dist/components/ErrorBoundary.es.js +158 -0
  49. package/dist/components/ErrorBoundary.es.js.map +1 -0
  50. package/dist/components/ExpandablePanel.es.js +91 -0
  51. package/dist/components/ExpandablePanel.es.js.map +1 -0
  52. package/dist/components/FileUpload.es.js +58 -0
  53. package/dist/components/FileUpload.es.js.map +1 -0
  54. package/dist/components/FilterChip.es.js +31 -0
  55. package/dist/components/FilterChip.es.js.map +1 -0
  56. package/dist/components/IconButton.es.js +52 -0
  57. package/dist/components/IconButton.es.js.map +1 -0
  58. package/dist/components/InfoLabel.es.js +18 -0
  59. package/dist/components/InfoLabel.es.js.map +1 -0
  60. package/dist/components/InputLabel.es.js +27 -0
  61. package/dist/components/InputLabel.es.js.map +1 -0
  62. package/dist/components/Label.es.js +18 -0
  63. package/dist/components/Label.es.js.map +1 -0
  64. package/dist/components/LoadingButton.es.js +21 -0
  65. package/dist/components/LoadingButton.es.js.map +1 -0
  66. package/dist/components/Markdown.es.js +88 -0
  67. package/dist/components/Markdown.es.js.map +1 -0
  68. package/dist/components/Menu.es.js +46 -0
  69. package/dist/components/Menu.es.js.map +1 -0
  70. package/dist/components/Menubar.es.js +142 -0
  71. package/dist/components/Menubar.es.js.map +1 -0
  72. package/dist/components/MultiSelect.d.ts +1 -7
  73. package/dist/components/MultiSelect.es.js +271 -0
  74. package/dist/components/MultiSelect.es.js.map +1 -0
  75. package/dist/components/Paper.es.js +16 -0
  76. package/dist/components/Paper.es.js.map +1 -0
  77. package/dist/components/Popover.es.js +113 -0
  78. package/dist/components/Popover.es.js.map +1 -0
  79. package/dist/components/RadioGroup.es.js +30 -0
  80. package/dist/components/RadioGroup.es.js.map +1 -0
  81. package/dist/components/ResizablePanels.d.ts +3 -1
  82. package/dist/components/ResizablePanels.es.js +137 -0
  83. package/dist/components/ResizablePanels.es.js.map +1 -0
  84. package/dist/components/SearchBar.es.js +82 -0
  85. package/dist/components/SearchBar.es.js.map +1 -0
  86. package/dist/components/Select.d.ts +8 -1
  87. package/dist/components/Select.es.js +300 -0
  88. package/dist/components/Select.es.js.map +1 -0
  89. package/dist/components/Separator.es.js +20 -0
  90. package/dist/components/Separator.es.js.map +1 -0
  91. package/dist/components/Sheet.es.js +73 -0
  92. package/dist/components/Sheet.es.js.map +1 -0
  93. package/dist/components/Skeleton.es.js +33 -0
  94. package/dist/components/Skeleton.es.js.map +1 -0
  95. package/dist/components/Slider.es.js +56 -0
  96. package/dist/components/Slider.es.js.map +1 -0
  97. package/dist/components/Table.d.ts +18 -3
  98. package/dist/components/Table.es.js +69 -0
  99. package/dist/components/Table.es.js.map +1 -0
  100. package/dist/components/Tabs.es.js +101 -0
  101. package/dist/components/Tabs.es.js.map +1 -0
  102. package/dist/components/TextField.d.ts +0 -8
  103. package/dist/components/TextField.es.js +111 -0
  104. package/dist/components/TextField.es.js.map +1 -0
  105. package/dist/components/TextareaAutosize.es.js +187 -0
  106. package/dist/components/TextareaAutosize.es.js.map +1 -0
  107. package/dist/components/ToggleButtonGroup.d.ts +6 -1
  108. package/dist/components/ToggleButtonGroup.es.js +35 -0
  109. package/dist/components/ToggleButtonGroup.es.js.map +1 -0
  110. package/dist/components/Tooltip.d.ts +24 -0
  111. package/dist/components/Tooltip.es.js +165 -0
  112. package/dist/components/Tooltip.es.js.map +1 -0
  113. package/dist/components/Typography.es.js +85 -0
  114. package/dist/components/Typography.es.js.map +1 -0
  115. package/dist/components/VirtualTable/VirtualTable.es.js +516 -0
  116. package/dist/components/VirtualTable/VirtualTable.es.js.map +1 -0
  117. package/dist/components/VirtualTable/VirtualTableCell.d.ts +1 -1
  118. package/dist/components/VirtualTable/VirtualTableCell.es.js +40 -0
  119. package/dist/components/VirtualTable/VirtualTableCell.es.js.map +1 -0
  120. package/dist/components/VirtualTable/VirtualTableHeader.es.js +209 -0
  121. package/dist/components/VirtualTable/VirtualTableHeader.es.js.map +1 -0
  122. package/dist/components/VirtualTable/VirtualTableHeaderRow.es.js +166 -0
  123. package/dist/components/VirtualTable/VirtualTableHeaderRow.es.js.map +1 -0
  124. package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -2
  125. package/dist/components/VirtualTable/VirtualTableRow.d.ts +6 -7
  126. package/dist/components/VirtualTable/VirtualTableRow.es.js +41 -0
  127. package/dist/components/VirtualTable/VirtualTableRow.es.js.map +1 -0
  128. package/dist/components/VirtualTable/fields/VirtualTableDateField.d.ts +2 -1
  129. package/dist/components/VirtualTable/fields/VirtualTableDateField.es.js +71 -0
  130. package/dist/components/VirtualTable/fields/VirtualTableDateField.es.js.map +1 -0
  131. package/dist/components/VirtualTable/fields/VirtualTableInput.es.js +73 -0
  132. package/dist/components/VirtualTable/fields/VirtualTableInput.es.js.map +1 -0
  133. package/dist/components/VirtualTable/fields/VirtualTableNumberInput.es.js +47 -0
  134. package/dist/components/VirtualTable/fields/VirtualTableNumberInput.es.js.map +1 -0
  135. package/dist/components/VirtualTable/fields/VirtualTableSelect.es.js +83 -0
  136. package/dist/components/VirtualTable/fields/VirtualTableSelect.es.js.map +1 -0
  137. package/dist/components/VirtualTable/fields/VirtualTableSwitch.es.js +22 -0
  138. package/dist/components/VirtualTable/fields/VirtualTableSwitch.es.js.map +1 -0
  139. package/dist/components/VirtualTable/selection/SelectionContext.es.js +23 -0
  140. package/dist/components/VirtualTable/selection/SelectionContext.es.js.map +1 -0
  141. package/dist/components/VirtualTable/selection/SelectionStore.es.js +43 -0
  142. package/dist/components/VirtualTable/selection/SelectionStore.es.js.map +1 -0
  143. package/dist/components/VirtualTable/types.d.ts +1 -1
  144. package/dist/components/common/SelectInputLabel.es.js +28 -0
  145. package/dist/components/common/SelectInputLabel.es.js.map +1 -0
  146. package/dist/components/index.es.js +64 -0
  147. package/dist/hooks/PortalContainerContext.es.js +40 -0
  148. package/dist/hooks/PortalContainerContext.es.js.map +1 -0
  149. package/dist/hooks/UiLabelsContext.d.ts +63 -0
  150. package/dist/hooks/UiLabelsContext.es.js +59 -0
  151. package/dist/hooks/UiLabelsContext.es.js.map +1 -0
  152. package/dist/hooks/useDebounceCallback.es.js +15 -0
  153. package/dist/hooks/useDebounceCallback.es.js.map +1 -0
  154. package/dist/hooks/useDebounceValue.es.js +19 -0
  155. package/dist/hooks/useDebounceValue.es.js.map +1 -0
  156. package/dist/hooks/useDebouncedCallback.es.js +36 -0
  157. package/dist/hooks/useDebouncedCallback.es.js.map +1 -0
  158. package/dist/hooks/useInjectStyles.es.js +27 -0
  159. package/dist/hooks/useInjectStyles.es.js.map +1 -0
  160. package/dist/hooks/useIsDarkMode.es.js +61 -0
  161. package/dist/hooks/useIsDarkMode.es.js.map +1 -0
  162. package/dist/hooks/useModalFocus.es.js +81 -0
  163. package/dist/hooks/useModalFocus.es.js.map +1 -0
  164. package/dist/hooks/useOutsideAlerter.es.js +41 -0
  165. package/dist/hooks/useOutsideAlerter.es.js.map +1 -0
  166. package/dist/hooks/useRestoreInterruptedFocus.es.js +61 -0
  167. package/dist/hooks/useRestoreInterruptedFocus.es.js.map +1 -0
  168. package/dist/icons/GitHubIcon.es.js +23 -0
  169. package/dist/icons/GitHubIcon.es.js.map +1 -0
  170. package/dist/icons/HandleIcon.es.js +60 -0
  171. package/dist/icons/HandleIcon.es.js.map +1 -0
  172. package/dist/icons/Icon.es.js +25 -0
  173. package/dist/icons/Icon.es.js.map +1 -0
  174. package/dist/icons/LucideIconByName.d.ts +12 -9
  175. package/dist/icons/LucideIconByName.es.js +83 -0
  176. package/dist/icons/LucideIconByName.es.js.map +1 -0
  177. package/dist/icons/cool_icon_keys.es.js +55 -0
  178. package/dist/icons/cool_icon_keys.es.js.map +1 -0
  179. package/dist/icons/icon_keys.es.js +1941 -0
  180. package/dist/icons/icon_keys.es.js.map +1 -0
  181. package/dist/icons/index.d.ts +4 -3
  182. package/dist/icons/index.es.js +8 -0
  183. package/dist/icons/lucide_icon_map.d.ts +12 -0
  184. package/dist/icons/lucide_icon_map.es.js +2 -0
  185. package/dist/index.d.ts +2 -0
  186. package/dist/index.es.js +87 -9563
  187. package/dist/styles.es.js +158 -0
  188. package/dist/styles.es.js.map +1 -0
  189. package/dist/util/chip_colors.es.js +290 -0
  190. package/dist/util/chip_colors.es.js.map +1 -0
  191. package/dist/util/cls.es.js +10 -0
  192. package/dist/util/cls.es.js.map +1 -0
  193. package/dist/util/debounce.es.js +22 -0
  194. package/dist/util/debounce.es.js.map +1 -0
  195. package/dist/util/hash.es.js +16 -0
  196. package/dist/util/hash.es.js.map +1 -0
  197. package/dist/util/keys.es.js +37 -0
  198. package/dist/util/keys.es.js.map +1 -0
  199. package/dist/util/lazy_chunk.es.js +96 -0
  200. package/dist/util/lazy_chunk.es.js.map +1 -0
  201. package/dist/views/CardView.d.ts +26 -2
  202. package/dist/views/CardView.es.js +435 -0
  203. package/dist/views/CardView.es.js.map +1 -0
  204. package/dist/views/CollectionView/CollectionCardView.es.js +179 -0
  205. package/dist/views/CollectionView/CollectionCardView.es.js.map +1 -0
  206. package/dist/views/CollectionView/CollectionKanbanView.es.js +172 -0
  207. package/dist/views/CollectionView/CollectionKanbanView.es.js.map +1 -0
  208. package/dist/views/CollectionView/CollectionListView.es.js +156 -0
  209. package/dist/views/CollectionView/CollectionListView.es.js.map +1 -0
  210. package/dist/views/CollectionView/CollectionTableView.es.js +149 -0
  211. package/dist/views/CollectionView/CollectionTableView.es.js.map +1 -0
  212. package/dist/views/CollectionView/CollectionView.es.js +197 -0
  213. package/dist/views/CollectionView/CollectionView.es.js.map +1 -0
  214. package/dist/views/CollectionView/CollectionViewToolbar.es.js +155 -0
  215. package/dist/views/CollectionView/CollectionViewToolbar.es.js.map +1 -0
  216. package/dist/views/CollectionView/DefaultCellRenderer.es.js +302 -0
  217. package/dist/views/CollectionView/DefaultCellRenderer.es.js.map +1 -0
  218. package/dist/views/CollectionView/resolveTitleProperty.es.js +56 -0
  219. package/dist/views/CollectionView/resolveTitleProperty.es.js.map +1 -0
  220. package/dist/views/CollectionView/utils.es.js +19 -0
  221. package/dist/views/CollectionView/utils.es.js.map +1 -0
  222. package/dist/views/Kanban/Board.es.js +237 -0
  223. package/dist/views/Kanban/Board.es.js.map +1 -0
  224. package/dist/views/Kanban/BoardColumn.es.js +81 -0
  225. package/dist/views/Kanban/BoardColumn.es.js.map +1 -0
  226. package/dist/views/Kanban/BoardColumnTitle.es.js +27 -0
  227. package/dist/views/Kanban/BoardColumnTitle.es.js.map +1 -0
  228. package/dist/views/Kanban/BoardSortableList.es.js +98 -0
  229. package/dist/views/Kanban/BoardSortableList.es.js.map +1 -0
  230. package/dist/views/Kanban/placement.es.js +27 -0
  231. package/dist/views/Kanban/placement.es.js.map +1 -0
  232. package/dist/views/KanbanView.es.js +11 -0
  233. package/dist/views/KanbanView.es.js.map +1 -0
  234. package/dist/views/ListView.d.ts +15 -2
  235. package/dist/views/ListView.es.js +245 -0
  236. package/dist/views/ListView.es.js.map +1 -0
  237. package/dist/views/useScrollParentRestoration.d.ts +8 -1
  238. package/dist/views/useScrollParentRestoration.es.js +75 -0
  239. package/dist/views/useScrollParentRestoration.es.js.map +1 -0
  240. package/package.json +2 -2
  241. package/dist/index.es.js.map +0 -1
@@ -8,5 +8,11 @@ export interface AlertProps {
8
8
  className?: string;
9
9
  outerClassName?: string;
10
10
  style?: React.CSSProperties;
11
+ /**
12
+ * The live-region role. Defaults to `alert` (announced at once) for
13
+ * `error` and `warning`, `status` (announced politely) otherwise. Pass
14
+ * `null` for an alert that is static page content, not news.
15
+ */
16
+ role?: "alert" | "status" | null;
11
17
  }
12
18
  export declare const Alert: React.FC<AlertProps>;
@@ -0,0 +1,82 @@
1
+ import { cls } from "../util/cls.es.js";
2
+ import { AlertCircleIcon, AlertTriangleIcon, CheckCircleIcon, InfoIcon, XIcon } from "../icons/index.es.js";
3
+ import "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/components/Alert.tsx
6
+ var getSizeClasses = (size) => {
7
+ switch (size) {
8
+ case "small": return "px-3 py-1.5 text-xs gap-2 rounded-md";
9
+ case "large": return "px-4 py-3.5 text-sm gap-3 rounded-lg";
10
+ default: return "px-3.5 py-2.5 text-sm gap-2.5 rounded-lg";
11
+ }
12
+ };
13
+ var getIconSize = (size) => size === "small" ? 16 : 18;
14
+ var getColorClasses = (severity) => {
15
+ switch (severity) {
16
+ case "error": return "bg-red-500/8 dark:bg-red-500/12 text-red-800 dark:text-red-200 border border-red-500/20 dark:border-red-500/25";
17
+ case "warning": return "bg-amber-500/8 dark:bg-amber-500/12 text-amber-800 dark:text-amber-200 border border-amber-500/20 dark:border-amber-500/25";
18
+ case "info": return "bg-blue-500/8 dark:bg-blue-500/12 text-blue-800 dark:text-blue-200 border border-blue-500/20 dark:border-blue-500/25";
19
+ case "success": return "bg-emerald-500/8 dark:bg-emerald-500/12 text-emerald-800 dark:text-emerald-200 border border-emerald-500/20 dark:border-emerald-500/25";
20
+ default: return "bg-surface-field text-text-primary dark:text-text-primary-dark border border-hairline";
21
+ }
22
+ };
23
+ var getIconColor = (severity) => {
24
+ switch (severity) {
25
+ case "error": return "text-red-500 dark:text-red-400";
26
+ case "warning": return "text-amber-500 dark:text-amber-400";
27
+ case "info": return "text-blue-500 dark:text-blue-400";
28
+ case "success": return "text-emerald-500 dark:text-emerald-400";
29
+ default: return "text-surface-accent-500 dark:text-surface-accent-400";
30
+ }
31
+ };
32
+ var getIcon = (severity, size, className) => {
33
+ switch (severity) {
34
+ case "error": return /* @__PURE__ */ jsx(AlertCircleIcon, {
35
+ size,
36
+ className
37
+ });
38
+ case "warning": return /* @__PURE__ */ jsx(AlertTriangleIcon, {
39
+ size,
40
+ className
41
+ });
42
+ case "success": return /* @__PURE__ */ jsx(CheckCircleIcon, {
43
+ size,
44
+ className
45
+ });
46
+ default: return /* @__PURE__ */ jsx(InfoIcon, {
47
+ size,
48
+ className
49
+ });
50
+ }
51
+ };
52
+ var Alert = ({ children, onDismiss, color = "info", size = "medium", action, outerClassName, className, style, role }) => {
53
+ const classes = getColorClasses(color);
54
+ const iconSize = getIconSize(size);
55
+ return /* @__PURE__ */ jsxs("div", {
56
+ role: role === null ? void 0 : role ?? (color === "error" || color === "warning" ? "alert" : "status"),
57
+ style,
58
+ className: cls(getSizeClasses(size), "w-full", "font-medium leading-snug", "flex items-start", classes, outerClassName),
59
+ children: [
60
+ /* @__PURE__ */ jsx("span", {
61
+ className: cls("shrink-0 mt-px", getIconColor(color)),
62
+ children: getIcon(color, iconSize, "")
63
+ }),
64
+ /* @__PURE__ */ jsx("div", {
65
+ className: cls("grow min-w-0 self-center", className),
66
+ children
67
+ }),
68
+ action,
69
+ onDismiss && /* @__PURE__ */ jsx("button", {
70
+ type: "button",
71
+ "aria-label": "Dismiss",
72
+ className: cls("shrink-0 rounded p-0.5 opacity-60 transition-opacity hover:opacity-100", "focus:outline-none focus-visible:ring-2 focus-visible:ring-current/40"),
73
+ onClick: onDismiss,
74
+ children: /* @__PURE__ */ jsx(XIcon, { size: iconSize - 2 })
75
+ })
76
+ ]
77
+ });
78
+ };
79
+ //#endregion
80
+ export { Alert };
81
+
82
+ //# sourceMappingURL=Alert.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Alert.es.js","names":[],"sources":["../../src/components/Alert.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cls } from \"../util\";\nimport { AlertCircleIcon, AlertTriangleIcon, CheckCircleIcon, InfoIcon, XIcon } from \"../icons\";\n\nexport interface AlertProps {\n children: React.ReactNode;\n onDismiss?: () => void;\n color?: \"error\" | \"warning\" | \"info\" | \"success\" | \"base\";\n size?: \"small\" | \"medium\" | \"large\";\n action?: React.ReactNode;\n className?: string;\n outerClassName?: string;\n style?: React.CSSProperties;\n /**\n * The live-region role. Defaults to `alert` (announced at once) for\n * `error` and `warning`, `status` (announced politely) otherwise. Pass\n * `null` for an alert that is static page content, not news.\n */\n role?: \"alert\" | \"status\" | null;\n}\n\nconst getSizeClasses = (size: \"small\" | \"medium\" | \"large\") => {\n switch (size) {\n case \"small\":\n return \"px-3 py-1.5 text-xs gap-2 rounded-md\";\n case \"large\":\n return \"px-4 py-3.5 text-sm gap-3 rounded-lg\";\n case \"medium\":\n default:\n return \"px-3.5 py-2.5 text-sm gap-2.5 rounded-lg\";\n }\n}\n\nconst getIconSize = (size: \"small\" | \"medium\" | \"large\") => size === \"small\" ? 16 : 18;\n\nconst getColorClasses = (severity: string) => {\n switch (severity) {\n case \"error\":\n return \"bg-red-500/8 dark:bg-red-500/12 text-red-800 dark:text-red-200 border border-red-500/20 dark:border-red-500/25\";\n case \"warning\":\n return \"bg-amber-500/8 dark:bg-amber-500/12 text-amber-800 dark:text-amber-200 border border-amber-500/20 dark:border-amber-500/25\";\n case \"info\":\n return \"bg-blue-500/8 dark:bg-blue-500/12 text-blue-800 dark:text-blue-200 border border-blue-500/20 dark:border-blue-500/25\";\n case \"success\":\n return \"bg-emerald-500/8 dark:bg-emerald-500/12 text-emerald-800 dark:text-emerald-200 border border-emerald-500/20 dark:border-emerald-500/25\";\n case \"base\":\n default:\n return \"bg-surface-field text-text-primary dark:text-text-primary-dark border border-hairline\";\n }\n};\n\nconst getIconColor = (severity: string) => {\n switch (severity) {\n case \"error\":\n return \"text-red-500 dark:text-red-400\";\n case \"warning\":\n return \"text-amber-500 dark:text-amber-400\";\n case \"info\":\n return \"text-blue-500 dark:text-blue-400\";\n case \"success\":\n return \"text-emerald-500 dark:text-emerald-400\";\n case \"base\":\n default:\n return \"text-surface-accent-500 dark:text-surface-accent-400\";\n }\n};\n\nconst getIcon = (severity: string, size: number, className: string) => {\n switch (severity) {\n case \"error\":\n return <AlertCircleIcon size={size} className={className}/>;\n case \"warning\":\n return <AlertTriangleIcon size={size} className={className}/>;\n case \"success\":\n return <CheckCircleIcon size={size} className={className}/>;\n case \"info\":\n case \"base\":\n default:\n return <InfoIcon size={size} className={className}/>;\n }\n};\n\nexport const Alert: React.FC<AlertProps> = ({\n children,\n onDismiss,\n color = \"info\",\n size = \"medium\",\n action,\n outerClassName,\n className,\n style,\n role\n }) => {\n const classes = getColorClasses(color);\n const iconSize = getIconSize(size);\n\n return (\n <div\n role={role === null ? undefined : role ?? (color === \"error\" || color === \"warning\" ? \"alert\" : \"status\")}\n style={style}\n className={cls(\n getSizeClasses(size),\n \"w-full\",\n \"font-medium leading-snug\",\n \"flex items-start\",\n classes,\n outerClassName)}>\n <span className={cls(\"shrink-0 mt-px\", getIconColor(color))}>\n {getIcon(color, iconSize, \"\")}\n </span>\n <div className={cls(\"grow min-w-0 self-center\", className)}>{children}</div>\n {action}\n {onDismiss && (\n <button\n type=\"button\"\n aria-label=\"Dismiss\"\n className={cls(\n \"shrink-0 rounded p-0.5 opacity-60 transition-opacity hover:opacity-100\",\n \"focus:outline-none focus-visible:ring-2 focus-visible:ring-current/40\")}\n onClick={onDismiss}>\n <XIcon size={iconSize - 2}/>\n </button>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;AAqBA,IAAM,kBAAkB,SAAuC;CAC3D,QAAQ,MAAR;EACI,KAAK,SACD,OAAO;EACX,KAAK,SACD,OAAO;EAEX,SACI,OAAO;CACf;AACJ;AAEA,IAAM,eAAe,SAAuC,SAAS,UAAU,KAAK;AAEpF,IAAM,mBAAmB,aAAqB;CAC1C,QAAQ,UAAR;EACI,KAAK,SACD,OAAO;EACX,KAAK,WACD,OAAO;EACX,KAAK,QACD,OAAO;EACX,KAAK,WACD,OAAO;EAEX,SACI,OAAO;CACf;AACJ;AAEA,IAAM,gBAAgB,aAAqB;CACvC,QAAQ,UAAR;EACI,KAAK,SACD,OAAO;EACX,KAAK,WACD,OAAO;EACX,KAAK,QACD,OAAO;EACX,KAAK,WACD,OAAO;EAEX,SACI,OAAO;CACf;AACJ;AAEA,IAAM,WAAW,UAAkB,MAAc,cAAsB;CACnE,QAAQ,UAAR;EACI,KAAK,SACD,OAAO,oBAAC,iBAAD;GAAuB;GAAiB;EAAW,CAAA;EAC9D,KAAK,WACD,OAAO,oBAAC,mBAAD;GAAyB;GAAiB;EAAW,CAAA;EAChE,KAAK,WACD,OAAO,oBAAC,iBAAD;GAAuB;GAAiB;EAAW,CAAA;EAG9D,SACI,OAAO,oBAAC,UAAD;GAAgB;GAAiB;EAAW,CAAA;CAC3D;AACJ;AAEA,IAAa,SAA+B,EACI,UACA,WACA,QAAQ,QACR,OAAO,UACP,QACA,gBACA,WACA,OACA,WACE;CAC9C,MAAM,UAAU,gBAAgB,KAAK;CACrC,MAAM,WAAW,YAAY,IAAI;CAEjC,OACI,qBAAC,OAAD;EACI,MAAM,SAAS,OAAO,KAAA,IAAY,SAAS,UAAU,WAAW,UAAU,YAAY,UAAU;EACzF;EACP,WAAW,IACP,eAAe,IAAI,GACnB,UACA,4BACA,oBACA,SACA,cAAc;YATtB;GAUI,oBAAC,QAAD;IAAM,WAAW,IAAI,kBAAkB,aAAa,KAAK,CAAC;cACrD,QAAQ,OAAO,UAAU,EAAE;GAC1B,CAAA;GACN,oBAAC,OAAD;IAAK,WAAW,IAAI,4BAA4B,SAAS;IAAI;GAAc,CAAA;GAC1E;GACA,aACG,oBAAC,UAAD;IACI,MAAK;IACL,cAAW;IACX,WAAW,IACP,0EACA,uEAAuE;IAC3E,SAAS;cACT,oBAAC,OAAD,EAAO,MAAM,WAAW,EAAG,CAAA;GACvB,CAAA;EAEX;;AAEb"}
@@ -0,0 +1,53 @@
1
+ "use client";
2
+ import { paperMixin } from "../styles.es.js";
3
+ import { cls } from "../util/cls.es.js";
4
+ import { useOutsideAlerter } from "../hooks/useOutsideAlerter.es.js";
5
+ import { Collapse } from "./Collapse.es.js";
6
+ import React from "react";
7
+ import { jsx } from "react/jsx-runtime";
8
+ //#region src/components/Autocomplete.tsx
9
+ var useAutoComplete = ({ ref }) => {
10
+ const [autoCompleteOpen, setAutoCompleteOpen] = React.useState(false);
11
+ const [inputFocused, setInputFocused] = React.useState(false);
12
+ React.useEffect(() => {
13
+ if (ref.current) {
14
+ ref.current.onfocus = () => {
15
+ setAutoCompleteOpen(true);
16
+ setInputFocused(true);
17
+ };
18
+ ref.current.onblur = () => {
19
+ setInputFocused(false);
20
+ };
21
+ }
22
+ }, [ref]);
23
+ return {
24
+ inputFocused,
25
+ autoCompleteOpen,
26
+ setAutoCompleteOpen
27
+ };
28
+ };
29
+ function Autocomplete({ children, open, setOpen, className }) {
30
+ const autocompleteRef = React.useRef(null);
31
+ useOutsideAlerter(autocompleteRef, () => setOpen(false));
32
+ return /* @__PURE__ */ jsx(Collapse, {
33
+ in: open,
34
+ duration: 30,
35
+ className: cls("absolute top-full left-0 right-0 overflow-visible", open ? "shadow-2xs" : "", "my-2", "z-20", "w-full"),
36
+ children: /* @__PURE__ */ jsx("div", {
37
+ ref: autocompleteRef,
38
+ className: cls(open ? paperMixin : "", "bg-surface-card", className),
39
+ children
40
+ })
41
+ });
42
+ }
43
+ var AutocompleteItem = React.memo(function AutocompleteItem({ children, onClick, className }) {
44
+ return /* @__PURE__ */ jsx("div", {
45
+ className: cls("flex w-full items-center h-[48px] cursor-pointer transition-colors duration-150 hover:bg-surface-hover", className),
46
+ onClick,
47
+ children
48
+ });
49
+ });
50
+ //#endregion
51
+ export { Autocomplete, AutocompleteItem, useAutoComplete };
52
+
53
+ //# sourceMappingURL=Autocomplete.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Autocomplete.es.js","names":[],"sources":["../../src/components/Autocomplete.tsx"],"sourcesContent":["\"use client\";\nimport React from \"react\";\n\nimport { paperMixin } from \"../styles\";\nimport { Collapse } from \"./Collapse\";\nimport { cls } from \"../util\";\nimport { useOutsideAlerter } from \"../hooks\";\n\nexport type AutocompleteProps = {\n children: React.ReactNode;\n open: boolean;\n setOpen: (open: boolean) => void;\n className?: string;\n}\n\nexport const useAutoComplete = ({ ref }: {\n ref: React.MutableRefObject<HTMLDivElement | null>;\n}) => {\n\n const [autoCompleteOpen, setAutoCompleteOpen] = React.useState(false);\n const [inputFocused, setInputFocused] = React.useState(false);\n\n // if ref is not focused, close autocomplete\n React.useEffect(() => {\n if (ref.current) {\n ref.current.onfocus = () => {\n setAutoCompleteOpen(true);\n setInputFocused(true);\n }\n ref.current.onblur = () => {\n setInputFocused(false);\n }\n }\n }, [ref]);\n\n return {\n inputFocused,\n autoCompleteOpen,\n setAutoCompleteOpen\n };\n}\n\nexport function Autocomplete({\n children,\n open,\n setOpen,\n className\n }: AutocompleteProps) {\n\n const autocompleteRef = React.useRef<HTMLDivElement>(null);\n useOutsideAlerter(autocompleteRef, () => setOpen(false));\n\n return <Collapse\n in={open}\n duration={30}\n className={cls(\n \"absolute top-full left-0 right-0 overflow-visible\",\n open ? \"shadow-2xs\" : \"\",\n \"my-2\",\n \"z-20\",\n \"w-full\")}>\n <div ref={autocompleteRef}\n className={cls(\n open ? paperMixin : \"\",\n \"bg-surface-card\",\n className\n )}>\n {children}\n </div>\n </Collapse>;\n\n}\n\nexport type AutocompleteItemProps = {\n children: React.ReactNode,\n onClick?: () => void,\n className?: string\n};\n\nexport const AutocompleteItem = React.memo(function AutocompleteItem({\n children,\n onClick,\n className\n }: AutocompleteItemProps) {\n\n return (\n <div\n className={cls(\"flex w-full items-center h-[48px] cursor-pointer transition-colors duration-150 hover:bg-surface-hover\", className)}\n onClick={onClick}>\n {children}\n </div>\n )\n});\n"],"mappings":";;;;;;;;AAeA,IAAa,mBAAmB,EAAE,UAE5B;CAEF,MAAM,CAAC,kBAAkB,uBAAuB,MAAM,SAAS,KAAK;CACpE,MAAM,CAAC,cAAc,mBAAmB,MAAM,SAAS,KAAK;CAG5D,MAAM,gBAAgB;EAClB,IAAI,IAAI,SAAS;GACb,IAAI,QAAQ,gBAAgB;IACxB,oBAAoB,IAAI;IACxB,gBAAgB,IAAI;GACxB;GACA,IAAI,QAAQ,eAAe;IACvB,gBAAgB,KAAK;GACzB;EACJ;CACJ,GAAG,CAAC,GAAG,CAAC;CAER,OAAO;EACH;EACA;EACA;CACJ;AACJ;AAEA,SAAgB,aAAa,EACI,UACA,MACA,SACA,aACkB;CAE/C,MAAM,kBAAkB,MAAM,OAAuB,IAAI;CACzD,kBAAkB,uBAAuB,QAAQ,KAAK,CAAC;CAEvD,OAAO,oBAAC,UAAD;EACH,IAAI;EACJ,UAAU;EACV,WAAW,IACP,qDACA,OAAO,eAAe,IACtB,QACA,QACA,QAAQ;YACZ,oBAAC,OAAD;GAAK,KAAK;GACL,WAAW,IACP,OAAO,aAAa,IACpB,mBACA,SACJ;GACA;EACA,CAAA;CACC,CAAA;AAEd;AAQA,IAAa,mBAAmB,MAAM,KAAK,SAAS,iBAAiB,EAChC,UACA,SACA,aACsB;CAEvD,OACI,oBAAC,OAAD;EACI,WAAW,IAAI,0GAA0G,SAAS;EACzH;EACR;CACA,CAAA;AAEb,CAAC"}
@@ -7,5 +7,7 @@ export interface AvatarProps {
7
7
  outerClassName?: string;
8
8
  hover?: boolean;
9
9
  style?: React.CSSProperties;
10
+ /** Makes the avatar a button. Without it (or a menu trigger's handlers) it is a plain image. */
11
+ onClick?: React.MouseEventHandler<HTMLElement>;
10
12
  }
11
- export declare const Avatar: React.ForwardRefExoticComponent<AvatarProps & React.RefAttributes<HTMLButtonElement>>;
13
+ export declare const Avatar: React.ForwardRefExoticComponent<AvatarProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,37 @@
1
+ "use client";
2
+ import { cls } from "../util/cls.es.js";
3
+ import React, { useState } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/components/Avatar.tsx
6
+ var AvatarInner = ({ src, alt, children, className, style, outerClassName, hover = true, ...props }, ref) => {
7
+ const [failedSrc, setFailedSrc] = useState(void 0);
8
+ const isImageError = src !== void 0 && failedSrc === src;
9
+ const handleImageError = () => {
10
+ setFailedSrc(src);
11
+ };
12
+ const interactive = Object.keys(props).some((key) => /^on[A-Z]/.test(key));
13
+ return /* @__PURE__ */ jsx(interactive ? "button" : "span", {
14
+ ref: React.useCallback((element) => {
15
+ if (typeof ref === "function") ref(element);
16
+ else if (ref) ref.current = element;
17
+ }, [ref]),
18
+ style,
19
+ ...interactive ? { type: "button" } : {},
20
+ ...props,
21
+ className: cls("rounded-full flex items-center justify-center overflow-hidden", "p-1 w-12 h-12 min-w-12 min-h-12", hover && "transition-colors duration-150 hover:bg-surface-raised-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50", outerClassName),
22
+ children: src && !isImageError ? /* @__PURE__ */ jsx("img", {
23
+ className: cls("bg-surface-raised", "w-full h-full object-cover rounded-full", className),
24
+ src,
25
+ alt,
26
+ onError: handleImageError
27
+ }) : /* @__PURE__ */ jsx("span", {
28
+ className: cls("bg-surface-raised", "flex items-center justify-center", "w-full h-full py-1.5 text-lg font-medium text-surface-accent-900 dark:text-text-primary-dark rounded-full", className),
29
+ children
30
+ })
31
+ });
32
+ };
33
+ var Avatar = React.forwardRef(AvatarInner);
34
+ //#endregion
35
+ export { Avatar };
36
+
37
+ //# sourceMappingURL=Avatar.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Avatar.es.js","names":[],"sources":["../../src/components/Avatar.tsx"],"sourcesContent":["\"use client\";\nimport React, { useState } from \"react\";\nimport { cls } from \"../util\";\n\nexport interface AvatarProps {\n src?: string;\n alt?: string;\n children?: React.ReactNode;\n className?: string;\n outerClassName?: string;\n hover?: boolean;\n style?: React.CSSProperties;\n /** Makes the avatar a button. Without it (or a menu trigger's handlers) it is a plain image. */\n onClick?: React.MouseEventHandler<HTMLElement>;\n}\n\nconst AvatarInner: React.ForwardRefRenderFunction<HTMLElement, AvatarProps> = (\n {\n src,\n alt,\n children,\n className,\n style,\n outerClassName,\n hover = true,\n ...props\n },\n ref\n) => {\n // The source that failed, not a flag: a flag outlived it, so once one URL\n // failed every later one showed the initials too.\n const [failedSrc, setFailedSrc] = useState<string | undefined>(undefined);\n const isImageError = src !== undefined && failedSrc === src;\n\n const handleImageError = () => {\n setFailedSrc(src);\n };\n\n // A button only when something handles it: an `onClick`, or the handlers a\n // Radix trigger (`Menu trigger={<Avatar/>}`) slots in. A bare avatar inside\n // a caller's own button was a second, unnamed tab stop that did nothing.\n const interactive = Object.keys(props).some((key) => /^on[A-Z]/.test(key));\n const Root = interactive ? \"button\" : \"span\";\n // One ref for either element, without asserting which one it is.\n const setRef = React.useCallback((element: HTMLElement | null) => {\n if (typeof ref === \"function\") ref(element);\n else if (ref) ref.current = element;\n }, [ref]);\n\n return (\n <Root\n ref={setRef}\n style={style}\n {...(interactive ? { type: \"button\" as const } : {})}\n {...props}\n className={cls(\n \"rounded-full flex items-center justify-center overflow-hidden\",\n \"p-1 w-12 h-12 min-w-12 min-h-12\",\n hover && \"transition-colors duration-150 hover:bg-surface-raised-hover focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50\",\n outerClassName\n )}\n >\n {src && !isImageError ? (\n <img\n className={cls(\n \"bg-surface-raised\",\n \"w-full h-full object-cover rounded-full\",\n className\n )}\n src={src}\n alt={alt}\n onError={handleImageError}\n />\n ) : (\n <span\n className={cls(\n \"bg-surface-raised\",\n \"flex items-center justify-center\",\n \"w-full h-full py-1.5 text-lg font-medium text-surface-accent-900 dark:text-text-primary-dark rounded-full\",\n className\n )}\n >\n {children}\n </span>\n )}\n </Root>\n );\n};\n\nexport const Avatar = React.forwardRef(AvatarInner);\n"],"mappings":";;;;;AAgBA,IAAM,eACF,EACI,KACA,KACA,UACA,WACA,OACA,gBACA,QAAQ,MACR,GAAG,SAEP,QACC;CAGD,MAAM,CAAC,WAAW,gBAAgB,SAA6B,KAAA,CAAS;CACxE,MAAM,eAAe,QAAQ,KAAA,KAAa,cAAc;CAExD,MAAM,yBAAyB;EAC3B,aAAa,GAAG;CACpB;CAKA,MAAM,cAAc,OAAO,KAAK,KAAK,CAAC,CAAC,MAAM,QAAQ,WAAW,KAAK,GAAG,CAAC;CAQzE,OACI,oBARS,cAAc,WAAW,QAQlC;EACI,KAPO,MAAM,aAAa,YAAgC;GAC9D,IAAI,OAAO,QAAQ,YAAY,IAAI,OAAO;QACrC,IAAI,KAAK,IAAI,UAAU;EAChC,GAAG,CAAC,GAAG,CAIM;EACE;EACP,GAAK,cAAc,EAAE,MAAM,SAAkB,IAAI,CAAC;EAClD,GAAI;EACJ,WAAW,IACP,iEACA,mCACA,SAAS,sIACT,cACJ;YAEC,OAAO,CAAC,eACL,oBAAC,OAAD;GACI,WAAW,IACP,qBACA,2CACA,SACJ;GACK;GACA;GACL,SAAS;EACZ,CAAA,IAED,oBAAC,QAAD;GACI,WAAW,IACP,qBACA,oCACA,6GACA,SACJ;GAET;EACG,CAAA;CAEA,CAAA;AAEd;AAEA,IAAa,SAAS,MAAM,WAAW,WAAW"}
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ //#region src/components/Badge.tsx
4
+ var getColor = (color) => {
5
+ switch (color) {
6
+ case "primary": return "bg-primary";
7
+ case "secondary": return "bg-secondary";
8
+ case "warning": return "bg-orange-500";
9
+ case "error": return "bg-red-500";
10
+ default: return "bg-surface-raised-hover";
11
+ }
12
+ };
13
+ var Badge = React.forwardRef(({ color = "primary", invisible = false, children }, ref) => {
14
+ return /* @__PURE__ */ jsxs("div", {
15
+ ref,
16
+ className: "relative inline-block w-fit",
17
+ children: [children, /* @__PURE__ */ jsx("span", { className: `absolute top-0.5 right-0.5 transform translate-x-1/2 -translate-y-1/2 rounded-full
18
+ ${getColor(color)}
19
+ transition-all duration-200 ease-out
20
+ ${invisible ? "w-0 h-0" : "w-2 h-2"}` })]
21
+ });
22
+ });
23
+ Badge.displayName = "Badge";
24
+ //#endregion
25
+ export { Badge };
26
+
27
+ //# sourceMappingURL=Badge.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Badge.es.js","names":[],"sources":["../../src/components/Badge.tsx"],"sourcesContent":["import React from \"react\";\n\nexport type BadgeColor = \"primary\" | \"secondary\" | \"warning\" | \"error\";\n\nexport interface BadgeProps {\n color?: BadgeColor;\n children: React.ReactNode;\n invisible?: boolean;\n}\n\nconst getColor = (color: BadgeColor) => {\n switch (color) {\n case \"primary\":\n return \"bg-primary\";\n case \"secondary\":\n return \"bg-secondary\";\n case \"warning\":\n return \"bg-orange-500\";\n case \"error\":\n return \"bg-red-500\";\n default:\n return \"bg-surface-raised-hover\";\n }\n}\n\nexport const Badge = React.forwardRef<HTMLDivElement, BadgeProps>(({\n color = \"primary\",\n invisible = false,\n children\n }, ref) => {\n return (\n <div ref={ref} className=\"relative inline-block w-fit\">\n {children}\n <span\n className={`absolute top-0.5 right-0.5 transform translate-x-1/2 -translate-y-1/2 rounded-full\n ${getColor(color)}\n transition-all duration-200 ease-out\n ${invisible ? \"w-0 h-0\" : \"w-2 h-2\"}`}\n />\n </div>\n );\n});\n\nBadge.displayName = \"Badge\";\n"],"mappings":";;;AAUA,IAAM,YAAY,UAAsB;CACpC,QAAQ,OAAR;EACI,KAAK,WACD,OAAO;EACX,KAAK,aACD,OAAO;EACX,KAAK,WACD,OAAO;EACX,KAAK,SACD,OAAO;EACX,SACI,OAAO;CACf;AACJ;AAEA,IAAa,QAAQ,MAAM,YAAwC,EACE,QAAQ,WACR,YAAY,OACZ,YACD,QAAQ;CACxE,OACI,qBAAC,OAAD;EAAU;EAAK,WAAU;YAAzB,CACK,UACD,oBAAC,QAAD,EACI,WAAW;UACjB,SAAS,KAAK,EAAE;;UAEhB,YAAY,YAAY,YACrB,CAAA,CACA;;AAEb,CAAC;AAED,MAAM,cAAc"}
@@ -0,0 +1,75 @@
1
+ "use client";
2
+ import { cls } from "../util/cls.es.js";
3
+ import React from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/components/BooleanSwitch.tsx
6
+ /**
7
+ * Switch geometry, one row per size: track w x h, knob k, and the knob's
8
+ * off/on x-offsets. `on` is always `w - k - inset` so the knob is inset by the
9
+ * same amount at both ends and vertically centred.
10
+ *
11
+ * This is a table rather than inline `cls({...})` conditions on purpose. The
12
+ * offsets used to be computed object keys — `[value ? "translate-x-[24px]" :
13
+ * "translate-x-[3px]"]: size === "large"` — and `large` and `medium` both
14
+ * produced the key `translate-x-[3px]` when off. The later literal overwrote
15
+ * the earlier, so the off-state class was silently dropped for `large` and the
16
+ * knob sat flush against the edge.
17
+ */
18
+ var SWITCH_GEOMETRY = {
19
+ smallest: {
20
+ track: "w-[34px] h-[18px] min-w-[34px] min-h-[18px]",
21
+ knob: "w-[16px] h-[16px]",
22
+ off: "translate-x-[1px]",
23
+ on: "translate-x-[17px]",
24
+ bar: "w-[16px] h-[6px]",
25
+ barX: "translate-x-[9px]"
26
+ },
27
+ small: {
28
+ track: "w-[38px] h-[22px] min-w-[38px] min-h-[22px]",
29
+ knob: "w-[18px] h-[18px]",
30
+ off: "translate-x-[2px]",
31
+ on: "translate-x-[18px]",
32
+ bar: "w-[18px] h-[8px]",
33
+ barX: "translate-x-[10px]"
34
+ },
35
+ medium: {
36
+ track: "w-[44px] h-[26px] min-w-[44px] min-h-[26px]",
37
+ knob: "w-[20px] h-[20px]",
38
+ off: "translate-x-[3px]",
39
+ on: "translate-x-[21px]",
40
+ bar: "w-[20px] h-[10px]",
41
+ barX: "translate-x-[12px]"
42
+ },
43
+ large: {
44
+ track: "w-[48px] h-[28px] min-w-[48px] min-h-[28px]",
45
+ knob: "w-[22px] h-[22px]",
46
+ off: "translate-x-[3px]",
47
+ on: "translate-x-[23px]",
48
+ bar: "w-[22px] h-[11px]",
49
+ barX: "translate-x-[13px]"
50
+ }
51
+ };
52
+ var BooleanSwitch = React.forwardRef(function BooleanSwitch({ value, allowIndeterminate, className, onValueChange, disabled = false, size = "medium", ...props }, ref) {
53
+ return /* @__PURE__ */ jsxs("button", {
54
+ type: "button",
55
+ role: "switch",
56
+ "aria-checked": allowIndeterminate && (value === null || value === void 0) ? "mixed" : !!value,
57
+ "aria-disabled": disabled || void 0,
58
+ ref,
59
+ tabIndex: disabled ? -1 : void 0,
60
+ onClick: disabled ? (e) => e.preventDefault() : (e) => {
61
+ e.preventDefault();
62
+ if (allowIndeterminate) if (value === null || value === void 0) onValueChange?.(true);
63
+ else if (value) onValueChange?.(false);
64
+ else onValueChange?.(null);
65
+ else onValueChange?.(!value);
66
+ },
67
+ className: cls(SWITCH_GEOMETRY[size].track, "outline-none outline-hidden rounded-full relative shadow-sm", disabled ? value ? "bg-primary/40 ring-1 ring-transparent" : "bg-surface-field ring-1 ring-hairline" : value ? "bg-primary ring-1 ring-primary" : "bg-surface-active ring-1 ring-hairline-strong", "focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-surface-card", className),
68
+ ...props,
69
+ children: [allowIndeterminate && (value === null || value === void 0) && /* @__PURE__ */ jsx("div", { className: cls("block rounded-full transition-transform duration-100 ease-out transform will-change-auto shadow-sm", "bg-surface-400", SWITCH_GEOMETRY[size].bar, SWITCH_GEOMETRY[size].barX) }, "knob"), !(allowIndeterminate && (value === null || value === void 0)) && /* @__PURE__ */ jsx("div", { className: cls("block rounded-full transition-transform duration-100 ease-out transform will-change-auto shadow-sm", disabled ? "bg-surface-300 dark:bg-surface-600" : value ? "bg-white shadow" : "bg-surface-500 dark:bg-surface-400", SWITCH_GEOMETRY[size].knob, value ? SWITCH_GEOMETRY[size].on : SWITCH_GEOMETRY[size].off) }, "knob")]
70
+ });
71
+ });
72
+ //#endregion
73
+ export { BooleanSwitch };
74
+
75
+ //# sourceMappingURL=BooleanSwitch.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BooleanSwitch.es.js","names":[],"sources":["../../src/components/BooleanSwitch.tsx"],"sourcesContent":["\"use client\";\nimport React from \"react\";\nimport { cls } from \"../util\";\n\n/**\n * Switch geometry, one row per size: track w x h, knob k, and the knob's\n * off/on x-offsets. `on` is always `w - k - inset` so the knob is inset by the\n * same amount at both ends and vertically centred.\n *\n * This is a table rather than inline `cls({...})` conditions on purpose. The\n * offsets used to be computed object keys — `[value ? \"translate-x-[24px]\" :\n * \"translate-x-[3px]\"]: size === \"large\"` — and `large` and `medium` both\n * produced the key `translate-x-[3px]` when off. The later literal overwrote\n * the earlier, so the off-state class was silently dropped for `large` and the\n * knob sat flush against the edge.\n */\nconst SWITCH_GEOMETRY = {\n smallest: {\n track: \"w-[34px] h-[18px] min-w-[34px] min-h-[18px]\",\n knob: \"w-[16px] h-[16px]\", off: \"translate-x-[1px]\", on: \"translate-x-[17px]\",\n bar: \"w-[16px] h-[6px]\", barX: \"translate-x-[9px]\"\n },\n small: {\n track: \"w-[38px] h-[22px] min-w-[38px] min-h-[22px]\",\n knob: \"w-[18px] h-[18px]\", off: \"translate-x-[2px]\", on: \"translate-x-[18px]\",\n bar: \"w-[18px] h-[8px]\", barX: \"translate-x-[10px]\"\n },\n medium: {\n track: \"w-[44px] h-[26px] min-w-[44px] min-h-[26px]\",\n knob: \"w-[20px] h-[20px]\", off: \"translate-x-[3px]\", on: \"translate-x-[21px]\",\n bar: \"w-[20px] h-[10px]\", barX: \"translate-x-[12px]\"\n },\n large: {\n track: \"w-[48px] h-[28px] min-w-[48px] min-h-[28px]\",\n knob: \"w-[22px] h-[22px]\", off: \"translate-x-[3px]\", on: \"translate-x-[23px]\",\n bar: \"w-[22px] h-[11px]\", barX: \"translate-x-[13px]\"\n }\n} as const;\n\nexport type BooleanSwitchProps = {\n value: boolean | null;\n className?: string;\n disabled?: boolean;\n size?: \"smallest\" | \"small\" | \"medium\" | \"large\";\n /** Names the switch when no visible label is tied to it. */\n \"aria-label\"?: string;\n /** The id of the element whose text names the switch. */\n \"aria-labelledby\"?: string;\n id?: string;\n} & ({\n allowIndeterminate: true;\n onValueChange?: (newValue: boolean | null) => void;\n} | {\n allowIndeterminate?: false;\n onValueChange?: (newValue: boolean) => void;\n});\n\nexport const BooleanSwitch = React.forwardRef(function BooleanSwitch({\n value,\n allowIndeterminate,\n className,\n onValueChange,\n disabled = false,\n size = \"medium\",\n ...props\n }: BooleanSwitchProps, ref: React.Ref<HTMLButtonElement>) {\n return <button\n type=\"button\"\n role=\"switch\"\n aria-checked={allowIndeterminate && (value === null || value === undefined) ? \"mixed\" : !!value}\n aria-disabled={disabled || undefined}\n ref={ref}\n tabIndex={disabled ? -1 : undefined}\n onClick={disabled\n ? (e) => e.preventDefault()\n : (e) => {\n e.preventDefault();\n if (allowIndeterminate) {\n if (value === null || value === undefined) onValueChange?.(true)\n else if (value) onValueChange?.(false)\n else onValueChange?.(null);\n } else {\n onValueChange?.(!value);\n }\n }}\n className={cls(\n // `large` used to share the `medium` branch, so the two sizes\n // rendered identically and the prop looked inert. Geometry is\n // now derived from one table (see SWITCH_GEOMETRY) so the knob\n // inset is symmetric at every size.\n SWITCH_GEOMETRY[size].track,\n \"outline-none outline-hidden rounded-full relative shadow-sm\",\n // On is the primary, not the secondary rose: a boolean is the one\n // place the product turns a hue into a value, and the hue it uses\n // should be the one that means \"yes\" everywhere else (the primary\n // button, the checked checkbox). The rose stays a marketing token.\n // Off is the neutral `active` fill with a strong hairline, so the\n // track is visible on every surface without a fill of its own;\n // disabled keeps its state legible at reduced strength.\n disabled\n ? (value ? \"bg-primary/40 ring-1 ring-transparent\" : \"bg-surface-field ring-1 ring-hairline\")\n : (value ? \"bg-primary ring-1 ring-primary\" : \"bg-surface-active ring-1 ring-hairline-strong\"),\n // The track's own 1px ring is a utility, so it replaced the default\n // focus ring's shadow and colour: focused looked exactly like\n // unfocused. Focus draws a 2px primary ring outside the track,\n // separated from it by a gap — the switch is small and has room\n // around it, the same exception Checkbox and Slider take.\n \"focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-surface-card\",\n className\n )}\n {...props}\n >\n {allowIndeterminate && (value === null || value === undefined) && <div\n key={\"knob\"}\n className={cls(\n \"block rounded-full transition-transform duration-100 ease-out transform will-change-auto shadow-sm\",\n // A glyph on the track, not a surface: the numbered grey is the\n // knob's own colour on both themes.\n \"bg-surface-400\",\n SWITCH_GEOMETRY[size].bar,\n SWITCH_GEOMETRY[size].barX\n )}\n />}\n\n {!(allowIndeterminate && (value === null || value === undefined)) && <div\n key={\"knob\"}\n className={cls(\n \"block rounded-full transition-transform duration-100 ease-out transform will-change-auto shadow-sm\",\n disabled ? \"bg-surface-300 dark:bg-surface-600\" : (value ? \"bg-white shadow\" : \"bg-surface-500 dark:bg-surface-400\"),\n SWITCH_GEOMETRY[size].knob,\n value ? SWITCH_GEOMETRY[size].on : SWITCH_GEOMETRY[size].off\n )}\n />}\n </button>;\n }\n) as React.ForwardRefExoticComponent<BooleanSwitchProps & React.RefAttributes<HTMLButtonElement>>;\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,IAAM,kBAAkB;CACpB,UAAU;EACN,OAAO;EACP,MAAM;EAAqB,KAAK;EAAqB,IAAI;EACzD,KAAK;EAAoB,MAAM;CACnC;CACA,OAAO;EACH,OAAO;EACP,MAAM;EAAqB,KAAK;EAAqB,IAAI;EACzD,KAAK;EAAoB,MAAM;CACnC;CACA,QAAQ;EACJ,OAAO;EACP,MAAM;EAAqB,KAAK;EAAqB,IAAI;EACzD,KAAK;EAAqB,MAAM;CACpC;CACA,OAAO;EACH,OAAO;EACP,MAAM;EAAqB,KAAK;EAAqB,IAAI;EACzD,KAAK;EAAqB,MAAM;CACpC;AACJ;AAoBA,IAAa,gBAAgB,MAAM,WAAW,SAAS,cAAc,EACI,OACA,oBACA,WACA,eACA,WAAW,OACX,OAAO,UACP,GAAG,SACgB,KAAmC;CACvH,OAAO,qBAAC,UAAD;EACH,MAAK;EACL,MAAK;EACL,gBAAc,uBAAuB,UAAU,QAAQ,UAAU,KAAA,KAAa,UAAU,CAAC,CAAC;EAC1F,iBAAe,YAAY,KAAA;EACtB;EACL,UAAU,WAAW,KAAK,KAAA;EAC1B,SAAS,YACF,MAAM,EAAE,eAAe,KACvB,MAAM;GACL,EAAE,eAAe;GACjB,IAAI,oBACA,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,gBAAgB,IAAI;QAC1D,IAAI,OAAO,gBAAgB,KAAK;QAChC,gBAAgB,IAAI;QAEzB,gBAAgB,CAAC,KAAK;EAE9B;EACJ,WAAW,IAKP,gBAAgB,KAAK,CAAC,OACtB,+DAQA,WACO,QAAQ,0CAA0C,0CAClD,QAAQ,mCAAmC,iDAMlD,sHACA,SACJ;EACA,GAAI;YA5CD,CA8CF,uBAAuB,UAAU,QAAQ,UAAU,KAAA,MAAc,oBAAC,OAAD,EAE9D,WAAW,IACP,sGAGA,kBACA,gBAAgB,KAAK,CAAC,KACtB,gBAAgB,KAAK,CAAC,IAC1B,EACH,GATQ,MASR,GAEA,EAAE,uBAAuB,UAAU,QAAQ,UAAU,KAAA,OAAe,oBAAC,OAAD,EAEjE,WAAW,IACP,sGACA,WAAW,uCAAwC,QAAQ,oBAAoB,sCAC/E,gBAAgB,KAAK,CAAC,MACtB,QAAQ,gBAAgB,KAAK,CAAC,KAAK,gBAAgB,KAAK,CAAC,GAC7D,EACH,GAPQ,MAOR,CACG;;AACZ,CACJ"}
@@ -0,0 +1,55 @@
1
+ "use client";
2
+ import { controlHeightMixin, focusedClasses, focusedDisabled } from "../styles.es.js";
3
+ import { cls } from "../util/cls.es.js";
4
+ import { BooleanSwitch } from "./BooleanSwitch.es.js";
5
+ import React from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ //#region src/components/BooleanSwitchWithLabel.tsx
8
+ /**
9
+ * Simple boolean switch.
10
+ *
11
+ */
12
+ var BooleanSwitchWithLabel = function BooleanSwitchWithLabel({ value, position = "end", size = "medium", invisible, onValueChange, error, label, autoFocus, disabled, className, fullWidth = true, inputClassName, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }) {
13
+ const ref = React.useRef(null);
14
+ const refInput = React.useRef(null);
15
+ const switchLabelId = React.useId();
16
+ const [_, setFocused] = React.useState(autoFocus);
17
+ const onFocus = () => setFocused(true);
18
+ const onBlur = () => setFocused(false);
19
+ React.useEffect(() => {
20
+ if (autoFocus) refInput.current?.focus();
21
+ }, []);
22
+ const focus = document.activeElement === refInput?.current || document.activeElement === ref?.current;
23
+ return /* @__PURE__ */ jsxs("div", {
24
+ ref,
25
+ onFocus,
26
+ onBlur,
27
+ className: cls(!invisible && "bg-surface-field border border-hairline", !invisible && (disabled ? "bg-surface-field/60" : "transition-colors duration-150 hover:bg-surface-field-hover"), disabled ? "cursor-default" : "cursor-pointer", "rounded-lg max-w-full justify-between box-border relative inline-flex items-center", !invisible && focus && !disabled ? focusedClasses : "", error ? "text-red-500 dark:text-red-600" : focus && !disabled ? "text-primary" : !disabled ? "text-text-primary dark:text-text-primary-dark" : "text-text-secondary dark:text-text-secondary-dark", controlHeightMixin[size], size === "small" || size === "smallest" ? "pl-2" : "pl-4", size === "small" || size === "smallest" ? "pr-4" : "pr-6", position === "end" ? "flex-row-reverse" : "flex-row", fullWidth ? "w-full" : "", className),
28
+ onClick: disabled ? void 0 : (e) => {
29
+ if (props.allowIndeterminate) {
30
+ const onChange = onValueChange;
31
+ if (value === null || value === void 0) onChange?.(true);
32
+ else if (value) onChange?.(false);
33
+ else onChange?.(null);
34
+ } else onValueChange?.(!value);
35
+ },
36
+ children: [/* @__PURE__ */ jsx(BooleanSwitch, {
37
+ value,
38
+ ref: refInput,
39
+ size,
40
+ "aria-labelledby": ariaLabelledBy ?? (label ? switchLabelId : void 0),
41
+ "aria-label": ariaLabel,
42
+ className: cls(invisible ? focus ? focusedClasses : "" : focusedDisabled, inputClassName),
43
+ disabled,
44
+ ...props
45
+ }), /* @__PURE__ */ jsx("div", {
46
+ id: switchLabelId,
47
+ className: cls("grow", position === "end" ? "mr-4" : "ml-4", size === "small" || size === "smallest" ? "text-sm" : "text-base"),
48
+ children: label
49
+ })]
50
+ });
51
+ };
52
+ //#endregion
53
+ export { BooleanSwitchWithLabel };
54
+
55
+ //# sourceMappingURL=BooleanSwitchWithLabel.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BooleanSwitchWithLabel.es.js","names":[],"sources":["../../src/components/BooleanSwitchWithLabel.tsx"],"sourcesContent":["\"use client\";\nimport React from \"react\";\nimport {\n controlHeightMixin,\n fieldBackgroundDisabledMixin,\n fieldBackgroundHoverMixin,\n fieldBackgroundMixin,\n focusedClasses,\n focusedDisabled\n} from \"../styles\";\nimport { BooleanSwitch, BooleanSwitchProps } from \"./BooleanSwitch\";\nimport { cls } from \"../util\";\n\nexport type BooleanSwitchWithLabelProps = BooleanSwitchProps & {\n position?: \"start\" | \"end\",\n invisible?: boolean,\n label?: React.ReactNode,\n error?: boolean,\n autoFocus?: boolean,\n fullWidth?: boolean,\n className?: string,\n inputClassName?: string,\n};\n\n/**\n * Simple boolean switch.\n *\n */\nexport const BooleanSwitchWithLabel = function BooleanSwitchWithLabel({\n value,\n position = \"end\",\n size = \"medium\",\n invisible,\n onValueChange,\n error,\n label,\n autoFocus,\n disabled,\n className,\n fullWidth = true,\n inputClassName,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...props\n }: BooleanSwitchWithLabelProps) {\n\n const ref = React.useRef<HTMLDivElement | null>(null);\n const refInput = React.useRef<HTMLButtonElement | null>(null);\n const switchLabelId = React.useId();\n const [_, setFocused] = React.useState(autoFocus)\n const onFocus = () => setFocused(true);\n const onBlur = () => setFocused(false);\n\n React.useEffect(() => {\n if (autoFocus) refInput.current?.focus();\n // Mount only, like the `autoFocus` attribute it stands in for.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const focus = document.activeElement === refInput?.current || document.activeElement === ref?.current\n\n return (\n // The row is a click target only. It used to be a second\n // `role=\"switch\"` carrying the label, wrapped around the real switch\n // (the one that takes focus), which had no name: a screen reader\n // tabbing in heard \"switch, off\". The label now names the switch.\n <div\n ref={ref}\n onFocus={onFocus}\n onBlur={onBlur}\n className={cls(\n !invisible && fieldBackgroundMixin,\n !invisible && (disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin),\n disabled ? \"cursor-default\" : \"cursor-pointer\",\n \"rounded-lg max-w-full justify-between box-border relative inline-flex items-center\",\n !invisible && focus && !disabled ? focusedClasses : \"\",\n error ? \"text-red-500 dark:text-red-600\" : (focus && !disabled ? \"text-primary\" : (!disabled ? \"text-text-primary dark:text-text-primary-dark\" : \"text-text-secondary dark:text-text-secondary-dark\")),\n // The one control size scale — 28/32/40/48. This component still\n // carried its own map (…/44/64), so a switch at `large` stood\n // 16px taller than the text field beside it, which read as a\n // giant empty box once the label moved out of the control.\n controlHeightMixin[size],\n size === \"small\" || size === \"smallest\" ? \"pl-2\" : \"pl-4\",\n size === \"small\" || size === \"smallest\" ? \"pr-4\" : \"pr-6\",\n position === \"end\" ? \"flex-row-reverse\" : \"flex-row\",\n fullWidth ? \"w-full\" : \"\",\n className\n )}\n onClick={disabled ? undefined : (e) => {\n if (props.allowIndeterminate) {\n const onChange = onValueChange as ((newValue: boolean | null) => void) | undefined;\n if (value === null || value === undefined) onChange?.(true)\n else if (value) onChange?.(false)\n else onChange?.(null);\n } else {\n onValueChange?.(!value);\n }\n }}\n >\n\n <BooleanSwitch\n value={value}\n ref={refInput}\n size={size}\n aria-labelledby={ariaLabelledBy ?? (label ? switchLabelId : undefined)}\n aria-label={ariaLabel}\n // The row draws the focus ring around the whole field; a second\n // ring on the switch inside it would be noise. Invisible rows\n // have no ring of their own, so the switch keeps it.\n className={cls(invisible ? (focus ? focusedClasses : \"\") : focusedDisabled, inputClassName)}\n disabled={disabled}\n {...props}\n />\n\n <div id={switchLabelId} className={cls(\n \"grow\",\n position === \"end\" ? \"mr-4\" : \"ml-4\",\n size === \"small\" || size === \"smallest\" ? \"text-sm\" : \"text-base\"\n )}>\n {label}\n </div>\n\n </div>\n\n );\n};\n"],"mappings":";;;;;;;;;;;AA4BA,IAAa,yBAAyB,SAAS,uBAAuB,EACI,OACA,WAAW,OACX,OAAO,UACP,WACA,eACA,OACA,OACA,WACA,UACA,WACA,YAAY,MACZ,gBACA,cAAc,WACd,mBAAmB,gBACnB,GAAG,SACyB;CAElG,MAAM,MAAM,MAAM,OAA8B,IAAI;CACpD,MAAM,WAAW,MAAM,OAAiC,IAAI;CAC5D,MAAM,gBAAgB,MAAM,MAAM;CAClC,MAAM,CAAC,GAAG,cAAc,MAAM,SAAS,SAAS;CAChD,MAAM,gBAAgB,WAAW,IAAI;CACrC,MAAM,eAAe,WAAW,KAAK;CAErC,MAAM,gBAAgB;EAClB,IAAI,WAAW,SAAS,SAAS,MAAM;CAG3C,GAAG,CAAC,CAAC;CAEL,MAAM,QAAQ,SAAS,kBAAkB,UAAU,WAAW,SAAS,kBAAkB,KAAK;CAE9F,OAKI,qBAAC,OAAD;EACS;EACI;EACD;EACR,WAAW,IACP,CAAC,aAAA,2CACD,CAAC,cAAc,WAAA,wBAAA,gEACf,WAAW,mBAAmB,kBAC9B,sFACA,CAAC,aAAa,SAAS,CAAC,WAAW,iBAAiB,IACpD,QAAQ,mCAAoC,SAAS,CAAC,WAAW,iBAAkB,CAAC,WAAW,kDAAkD,qDAKjJ,mBAAmB,OACnB,SAAS,WAAW,SAAS,aAAa,SAAS,QACnD,SAAS,WAAW,SAAS,aAAa,SAAS,QACnD,aAAa,QAAQ,qBAAqB,YAC1C,YAAY,WAAW,IACvB,SACJ;EACA,SAAS,WAAW,KAAA,KAAa,MAAM;GACnC,IAAI,MAAM,oBAAoB;IAC1B,MAAM,WAAW;IACjB,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,WAAW,IAAI;SACrD,IAAI,OAAO,WAAW,KAAK;SAC3B,WAAW,IAAI;GACxB,OACI,gBAAgB,CAAC,KAAK;EAE9B;YA/BJ,CAkCI,oBAAC,eAAD;GACW;GACP,KAAK;GACC;GACN,mBAAiB,mBAAmB,QAAQ,gBAAgB,KAAA;GAC5D,cAAY;GAIZ,WAAW,IAAI,YAAa,QAAQ,iBAAiB,KAAM,iBAAiB,cAAc;GAChF;GACV,GAAI;EACP,CAAA,GAED,oBAAC,OAAD;GAAK,IAAI;GAAe,WAAW,IAC/B,QACA,aAAa,QAAQ,SAAS,QAC9B,SAAS,WAAW,SAAS,aAAa,YAAY,WAC1D;aACK;EACA,CAAA,CAEJ;;AAGb"}
@@ -0,0 +1,58 @@
1
+ "use client";
2
+ import { controlHeightMixin, controlPaddingMixin } from "../styles.es.js";
3
+ import { cls } from "../util/cls.es.js";
4
+ import React from "react";
5
+ import { jsxs } from "react/jsx-runtime";
6
+ //#region src/components/Button.tsx
7
+ var ButtonInner = React.memo(React.forwardRef(({ children, className, variant = "filled", disabled = false, size = "medium", startIcon = null, fullWidth = false, component: Component, color = "neutral", ...props }, ref) => {
8
+ const baseClasses = "typography-button h-fit rounded-lg whitespace-nowrap inline-flex items-center justify-center p-2 px-4 focus:outline-none transition-colors ease-in-out duration-150 gap-2";
9
+ const buttonClasses = cls({
10
+ "w-full": fullWidth,
11
+ "w-fit": !fullWidth,
12
+ "border border-primary bg-primary focus-visible:ring-white/90 text-white hover:text-white hover:brightness-105": variant === "filled" && color === "primary" && !disabled,
13
+ "border border-secondary bg-secondary focus-visible:ring-white/90 text-white hover:text-white hover:brightness-105": variant === "filled" && color === "secondary" && !disabled,
14
+ "border border-red-600 bg-red-600 hover:bg-red-700 focus-visible:ring-white/90 text-white hover:text-white": variant === "filled" && color === "error" && !disabled,
15
+ "border border-hairline-strong bg-surface-raised hover:bg-surface-raised-hover text-text-primary hover:text-text-primary dark:text-text-primary-dark hover:dark:text-text-primary-dark": variant === "filled" && color === "text" && !disabled,
16
+ "border border-transparent bg-surface-raised hover:bg-surface-raised-hover text-text-primary hover:text-text-primary dark:text-text-primary-dark hover:dark:text-text-primary-dark": variant === "filled" && color === "neutral" && !disabled,
17
+ "border border-transparent text-primary hover:text-primary hover:bg-surface-hover": variant === "text" && color === "primary" && !disabled,
18
+ "border border-transparent text-secondary hover:text-secondary hover:bg-surface-hover": variant === "text" && color === "secondary" && !disabled,
19
+ "border border-transparent text-red-600 hover:text-red-600 hover:bg-red-600/10": variant === "text" && color === "error" && !disabled,
20
+ "border border-transparent text-text-primary hover:text-text-primary dark:text-text-primary-dark hover:dark:text-text-primary-dark hover:bg-surface-hover": variant === "text" && color === "text" && !disabled,
21
+ "border border-transparent text-text-primary hover:text-text-primary dark:text-text-primary-dark dark:hover:text-text-primary-dark hover:bg-surface-hover": variant === "text" && color === "neutral" && !disabled,
22
+ "border border-primary text-primary hover:text-primary hover:bg-primary-bg hover:bg-primary/10": variant === "outlined" && color === "primary" && !disabled,
23
+ "border border-secondary text-secondary hover:text-secondary hover:bg-secondary-bg": variant === "outlined" && color === "secondary" && !disabled,
24
+ "border border-red-500 text-red-600 hover:text-white hover:bg-red-600": variant === "outlined" && color === "error" && !disabled,
25
+ "border border-hairline-strong text-text-primary hover:text-text-primary dark:text-text-primary-dark hover:bg-surface-hover": variant === "outlined" && color === "text" && !disabled,
26
+ "border border-hairline-strong text-text-primary dark:text-text-primary-dark hover:bg-surface-hover": variant === "outlined" && color === "neutral" && !disabled,
27
+ "text-text-disabled dark:text-text-disabled-dark": disabled,
28
+ "border border-transparent opacity-50": variant === "text" && disabled,
29
+ "border border-hairline-strong opacity-50": variant === "outlined" && disabled,
30
+ "border border-transparent bg-surface-raised": variant === "filled" && disabled
31
+ });
32
+ const sizeClasses = cls("py-0", controlHeightMixin[size], controlPaddingMixin[size]);
33
+ const iconColorClass = (color === "neutral" || color === "text") && !disabled ? "[&>svg]:text-surface-accent-500 dark:[&>svg]:text-surface-accent-300" : "";
34
+ if (Component) return /* @__PURE__ */ jsxs(Component, {
35
+ ref,
36
+ onClick: props.onClick,
37
+ className: cls(startIcon ? "pl-3" : "", baseClasses, buttonClasses, sizeClasses, iconColorClass, className),
38
+ ...props,
39
+ children: [startIcon, children]
40
+ });
41
+ return /* @__PURE__ */ jsxs("button", {
42
+ ref,
43
+ type: props.type ?? "button",
44
+ onClick: props.onClick,
45
+ className: cls(startIcon ? "pl-3" : "", baseClasses, buttonClasses, sizeClasses, iconColorClass, className),
46
+ disabled,
47
+ "data-variant": variant,
48
+ "data-size": size,
49
+ ...props,
50
+ children: [startIcon, children]
51
+ });
52
+ }));
53
+ ButtonInner.displayName = "Button";
54
+ var Button = ButtonInner;
55
+ //#endregion
56
+ export { Button };
57
+
58
+ //# sourceMappingURL=Button.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.es.js","names":[],"sources":["../../src/components/Button.tsx"],"sourcesContent":["\"use client\";\nimport React from \"react\";\nimport { cls } from \"../util\";\nimport { type ButtonSize, controlHeightMixin, controlPaddingMixin } from \"../styles\";\n\ntype ButtonOwnProps<C extends React.ElementType> = {\n children?: React.ReactNode;\n variant?: \"filled\" | \"outlined\" | \"text\";\n disabled?: boolean;\n color?: \"primary\" | \"secondary\" | \"text\" | \"error\" | \"neutral\";\n size?: ButtonSize;\n startIcon?: React.ReactNode;\n fullWidth?: boolean;\n className?: string;\n component?: C;\n onClick?: React.MouseEventHandler<HTMLElement>;\n};\n\n/**\n * The kit's own props, plus those of the element it renders (`button`, or\n * `component`). It used to intersect with `ComponentPropsWithoutRef` of a bare\n * `ElementType`, which is as good as `any`: any misspelt or invented prop on\n * the most-used control in the product compiled, and landed on the DOM.\n */\nexport type ButtonProps<C extends React.ElementType = \"button\"> =\n ButtonOwnProps<C> & Omit<React.ComponentPropsWithoutRef<C>, keyof ButtonOwnProps<C>>;\n\nconst ButtonInner = React.memo(React.forwardRef<\n HTMLButtonElement,\n ButtonProps<React.ElementType>\n>(({\n children,\n className,\n variant = \"filled\",\n disabled = false,\n size = \"medium\",\n startIcon = null,\n fullWidth = false,\n component: Component,\n color = \"neutral\",\n ...props\n }: ButtonProps<React.ElementType>, ref) => {\n\n const baseClasses =\n \"typography-button h-fit rounded-lg whitespace-nowrap inline-flex items-center justify-center p-2 px-4 focus:outline-none transition-colors ease-in-out duration-150 gap-2\";\n\n const buttonClasses = cls({\n \"w-full\": fullWidth,\n \"w-fit\": !fullWidth,\n\n // Filled Variants\n // The default focus ring is an inset ring in the primary colour, which on\n // a fill of that same colour (or the rose, or the red) is invisible: a\n // keyboard user tabbing to the one main action on a screen saw nothing\n // change. A white ring inside the fill reads on all three.\n \"border border-primary bg-primary focus-visible:ring-white/90 text-white hover:text-white hover:brightness-105\": variant === \"filled\" && color === \"primary\" && !disabled,\n \"border border-secondary bg-secondary focus-visible:ring-white/90 text-white hover:text-white hover:brightness-105\": variant === \"filled\" && color === \"secondary\" && !disabled,\n \"border border-red-600 bg-red-600 hover:bg-red-700 focus-visible:ring-white/90 text-white hover:text-white\": variant === \"filled\" && color === \"error\" && !disabled,\n \"border border-hairline-strong bg-surface-raised hover:bg-surface-raised-hover text-text-primary hover:text-text-primary dark:text-text-primary-dark hover:dark:text-text-primary-dark\": variant === \"filled\" && color === \"text\" && !disabled,\n \"border border-transparent bg-surface-raised hover:bg-surface-raised-hover text-text-primary hover:text-text-primary dark:text-text-primary-dark hover:dark:text-text-primary-dark\": variant === \"filled\" && color === \"neutral\" && !disabled,\n\n // Text Variants\n \"border border-transparent text-primary hover:text-primary hover:bg-surface-hover\": variant === \"text\" && color === \"primary\" && !disabled,\n \"border border-transparent text-secondary hover:text-secondary hover:bg-surface-hover\": variant === \"text\" && color === \"secondary\" && !disabled,\n \"border border-transparent text-red-600 hover:text-red-600 hover:bg-red-600/10\": variant === \"text\" && color === \"error\" && !disabled,\n \"border border-transparent text-text-primary hover:text-text-primary dark:text-text-primary-dark hover:dark:text-text-primary-dark hover:bg-surface-hover\": variant === \"text\" && color === \"text\" && !disabled,\n \"border border-transparent text-text-primary hover:text-text-primary dark:text-text-primary-dark dark:hover:text-text-primary-dark hover:bg-surface-hover\": variant === \"text\" && color === \"neutral\" && !disabled,\n\n // Outlined Variants\n \"border border-primary text-primary hover:text-primary hover:bg-primary-bg hover:bg-primary/10\": variant === \"outlined\" && color === \"primary\" && !disabled,\n \"border border-secondary text-secondary hover:text-secondary hover:bg-secondary-bg\": variant === \"outlined\" && color === \"secondary\" && !disabled,\n \"border border-red-500 text-red-600 hover:text-white hover:bg-red-600\": variant === \"outlined\" && color === \"error\" && !disabled,\n \"border border-hairline-strong text-text-primary hover:text-text-primary dark:text-text-primary-dark hover:bg-surface-hover\": variant === \"outlined\" && color === \"text\" && !disabled,\n \"border border-hairline-strong text-text-primary dark:text-text-primary-dark hover:bg-surface-hover\": variant === \"outlined\" && color === \"neutral\" && !disabled,\n\n // Disabled states for all variants\n \"text-text-disabled dark:text-text-disabled-dark\": disabled,\n \"border border-transparent opacity-50\": variant === \"text\" && disabled,\n \"border border-hairline-strong opacity-50\": variant === \"outlined\" && disabled,\n \"border border-transparent bg-surface-raised\": variant === \"filled\" && disabled\n });\n\n // Height comes from the shared control scale (see styles.ts) so a Button\n // and a TextField at the same `size` line up. Vertical padding is dropped:\n // the button is an inline-flex box centring its content inside min-height.\n const sizeClasses = cls(\"py-0\", controlHeightMixin[size], controlPaddingMixin[size]);\n\n const iconColorClass = (color === \"neutral\" || color === \"text\") && !disabled\n ? \"[&>svg]:text-surface-accent-500 dark:[&>svg]:text-surface-accent-300\"\n : \"\";\n\n if (Component) {\n return (\n <Component\n ref={ref}\n onClick={props.onClick}\n className={cls(startIcon ? \"pl-3\" : \"\", baseClasses, buttonClasses, sizeClasses, iconColorClass, className)}\n {...props}>\n {startIcon}\n {children}\n </Component>\n );\n }\n\n return (\n <button ref={ref as React.Ref<HTMLButtonElement>}\n type={props.type ?? \"button\"}\n onClick={props.onClick}\n className={cls(startIcon ? \"pl-3\" : \"\", baseClasses, buttonClasses, sizeClasses, iconColorClass, className)}\n disabled={disabled}\n data-variant={variant}\n data-size={size}\n {...props as React.ButtonHTMLAttributes<HTMLButtonElement>}>\n {startIcon}\n {children}\n </button>\n );\n\n}));\n\nButtonInner.displayName = \"Button\"\n\nexport const Button = ButtonInner as\n <C extends React.ElementType = \"button\">(props: ButtonProps<C> & React.RefAttributes<HTMLButtonElement>) => React.ReactElement | null;\n"],"mappings":";;;;;;AA2BA,IAAM,cAAc,MAAM,KAAK,MAAM,YAGlC,EACI,UACA,WACA,UAAU,UACV,WAAW,OACX,OAAO,UACP,YAAY,MACZ,YAAY,OACZ,WAAW,WACX,QAAQ,WACR,GAAG,SAC4B,QAAQ;CAE1C,MAAM,cACF;CAEJ,MAAM,gBAAgB,IAAI;EACtB,UAAU;EACV,SAAS,CAAC;EAOV,iHAAiH,YAAY,YAAY,UAAU,aAAa,CAAC;EACjK,qHAAqH,YAAY,YAAY,UAAU,eAAe,CAAC;EACvK,6GAA6G,YAAY,YAAY,UAAU,WAAW,CAAC;EAC3J,yLAAyL,YAAY,YAAY,UAAU,UAAU,CAAC;EACtO,qLAAqL,YAAY,YAAY,UAAU,aAAa,CAAC;EAGrO,oFAAoF,YAAY,UAAU,UAAU,aAAa,CAAC;EAClI,wFAAwF,YAAY,UAAU,UAAU,eAAe,CAAC;EACxI,iFAAiF,YAAY,UAAU,UAAU,WAAW,CAAC;EAC7H,4JAA4J,YAAY,UAAU,UAAU,UAAU,CAAC;EACvM,4JAA4J,YAAY,UAAU,UAAU,aAAa,CAAC;EAG1M,iGAAiG,YAAY,cAAc,UAAU,aAAa,CAAC;EACnJ,qFAAqF,YAAY,cAAc,UAAU,eAAe,CAAC;EACzI,wEAAwE,YAAY,cAAc,UAAU,WAAW,CAAC;EACxH,8HAA8H,YAAY,cAAc,UAAU,UAAU,CAAC;EAC7K,sGAAsG,YAAY,cAAc,UAAU,aAAa,CAAC;EAGxJ,mDAAmD;EACnD,wCAAwC,YAAY,UAAU;EAC9D,4CAA4C,YAAY,cAAc;EACtE,+CAA+C,YAAY,YAAY;CAC3E,CAAC;CAKD,MAAM,cAAc,IAAI,QAAQ,mBAAmB,OAAO,oBAAoB,KAAK;CAEnF,MAAM,kBAAkB,UAAU,aAAa,UAAU,WAAW,CAAC,WAC/D,yEACA;CAEN,IAAI,WACA,OACI,qBAAC,WAAD;EACS;EACL,SAAS,MAAM;EACf,WAAW,IAAI,YAAY,SAAS,IAAI,aAAa,eAAe,aAAa,gBAAgB,SAAS;EAC1G,GAAI;YAJR,CAKK,WACA,QACM;;CAInB,OACI,qBAAC,UAAD;EAAa;EACL,MAAM,MAAM,QAAQ;EACpB,SAAS,MAAM;EACf,WAAW,IAAI,YAAY,SAAS,IAAI,aAAa,eAAe,aAAa,gBAAgB,SAAS;EAChG;EACV,gBAAc;EACd,aAAW;EACX,GAAI;YAPZ,CAQK,WACA,QACG;;AAGhB,CAAC,CAAC;AAEF,YAAY,cAAc;AAE1B,IAAa,SAAS"}
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { cardMixin } from "../styles.es.js";
3
+ import { cls } from "../util/cls.es.js";
4
+ import React, { useCallback } from "react";
5
+ import { jsx } from "react/jsx-runtime";
6
+ //#region src/components/Card.tsx
7
+ var Card = React.forwardRef(({ children, className, onClick, style, ...props }, ref) => {
8
+ return /* @__PURE__ */ jsx("div", {
9
+ ref,
10
+ onKeyPress: useCallback((e) => {
11
+ if (e.key === "Enter" || e.key === " ") onClick?.();
12
+ }, [onClick]),
13
+ role: onClick ? "button" : void 0,
14
+ tabIndex: onClick ? 0 : void 0,
15
+ onClick,
16
+ className: cls(cardMixin, onClick && "hover:bg-surface-card-hover cursor-pointer transition-colors duration-150", className),
17
+ style,
18
+ ...props,
19
+ children
20
+ });
21
+ });
22
+ Card.displayName = "Card";
23
+ //#endregion
24
+ export { Card };
25
+
26
+ //# sourceMappingURL=Card.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.es.js","names":[],"sources":["../../src/components/Card.tsx"],"sourcesContent":["\"use client\";\nimport React, { useCallback } from \"react\";\nimport { cardClickableMixin, cardMixin } from \"../styles\";\nimport { cls } from \"../util\";\n\ntype CardProps = {\n children: React.ReactNode;\n style?: React.CSSProperties;\n onClick?: (e?: React.MouseEvent) => void;\n className?: string;\n} & React.HTMLAttributes<HTMLDivElement>;\n\nconst Card = React.forwardRef<HTMLDivElement, CardProps>(({\n children,\n className,\n onClick,\n style,\n ...props\n}, ref) => {\n const onKeyPress = useCallback((e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n onClick?.();\n }\n }, [onClick]);\n\n return (\n <div\n ref={ref}\n onKeyPress={onKeyPress}\n role={onClick ? \"button\" : undefined}\n tabIndex={onClick ? 0 : undefined}\n onClick={onClick}\n className={cls(cardMixin, onClick && cardClickableMixin, className)}\n style={style}\n {...props}>\n {children}\n </div>\n );\n});\n\nCard.displayName = \"Card\";\n\nexport { Card };\n"],"mappings":";;;;;;AAYA,IAAM,OAAO,MAAM,YAAuC,EACtD,UACA,WACA,SACA,OACA,GAAG,SACJ,QAAQ;CAOP,OACI,oBAAC,OAAD;EACS;EACO,YATD,aAAa,MAA2C;GACvE,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAC/B,UAAU;EAElB,GAAG,CAAC,OAAO,CAKS;EACZ,MAAM,UAAU,WAAW,KAAA;EAC3B,UAAU,UAAU,IAAI,KAAA;EACf;EACT,WAAW,IAAI,WAAW,WAAA,6EAA+B,SAAS;EAC3D;EACP,GAAI;EACH;CACA,CAAA;AAEb,CAAC;AAED,KAAK,cAAc"}
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ import { cls } from "../util/cls.es.js";
3
+ import { Container } from "./Container.es.js";
4
+ import React from "react";
5
+ import { jsx } from "react/jsx-runtime";
6
+ //#region src/components/CenteredView.tsx
7
+ var CenteredView = React.forwardRef(({ children, maxWidth, outerClassName, className, fullScreen, ...rest }, ref) => {
8
+ return /* @__PURE__ */ jsx("div", {
9
+ ref,
10
+ className: cls("flex flex-col grow", fullScreen ? "h-screen" : "h-full", outerClassName),
11
+ ...rest,
12
+ children: /* @__PURE__ */ jsx(Container, {
13
+ className: cls("m-auto", className),
14
+ maxWidth,
15
+ children
16
+ })
17
+ });
18
+ });
19
+ CenteredView.displayName = "CenteredView";
20
+ //#endregion
21
+ export { CenteredView };
22
+
23
+ //# sourceMappingURL=CenteredView.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CenteredView.es.js","names":[],"sources":["../../src/components/CenteredView.tsx"],"sourcesContent":["\"use client\";\nimport React from \"react\";\nimport { Container } from \"./Container\";\nimport { cls } from \"../util\";\n\nexport type CenteredViewProps = {\n children: React.ReactNode;\n maxWidth?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" | \"4xl\" | \"5xl\" | \"6xl\" | \"7xl\";\n outerClassName?: string;\n className?: string;\n fullScreen?: boolean;\n};\n\nexport const CenteredView = React.forwardRef<HTMLDivElement, CenteredViewProps>(({\n children,\n maxWidth,\n outerClassName,\n className,\n fullScreen,\n ...rest\n }, ref) => { // Notice how the ref is now received as the second argument\n\n return (\n <div ref={ref}\n className={cls(\"flex flex-col grow\", fullScreen ? \"h-screen\" : \"h-full\", outerClassName)}\n {...rest}>\n <Container className={cls(\"m-auto\", className)} maxWidth={maxWidth}>\n {children}\n </Container>\n </div>\n );\n\n});\n\nCenteredView.displayName = \"CenteredView\";\n"],"mappings":";;;;;;AAaA,IAAa,eAAe,MAAM,YAA+C,EACI,UACA,UACA,gBACA,WACA,YACA,GAAG,QACJ,QAAQ;CAExF,OACI,oBAAC,OAAD;EAAU;EACL,WAAW,IAAI,sBAAsB,aAAa,aAAa,UAAU,cAAc;EACvF,GAAI;YACL,oBAAC,WAAD;GAAW,WAAW,IAAI,UAAU,SAAS;GAAa;GACrD;EACM,CAAA;CACV,CAAA;AAGb,CAAC;AAED,aAAa,cAAc"}