@bridger-kr/react 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 (273) hide show
  1. package/README.md +62 -0
  2. package/dist/components/core/Badge.cjs +36 -0
  3. package/dist/components/core/Badge.cjs.map +1 -0
  4. package/dist/components/core/Badge.d.cts +18 -0
  5. package/dist/components/core/Badge.d.ts +18 -0
  6. package/dist/components/core/Badge.mjs +34 -0
  7. package/dist/components/core/Badge.mjs.map +1 -0
  8. package/dist/components/core/Button.cjs +57 -0
  9. package/dist/components/core/Button.cjs.map +1 -0
  10. package/dist/components/core/Button.d.cts +26 -0
  11. package/dist/components/core/Button.d.ts +26 -0
  12. package/dist/components/core/Button.mjs +55 -0
  13. package/dist/components/core/Button.mjs.map +1 -0
  14. package/dist/components/core/Card.cjs +57 -0
  15. package/dist/components/core/Card.cjs.map +1 -0
  16. package/dist/components/core/Card.d.cts +27 -0
  17. package/dist/components/core/Card.d.ts +27 -0
  18. package/dist/components/core/Card.mjs +54 -0
  19. package/dist/components/core/Card.mjs.map +1 -0
  20. package/dist/components/core/FilterChip.cjs +54 -0
  21. package/dist/components/core/FilterChip.cjs.map +1 -0
  22. package/dist/components/core/FilterChip.d.cts +23 -0
  23. package/dist/components/core/FilterChip.d.ts +23 -0
  24. package/dist/components/core/FilterChip.mjs +52 -0
  25. package/dist/components/core/FilterChip.mjs.map +1 -0
  26. package/dist/components/core/Input.cjs +67 -0
  27. package/dist/components/core/Input.cjs.map +1 -0
  28. package/dist/components/core/Input.d.cts +20 -0
  29. package/dist/components/core/Input.d.ts +20 -0
  30. package/dist/components/core/Input.mjs +65 -0
  31. package/dist/components/core/Input.mjs.map +1 -0
  32. package/dist/components/core/StatusPill.cjs +57 -0
  33. package/dist/components/core/StatusPill.cjs.map +1 -0
  34. package/dist/components/core/StatusPill.d.cts +19 -0
  35. package/dist/components/core/StatusPill.d.ts +19 -0
  36. package/dist/components/core/StatusPill.mjs +55 -0
  37. package/dist/components/core/StatusPill.mjs.map +1 -0
  38. package/dist/components/core/Surface.cjs +52 -0
  39. package/dist/components/core/Surface.cjs.map +1 -0
  40. package/dist/components/core/Surface.d.cts +24 -0
  41. package/dist/components/core/Surface.d.ts +24 -0
  42. package/dist/components/core/Surface.mjs +47 -0
  43. package/dist/components/core/Surface.mjs.map +1 -0
  44. package/dist/components/core/Tabs.cjs +64 -0
  45. package/dist/components/core/Tabs.cjs.map +1 -0
  46. package/dist/components/core/Tabs.d.cts +24 -0
  47. package/dist/components/core/Tabs.d.ts +24 -0
  48. package/dist/components/core/Tabs.mjs +62 -0
  49. package/dist/components/core/Tabs.mjs.map +1 -0
  50. package/dist/components/data/Avatar.cjs +40 -0
  51. package/dist/components/data/Avatar.cjs.map +1 -0
  52. package/dist/components/data/Avatar.d.cts +24 -0
  53. package/dist/components/data/Avatar.d.ts +24 -0
  54. package/dist/components/data/Avatar.mjs +38 -0
  55. package/dist/components/data/Avatar.mjs.map +1 -0
  56. package/dist/components/data/CodeBlock.cjs +92 -0
  57. package/dist/components/data/CodeBlock.cjs.map +1 -0
  58. package/dist/components/data/CodeBlock.d.cts +20 -0
  59. package/dist/components/data/CodeBlock.d.ts +20 -0
  60. package/dist/components/data/CodeBlock.mjs +90 -0
  61. package/dist/components/data/CodeBlock.mjs.map +1 -0
  62. package/dist/components/data/KeyValue.cjs +55 -0
  63. package/dist/components/data/KeyValue.cjs.map +1 -0
  64. package/dist/components/data/KeyValue.d.cts +24 -0
  65. package/dist/components/data/KeyValue.d.ts +24 -0
  66. package/dist/components/data/KeyValue.mjs +53 -0
  67. package/dist/components/data/KeyValue.mjs.map +1 -0
  68. package/dist/components/data/LogRow.cjs +55 -0
  69. package/dist/components/data/LogRow.cjs.map +1 -0
  70. package/dist/components/data/LogRow.d.cts +23 -0
  71. package/dist/components/data/LogRow.d.ts +23 -0
  72. package/dist/components/data/LogRow.mjs +53 -0
  73. package/dist/components/data/LogRow.mjs.map +1 -0
  74. package/dist/components/data/Pagination.cjs +44 -0
  75. package/dist/components/data/Pagination.cjs.map +1 -0
  76. package/dist/components/data/Pagination.d.cts +13 -0
  77. package/dist/components/data/Pagination.d.ts +13 -0
  78. package/dist/components/data/Pagination.mjs +42 -0
  79. package/dist/components/data/Pagination.mjs.map +1 -0
  80. package/dist/components/data/StatTile.cjs +20 -0
  81. package/dist/components/data/StatTile.cjs.map +1 -0
  82. package/dist/components/data/StatTile.d.cts +19 -0
  83. package/dist/components/data/StatTile.d.ts +19 -0
  84. package/dist/components/data/StatTile.mjs +18 -0
  85. package/dist/components/data/StatTile.mjs.map +1 -0
  86. package/dist/components/data/Table.cjs +45 -0
  87. package/dist/components/data/Table.cjs.map +1 -0
  88. package/dist/components/data/Table.d.cts +27 -0
  89. package/dist/components/data/Table.d.ts +27 -0
  90. package/dist/components/data/Table.mjs +43 -0
  91. package/dist/components/data/Table.mjs.map +1 -0
  92. package/dist/components/data/UsageMeter.cjs +28 -0
  93. package/dist/components/data/UsageMeter.cjs.map +1 -0
  94. package/dist/components/data/UsageMeter.d.cts +19 -0
  95. package/dist/components/data/UsageMeter.d.ts +19 -0
  96. package/dist/components/data/UsageMeter.mjs +26 -0
  97. package/dist/components/data/UsageMeter.mjs.map +1 -0
  98. package/dist/components/feedback/Alert.cjs +78 -0
  99. package/dist/components/feedback/Alert.cjs.map +1 -0
  100. package/dist/components/feedback/Alert.d.cts +29 -0
  101. package/dist/components/feedback/Alert.d.ts +29 -0
  102. package/dist/components/feedback/Alert.mjs +74 -0
  103. package/dist/components/feedback/Alert.mjs.map +1 -0
  104. package/dist/components/feedback/Dialog.cjs +62 -0
  105. package/dist/components/feedback/Dialog.cjs.map +1 -0
  106. package/dist/components/feedback/Dialog.d.cts +17 -0
  107. package/dist/components/feedback/Dialog.d.ts +17 -0
  108. package/dist/components/feedback/Dialog.mjs +60 -0
  109. package/dist/components/feedback/Dialog.mjs.map +1 -0
  110. package/dist/components/feedback/Drawer.cjs +58 -0
  111. package/dist/components/feedback/Drawer.cjs.map +1 -0
  112. package/dist/components/feedback/Drawer.d.cts +22 -0
  113. package/dist/components/feedback/Drawer.d.ts +22 -0
  114. package/dist/components/feedback/Drawer.mjs +56 -0
  115. package/dist/components/feedback/Drawer.mjs.map +1 -0
  116. package/dist/components/feedback/EmptyState.cjs +36 -0
  117. package/dist/components/feedback/EmptyState.cjs.map +1 -0
  118. package/dist/components/feedback/EmptyState.d.cts +14 -0
  119. package/dist/components/feedback/EmptyState.d.ts +14 -0
  120. package/dist/components/feedback/EmptyState.mjs +34 -0
  121. package/dist/components/feedback/EmptyState.mjs.map +1 -0
  122. package/dist/components/feedback/Skeleton.cjs +19 -0
  123. package/dist/components/feedback/Skeleton.cjs.map +1 -0
  124. package/dist/components/feedback/Skeleton.d.cts +12 -0
  125. package/dist/components/feedback/Skeleton.d.ts +12 -0
  126. package/dist/components/feedback/Skeleton.mjs +17 -0
  127. package/dist/components/feedback/Skeleton.mjs.map +1 -0
  128. package/dist/components/feedback/Spinner.cjs +17 -0
  129. package/dist/components/feedback/Spinner.cjs.map +1 -0
  130. package/dist/components/feedback/Spinner.d.cts +12 -0
  131. package/dist/components/feedback/Spinner.d.ts +12 -0
  132. package/dist/components/feedback/Spinner.mjs +15 -0
  133. package/dist/components/feedback/Spinner.mjs.map +1 -0
  134. package/dist/components/feedback/Toast.cjs +32 -0
  135. package/dist/components/feedback/Toast.cjs.map +1 -0
  136. package/dist/components/feedback/Toast.d.cts +20 -0
  137. package/dist/components/feedback/Toast.d.ts +20 -0
  138. package/dist/components/feedback/Toast.mjs +30 -0
  139. package/dist/components/feedback/Toast.mjs.map +1 -0
  140. package/dist/components/feedback/Tooltip.cjs +51 -0
  141. package/dist/components/feedback/Tooltip.cjs.map +1 -0
  142. package/dist/components/feedback/Tooltip.d.cts +11 -0
  143. package/dist/components/feedback/Tooltip.d.ts +11 -0
  144. package/dist/components/feedback/Tooltip.mjs +49 -0
  145. package/dist/components/feedback/Tooltip.mjs.map +1 -0
  146. package/dist/components/forms/Checkbox.cjs +74 -0
  147. package/dist/components/forms/Checkbox.cjs.map +1 -0
  148. package/dist/components/forms/Checkbox.d.cts +16 -0
  149. package/dist/components/forms/Checkbox.d.ts +16 -0
  150. package/dist/components/forms/Checkbox.mjs +72 -0
  151. package/dist/components/forms/Checkbox.mjs.map +1 -0
  152. package/dist/components/forms/Combobox.cjs +217 -0
  153. package/dist/components/forms/Combobox.cjs.map +1 -0
  154. package/dist/components/forms/Combobox.d.cts +27 -0
  155. package/dist/components/forms/Combobox.d.ts +27 -0
  156. package/dist/components/forms/Combobox.mjs +215 -0
  157. package/dist/components/forms/Combobox.mjs.map +1 -0
  158. package/dist/components/forms/FileUpload.cjs +187 -0
  159. package/dist/components/forms/FileUpload.cjs.map +1 -0
  160. package/dist/components/forms/FileUpload.d.cts +26 -0
  161. package/dist/components/forms/FileUpload.d.ts +26 -0
  162. package/dist/components/forms/FileUpload.mjs +185 -0
  163. package/dist/components/forms/FileUpload.mjs.map +1 -0
  164. package/dist/components/forms/RadioGroup.cjs +73 -0
  165. package/dist/components/forms/RadioGroup.cjs.map +1 -0
  166. package/dist/components/forms/RadioGroup.d.cts +21 -0
  167. package/dist/components/forms/RadioGroup.d.ts +21 -0
  168. package/dist/components/forms/RadioGroup.mjs +71 -0
  169. package/dist/components/forms/RadioGroup.mjs.map +1 -0
  170. package/dist/components/forms/SegmentedControl.cjs +67 -0
  171. package/dist/components/forms/SegmentedControl.cjs.map +1 -0
  172. package/dist/components/forms/SegmentedControl.d.cts +19 -0
  173. package/dist/components/forms/SegmentedControl.d.ts +19 -0
  174. package/dist/components/forms/SegmentedControl.mjs +65 -0
  175. package/dist/components/forms/SegmentedControl.mjs.map +1 -0
  176. package/dist/components/forms/Select.cjs +67 -0
  177. package/dist/components/forms/Select.cjs.map +1 -0
  178. package/dist/components/forms/Select.d.cts +23 -0
  179. package/dist/components/forms/Select.d.ts +23 -0
  180. package/dist/components/forms/Select.mjs +65 -0
  181. package/dist/components/forms/Select.mjs.map +1 -0
  182. package/dist/components/forms/Slider.cjs +129 -0
  183. package/dist/components/forms/Slider.cjs.map +1 -0
  184. package/dist/components/forms/Slider.d.cts +24 -0
  185. package/dist/components/forms/Slider.d.ts +24 -0
  186. package/dist/components/forms/Slider.mjs +127 -0
  187. package/dist/components/forms/Slider.mjs.map +1 -0
  188. package/dist/components/forms/Switch.cjs +101 -0
  189. package/dist/components/forms/Switch.cjs.map +1 -0
  190. package/dist/components/forms/Switch.d.cts +24 -0
  191. package/dist/components/forms/Switch.d.ts +24 -0
  192. package/dist/components/forms/Switch.mjs +98 -0
  193. package/dist/components/forms/Switch.mjs.map +1 -0
  194. package/dist/components/forms/Textarea.cjs +35 -0
  195. package/dist/components/forms/Textarea.cjs.map +1 -0
  196. package/dist/components/forms/Textarea.d.cts +15 -0
  197. package/dist/components/forms/Textarea.d.ts +15 -0
  198. package/dist/components/forms/Textarea.mjs +33 -0
  199. package/dist/components/forms/Textarea.mjs.map +1 -0
  200. package/dist/components/navigation/Breadcrumb.cjs +27 -0
  201. package/dist/components/navigation/Breadcrumb.cjs.map +1 -0
  202. package/dist/components/navigation/Breadcrumb.d.cts +15 -0
  203. package/dist/components/navigation/Breadcrumb.d.ts +15 -0
  204. package/dist/components/navigation/Breadcrumb.mjs +25 -0
  205. package/dist/components/navigation/Breadcrumb.mjs.map +1 -0
  206. package/dist/components/navigation/CommandPalette.cjs +136 -0
  207. package/dist/components/navigation/CommandPalette.cjs.map +1 -0
  208. package/dist/components/navigation/CommandPalette.d.cts +26 -0
  209. package/dist/components/navigation/CommandPalette.d.ts +26 -0
  210. package/dist/components/navigation/CommandPalette.mjs +134 -0
  211. package/dist/components/navigation/CommandPalette.mjs.map +1 -0
  212. package/dist/components/navigation/Menu.cjs +104 -0
  213. package/dist/components/navigation/Menu.cjs.map +1 -0
  214. package/dist/components/navigation/Menu.d.cts +20 -0
  215. package/dist/components/navigation/Menu.d.ts +20 -0
  216. package/dist/components/navigation/Menu.mjs +102 -0
  217. package/dist/components/navigation/Menu.mjs.map +1 -0
  218. package/dist/components/navigation/Sidebar.cjs +60 -0
  219. package/dist/components/navigation/Sidebar.cjs.map +1 -0
  220. package/dist/components/navigation/Sidebar.d.cts +30 -0
  221. package/dist/components/navigation/Sidebar.d.ts +30 -0
  222. package/dist/components/navigation/Sidebar.mjs +58 -0
  223. package/dist/components/navigation/Sidebar.mjs.map +1 -0
  224. package/dist/components/navigation/Stepper.cjs +55 -0
  225. package/dist/components/navigation/Stepper.cjs.map +1 -0
  226. package/dist/components/navigation/Stepper.d.cts +21 -0
  227. package/dist/components/navigation/Stepper.d.ts +21 -0
  228. package/dist/components/navigation/Stepper.mjs +53 -0
  229. package/dist/components/navigation/Stepper.mjs.map +1 -0
  230. package/dist/components/product/BrandLogo.cjs +159 -0
  231. package/dist/components/product/BrandLogo.cjs.map +1 -0
  232. package/dist/components/product/BrandLogo.d.cts +28 -0
  233. package/dist/components/product/BrandLogo.d.ts +28 -0
  234. package/dist/components/product/BrandLogo.mjs +156 -0
  235. package/dist/components/product/BrandLogo.mjs.map +1 -0
  236. package/dist/components/product/ProductActionPill.cjs +57 -0
  237. package/dist/components/product/ProductActionPill.cjs.map +1 -0
  238. package/dist/components/product/ProductActionPill.d.cts +31 -0
  239. package/dist/components/product/ProductActionPill.d.ts +31 -0
  240. package/dist/components/product/ProductActionPill.mjs +52 -0
  241. package/dist/components/product/ProductActionPill.mjs.map +1 -0
  242. package/dist/components/product/ProductCinematic.cjs +69 -0
  243. package/dist/components/product/ProductCinematic.cjs.map +1 -0
  244. package/dist/components/product/ProductCinematic.d.cts +33 -0
  245. package/dist/components/product/ProductCinematic.d.ts +33 -0
  246. package/dist/components/product/ProductCinematic.mjs +63 -0
  247. package/dist/components/product/ProductCinematic.mjs.map +1 -0
  248. package/dist/components/product/ProductPageHeader.cjs +35 -0
  249. package/dist/components/product/ProductPageHeader.cjs.map +1 -0
  250. package/dist/components/product/ProductPageHeader.d.cts +13 -0
  251. package/dist/components/product/ProductPageHeader.d.ts +13 -0
  252. package/dist/components/product/ProductPageHeader.mjs +33 -0
  253. package/dist/components/product/ProductPageHeader.mjs.map +1 -0
  254. package/dist/components/product/SectionCard.cjs +72 -0
  255. package/dist/components/product/SectionCard.cjs.map +1 -0
  256. package/dist/components/product/SectionCard.d.cts +20 -0
  257. package/dist/components/product/SectionCard.d.ts +20 -0
  258. package/dist/components/product/SectionCard.mjs +70 -0
  259. package/dist/components/product/SectionCard.mjs.map +1 -0
  260. package/dist/components/product/ToolCard.cjs +70 -0
  261. package/dist/components/product/ToolCard.cjs.map +1 -0
  262. package/dist/components/product/ToolCard.d.cts +22 -0
  263. package/dist/components/product/ToolCard.d.ts +22 -0
  264. package/dist/components/product/ToolCard.mjs +68 -0
  265. package/dist/components/product/ToolCard.mjs.map +1 -0
  266. package/dist/index.cjs +2593 -0
  267. package/dist/index.cjs.map +1 -0
  268. package/dist/index.d.cts +49 -0
  269. package/dist/index.d.ts +49 -0
  270. package/dist/index.mjs +2532 -0
  271. package/dist/index.mjs.map +1 -0
  272. package/dist/styles.css +463 -0
  273. package/package.json +50 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/cx.ts","../../../src/components/core/Surface.tsx"],"names":[],"mappings":";;;AAAO,SAAS,MAAM,OAAA,EAA2D;AAC/E,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA,CAAE,KAAK,GAAG,CAAA;AACzC;ACCO,IAAM,WAAA,GAAc;AAAA,EACzB,OAAA,EAAS,SAAA;AAAA,EACT,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ;AACV;AAIO,IAAM,YAAA,GAAe;AAAA,EAC1B,MAAA,EAAQ,QAAA;AAAA,EACR,OAAA,EAAS,SAAA;AAAA,EACT,IAAA,EAAM;AACR;AAKA,IAAM,gBAAA,GAAgD;AAAA,EACpD,CAAC,WAAA,CAAY,OAAO,GAAG,wBAAA;AAAA,EACvB,CAAC,WAAA,CAAY,MAAM,GAAG,+BAAA;AAAA,EACtB,CAAC,WAAA,CAAY,MAAM,GAAG;AACxB,CAAA;AAEA,IAAM,iBAAA,GAAsD;AAAA,EAC1D,CAAC,YAAA,CAAa,MAAM,GAAG,yBAAA;AAAA,EACvB,CAAC,YAAA,CAAa,OAAO,GAAG,0BAAA;AAAA,EACxB,CAAC,YAAA,CAAa,IAAI,GAAG;AACvB,CAAA;AAOO,SAAS,KAAA,CAAM,EAAE,IAAA,GAAO,WAAA,CAAY,SAAS,SAAA,EAAW,QAAA,EAAU,GAAG,KAAA,EAAM,EAAe;AAC/F,EAAA,uBACE,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,yEAAA;AAAA,QACA,iBAAiB,IAAI,CAAA;AAAA,QACrB;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAEO,SAAS,kBAAkB,MAAA,EAAkC;AAClE,EAAA,OAAO,kBAAkB,MAAM,CAAA;AACjC","file":"Surface.mjs","sourcesContent":["export function cx(...classes: Array<string | false | null | undefined>): string {\n return classes.filter(Boolean).join(' ');\n}\n","import type { ComponentPropsWithoutRef, ReactNode } from 'react';\nimport { cx } from '../../lib/cx';\n\nexport const SurfaceTone = {\n Default: 'default',\n Raised: 'raised',\n Sunken: 'sunken',\n} as const;\n\nexport type SurfaceTone = (typeof SurfaceTone)[keyof typeof SurfaceTone];\n\nexport const MetricAccent = {\n Accent: 'accent',\n Success: 'success',\n Info: 'info',\n} as const;\n\nexport type MetricAccent = (typeof MetricAccent)[keyof typeof MetricAccent];\nexport type MetricAccentName = MetricAccent;\n\nconst surfaceToneClass: Record<SurfaceTone, string> = {\n [SurfaceTone.Default]: 'bg-[var(--dt-surface)]',\n [SurfaceTone.Raised]: 'bg-[var(--dt-surface-raised)]',\n [SurfaceTone.Sunken]: 'bg-[var(--dt-surface-sunken)]',\n};\n\nconst metricAccentClass: Record<MetricAccentName, string> = {\n [MetricAccent.Accent]: 'text-[var(--dt-accent)]',\n [MetricAccent.Success]: 'text-[var(--dt-success)]',\n [MetricAccent.Info]: 'text-[var(--dt-info)]',\n};\n\nexport type PanelProps = ComponentPropsWithoutRef<'section'> & {\n readonly tone?: SurfaceTone;\n readonly children: ReactNode;\n};\n\nexport function Panel({ tone = SurfaceTone.Default, className, children, ...props }: PanelProps) {\n return (\n <section\n className={cx(\n 'rounded-dtLg border border-[var(--dt-border)] px-5 py-5 md:px-6 md:py-6',\n surfaceToneClass[tone],\n className,\n )}\n {...props}\n >\n {children}\n </section>\n );\n}\n\nexport function metricAccentColor(accent: MetricAccentName): string {\n return metricAccentClass[accent];\n}\n"]}
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ // src/components/core/Tabs.tsx
7
+ function Tabs({ tabs = [], value, defaultValue, onChange, style }) {
8
+ const [internal, setInternal] = react.useState(defaultValue ?? tabs[0]?.id);
9
+ const active = value !== void 0 ? value : internal;
10
+ const select = (id) => {
11
+ if (value === void 0) setInternal(id);
12
+ onChange?.(id);
13
+ };
14
+ return /* @__PURE__ */ jsxRuntime.jsx(
15
+ "div",
16
+ {
17
+ role: "tablist",
18
+ style: {
19
+ display: "flex",
20
+ gap: 4,
21
+ borderBottom: "1px solid var(--dt-border)",
22
+ ...style
23
+ },
24
+ children: tabs.map((tab) => {
25
+ const isActive = tab.id === active;
26
+ return /* @__PURE__ */ jsxRuntime.jsxs(
27
+ "button",
28
+ {
29
+ role: "tab",
30
+ "aria-selected": isActive,
31
+ type: "button",
32
+ onClick: () => select(tab.id),
33
+ style: {
34
+ position: "relative",
35
+ display: "inline-flex",
36
+ alignItems: "center",
37
+ gap: 7,
38
+ background: "transparent",
39
+ border: "none",
40
+ cursor: "pointer",
41
+ padding: "10px 12px",
42
+ marginBottom: -1,
43
+ fontSize: 13,
44
+ fontWeight: 600,
45
+ color: isActive ? "var(--dt-ink-strong)" : "var(--dt-muted)",
46
+ borderBottom: `2px solid ${isActive ? "var(--dt-accent)" : "transparent"}`,
47
+ transition: "color var(--dt-motion-fast)"
48
+ },
49
+ children: [
50
+ tab.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: { display: "inline-flex" }, children: tab.icon }) : null,
51
+ tab.label,
52
+ tab.count != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontFamily: "var(--dt-font-mono)", fontSize: 11, color: "var(--dt-muted)" }, children: tab.count }) : null
53
+ ]
54
+ },
55
+ tab.id
56
+ );
57
+ })
58
+ }
59
+ );
60
+ }
61
+
62
+ exports.Tabs = Tabs;
63
+ //# sourceMappingURL=Tabs.cjs.map
64
+ //# sourceMappingURL=Tabs.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/core/Tabs.tsx"],"names":["useState","jsx","jsxs"],"mappings":";;;;;;AAuBO,SAAS,IAAA,CAAK,EAAE,IAAA,GAAO,IAAI,KAAA,EAAO,YAAA,EAAc,QAAA,EAAU,KAAA,EAAM,EAAc;AACnF,EAAA,MAAM,CAAC,UAAU,WAAW,CAAA,GAAIA,eAAS,YAAA,IAAgB,IAAA,CAAK,CAAC,CAAA,EAAG,EAAE,CAAA;AACpE,EAAA,MAAM,MAAA,GAAS,KAAA,KAAU,MAAA,GAAY,KAAA,GAAQ,QAAA;AAE7C,EAAA,MAAM,MAAA,GAAS,CAAC,EAAA,KAAe;AAC7B,IAAA,IAAI,KAAA,KAAU,MAAA,EAAW,WAAA,CAAY,EAAE,CAAA;AACvC,IAAA,QAAA,GAAW,EAAE,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,uBACEC,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,SAAA;AAAA,MACL,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,MAAA;AAAA,QACT,GAAA,EAAK,CAAA;AAAA,QACL,YAAA,EAAc,4BAAA;AAAA,QACd,GAAG;AAAA,OACL;AAAA,MAEC,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,KAAQ;AACjB,QAAA,MAAM,QAAA,GAAW,IAAI,EAAA,KAAO,MAAA;AAC5B,QAAA,uBACEC,eAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAK,KAAA;AAAA,YACL,eAAA,EAAe,QAAA;AAAA,YACf,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,MAAA,CAAO,GAAA,CAAI,EAAE,CAAA;AAAA,YAC5B,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,OAAA,EAAS,aAAA;AAAA,cACT,UAAA,EAAY,QAAA;AAAA,cACZ,GAAA,EAAK,CAAA;AAAA,cACL,UAAA,EAAY,aAAA;AAAA,cACZ,MAAA,EAAQ,MAAA;AAAA,cACR,MAAA,EAAQ,SAAA;AAAA,cACR,OAAA,EAAS,WAAA;AAAA,cACT,YAAA,EAAc,EAAA;AAAA,cACd,QAAA,EAAU,EAAA;AAAA,cACV,UAAA,EAAY,GAAA;AAAA,cACZ,KAAA,EAAO,WAAW,sBAAA,GAAyB,iBAAA;AAAA,cAC3C,YAAA,EAAc,CAAA,UAAA,EAAa,QAAA,GAAW,kBAAA,GAAqB,aAAa,CAAA,CAAA;AAAA,cACxE,UAAA,EAAY;AAAA,aACd;AAAA,YAEC,QAAA,EAAA;AAAA,cAAA,GAAA,CAAI,IAAA,mBAAOD,cAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAO,KAAA,EAAO,EAAE,OAAA,EAAS,aAAA,EAAc,EAAI,QAAA,EAAA,GAAA,CAAI,IAAA,EAAK,CAAA,GAAU,IAAA;AAAA,cAC3F,GAAA,CAAI,KAAA;AAAA,cACJ,IAAI,KAAA,IAAS,IAAA,mBACZA,cAAA,CAAC,MAAA,EAAA,EAAK,OAAO,EAAE,UAAA,EAAY,qBAAA,EAAuB,QAAA,EAAU,IAAI,KAAA,EAAO,iBAAA,EAAkB,EACtF,QAAA,EAAA,GAAA,CAAI,OACP,CAAA,GACE;AAAA;AAAA,WAAA;AAAA,UA5BC,GAAA,CAAI;AAAA,SA6BX;AAAA,MAEJ,CAAC;AAAA;AAAA,GACH;AAEJ","file":"Tabs.cjs","sourcesContent":["import { useState } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\n\nexport interface TabItem {\n id: string;\n label: string;\n icon?: ReactNode;\n count?: number | string;\n}\n\nexport interface TabsProps {\n tabs?: TabItem[];\n /** Controlled active tab id. */\n value?: string;\n defaultValue?: string;\n onChange?: (id: string) => void;\n style?: CSSProperties;\n}\n\n/**\n * Underline-style tab bar for switching console views. Controlled via\n * `value` + `onChange`, or uncontrolled with `defaultValue`.\n */\nexport function Tabs({ tabs = [], value, defaultValue, onChange, style }: TabsProps) {\n const [internal, setInternal] = useState(defaultValue ?? tabs[0]?.id);\n const active = value !== undefined ? value : internal;\n\n const select = (id: string) => {\n if (value === undefined) setInternal(id);\n onChange?.(id);\n };\n\n return (\n <div\n role=\"tablist\"\n style={{\n display: 'flex',\n gap: 4,\n borderBottom: '1px solid var(--dt-border)',\n ...style,\n }}\n >\n {tabs.map((tab) => {\n const isActive = tab.id === active;\n return (\n <button\n key={tab.id}\n role=\"tab\"\n aria-selected={isActive}\n type=\"button\"\n onClick={() => select(tab.id)}\n style={{\n position: 'relative',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 7,\n background: 'transparent',\n border: 'none',\n cursor: 'pointer',\n padding: '10px 12px',\n marginBottom: -1,\n fontSize: 13,\n fontWeight: 600,\n color: isActive ? 'var(--dt-ink-strong)' : 'var(--dt-muted)',\n borderBottom: `2px solid ${isActive ? 'var(--dt-accent)' : 'transparent'}`,\n transition: 'color var(--dt-motion-fast)',\n }}\n >\n {tab.icon ? <span aria-hidden=\"true\" style={{ display: 'inline-flex' }}>{tab.icon}</span> : null}\n {tab.label}\n {tab.count != null ? (\n <span style={{ fontFamily: 'var(--dt-font-mono)', fontSize: 11, color: 'var(--dt-muted)' }}>\n {tab.count}\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n );\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, CSSProperties } from 'react';
3
+
4
+ interface TabItem {
5
+ id: string;
6
+ label: string;
7
+ icon?: ReactNode;
8
+ count?: number | string;
9
+ }
10
+ interface TabsProps {
11
+ tabs?: TabItem[];
12
+ /** Controlled active tab id. */
13
+ value?: string;
14
+ defaultValue?: string;
15
+ onChange?: (id: string) => void;
16
+ style?: CSSProperties;
17
+ }
18
+ /**
19
+ * Underline-style tab bar for switching console views. Controlled via
20
+ * `value` + `onChange`, or uncontrolled with `defaultValue`.
21
+ */
22
+ declare function Tabs({ tabs, value, defaultValue, onChange, style }: TabsProps): react.JSX.Element;
23
+
24
+ export { type TabItem, Tabs, type TabsProps };
@@ -0,0 +1,24 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, CSSProperties } from 'react';
3
+
4
+ interface TabItem {
5
+ id: string;
6
+ label: string;
7
+ icon?: ReactNode;
8
+ count?: number | string;
9
+ }
10
+ interface TabsProps {
11
+ tabs?: TabItem[];
12
+ /** Controlled active tab id. */
13
+ value?: string;
14
+ defaultValue?: string;
15
+ onChange?: (id: string) => void;
16
+ style?: CSSProperties;
17
+ }
18
+ /**
19
+ * Underline-style tab bar for switching console views. Controlled via
20
+ * `value` + `onChange`, or uncontrolled with `defaultValue`.
21
+ */
22
+ declare function Tabs({ tabs, value, defaultValue, onChange, style }: TabsProps): react.JSX.Element;
23
+
24
+ export { type TabItem, Tabs, type TabsProps };
@@ -0,0 +1,62 @@
1
+ import { useState } from 'react';
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+
4
+ // src/components/core/Tabs.tsx
5
+ function Tabs({ tabs = [], value, defaultValue, onChange, style }) {
6
+ const [internal, setInternal] = useState(defaultValue ?? tabs[0]?.id);
7
+ const active = value !== void 0 ? value : internal;
8
+ const select = (id) => {
9
+ if (value === void 0) setInternal(id);
10
+ onChange?.(id);
11
+ };
12
+ return /* @__PURE__ */ jsx(
13
+ "div",
14
+ {
15
+ role: "tablist",
16
+ style: {
17
+ display: "flex",
18
+ gap: 4,
19
+ borderBottom: "1px solid var(--dt-border)",
20
+ ...style
21
+ },
22
+ children: tabs.map((tab) => {
23
+ const isActive = tab.id === active;
24
+ return /* @__PURE__ */ jsxs(
25
+ "button",
26
+ {
27
+ role: "tab",
28
+ "aria-selected": isActive,
29
+ type: "button",
30
+ onClick: () => select(tab.id),
31
+ style: {
32
+ position: "relative",
33
+ display: "inline-flex",
34
+ alignItems: "center",
35
+ gap: 7,
36
+ background: "transparent",
37
+ border: "none",
38
+ cursor: "pointer",
39
+ padding: "10px 12px",
40
+ marginBottom: -1,
41
+ fontSize: 13,
42
+ fontWeight: 600,
43
+ color: isActive ? "var(--dt-ink-strong)" : "var(--dt-muted)",
44
+ borderBottom: `2px solid ${isActive ? "var(--dt-accent)" : "transparent"}`,
45
+ transition: "color var(--dt-motion-fast)"
46
+ },
47
+ children: [
48
+ tab.icon ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { display: "inline-flex" }, children: tab.icon }) : null,
49
+ tab.label,
50
+ tab.count != null ? /* @__PURE__ */ jsx("span", { style: { fontFamily: "var(--dt-font-mono)", fontSize: 11, color: "var(--dt-muted)" }, children: tab.count }) : null
51
+ ]
52
+ },
53
+ tab.id
54
+ );
55
+ })
56
+ }
57
+ );
58
+ }
59
+
60
+ export { Tabs };
61
+ //# sourceMappingURL=Tabs.mjs.map
62
+ //# sourceMappingURL=Tabs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/core/Tabs.tsx"],"names":[],"mappings":";;;;AAuBO,SAAS,IAAA,CAAK,EAAE,IAAA,GAAO,IAAI,KAAA,EAAO,YAAA,EAAc,QAAA,EAAU,KAAA,EAAM,EAAc;AACnF,EAAA,MAAM,CAAC,UAAU,WAAW,CAAA,GAAI,SAAS,YAAA,IAAgB,IAAA,CAAK,CAAC,CAAA,EAAG,EAAE,CAAA;AACpE,EAAA,MAAM,MAAA,GAAS,KAAA,KAAU,MAAA,GAAY,KAAA,GAAQ,QAAA;AAE7C,EAAA,MAAM,MAAA,GAAS,CAAC,EAAA,KAAe;AAC7B,IAAA,IAAI,KAAA,KAAU,MAAA,EAAW,WAAA,CAAY,EAAE,CAAA;AACvC,IAAA,QAAA,GAAW,EAAE,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,SAAA;AAAA,MACL,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,MAAA;AAAA,QACT,GAAA,EAAK,CAAA;AAAA,QACL,YAAA,EAAc,4BAAA;AAAA,QACd,GAAG;AAAA,OACL;AAAA,MAEC,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,KAAQ;AACjB,QAAA,MAAM,QAAA,GAAW,IAAI,EAAA,KAAO,MAAA;AAC5B,QAAA,uBACE,IAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAK,KAAA;AAAA,YACL,eAAA,EAAe,QAAA;AAAA,YACf,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,MAAA,CAAO,GAAA,CAAI,EAAE,CAAA;AAAA,YAC5B,KAAA,EAAO;AAAA,cACL,QAAA,EAAU,UAAA;AAAA,cACV,OAAA,EAAS,aAAA;AAAA,cACT,UAAA,EAAY,QAAA;AAAA,cACZ,GAAA,EAAK,CAAA;AAAA,cACL,UAAA,EAAY,aAAA;AAAA,cACZ,MAAA,EAAQ,MAAA;AAAA,cACR,MAAA,EAAQ,SAAA;AAAA,cACR,OAAA,EAAS,WAAA;AAAA,cACT,YAAA,EAAc,EAAA;AAAA,cACd,QAAA,EAAU,EAAA;AAAA,cACV,UAAA,EAAY,GAAA;AAAA,cACZ,KAAA,EAAO,WAAW,sBAAA,GAAyB,iBAAA;AAAA,cAC3C,YAAA,EAAc,CAAA,UAAA,EAAa,QAAA,GAAW,kBAAA,GAAqB,aAAa,CAAA,CAAA;AAAA,cACxE,UAAA,EAAY;AAAA,aACd;AAAA,YAEC,QAAA,EAAA;AAAA,cAAA,GAAA,CAAI,IAAA,mBAAO,GAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAO,KAAA,EAAO,EAAE,OAAA,EAAS,aAAA,EAAc,EAAI,QAAA,EAAA,GAAA,CAAI,IAAA,EAAK,CAAA,GAAU,IAAA;AAAA,cAC3F,GAAA,CAAI,KAAA;AAAA,cACJ,IAAI,KAAA,IAAS,IAAA,mBACZ,GAAA,CAAC,MAAA,EAAA,EAAK,OAAO,EAAE,UAAA,EAAY,qBAAA,EAAuB,QAAA,EAAU,IAAI,KAAA,EAAO,iBAAA,EAAkB,EACtF,QAAA,EAAA,GAAA,CAAI,OACP,CAAA,GACE;AAAA;AAAA,WAAA;AAAA,UA5BC,GAAA,CAAI;AAAA,SA6BX;AAAA,MAEJ,CAAC;AAAA;AAAA,GACH;AAEJ","file":"Tabs.mjs","sourcesContent":["import { useState } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\n\nexport interface TabItem {\n id: string;\n label: string;\n icon?: ReactNode;\n count?: number | string;\n}\n\nexport interface TabsProps {\n tabs?: TabItem[];\n /** Controlled active tab id. */\n value?: string;\n defaultValue?: string;\n onChange?: (id: string) => void;\n style?: CSSProperties;\n}\n\n/**\n * Underline-style tab bar for switching console views. Controlled via\n * `value` + `onChange`, or uncontrolled with `defaultValue`.\n */\nexport function Tabs({ tabs = [], value, defaultValue, onChange, style }: TabsProps) {\n const [internal, setInternal] = useState(defaultValue ?? tabs[0]?.id);\n const active = value !== undefined ? value : internal;\n\n const select = (id: string) => {\n if (value === undefined) setInternal(id);\n onChange?.(id);\n };\n\n return (\n <div\n role=\"tablist\"\n style={{\n display: 'flex',\n gap: 4,\n borderBottom: '1px solid var(--dt-border)',\n ...style,\n }}\n >\n {tabs.map((tab) => {\n const isActive = tab.id === active;\n return (\n <button\n key={tab.id}\n role=\"tab\"\n aria-selected={isActive}\n type=\"button\"\n onClick={() => select(tab.id)}\n style={{\n position: 'relative',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 7,\n background: 'transparent',\n border: 'none',\n cursor: 'pointer',\n padding: '10px 12px',\n marginBottom: -1,\n fontSize: 13,\n fontWeight: 600,\n color: isActive ? 'var(--dt-ink-strong)' : 'var(--dt-muted)',\n borderBottom: `2px solid ${isActive ? 'var(--dt-accent)' : 'transparent'}`,\n transition: 'color var(--dt-motion-fast)',\n }}\n >\n {tab.icon ? <span aria-hidden=\"true\" style={{ display: 'inline-flex' }}>{tab.icon}</span> : null}\n {tab.label}\n {tab.count != null ? (\n <span style={{ fontFamily: 'var(--dt-font-mono)', fontSize: 11, color: 'var(--dt-muted)' }}>\n {tab.count}\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n );\n}\n"]}
@@ -0,0 +1,40 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+
5
+ // src/components/data/Avatar.tsx
6
+ var SIZE = { sm: 26, md: 34, lg: 44 };
7
+ function Avatar({ name = "", src, size = "md", status, square = true, style, ...rest }) {
8
+ const px = typeof size === "number" ? size : SIZE[size] ?? SIZE.md;
9
+ const initials = name.trim().split(/\s+/).map((word) => word[0]).slice(0, 2).join("").toUpperCase() || "\xB7";
10
+ const radius = square ? Math.round(px * 0.28) : px;
11
+ const statusColor = status ? { online: "var(--dt-success)", busy: "var(--dt-danger)", away: "var(--dt-warning)", offline: "var(--dt-muted)" }[status] ?? void 0 : void 0;
12
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { ...rest, style: { position: "relative", display: "inline-flex", flex: "0 0 auto", ...style }, children: [
13
+ src ? /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: name, width: px, height: px, style: { borderRadius: radius, objectFit: "cover", boxShadow: "var(--dt-ring)" } }) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
14
+ width: px,
15
+ height: px,
16
+ borderRadius: radius,
17
+ display: "grid",
18
+ placeItems: "center",
19
+ background: "var(--dt-tint-accent)",
20
+ color: "var(--dt-accent)",
21
+ fontSize: px * 0.38,
22
+ fontWeight: 700,
23
+ letterSpacing: "-0.02em"
24
+ }, children: initials }),
25
+ statusColor ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
26
+ position: "absolute",
27
+ right: -1,
28
+ bottom: -1,
29
+ width: px * 0.3,
30
+ height: px * 0.3,
31
+ borderRadius: 9999,
32
+ background: statusColor,
33
+ boxShadow: "0 0 0 2px var(--dt-surface)"
34
+ } }) : null
35
+ ] });
36
+ }
37
+
38
+ exports.Avatar = Avatar;
39
+ //# sourceMappingURL=Avatar.cjs.map
40
+ //# sourceMappingURL=Avatar.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/data/Avatar.tsx"],"names":["jsxs","jsx"],"mappings":";;;;;AAEA,IAAM,OAAO,EAAE,EAAA,EAAI,IAAI,EAAA,EAAI,EAAA,EAAI,IAAI,EAAA,EAAG;AAgB/B,SAAS,MAAA,CAAO,EAAE,IAAA,GAAO,EAAA,EAAI,GAAA,EAAK,IAAA,GAAO,IAAA,EAAM,MAAA,EAAQ,MAAA,GAAS,IAAA,EAAM,KAAA,EAAO,GAAG,MAAK,EAAgB;AAC1G,EAAA,MAAM,EAAA,GAAK,OAAO,IAAA,KAAS,QAAA,GAAW,OAAQ,IAAA,CAAK,IAAI,KAAK,IAAA,CAAK,EAAA;AACjE,EAAA,MAAM,QAAA,GAAW,KAAK,IAAA,EAAK,CAAE,MAAM,KAAK,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,KAAS,IAAA,CAAK,CAAC,CAAC,CAAA,CAAE,MAAM,CAAA,EAAG,CAAC,EAAE,IAAA,CAAK,EAAE,CAAA,CAAE,WAAA,EAAY,IAAK,MAAA;AACvG,EAAA,MAAM,SAAS,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,IAAI,CAAA,GAAI,EAAA;AAChD,EAAA,MAAM,WAAA,GAAc,MAAA,GAAS,EAAE,MAAA,EAAQ,qBAAqB,IAAA,EAAM,kBAAA,EAAoB,IAAA,EAAM,mBAAA,EAAqB,OAAA,EAAS,iBAAA,EAAkB,CAAE,MAAM,KAAK,MAAA,GAAY,MAAA;AAErK,EAAA,uBACEA,eAAA,CAAC,MAAA,EAAA,EAAM,GAAG,IAAA,EAAM,OAAO,EAAE,QAAA,EAAU,UAAA,EAAY,OAAA,EAAS,aAAA,EAAe,IAAA,EAAM,UAAA,EAAY,GAAG,OAAM,EAC/F,QAAA,EAAA;AAAA,IAAA,GAAA,mBACCC,cAAA,CAAC,SAAI,GAAA,EAAU,GAAA,EAAK,MAAM,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA,EAAI,KAAA,EAAO,EAAE,YAAA,EAAc,MAAA,EAAQ,WAAW,OAAA,EAAS,SAAA,EAAW,kBAAiB,EAAG,CAAA,mBAEnIA,cAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO;AAAA,MACX,KAAA,EAAO,EAAA;AAAA,MAAI,MAAA,EAAQ,EAAA;AAAA,MAAI,YAAA,EAAc,MAAA;AAAA,MAAQ,OAAA,EAAS,MAAA;AAAA,MAAQ,UAAA,EAAY,QAAA;AAAA,MAC1E,UAAA,EAAY,uBAAA;AAAA,MAAyB,KAAA,EAAO,kBAAA;AAAA,MAC5C,UAAU,EAAA,GAAK,IAAA;AAAA,MAAM,UAAA,EAAY,GAAA;AAAA,MAAK,aAAA,EAAe;AAAA,OACnD,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,IAEd,WAAA,mBACCA,cAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO;AAAA,MACX,QAAA,EAAU,UAAA;AAAA,MAAY,KAAA,EAAO,EAAA;AAAA,MAAI,MAAA,EAAQ,EAAA;AAAA,MAAI,OAAO,EAAA,GAAK,GAAA;AAAA,MAAK,QAAQ,EAAA,GAAK,GAAA;AAAA,MAC3E,YAAA,EAAc,IAAA;AAAA,MAAM,UAAA,EAAY,WAAA;AAAA,MAAa,SAAA,EAAW;AAAA,OACvD,CAAA,GACD;AAAA,GAAA,EACN,CAAA;AAEJ","file":"Avatar.cjs","sourcesContent":["import type { CSSProperties, HTMLAttributes } from 'react';\n\nconst SIZE = { sm: 26, md: 34, lg: 44 } as const;\n\nexport interface AvatarProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'style'> {\n name?: string;\n src?: string;\n size?: keyof typeof SIZE | number;\n status?: 'online' | 'busy' | 'away' | 'offline';\n /** Rounded square (default) vs full circle. */\n square?: boolean;\n style?: CSSProperties;\n}\n\n/**\n * Avatar — image or initials in a rounded square. Optional status dot.\n * Deterministic tint from the name when no image is given.\n */\nexport function Avatar({ name = '', src, size = 'md', status, square = true, style, ...rest }: AvatarProps) {\n const px = typeof size === 'number' ? size : (SIZE[size] ?? SIZE.md);\n const initials = name.trim().split(/\\s+/).map((word) => word[0]).slice(0, 2).join('').toUpperCase() || '·';\n const radius = square ? Math.round(px * 0.28) : px;\n const statusColor = status ? { online: 'var(--dt-success)', busy: 'var(--dt-danger)', away: 'var(--dt-warning)', offline: 'var(--dt-muted)' }[status] ?? undefined : undefined;\n\n return (\n <span {...rest} style={{ position: 'relative', display: 'inline-flex', flex: '0 0 auto', ...style }}>\n {src ? (\n <img src={src} alt={name} width={px} height={px} style={{ borderRadius: radius, objectFit: 'cover', boxShadow: 'var(--dt-ring)' }} />\n ) : (\n <span style={{\n width: px, height: px, borderRadius: radius, display: 'grid', placeItems: 'center',\n background: 'var(--dt-tint-accent)', color: 'var(--dt-accent)',\n fontSize: px * 0.38, fontWeight: 700, letterSpacing: '-0.02em',\n }}>{initials}</span>\n )}\n {statusColor ? (\n <span style={{\n position: 'absolute', right: -1, bottom: -1, width: px * 0.3, height: px * 0.3,\n borderRadius: 9999, background: statusColor, boxShadow: '0 0 0 2px var(--dt-surface)',\n }} />\n ) : null}\n </span>\n );\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, CSSProperties } from 'react';
3
+
4
+ declare const SIZE: {
5
+ readonly sm: 26;
6
+ readonly md: 34;
7
+ readonly lg: 44;
8
+ };
9
+ interface AvatarProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'style'> {
10
+ name?: string;
11
+ src?: string;
12
+ size?: keyof typeof SIZE | number;
13
+ status?: 'online' | 'busy' | 'away' | 'offline';
14
+ /** Rounded square (default) vs full circle. */
15
+ square?: boolean;
16
+ style?: CSSProperties;
17
+ }
18
+ /**
19
+ * Avatar — image or initials in a rounded square. Optional status dot.
20
+ * Deterministic tint from the name when no image is given.
21
+ */
22
+ declare function Avatar({ name, src, size, status, square, style, ...rest }: AvatarProps): react.JSX.Element;
23
+
24
+ export { Avatar, type AvatarProps };
@@ -0,0 +1,24 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, CSSProperties } from 'react';
3
+
4
+ declare const SIZE: {
5
+ readonly sm: 26;
6
+ readonly md: 34;
7
+ readonly lg: 44;
8
+ };
9
+ interface AvatarProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'style'> {
10
+ name?: string;
11
+ src?: string;
12
+ size?: keyof typeof SIZE | number;
13
+ status?: 'online' | 'busy' | 'away' | 'offline';
14
+ /** Rounded square (default) vs full circle. */
15
+ square?: boolean;
16
+ style?: CSSProperties;
17
+ }
18
+ /**
19
+ * Avatar — image or initials in a rounded square. Optional status dot.
20
+ * Deterministic tint from the name when no image is given.
21
+ */
22
+ declare function Avatar({ name, src, size, status, square, style, ...rest }: AvatarProps): react.JSX.Element;
23
+
24
+ export { Avatar, type AvatarProps };
@@ -0,0 +1,38 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+
3
+ // src/components/data/Avatar.tsx
4
+ var SIZE = { sm: 26, md: 34, lg: 44 };
5
+ function Avatar({ name = "", src, size = "md", status, square = true, style, ...rest }) {
6
+ const px = typeof size === "number" ? size : SIZE[size] ?? SIZE.md;
7
+ const initials = name.trim().split(/\s+/).map((word) => word[0]).slice(0, 2).join("").toUpperCase() || "\xB7";
8
+ const radius = square ? Math.round(px * 0.28) : px;
9
+ const statusColor = status ? { online: "var(--dt-success)", busy: "var(--dt-danger)", away: "var(--dt-warning)", offline: "var(--dt-muted)" }[status] ?? void 0 : void 0;
10
+ return /* @__PURE__ */ jsxs("span", { ...rest, style: { position: "relative", display: "inline-flex", flex: "0 0 auto", ...style }, children: [
11
+ src ? /* @__PURE__ */ jsx("img", { src, alt: name, width: px, height: px, style: { borderRadius: radius, objectFit: "cover", boxShadow: "var(--dt-ring)" } }) : /* @__PURE__ */ jsx("span", { style: {
12
+ width: px,
13
+ height: px,
14
+ borderRadius: radius,
15
+ display: "grid",
16
+ placeItems: "center",
17
+ background: "var(--dt-tint-accent)",
18
+ color: "var(--dt-accent)",
19
+ fontSize: px * 0.38,
20
+ fontWeight: 700,
21
+ letterSpacing: "-0.02em"
22
+ }, children: initials }),
23
+ statusColor ? /* @__PURE__ */ jsx("span", { style: {
24
+ position: "absolute",
25
+ right: -1,
26
+ bottom: -1,
27
+ width: px * 0.3,
28
+ height: px * 0.3,
29
+ borderRadius: 9999,
30
+ background: statusColor,
31
+ boxShadow: "0 0 0 2px var(--dt-surface)"
32
+ } }) : null
33
+ ] });
34
+ }
35
+
36
+ export { Avatar };
37
+ //# sourceMappingURL=Avatar.mjs.map
38
+ //# sourceMappingURL=Avatar.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/data/Avatar.tsx"],"names":[],"mappings":";;;AAEA,IAAM,OAAO,EAAE,EAAA,EAAI,IAAI,EAAA,EAAI,EAAA,EAAI,IAAI,EAAA,EAAG;AAgB/B,SAAS,MAAA,CAAO,EAAE,IAAA,GAAO,EAAA,EAAI,GAAA,EAAK,IAAA,GAAO,IAAA,EAAM,MAAA,EAAQ,MAAA,GAAS,IAAA,EAAM,KAAA,EAAO,GAAG,MAAK,EAAgB;AAC1G,EAAA,MAAM,EAAA,GAAK,OAAO,IAAA,KAAS,QAAA,GAAW,OAAQ,IAAA,CAAK,IAAI,KAAK,IAAA,CAAK,EAAA;AACjE,EAAA,MAAM,QAAA,GAAW,KAAK,IAAA,EAAK,CAAE,MAAM,KAAK,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,KAAS,IAAA,CAAK,CAAC,CAAC,CAAA,CAAE,MAAM,CAAA,EAAG,CAAC,EAAE,IAAA,CAAK,EAAE,CAAA,CAAE,WAAA,EAAY,IAAK,MAAA;AACvG,EAAA,MAAM,SAAS,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,EAAA,GAAK,IAAI,CAAA,GAAI,EAAA;AAChD,EAAA,MAAM,WAAA,GAAc,MAAA,GAAS,EAAE,MAAA,EAAQ,qBAAqB,IAAA,EAAM,kBAAA,EAAoB,IAAA,EAAM,mBAAA,EAAqB,OAAA,EAAS,iBAAA,EAAkB,CAAE,MAAM,KAAK,MAAA,GAAY,MAAA;AAErK,EAAA,uBACE,IAAA,CAAC,MAAA,EAAA,EAAM,GAAG,IAAA,EAAM,OAAO,EAAE,QAAA,EAAU,UAAA,EAAY,OAAA,EAAS,aAAA,EAAe,IAAA,EAAM,UAAA,EAAY,GAAG,OAAM,EAC/F,QAAA,EAAA;AAAA,IAAA,GAAA,mBACC,GAAA,CAAC,SAAI,GAAA,EAAU,GAAA,EAAK,MAAM,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA,EAAI,KAAA,EAAO,EAAE,YAAA,EAAc,MAAA,EAAQ,WAAW,OAAA,EAAS,SAAA,EAAW,kBAAiB,EAAG,CAAA,mBAEnI,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO;AAAA,MACX,KAAA,EAAO,EAAA;AAAA,MAAI,MAAA,EAAQ,EAAA;AAAA,MAAI,YAAA,EAAc,MAAA;AAAA,MAAQ,OAAA,EAAS,MAAA;AAAA,MAAQ,UAAA,EAAY,QAAA;AAAA,MAC1E,UAAA,EAAY,uBAAA;AAAA,MAAyB,KAAA,EAAO,kBAAA;AAAA,MAC5C,UAAU,EAAA,GAAK,IAAA;AAAA,MAAM,UAAA,EAAY,GAAA;AAAA,MAAK,aAAA,EAAe;AAAA,OACnD,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,IAEd,WAAA,mBACC,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO;AAAA,MACX,QAAA,EAAU,UAAA;AAAA,MAAY,KAAA,EAAO,EAAA;AAAA,MAAI,MAAA,EAAQ,EAAA;AAAA,MAAI,OAAO,EAAA,GAAK,GAAA;AAAA,MAAK,QAAQ,EAAA,GAAK,GAAA;AAAA,MAC3E,YAAA,EAAc,IAAA;AAAA,MAAM,UAAA,EAAY,WAAA;AAAA,MAAa,SAAA,EAAW;AAAA,OACvD,CAAA,GACD;AAAA,GAAA,EACN,CAAA;AAEJ","file":"Avatar.mjs","sourcesContent":["import type { CSSProperties, HTMLAttributes } from 'react';\n\nconst SIZE = { sm: 26, md: 34, lg: 44 } as const;\n\nexport interface AvatarProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'style'> {\n name?: string;\n src?: string;\n size?: keyof typeof SIZE | number;\n status?: 'online' | 'busy' | 'away' | 'offline';\n /** Rounded square (default) vs full circle. */\n square?: boolean;\n style?: CSSProperties;\n}\n\n/**\n * Avatar — image or initials in a rounded square. Optional status dot.\n * Deterministic tint from the name when no image is given.\n */\nexport function Avatar({ name = '', src, size = 'md', status, square = true, style, ...rest }: AvatarProps) {\n const px = typeof size === 'number' ? size : (SIZE[size] ?? SIZE.md);\n const initials = name.trim().split(/\\s+/).map((word) => word[0]).slice(0, 2).join('').toUpperCase() || '·';\n const radius = square ? Math.round(px * 0.28) : px;\n const statusColor = status ? { online: 'var(--dt-success)', busy: 'var(--dt-danger)', away: 'var(--dt-warning)', offline: 'var(--dt-muted)' }[status] ?? undefined : undefined;\n\n return (\n <span {...rest} style={{ position: 'relative', display: 'inline-flex', flex: '0 0 auto', ...style }}>\n {src ? (\n <img src={src} alt={name} width={px} height={px} style={{ borderRadius: radius, objectFit: 'cover', boxShadow: 'var(--dt-ring)' }} />\n ) : (\n <span style={{\n width: px, height: px, borderRadius: radius, display: 'grid', placeItems: 'center',\n background: 'var(--dt-tint-accent)', color: 'var(--dt-accent)',\n fontSize: px * 0.38, fontWeight: 700, letterSpacing: '-0.02em',\n }}>{initials}</span>\n )}\n {statusColor ? (\n <span style={{\n position: 'absolute', right: -1, bottom: -1, width: px * 0.3, height: px * 0.3,\n borderRadius: 9999, background: statusColor, boxShadow: '0 0 0 2px var(--dt-surface)',\n }} />\n ) : null}\n </span>\n );\n}\n"]}
@@ -0,0 +1,92 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ // src/components/data/CodeBlock.tsx
7
+ function highlight(line) {
8
+ const out = [];
9
+ const re = /("(?:[^"\\]|\\.)*"\s*:)|("(?:[^"\\]|\\.)*")|(\b-?\d+(?:\.\d+)?\b)|(\b(?:true|false|null|GET|POST|PUT|DELETE)\b)|([{}[\],:])/g;
10
+ let last = 0;
11
+ let match;
12
+ while ((match = re.exec(line)) !== null) {
13
+ if (match.index > last) out.push({ t: line.slice(last, match.index), c: "plain" });
14
+ if (match[1]) out.push({ t: match[1], c: "key" });
15
+ else if (match[2]) out.push({ t: match[2], c: "str" });
16
+ else if (match[3]) out.push({ t: match[3], c: "num" });
17
+ else if (match[4]) out.push({ t: match[4], c: "kw" });
18
+ else if (match[5]) out.push({ t: match[5], c: "pun" });
19
+ last = re.lastIndex;
20
+ }
21
+ if (last < line.length) out.push({ t: line.slice(last), c: "plain" });
22
+ return out;
23
+ }
24
+ var COLOR = { plain: "#cdd0d8", key: "#7fd1c0", str: "#e0a96d", num: "#8fb3ff", kw: "#c98aff", pun: "#8a91a3" };
25
+ function CodeBlock({ code = "", label, language = "json", showLineNumbers = true, copyable = true, style, ...rest }) {
26
+ const [copied, setCopied] = react.useState(false);
27
+ const lines = String(code).replace(/\n$/, "").split("\n");
28
+ const copy = () => {
29
+ try {
30
+ navigator.clipboard?.writeText(code);
31
+ } catch {
32
+ }
33
+ setCopied(true);
34
+ setTimeout(() => setCopied(false), 1400);
35
+ };
36
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ...rest, style: {
37
+ background: "var(--dt-code-bg)",
38
+ border: "1px solid var(--dt-code-border)",
39
+ borderRadius: "var(--dt-radius-lg)",
40
+ overflow: "hidden",
41
+ ...style
42
+ }, children: [
43
+ label || copyable ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
44
+ display: "flex",
45
+ alignItems: "center",
46
+ gap: 10,
47
+ padding: "9px 12px",
48
+ borderBottom: "1px solid var(--dt-code-border)"
49
+ }, children: [
50
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontFamily: "var(--dt-font-mono)", fontSize: 11, color: "#8a91a3" }, children: label || language }),
51
+ copyable ? /* @__PURE__ */ jsxRuntime.jsx(
52
+ "button",
53
+ {
54
+ type: "button",
55
+ onClick: copy,
56
+ style: {
57
+ marginLeft: "auto",
58
+ display: "inline-flex",
59
+ alignItems: "center",
60
+ gap: 6,
61
+ border: "none",
62
+ background: "transparent",
63
+ color: copied ? "#34d399" : "#8a91a3",
64
+ cursor: "pointer",
65
+ fontFamily: "var(--dt-font-mono)",
66
+ fontSize: 11,
67
+ fontWeight: 600,
68
+ padding: 0
69
+ },
70
+ children: copied ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
71
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6L9 17l-5-5", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round" }) }),
72
+ "\uBCF5\uC0AC\uB428"
73
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
74
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
75
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "9", width: "11", height: "11", rx: "2", stroke: "currentColor", strokeWidth: "2" }),
76
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 15V5a2 2 0 0 1 2-2h10", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
77
+ ] }),
78
+ "\uBCF5\uC0AC"
79
+ ] })
80
+ }
81
+ ) : null
82
+ ] }) : null,
83
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "12px 0", overflowX: "auto" }, children: lines.map((line, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gridTemplateColumns: showLineNumbers ? "38px 1fr" : "1fr", fontFamily: "var(--dt-font-mono)", fontSize: 12.5, lineHeight: 1.75 }, children: [
84
+ showLineNumbers ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { textAlign: "right", paddingRight: 14, color: "#5a6273", userSelect: "none" }, children: index + 1 }) : null,
85
+ /* @__PURE__ */ jsxRuntime.jsx("code", { style: { color: COLOR.plain, whiteSpace: "pre", paddingRight: 14 }, children: highlight(line).map((segment, segmentIndex) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: COLOR[segment.c] }, children: segment.t }, segmentIndex)) })
86
+ ] }, index)) })
87
+ ] });
88
+ }
89
+
90
+ exports.CodeBlock = CodeBlock;
91
+ //# sourceMappingURL=CodeBlock.cjs.map
92
+ //# sourceMappingURL=CodeBlock.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/data/CodeBlock.tsx"],"names":["useState","jsxs","jsx","Fragment"],"mappings":";;;;;;AAUA,SAAS,UAAU,IAAA,EAA2B;AAC5C,EAAA,MAAM,MAAmB,EAAC;AAC1B,EAAA,MAAM,EAAA,GAAK,8HAAA;AACX,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,IAAI,KAAA;AAEJ,EAAA,OAAA,CAAQ,KAAA,GAAQ,EAAA,CAAG,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AACvC,IAAA,IAAI,KAAA,CAAM,KAAA,GAAQ,IAAA,EAAM,GAAA,CAAI,KAAK,EAAE,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,MAAM,KAAA,CAAM,KAAK,CAAA,EAAG,CAAA,EAAG,SAAS,CAAA;AACjF,IAAA,IAAI,KAAA,CAAM,CAAC,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,CAAA;AAAA,SAAA,IACvC,KAAA,CAAM,CAAC,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,CAAA;AAAA,SAAA,IAC5C,KAAA,CAAM,CAAC,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,CAAA;AAAA,SAAA,IAC5C,KAAA,CAAM,CAAC,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,EAAG,IAAA,EAAM,CAAA;AAAA,SAAA,IAC3C,KAAA,CAAM,CAAC,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,CAAA;AACrD,IAAA,IAAA,GAAO,EAAA,CAAG,SAAA;AAAA,EACZ;AAEA,EAAA,IAAI,IAAA,GAAO,IAAA,CAAK,MAAA,EAAQ,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,EAAG,CAAA,EAAG,SAAS,CAAA;AACpE,EAAA,OAAO,GAAA;AACT;AAEA,IAAM,KAAA,GAAmC,EAAE,KAAA,EAAO,SAAA,EAAW,GAAA,EAAK,SAAA,EAAW,GAAA,EAAK,SAAA,EAAW,GAAA,EAAK,SAAA,EAAW,EAAA,EAAI,SAAA,EAAW,KAAK,SAAA,EAAU;AAiBpI,SAAS,SAAA,CAAU,EAAE,IAAA,GAAO,EAAA,EAAI,OAAO,QAAA,GAAW,MAAA,EAAQ,eAAA,GAAkB,IAAA,EAAM,QAAA,GAAW,IAAA,EAAM,KAAA,EAAO,GAAG,MAAK,EAAmB;AAC1I,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIA,eAAS,KAAK,CAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,OAAO,IAAI,CAAA,CAAE,QAAQ,KAAA,EAAO,EAAE,CAAA,CAAE,KAAA,CAAM,IAAI,CAAA;AAExD,EAAA,MAAM,OAAO,MAAM;AACjB,IAAA,IAAI;AAAE,MAAA,SAAA,CAAU,SAAA,EAAW,UAAU,IAAI,CAAA;AAAA,IAAG,CAAA,CAAA,MAAQ;AAAA,IAA8B;AAClF,IAAA,SAAA,CAAU,IAAI,CAAA;AAAG,IAAA,UAAA,CAAW,MAAM,SAAA,CAAU,KAAK,CAAA,EAAG,IAAI,CAAA;AAAA,EAC1D,CAAA;AAEA,EAAA,uBACEC,eAAA,CAAC,KAAA,EAAA,EAAK,GAAG,IAAA,EAAM,KAAA,EAAO;AAAA,IACpB,UAAA,EAAY,mBAAA;AAAA,IAAqB,MAAA,EAAQ,iCAAA;AAAA,IACzC,YAAA,EAAc,qBAAA;AAAA,IAAuB,QAAA,EAAU,QAAA;AAAA,IAAU,GAAG;AAAA,GAC9D,EACI,QAAA,EAAA;AAAA,IAAA,KAAA,IAAS,QAAA,mBACTA,eAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO;AAAA,MACV,OAAA,EAAS,MAAA;AAAA,MAAQ,UAAA,EAAY,QAAA;AAAA,MAAU,GAAA,EAAK,EAAA;AAAA,MAAI,OAAA,EAAS,UAAA;AAAA,MACzD,YAAA,EAAc;AAAA,KAChB,EACE,QAAA,EAAA;AAAA,sBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,UAAA,EAAY,qBAAA,EAAuB,QAAA,EAAU,EAAA,EAAI,KAAA,EAAO,SAAA,EAAU,EAAI,QAAA,EAAA,KAAA,IAAS,QAAA,EAAS,CAAA;AAAA,MACtG,QAAA,mBACCA,cAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UAAS,OAAA,EAAS,IAAA;AAAA,UACvB,KAAA,EAAO;AAAA,YACL,UAAA,EAAY,MAAA;AAAA,YAAQ,OAAA,EAAS,aAAA;AAAA,YAAe,UAAA,EAAY,QAAA;AAAA,YAAU,GAAA,EAAK,CAAA;AAAA,YAAG,MAAA,EAAQ,MAAA;AAAA,YAClF,UAAA,EAAY,aAAA;AAAA,YAAe,KAAA,EAAO,SAAS,SAAA,GAAY,SAAA;AAAA,YAAW,MAAA,EAAQ,SAAA;AAAA,YAC1E,UAAA,EAAY,qBAAA;AAAA,YAAuB,QAAA,EAAU,EAAA;AAAA,YAAI,UAAA,EAAY,GAAA;AAAA,YAAK,OAAA,EAAS;AAAA,WAC7E;AAAA,UAEC,mCACCD,eAAA,CAAAE,mBAAA,EAAA,EAAE,QAAA,EAAA;AAAA,4BAAAD,cAAA,CAAC,KAAA,EAAA,EAAI,OAAM,IAAA,EAAK,MAAA,EAAO,MAAK,OAAA,EAAQ,WAAA,EAAY,IAAA,EAAK,MAAA,EAAO,aAAA,EAAY,MAAA,EAAO,yCAAC,MAAA,EAAA,EAAK,CAAA,EAAE,iBAAA,EAAkB,MAAA,EAAO,cAAA,EAAe,WAAA,EAAY,OAAM,aAAA,EAAc,OAAA,EAAQ,cAAA,EAAe,OAAA,EAAQ,CAAA,EAAE,CAAA;AAAA,YAAM;AAAA,WAAA,EAAG,oBAE3MD,eAAA,CAAAE,mBAAA,EAAA,EAAE,QAAA,EAAA;AAAA,4BAAAF,eAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,SAAQ,WAAA,EAAY,IAAA,EAAK,MAAA,EAAO,aAAA,EAAY,MAAA,EAAO,QAAA,EAAA;AAAA,8BAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,GAAA,EAAI,CAAA,EAAE,KAAI,KAAA,EAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,MAAA,EAAO,cAAA,EAAe,aAAY,GAAA,EAAI,CAAA;AAAA,8BAAEA,cAAA,CAAC,UAAK,CAAA,EAAE,0BAAA,EAA2B,QAAO,cAAA,EAAe,WAAA,EAAY,GAAA,EAAI,aAAA,EAAc,OAAA,EAAQ;AAAA,aAAA,EAAE,CAAA;AAAA,YAAM;AAAA,WAAA,EAAE;AAAA;AAAA,OAEtR,GACE;AAAA,KAAA,EACN,CAAA,GACE,IAAA;AAAA,oBACJA,cAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,QAAA,EAAU,SAAA,EAAW,MAAA,EAAO,EAChD,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,KAAA,qBAChBD,eAAA,CAAC,KAAA,EAAA,EAAgB,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,mBAAA,EAAqB,eAAA,GAAkB,UAAA,GAAa,KAAA,EAAO,UAAA,EAAY,qBAAA,EAAuB,QAAA,EAAU,IAAA,EAAM,UAAA,EAAY,MAAK,EACvK,QAAA,EAAA;AAAA,MAAA,eAAA,mBAAkBC,cAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,WAAW,OAAA,EAAS,YAAA,EAAc,EAAA,EAAI,KAAA,EAAO,WAAW,UAAA,EAAY,MAAA,EAAO,EAAI,QAAA,EAAA,KAAA,GAAQ,GAAE,CAAA,GAAU,IAAA;AAAA,sBACrIA,cAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,OAAO,KAAA,CAAM,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,YAAA,EAAc,EAAA,EAAG,EACpE,QAAA,EAAA,SAAA,CAAU,IAAI,CAAA,CAAE,GAAA,CAAI,CAAC,OAAA,EAAS,YAAA,qBAAiBA,cAAA,CAAC,MAAA,EAAA,EAAwB,KAAA,EAAO,EAAE,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,CAAC,GAAE,EAAI,QAAA,EAAA,OAAA,CAAQ,CAAA,EAAA,EAA3D,YAA6D,CAAO,CAAA,EACjI;AAAA,KAAA,EAAA,EAJQ,KAKV,CACD,CAAA,EACH;AAAA,GAAA,EACF,CAAA;AAEJ","file":"CodeBlock.cjs","sourcesContent":["import type { CSSProperties, HTMLAttributes } from 'react';\nimport { useState } from 'react';\n\ntype TokenKind = 'plain' | 'key' | 'str' | 'num' | 'kw' | 'pun';\n\ninterface CodeToken {\n t: string;\n c: TokenKind;\n}\n\nfunction highlight(line: string): CodeToken[] {\n const out: CodeToken[] = [];\n const re = /(\"(?:[^\"\\\\]|\\\\.)*\"\\s*:)|(\"(?:[^\"\\\\]|\\\\.)*\")|(\\b-?\\d+(?:\\.\\d+)?\\b)|(\\b(?:true|false|null|GET|POST|PUT|DELETE)\\b)|([{}[\\],:])/g;\n let last = 0;\n let match: RegExpExecArray | null;\n\n while ((match = re.exec(line)) !== null) {\n if (match.index > last) out.push({ t: line.slice(last, match.index), c: 'plain' });\n if (match[1]) out.push({ t: match[1], c: 'key' });\n else if (match[2]) out.push({ t: match[2], c: 'str' });\n else if (match[3]) out.push({ t: match[3], c: 'num' });\n else if (match[4]) out.push({ t: match[4], c: 'kw' });\n else if (match[5]) out.push({ t: match[5], c: 'pun' });\n last = re.lastIndex;\n }\n\n if (last < line.length) out.push({ t: line.slice(last), c: 'plain' });\n return out;\n}\n\nconst COLOR: Record<TokenKind, string> = { plain: '#cdd0d8', key: '#7fd1c0', str: '#e0a96d', num: '#8fb3ff', kw: '#c98aff', pun: '#8a91a3' };\n\nexport interface CodeBlockProps extends Omit<HTMLAttributes<HTMLDivElement>, 'style'> {\n /** The snippet, newline-separated. Lightly token-highlighted (JSON/shell). */\n code?: string;\n /** Header label, e.g. a filename or \"response\". Falls back to language. */\n label?: string;\n language?: string;\n showLineNumbers?: boolean;\n copyable?: boolean;\n style?: CSSProperties;\n}\n\n/**\n * Dark code surface for the light page (Stripe-style). Header + copy + line numbers.\n * @startingPoint section=\"Data\" subtitle=\"Dark code block with copy\" viewport=\"520x220\"\n */\nexport function CodeBlock({ code = '', label, language = 'json', showLineNumbers = true, copyable = true, style, ...rest }: CodeBlockProps) {\n const [copied, setCopied] = useState(false);\n const lines = String(code).replace(/\\n$/, '').split('\\n');\n\n const copy = () => {\n try { navigator.clipboard?.writeText(code); } catch { /* clipboard unavailable */ }\n setCopied(true); setTimeout(() => setCopied(false), 1400);\n };\n\n return (\n <div {...rest} style={{\n background: 'var(--dt-code-bg)', border: '1px solid var(--dt-code-border)',\n borderRadius: 'var(--dt-radius-lg)', overflow: 'hidden', ...style,\n }}>\n {(label || copyable) ? (\n <div style={{\n display: 'flex', alignItems: 'center', gap: 10, padding: '9px 12px',\n borderBottom: '1px solid var(--dt-code-border)',\n }}>\n <span style={{ fontFamily: 'var(--dt-font-mono)', fontSize: 11, color: '#8a91a3' }}>{label || language}</span>\n {copyable ? (\n <button\n type=\"button\" onClick={copy}\n style={{\n marginLeft: 'auto', display: 'inline-flex', alignItems: 'center', gap: 6, border: 'none',\n background: 'transparent', color: copied ? '#34d399' : '#8a91a3', cursor: 'pointer',\n fontFamily: 'var(--dt-font-mono)', fontSize: 11, fontWeight: 600, padding: 0,\n }}\n >\n {copied ? (\n <><svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><path d=\"M20 6L9 17l-5-5\" stroke=\"currentColor\" strokeWidth=\"2.4\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>복사됨</>\n ) : (\n <><svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"2\" /><path d=\"M5 15V5a2 2 0 0 1 2-2h10\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" /></svg>복사</>\n )}\n </button>\n ) : null}\n </div>\n ) : null}\n <div style={{ padding: '12px 0', overflowX: 'auto' }}>\n {lines.map((line, index) => (\n <div key={index} style={{ display: 'grid', gridTemplateColumns: showLineNumbers ? '38px 1fr' : '1fr', fontFamily: 'var(--dt-font-mono)', fontSize: 12.5, lineHeight: 1.75 }}>\n {showLineNumbers ? <span style={{ textAlign: 'right', paddingRight: 14, color: '#5a6273', userSelect: 'none' }}>{index + 1}</span> : null}\n <code style={{ color: COLOR.plain, whiteSpace: 'pre', paddingRight: 14 }}>\n {highlight(line).map((segment, segmentIndex) => <span key={segmentIndex} style={{ color: COLOR[segment.c] }}>{segment.t}</span>)}\n </code>\n </div>\n ))}\n </div>\n </div>\n );\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, CSSProperties } from 'react';
3
+
4
+ interface CodeBlockProps extends Omit<HTMLAttributes<HTMLDivElement>, 'style'> {
5
+ /** The snippet, newline-separated. Lightly token-highlighted (JSON/shell). */
6
+ code?: string;
7
+ /** Header label, e.g. a filename or "response". Falls back to language. */
8
+ label?: string;
9
+ language?: string;
10
+ showLineNumbers?: boolean;
11
+ copyable?: boolean;
12
+ style?: CSSProperties;
13
+ }
14
+ /**
15
+ * Dark code surface for the light page (Stripe-style). Header + copy + line numbers.
16
+ * @startingPoint section="Data" subtitle="Dark code block with copy" viewport="520x220"
17
+ */
18
+ declare function CodeBlock({ code, label, language, showLineNumbers, copyable, style, ...rest }: CodeBlockProps): react.JSX.Element;
19
+
20
+ export { CodeBlock, type CodeBlockProps };
@@ -0,0 +1,20 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, CSSProperties } from 'react';
3
+
4
+ interface CodeBlockProps extends Omit<HTMLAttributes<HTMLDivElement>, 'style'> {
5
+ /** The snippet, newline-separated. Lightly token-highlighted (JSON/shell). */
6
+ code?: string;
7
+ /** Header label, e.g. a filename or "response". Falls back to language. */
8
+ label?: string;
9
+ language?: string;
10
+ showLineNumbers?: boolean;
11
+ copyable?: boolean;
12
+ style?: CSSProperties;
13
+ }
14
+ /**
15
+ * Dark code surface for the light page (Stripe-style). Header + copy + line numbers.
16
+ * @startingPoint section="Data" subtitle="Dark code block with copy" viewport="520x220"
17
+ */
18
+ declare function CodeBlock({ code, label, language, showLineNumbers, copyable, style, ...rest }: CodeBlockProps): react.JSX.Element;
19
+
20
+ export { CodeBlock, type CodeBlockProps };
@@ -0,0 +1,90 @@
1
+ import { useState } from 'react';
2
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
+
4
+ // src/components/data/CodeBlock.tsx
5
+ function highlight(line) {
6
+ const out = [];
7
+ const re = /("(?:[^"\\]|\\.)*"\s*:)|("(?:[^"\\]|\\.)*")|(\b-?\d+(?:\.\d+)?\b)|(\b(?:true|false|null|GET|POST|PUT|DELETE)\b)|([{}[\],:])/g;
8
+ let last = 0;
9
+ let match;
10
+ while ((match = re.exec(line)) !== null) {
11
+ if (match.index > last) out.push({ t: line.slice(last, match.index), c: "plain" });
12
+ if (match[1]) out.push({ t: match[1], c: "key" });
13
+ else if (match[2]) out.push({ t: match[2], c: "str" });
14
+ else if (match[3]) out.push({ t: match[3], c: "num" });
15
+ else if (match[4]) out.push({ t: match[4], c: "kw" });
16
+ else if (match[5]) out.push({ t: match[5], c: "pun" });
17
+ last = re.lastIndex;
18
+ }
19
+ if (last < line.length) out.push({ t: line.slice(last), c: "plain" });
20
+ return out;
21
+ }
22
+ var COLOR = { plain: "#cdd0d8", key: "#7fd1c0", str: "#e0a96d", num: "#8fb3ff", kw: "#c98aff", pun: "#8a91a3" };
23
+ function CodeBlock({ code = "", label, language = "json", showLineNumbers = true, copyable = true, style, ...rest }) {
24
+ const [copied, setCopied] = useState(false);
25
+ const lines = String(code).replace(/\n$/, "").split("\n");
26
+ const copy = () => {
27
+ try {
28
+ navigator.clipboard?.writeText(code);
29
+ } catch {
30
+ }
31
+ setCopied(true);
32
+ setTimeout(() => setCopied(false), 1400);
33
+ };
34
+ return /* @__PURE__ */ jsxs("div", { ...rest, style: {
35
+ background: "var(--dt-code-bg)",
36
+ border: "1px solid var(--dt-code-border)",
37
+ borderRadius: "var(--dt-radius-lg)",
38
+ overflow: "hidden",
39
+ ...style
40
+ }, children: [
41
+ label || copyable ? /* @__PURE__ */ jsxs("div", { style: {
42
+ display: "flex",
43
+ alignItems: "center",
44
+ gap: 10,
45
+ padding: "9px 12px",
46
+ borderBottom: "1px solid var(--dt-code-border)"
47
+ }, children: [
48
+ /* @__PURE__ */ jsx("span", { style: { fontFamily: "var(--dt-font-mono)", fontSize: 11, color: "#8a91a3" }, children: label || language }),
49
+ copyable ? /* @__PURE__ */ jsx(
50
+ "button",
51
+ {
52
+ type: "button",
53
+ onClick: copy,
54
+ style: {
55
+ marginLeft: "auto",
56
+ display: "inline-flex",
57
+ alignItems: "center",
58
+ gap: 6,
59
+ border: "none",
60
+ background: "transparent",
61
+ color: copied ? "#34d399" : "#8a91a3",
62
+ cursor: "pointer",
63
+ fontFamily: "var(--dt-font-mono)",
64
+ fontSize: 11,
65
+ fontWeight: 600,
66
+ padding: 0
67
+ },
68
+ children: copied ? /* @__PURE__ */ jsxs(Fragment, { children: [
69
+ /* @__PURE__ */ jsx("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M20 6L9 17l-5-5", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round" }) }),
70
+ "\uBCF5\uC0AC\uB428"
71
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
72
+ /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
73
+ /* @__PURE__ */ jsx("rect", { x: "9", y: "9", width: "11", height: "11", rx: "2", stroke: "currentColor", strokeWidth: "2" }),
74
+ /* @__PURE__ */ jsx("path", { d: "M5 15V5a2 2 0 0 1 2-2h10", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
75
+ ] }),
76
+ "\uBCF5\uC0AC"
77
+ ] })
78
+ }
79
+ ) : null
80
+ ] }) : null,
81
+ /* @__PURE__ */ jsx("div", { style: { padding: "12px 0", overflowX: "auto" }, children: lines.map((line, index) => /* @__PURE__ */ jsxs("div", { style: { display: "grid", gridTemplateColumns: showLineNumbers ? "38px 1fr" : "1fr", fontFamily: "var(--dt-font-mono)", fontSize: 12.5, lineHeight: 1.75 }, children: [
82
+ showLineNumbers ? /* @__PURE__ */ jsx("span", { style: { textAlign: "right", paddingRight: 14, color: "#5a6273", userSelect: "none" }, children: index + 1 }) : null,
83
+ /* @__PURE__ */ jsx("code", { style: { color: COLOR.plain, whiteSpace: "pre", paddingRight: 14 }, children: highlight(line).map((segment, segmentIndex) => /* @__PURE__ */ jsx("span", { style: { color: COLOR[segment.c] }, children: segment.t }, segmentIndex)) })
84
+ ] }, index)) })
85
+ ] });
86
+ }
87
+
88
+ export { CodeBlock };
89
+ //# sourceMappingURL=CodeBlock.mjs.map
90
+ //# sourceMappingURL=CodeBlock.mjs.map