@twoux/ui 0.0.0-stage → 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 (325) hide show
  1. package/LICENSE.md +61 -0
  2. package/LICENSES/Apache-2.0.txt +202 -0
  3. package/NOTICE.md +64 -0
  4. package/SHADCN-DIFF.md +228 -0
  5. package/agent/AGENTS.md +358 -0
  6. package/agent/docs-md/accessibility.md +49 -0
  7. package/agent/docs-md/action-catalogue.md +81 -0
  8. package/agent/docs-md/actions.md +74 -0
  9. package/agent/docs-md/agent-activity-log.md +70 -0
  10. package/agent/docs-md/agent-permissions.md +82 -0
  11. package/agent/docs-md/agent-run.md +90 -0
  12. package/agent/docs-md/agents-on-behalf.md +74 -0
  13. package/agent/docs-md/ai-column.md +85 -0
  14. package/agent/docs-md/ai-origin-label.md +70 -0
  15. package/agent/docs-md/announcing-features.md +73 -0
  16. package/agent/docs-md/answer-actions.md +81 -0
  17. package/agent/docs-md/app-shell.md +114 -0
  18. package/agent/docs-md/artifact-card.md +89 -0
  19. package/agent/docs-md/ask-on-screen.md +72 -0
  20. package/agent/docs-md/assistant-page.md +100 -0
  21. package/agent/docs-md/assistant-panel.md +142 -0
  22. package/agent/docs-md/avatar.md +82 -0
  23. package/agent/docs-md/banner.md +106 -0
  24. package/agent/docs-md/board.md +163 -0
  25. package/agent/docs-md/breadcrumb.md +89 -0
  26. package/agent/docs-md/breakdown-table.md +97 -0
  27. package/agent/docs-md/bulk-action-bar.md +112 -0
  28. package/agent/docs-md/button.md +293 -0
  29. package/agent/docs-md/card.md +115 -0
  30. package/agent/docs-md/change-list.md +99 -0
  31. package/agent/docs-md/change-request.md +166 -0
  32. package/agent/docs-md/chart-area.md +87 -0
  33. package/agent/docs-md/chart-bar.md +100 -0
  34. package/agent/docs-md/chart-box-plot.md +88 -0
  35. package/agent/docs-md/chart-bullet.md +89 -0
  36. package/agent/docs-md/chart-candlestick.md +112 -0
  37. package/agent/docs-md/chart-card-line.md +120 -0
  38. package/agent/docs-md/chart-donut.md +90 -0
  39. package/agent/docs-md/chart-drill-down.md +72 -0
  40. package/agent/docs-md/chart-funnel.md +71 -0
  41. package/agent/docs-md/chart-heatmap.md +76 -0
  42. package/agent/docs-md/chart-histogram.md +81 -0
  43. package/agent/docs-md/chart-map.md +165 -0
  44. package/agent/docs-md/chart-mixed.md +88 -0
  45. package/agent/docs-md/chart-price.md +92 -0
  46. package/agent/docs-md/chart-radial-bars.md +109 -0
  47. package/agent/docs-md/chart-radial-lines.md +111 -0
  48. package/agent/docs-md/chart-sankey.md +104 -0
  49. package/agent/docs-md/chart-scatter.md +87 -0
  50. package/agent/docs-md/chart-share-bar.md +89 -0
  51. package/agent/docs-md/chart-treemap.md +98 -0
  52. package/agent/docs-md/chart-waterfall.md +93 -0
  53. package/agent/docs-md/checkbox.md +131 -0
  54. package/agent/docs-md/choosing-selection-control.md +71 -0
  55. package/agent/docs-md/citations-sources.md +79 -0
  56. package/agent/docs-md/citing-sources.md +63 -0
  57. package/agent/docs-md/clarify-before-acting.md +69 -0
  58. package/agent/docs-md/clarifying-question.md +92 -0
  59. package/agent/docs-md/code-block.md +174 -0
  60. package/agent/docs-md/colours.md +87 -0
  61. package/agent/docs-md/columns-menu.md +140 -0
  62. package/agent/docs-md/combobox.md +161 -0
  63. package/agent/docs-md/command-palette.md +126 -0
  64. package/agent/docs-md/confidence-note.md +87 -0
  65. package/agent/docs-md/configurable-dashboard.md +76 -0
  66. package/agent/docs-md/confirmation-dialog.md +93 -0
  67. package/agent/docs-md/connected-tools.md +80 -0
  68. package/agent/docs-md/connector-picker.md +127 -0
  69. package/agent/docs-md/consistency.md +53 -0
  70. package/agent/docs-md/content-density.md +61 -0
  71. package/agent/docs-md/conversation-history.md +78 -0
  72. package/agent/docs-md/create-record.md +80 -0
  73. package/agent/docs-md/csv-import.md +88 -0
  74. package/agent/docs-md/dashboard-items.md +78 -0
  75. package/agent/docs-md/data-export.md +61 -0
  76. package/agent/docs-md/data-grid.md +137 -0
  77. package/agent/docs-md/data-vis-colours.md +76 -0
  78. package/agent/docs-md/data-visualisation.md +76 -0
  79. package/agent/docs-md/date-picker.md +178 -0
  80. package/agent/docs-md/delete-record.md +75 -0
  81. package/agent/docs-md/dense-table.md +495 -0
  82. package/agent/docs-md/design-tokens.md +53 -0
  83. package/agent/docs-md/disabled-read-only.md +75 -0
  84. package/agent/docs-md/drag-and-drop.md +74 -0
  85. package/agent/docs-md/dropdown-menu.md +137 -0
  86. package/agent/docs-md/edit-record.md +73 -0
  87. package/agent/docs-md/empty-loading-error.md +78 -0
  88. package/agent/docs-md/empty-state.md +128 -0
  89. package/agent/docs-md/error-messages.md +75 -0
  90. package/agent/docs-md/error-state.md +123 -0
  91. package/agent/docs-md/export-menu.md +86 -0
  92. package/agent/docs-md/feedback-prompt.md +88 -0
  93. package/agent/docs-md/field-mapping.md +78 -0
  94. package/agent/docs-md/file-drop.md +110 -0
  95. package/agent/docs-md/filter-bar.md +138 -0
  96. package/agent/docs-md/filter-panel.md +103 -0
  97. package/agent/docs-md/filtering-search.md +79 -0
  98. package/agent/docs-md/follow-ups-starters.md +79 -0
  99. package/agent/docs-md/form-validation.md +95 -0
  100. package/agent/docs-md/generated-columns.md +65 -0
  101. package/agent/docs-md/generated-drafts-files.md +71 -0
  102. package/agent/docs-md/grouped-list.md +89 -0
  103. package/agent/docs-md/guide-cue.md +170 -0
  104. package/agent/docs-md/help-panel.md +103 -0
  105. package/agent/docs-md/help-system.md +74 -0
  106. package/agent/docs-md/iconography.md +49 -0
  107. package/agent/docs-md/inbox.md +108 -0
  108. package/agent/docs-md/inline-editing-validation.md +80 -0
  109. package/agent/docs-md/inline-input-in-answer.md +70 -0
  110. package/agent/docs-md/items-palette.md +116 -0
  111. package/agent/docs-md/keyboard-model.md +47 -0
  112. package/agent/docs-md/keyboard-navigation.md +68 -0
  113. package/agent/docs-md/keyboard-shortcut-hint.md +87 -0
  114. package/agent/docs-md/keyboard-shortcut-sheet.md +90 -0
  115. package/agent/docs-md/labelling-ai-output.md +66 -0
  116. package/agent/docs-md/layout.md +47 -0
  117. package/agent/docs-md/list-table.md +254 -0
  118. package/agent/docs-md/loading-skeleton.md +91 -0
  119. package/agent/docs-md/managing-agents.md +71 -0
  120. package/agent/docs-md/message-composer.md +105 -0
  121. package/agent/docs-md/migrating.md +49 -0
  122. package/agent/docs-md/motion.md +93 -0
  123. package/agent/docs-md/navigation.md +76 -0
  124. package/agent/docs-md/notification-channels.md +65 -0
  125. package/agent/docs-md/notifications-decision.md +100 -0
  126. package/agent/docs-md/onboarding-step.md +114 -0
  127. package/agent/docs-md/order-book.md +108 -0
  128. package/agent/docs-md/page-header.md +96 -0
  129. package/agent/docs-md/pagination.md +88 -0
  130. package/agent/docs-md/pane-layout.md +105 -0
  131. package/agent/docs-md/period-comparison.md +66 -0
  132. package/agent/docs-md/plan-card.md +120 -0
  133. package/agent/docs-md/popover-rules.md +88 -0
  134. package/agent/docs-md/prompt-editor.md +90 -0
  135. package/agent/docs-md/propose-apply.md +65 -0
  136. package/agent/docs-md/provider-logo.md +97 -0
  137. package/agent/docs-md/radio.md +83 -0
  138. package/agent/docs-md/ranked-list.md +102 -0
  139. package/agent/docs-md/reasoning-progress.md +72 -0
  140. package/agent/docs-md/record-detail.md +71 -0
  141. package/agent/docs-md/regenerating-answers.md +70 -0
  142. package/agent/docs-md/run-status-bar.md +94 -0
  143. package/agent/docs-md/saved-tasks-schedules.md +63 -0
  144. package/agent/docs-md/saved-views.md +149 -0
  145. package/agent/docs-md/saving-views.md +68 -0
  146. package/agent/docs-md/scheduler.md +258 -0
  147. package/agent/docs-md/secondary-panels.md +72 -0
  148. package/agent/docs-md/segmented-control.md +88 -0
  149. package/agent/docs-md/selection-bulk-actions.md +70 -0
  150. package/agent/docs-md/separator.md +75 -0
  151. package/agent/docs-md/setup-checklist.md +92 -0
  152. package/agent/docs-md/shape-elevation.md +55 -0
  153. package/agent/docs-md/sheet-grid.md +211 -0
  154. package/agent/docs-md/side-panel.md +134 -0
  155. package/agent/docs-md/sign-in.md +114 -0
  156. package/agent/docs-md/spacing.md +55 -0
  157. package/agent/docs-md/split-button.md +100 -0
  158. package/agent/docs-md/stat-compare.md +82 -0
  159. package/agent/docs-md/static-dashboard.md +75 -0
  160. package/agent/docs-md/status-badge.md +140 -0
  161. package/agent/docs-md/step-card.md +75 -0
  162. package/agent/docs-md/stepper.md +92 -0
  163. package/agent/docs-md/suggested-changes.md +91 -0
  164. package/agent/docs-md/switch.md +78 -0
  165. package/agent/docs-md/table-settings.md +81 -0
  166. package/agent/docs-md/tabs.md +85 -0
  167. package/agent/docs-md/tag-input.md +108 -0
  168. package/agent/docs-md/tag.md +79 -0
  169. package/agent/docs-md/task-builder.md +87 -0
  170. package/agent/docs-md/team-instructions.md +72 -0
  171. package/agent/docs-md/templates-gallery.md +85 -0
  172. package/agent/docs-md/text-input.md +160 -0
  173. package/agent/docs-md/thinking-steps.md +89 -0
  174. package/agent/docs-md/timeline.md +189 -0
  175. package/agent/docs-md/timestamp.md +84 -0
  176. package/agent/docs-md/timestamps.md +70 -0
  177. package/agent/docs-md/toast.md +117 -0
  178. package/agent/docs-md/tooltip.md +90 -0
  179. package/agent/docs-md/typography.md +62 -0
  180. package/agent/docs-md/undo-destructive.md +66 -0
  181. package/agent/docs-md/unsaved-changes.md +71 -0
  182. package/agent/docs-md/usage-meter.md +80 -0
  183. package/agent/docs-md/user-feedback.md +71 -0
  184. package/agent/docs-md/voice-and-tone.md +60 -0
  185. package/agent/docs-md/why-choice.md +93 -0
  186. package/agent/docs-md/workspace-onboarding.md +74 -0
  187. package/agent/docs-md/writing.md +48 -0
  188. package/agent/llms-full.txt +18369 -0
  189. package/agent/llms.txt +198 -0
  190. package/agent/skills/twoux-audit/SKILL.md +49 -0
  191. package/agent/skills/twoux-build/SKILL.md +39 -0
  192. package/agent/skills/twoux-design/SKILL.md +54 -0
  193. package/agent/skills/twoux-write/SKILL.md +32 -0
  194. package/bin/check.mjs +123 -0
  195. package/bin/docs.mjs +24 -0
  196. package/bin/guard.mjs +27 -0
  197. package/bin/init.mjs +113 -0
  198. package/bin/knowledge.mjs +87 -0
  199. package/bin/mcp.mjs +116 -0
  200. package/bin/theme.mjs +168 -0
  201. package/bin/twoux.mjs +25 -0
  202. package/package.json +80 -3
  203. package/registry/jobs.json +1028 -0
  204. package/registry/palette.json +770 -0
  205. package/registry/rules.json +913 -0
  206. package/src/components/agent-review.tsx +364 -0
  207. package/src/components/ai-basics.tsx +212 -0
  208. package/src/components/ai-work.tsx +304 -0
  209. package/src/components/ai.tsx +227 -0
  210. package/src/components/alert-dialog.tsx +203 -0
  211. package/src/components/alert.tsx +86 -0
  212. package/src/components/avatar.tsx +114 -0
  213. package/src/components/badge.tsx +59 -0
  214. package/src/components/board.tsx +397 -0
  215. package/src/components/breadcrumb.tsx +114 -0
  216. package/src/components/button-group.tsx +90 -0
  217. package/src/components/button.tsx +109 -0
  218. package/src/components/calendar.tsx +247 -0
  219. package/src/components/card.tsx +102 -0
  220. package/src/components/chart-map.tsx +336 -0
  221. package/src/components/charts-more.tsx +1331 -0
  222. package/src/components/charts-radial.tsx +328 -0
  223. package/src/components/charts.tsx +390 -0
  224. package/src/components/checkbox.tsx +40 -0
  225. package/src/components/code.tsx +139 -0
  226. package/src/components/collapsible.tsx +37 -0
  227. package/src/components/combobox.tsx +339 -0
  228. package/src/components/command-extras.tsx +11 -0
  229. package/src/components/command.tsx +196 -0
  230. package/src/components/data-grid.tsx +213 -0
  231. package/src/components/data-table.tsx +334 -0
  232. package/src/components/data-views.tsx +740 -0
  233. package/src/components/date-picker.tsx +686 -0
  234. package/src/components/dense-table.tsx +207 -0
  235. package/src/components/dialog.tsx +162 -0
  236. package/src/components/dropdown-menu.tsx +264 -0
  237. package/src/components/empty.tsx +114 -0
  238. package/src/components/feedback-prompt.tsx +80 -0
  239. package/src/components/field.tsx +254 -0
  240. package/src/components/fields.tsx +112 -0
  241. package/src/components/flow.tsx +840 -0
  242. package/src/components/guide-cue.tsx +273 -0
  243. package/src/components/inbox.tsx +113 -0
  244. package/src/components/input-group.tsx +176 -0
  245. package/src/components/input.tsx +26 -0
  246. package/src/components/kbd.tsx +34 -0
  247. package/src/components/label.tsx +27 -0
  248. package/src/components/labels.tsx +176 -0
  249. package/src/components/motion.tsx +136 -0
  250. package/src/components/onboarding.tsx +454 -0
  251. package/src/components/order-book.tsx +185 -0
  252. package/src/components/pane-layout.tsx +417 -0
  253. package/src/components/popover.tsx +96 -0
  254. package/src/components/provider-logos.data.ts +49 -0
  255. package/src/components/radio-group.tsx +52 -0
  256. package/src/components/scheduler.tsx +997 -0
  257. package/src/components/segmented-control.tsx +28 -0
  258. package/src/components/select.tsx +195 -0
  259. package/src/components/separator.tsx +31 -0
  260. package/src/components/sheet.tsx +148 -0
  261. package/src/components/shell.tsx +426 -0
  262. package/src/components/shortcut-sheet.tsx +83 -0
  263. package/src/components/skeleton.tsx +18 -0
  264. package/src/components/sonner.tsx +107 -0
  265. package/src/components/spinner.tsx +13 -0
  266. package/src/components/split-button.tsx +58 -0
  267. package/src/components/stepper.tsx +78 -0
  268. package/src/components/switch.tsx +43 -0
  269. package/src/components/table.tsx +126 -0
  270. package/src/components/tabs.tsx +118 -0
  271. package/src/components/tag-input.tsx +253 -0
  272. package/src/components/textarea.tsx +21 -0
  273. package/src/components/theme.tsx +80 -0
  274. package/src/components/timeline.tsx +408 -0
  275. package/src/components/toggle-group.tsx +87 -0
  276. package/src/components/toggle.tsx +54 -0
  277. package/src/components/tooltip.tsx +65 -0
  278. package/src/components/workspace-actions.tsx +294 -0
  279. package/src/components/workspace-import.tsx +465 -0
  280. package/src/components/workspace.tsx +1884 -0
  281. package/src/index.ts +80 -0
  282. package/src/lib/active-indicator.tsx +53 -0
  283. package/src/lib/chart-kit.tsx +72 -0
  284. package/src/lib/cn.ts +6 -0
  285. package/src/lib/shortcuts.tsx +61 -0
  286. package/src/lib/workspace.tsx +10 -0
  287. package/src/shadcn/alert-dialog.tsx +196 -0
  288. package/src/shadcn/alert.tsx +65 -0
  289. package/src/shadcn/avatar.tsx +108 -0
  290. package/src/shadcn/badge.tsx +47 -0
  291. package/src/shadcn/breadcrumb.tsx +108 -0
  292. package/src/shadcn/button-group.tsx +83 -0
  293. package/src/shadcn/button.tsx +63 -0
  294. package/src/shadcn/calendar.tsx +220 -0
  295. package/src/shadcn/card.tsx +91 -0
  296. package/src/shadcn/checkbox.tsx +31 -0
  297. package/src/shadcn/collapsible.tsx +33 -0
  298. package/src/shadcn/command.tsx +184 -0
  299. package/src/shadcn/dialog.tsx +158 -0
  300. package/src/shadcn/dropdown-menu.tsx +256 -0
  301. package/src/shadcn/empty.tsx +103 -0
  302. package/src/shadcn/field.tsx +248 -0
  303. package/src/shadcn/input-group.tsx +170 -0
  304. package/src/shadcn/input.tsx +20 -0
  305. package/src/shadcn/kbd.tsx +28 -0
  306. package/src/shadcn/label.tsx +23 -0
  307. package/src/shadcn/popover.tsx +88 -0
  308. package/src/shadcn/radio-group.tsx +44 -0
  309. package/src/shadcn/select.tsx +189 -0
  310. package/src/shadcn/separator.tsx +27 -0
  311. package/src/shadcn/sheet.tsx +142 -0
  312. package/src/shadcn/skeleton.tsx +13 -0
  313. package/src/shadcn/sonner.tsx +40 -0
  314. package/src/shadcn/switch.tsx +34 -0
  315. package/src/shadcn/table.tsx +115 -0
  316. package/src/shadcn/tabs.tsx +90 -0
  317. package/src/shadcn/textarea.tsx +17 -0
  318. package/src/shadcn/toggle-group.tsx +83 -0
  319. package/src/shadcn/toggle.tsx +46 -0
  320. package/src/shadcn/tooltip.tsx +56 -0
  321. package/src/styles/palette.css +127 -0
  322. package/src/styles/theme.css +35 -0
  323. package/src/styles/twoux.css +236 -0
  324. package/theme.json +14 -0
  325. package/README.md +0 -3
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Generated from shadcn/ui new-york-v4 "button" by scripts/tailor-shadcn.mjs. Do not edit by hand.
3
+ * TwoUX changes:
4
+ * - Compact heights: 32px default, 28px sm, 24px xs, 36px lg
5
+ * - Primary gets a hairline shadow so it sits on grey and white alike
6
+ * - Outline uses the light input edge and darkens it on hover
7
+ * - Adds warning: risky but reversible actions (from Geist)
8
+ * - Icons 14px beside 13px text, so they support the label instead of outweighing it
9
+ * - Button corners come from theme.json (radius.button: a px value or "pill"), so buttons can be rounder than fields without touching the component
10
+ * - Tactile press
11
+ * - Adds loading (spinner, aria-busy, stays focusable) and shortcut (Kbd after the label)
12
+ * - The shortcut works, not just shows: inside ShortcutsProvider, typing it presses the button (single keys obey the off setting, WCAG 2.1.4)
13
+ */
14
+ import * as React from "react"
15
+ import { cva, type VariantProps } from "class-variance-authority"
16
+ import { cn } from "../lib/cn"
17
+ import { useShortcut } from "../lib/shortcuts"
18
+ import { Slot } from "radix-ui"
19
+ import { Kbd } from "./kbd"
20
+ import { Spinner } from "./spinner"
21
+
22
+ const buttonVariants = cva(
23
+ "inline-flex shrink-0 items-center justify-center gap-2 rounded-(--radius-button) text-base font-medium whitespace-nowrap transition-all outline-none active:scale-98 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:not-focus-visible:border-destructive-edge [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
24
+ {
25
+ variants: {
26
+ variant: {
27
+ default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary-hover",
28
+ destructive:
29
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20",
30
+ outline:
31
+ "border border-input bg-background shadow-xs hover:border-input-hover hover:bg-accent hover:text-accent-foreground",
32
+ secondary:
33
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
34
+ ghost:
35
+ "hover:bg-accent hover:text-accent-foreground",
36
+ link: "text-primary-ink underline-offset-4 hover:underline",
37
+ warning: "border border-warn-line bg-warn-bg text-warn hover:border-warn",
38
+ },
39
+ size: {
40
+ default: "h-8 px-3 has-[>svg]:px-2.5",
41
+ xs: "h-6 gap-1 rounded-(--radius-button) px-2 text-sm has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
42
+ sm: "h-7 gap-1.5 rounded-(--radius-button) px-2.5 has-[>svg]:px-2",
43
+ lg: "h-9 rounded-(--radius-button) px-4 has-[>svg]:px-3",
44
+ icon: "size-8",
45
+ "icon-xs": "size-6 rounded-(--radius-button) [&_svg:not([class*='size-'])]:size-3",
46
+ "icon-sm": "size-7",
47
+ "icon-lg": "size-9",
48
+ },
49
+ },
50
+ defaultVariants: {
51
+ variant: "default",
52
+ size: "default",
53
+ },
54
+ }
55
+ )
56
+
57
+ function Button({
58
+ className,
59
+ variant = "default",
60
+ size = "default",
61
+ asChild = false,
62
+ loading = false,
63
+ shortcut,
64
+ children,
65
+ onClick,
66
+ ref,
67
+ ...props
68
+ }: React.ComponentProps<"button"> &
69
+ VariantProps<typeof buttonVariants> & {
70
+ asChild?: boolean
71
+ /** Spinner, aria-busy, ignores clicks, stays focusable. */
72
+ loading?: boolean
73
+ /** Key shown after the label, e.g. "C" or "⌘↵". */
74
+ shortcut?: string
75
+ }) {
76
+ const Comp = asChild ? Slot.Root : "button"
77
+ const iconOnly = String(size).startsWith("icon")
78
+ const own = React.useRef<HTMLButtonElement>(null)
79
+ useShortcut(shortcut, own, loading || !!props.disabled)
80
+ const setRef = (el: HTMLButtonElement | null) => {
81
+ own.current = el
82
+ if (typeof ref === "function") ref(el)
83
+ else if (ref) ref.current = el
84
+ }
85
+
86
+ return (
87
+ <Comp
88
+ ref={setRef}
89
+ data-slot="button"
90
+ data-variant={variant}
91
+ data-size={size}
92
+ className={cn(buttonVariants({ variant, size, className }))}
93
+ aria-busy={loading || undefined}
94
+ aria-disabled={loading || undefined}
95
+ onClick={(e: React.MouseEvent<HTMLButtonElement>) => (loading ? e.preventDefault() : onClick?.(e))}
96
+ {...props}
97
+ >
98
+ {asChild ? children : (
99
+ <>
100
+ {loading && <Spinner />}
101
+ {children}
102
+ {shortcut && !iconOnly && size !== "xs" && <Kbd className="-mr-1">{shortcut}</Kbd>}
103
+ </>
104
+ )}
105
+ </Comp>
106
+ )
107
+ }
108
+
109
+ export { Button, buttonVariants }
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Generated from shadcn/ui new-york-v4 "calendar" by scripts/tailor-shadcn.mjs. Do not edit by hand.
3
+ * TwoUX changes:
4
+ * - UK English by default: en-GB month and weekday names, weeks start on Monday
5
+ * - Month buttons named in plain words: Previous month, Next month
6
+ * - Weekday and week-number labels on TwoUX's 12px muted text, not an arbitrary 0.8rem
7
+ * - Today gets a ring, not a fill, so it never looks selected; the day's name also says Today
8
+ * - Days inside a range use the selection fill, as selected rows do
9
+ * - Parts kept between renders: shadcn creates Root, Chevron and WeekNumber afresh each render, so any state change remounted the grid and a click that started on one day button ended on a new one and was lost
10
+ */
11
+ "use client"
12
+
13
+ import * as React from "react"
14
+ import { cn } from "../lib/cn"
15
+ import {
16
+ ChevronDownIcon,
17
+ ChevronLeftIcon,
18
+ ChevronRightIcon,
19
+ } from "lucide-react"
20
+ import {
21
+ DayPicker,
22
+ getDefaultClassNames,
23
+ type DayButton,
24
+ } from "react-day-picker"
25
+
26
+ import { enGB } from "react-day-picker/locale"
27
+
28
+ import { Button, buttonVariants } from "./button"
29
+
30
+ function Calendar({
31
+ className,
32
+ classNames,
33
+ showOutsideDays = true,
34
+ locale = enGB,
35
+ weekStartsOn = 1,
36
+ labels,
37
+ captionLayout = "label",
38
+ buttonVariant = "ghost",
39
+ formatters,
40
+ components,
41
+ ...props
42
+ }: React.ComponentProps<typeof DayPicker> & {
43
+ buttonVariant?: React.ComponentProps<typeof Button>["variant"]
44
+ }) {
45
+ const defaultClassNames = getDefaultClassNames()
46
+
47
+ const parts = React.useMemo(
48
+ (): React.ComponentProps<typeof DayPicker>["components"] => ({
49
+ Root: ({ className, rootRef, ...props }) => {
50
+ return (
51
+ <div
52
+ data-slot="calendar"
53
+ ref={rootRef}
54
+ className={cn(className)}
55
+ {...props}
56
+ />
57
+ )
58
+ },
59
+ Chevron: ({ className, orientation, ...props }) => {
60
+ if (orientation === "left") {
61
+ return (
62
+ <ChevronLeftIcon className={cn("size-4", className)} {...props} />
63
+ )
64
+ }
65
+
66
+ if (orientation === "right") {
67
+ return (
68
+ <ChevronRightIcon
69
+ className={cn("size-4", className)}
70
+ {...props}
71
+ />
72
+ )
73
+ }
74
+
75
+ return (
76
+ <ChevronDownIcon className={cn("size-4", className)} {...props} />
77
+ )
78
+ },
79
+ DayButton: CalendarDayButton,
80
+ WeekNumber: ({ children, ...props }) => {
81
+ return (
82
+ <td {...props}>
83
+ <div className="flex size-(--cell-size) items-center justify-center text-center">
84
+ {children}
85
+ </div>
86
+ </td>
87
+ )
88
+ },
89
+ ...components,
90
+ }),
91
+ [components]
92
+ )
93
+
94
+ return (
95
+ <DayPicker
96
+ showOutsideDays={showOutsideDays}
97
+ locale={locale}
98
+ weekStartsOn={weekStartsOn}
99
+ className={cn(
100
+ "group/calendar bg-background p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
101
+ String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
102
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
103
+ className
104
+ )}
105
+ captionLayout={captionLayout}
106
+ formatters={{
107
+ formatMonthDropdown: (date) =>
108
+ date.toLocaleString("en-GB", { month: "short" }),
109
+ ...formatters,
110
+ }}
111
+ labels={{
112
+ labelPrevious: () => "Previous month",
113
+ labelNext: () => "Next month",
114
+ ...labels,
115
+ }}
116
+ classNames={{
117
+ root: cn("w-fit", defaultClassNames.root),
118
+ months: cn(
119
+ "relative flex flex-col gap-4 md:flex-row",
120
+ defaultClassNames.months
121
+ ),
122
+ month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
123
+ nav: cn(
124
+ "absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
125
+ defaultClassNames.nav
126
+ ),
127
+ button_previous: cn(
128
+ buttonVariants({ variant: buttonVariant }),
129
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
130
+ defaultClassNames.button_previous
131
+ ),
132
+ button_next: cn(
133
+ buttonVariants({ variant: buttonVariant }),
134
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
135
+ defaultClassNames.button_next
136
+ ),
137
+ month_caption: cn(
138
+ "flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)",
139
+ defaultClassNames.month_caption
140
+ ),
141
+ dropdowns: cn(
142
+ "flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-base font-medium",
143
+ defaultClassNames.dropdowns
144
+ ),
145
+ dropdown_root: cn(
146
+ "relative rounded-sm border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50",
147
+ defaultClassNames.dropdown_root
148
+ ),
149
+ dropdown: cn(
150
+ "absolute inset-0 bg-popover opacity-0",
151
+ defaultClassNames.dropdown
152
+ ),
153
+ caption_label: cn(
154
+ "font-medium select-none",
155
+ captionLayout === "label"
156
+ ? "text-base"
157
+ : "flex h-8 items-center gap-1 rounded-sm pr-1 pl-2 text-base [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
158
+ defaultClassNames.caption_label
159
+ ),
160
+ month_grid: cn("w-full border-collapse", defaultClassNames.month_grid),
161
+ weekdays: cn("flex", defaultClassNames.weekdays),
162
+ weekday: cn(
163
+ "flex-1 rounded-sm text-sm font-normal text-ink-3 select-none",
164
+ defaultClassNames.weekday
165
+ ),
166
+ week: cn("mt-2 flex w-full", defaultClassNames.week),
167
+ week_number_header: cn(
168
+ "w-(--cell-size) select-none",
169
+ defaultClassNames.week_number_header
170
+ ),
171
+ week_number: cn(
172
+ "text-sm text-ink-3 select-none",
173
+ defaultClassNames.week_number
174
+ ),
175
+ day: cn(
176
+ "group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-sm",
177
+ props.showWeekNumber
178
+ ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-sm"
179
+ : "[&:first-child[data-selected=true]_button]:rounded-l-sm",
180
+ defaultClassNames.day
181
+ ),
182
+ range_start: cn(
183
+ "rounded-l-sm bg-selected",
184
+ defaultClassNames.range_start
185
+ ),
186
+ range_middle: cn("rounded-none", defaultClassNames.range_middle),
187
+ range_end: cn("rounded-r-sm bg-selected", defaultClassNames.range_end),
188
+ today: cn(
189
+ "rounded-sm font-semibold text-ink [&:not([data-selected=true])_button]:ring-1 [&:not([data-selected=true])_button]:ring-control [&:not([data-selected=true])_button]:ring-inset data-[selected=true]:rounded-none",
190
+ defaultClassNames.today
191
+ ),
192
+ outside: cn(
193
+ "text-muted-foreground aria-selected:text-muted-foreground",
194
+ defaultClassNames.outside
195
+ ),
196
+ disabled: cn(
197
+ "text-muted-foreground opacity-50",
198
+ defaultClassNames.disabled
199
+ ),
200
+ hidden: cn("invisible", defaultClassNames.hidden),
201
+ ...classNames,
202
+ }}
203
+ components={parts}
204
+ {...props}
205
+ />
206
+ )
207
+ }
208
+
209
+ function CalendarDayButton({
210
+ className,
211
+ day,
212
+ modifiers,
213
+ ...props
214
+ }: React.ComponentProps<typeof DayButton>) {
215
+ const defaultClassNames = getDefaultClassNames()
216
+
217
+ const ref = React.useRef<HTMLButtonElement>(null)
218
+ React.useEffect(() => {
219
+ if (modifiers.focused) ref.current?.focus()
220
+ }, [modifiers.focused])
221
+
222
+ return (
223
+ <Button
224
+ ref={ref}
225
+ variant="ghost"
226
+ size="icon"
227
+ data-day={day.date.toLocaleDateString()}
228
+ data-selected-single={
229
+ modifiers.selected &&
230
+ !modifiers.range_start &&
231
+ !modifiers.range_end &&
232
+ !modifiers.range_middle
233
+ }
234
+ data-range-start={modifiers.range_start}
235
+ data-range-end={modifiers.range_end}
236
+ data-range-middle={modifiers.range_middle}
237
+ className={cn(
238
+ "flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-sm data-[range-end=true]:rounded-r-sm data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-selected data-[range-middle=true]:text-ink data-[range-start=true]:rounded-sm data-[range-start=true]:rounded-l-sm data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground [&>span]:text-sm [&>span]:opacity-70",
239
+ defaultClassNames.day,
240
+ className
241
+ )}
242
+ {...props}
243
+ />
244
+ )
245
+ }
246
+
247
+ export { Calendar, CalendarDayButton }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Generated from shadcn/ui new-york-v4 "card" by scripts/tailor-shadcn.mjs. Do not edit by hand.
3
+ * TwoUX changes:
4
+ * - Compact card: 16px padding and gaps, light edge, 6px corners, the resting card shadow
5
+ * - Title 14px semibold, description in readable grey
6
+ * - Optional level makes the title a heading, for cards that hold a page section
7
+ * - Adds CardFooter band: a tinted strip across the bottom for a secondary line (as in Clerk's “Already have an account?”)
8
+ */
9
+ import * as React from "react"
10
+ import { cn } from "../lib/cn"
11
+
12
+ function Card({ className, ...props }: React.ComponentProps<"div">) {
13
+ return (
14
+ <div
15
+ data-slot="card"
16
+ className={cn(
17
+ "flex flex-col gap-4 overflow-hidden rounded-sm border border-line bg-card py-4 text-card-foreground shadow-card",
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ )
23
+ }
24
+
25
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
26
+ return (
27
+ <div
28
+ data-slot="card-header"
29
+ className={cn(
30
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1 px-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-4",
31
+ className
32
+ )}
33
+ {...props}
34
+ />
35
+ )
36
+ }
37
+
38
+ function CardTitle({ className, level, ...props }: React.ComponentProps<"div"> & { level?: 1 | 2 | 3 | 4 | 5 | 6 }) {
39
+ return (
40
+ <div
41
+ role={level ? "heading" : undefined}
42
+ aria-level={level}
43
+ data-slot="card-title"
44
+ className={cn("text-md font-semibold", className)}
45
+ {...props}
46
+ />
47
+ )
48
+ }
49
+
50
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
51
+ return (
52
+ <div
53
+ data-slot="card-description"
54
+ className={cn("text-base text-ink-2", className)}
55
+ {...props}
56
+ />
57
+ )
58
+ }
59
+
60
+ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
61
+ return (
62
+ <div
63
+ data-slot="card-action"
64
+ className={cn(
65
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
66
+ className
67
+ )}
68
+ {...props}
69
+ />
70
+ )
71
+ }
72
+
73
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
74
+ return (
75
+ <div
76
+ data-slot="card-content"
77
+ className={cn("px-4", className)}
78
+ {...props}
79
+ />
80
+ )
81
+ }
82
+
83
+ function CardFooter({ className, band = false, ...props }: React.ComponentProps<"div"> & { band?: boolean }) {
84
+ return (
85
+ <div
86
+ data-slot="card-footer"
87
+ data-band={band || undefined}
88
+ className={cn("flex items-center px-4 [.border-t]:pt-4", band && "-mb-4 justify-center border-t border-line bg-surface-2 py-3 text-base text-ink-2 [.border-t]:pt-3", className)}
89
+ {...props}
90
+ />
91
+ )
92
+ }
93
+
94
+ export {
95
+ Card,
96
+ CardHeader,
97
+ CardFooter,
98
+ CardTitle,
99
+ CardAction,
100
+ CardDescription,
101
+ CardContent,
102
+ }