@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.
- package/LICENSE.md +61 -0
- package/LICENSES/Apache-2.0.txt +202 -0
- package/NOTICE.md +64 -0
- package/SHADCN-DIFF.md +228 -0
- package/agent/AGENTS.md +358 -0
- package/agent/docs-md/accessibility.md +49 -0
- package/agent/docs-md/action-catalogue.md +81 -0
- package/agent/docs-md/actions.md +74 -0
- package/agent/docs-md/agent-activity-log.md +70 -0
- package/agent/docs-md/agent-permissions.md +82 -0
- package/agent/docs-md/agent-run.md +90 -0
- package/agent/docs-md/agents-on-behalf.md +74 -0
- package/agent/docs-md/ai-column.md +85 -0
- package/agent/docs-md/ai-origin-label.md +70 -0
- package/agent/docs-md/announcing-features.md +73 -0
- package/agent/docs-md/answer-actions.md +81 -0
- package/agent/docs-md/app-shell.md +114 -0
- package/agent/docs-md/artifact-card.md +89 -0
- package/agent/docs-md/ask-on-screen.md +72 -0
- package/agent/docs-md/assistant-page.md +100 -0
- package/agent/docs-md/assistant-panel.md +142 -0
- package/agent/docs-md/avatar.md +82 -0
- package/agent/docs-md/banner.md +106 -0
- package/agent/docs-md/board.md +163 -0
- package/agent/docs-md/breadcrumb.md +89 -0
- package/agent/docs-md/breakdown-table.md +97 -0
- package/agent/docs-md/bulk-action-bar.md +112 -0
- package/agent/docs-md/button.md +293 -0
- package/agent/docs-md/card.md +115 -0
- package/agent/docs-md/change-list.md +99 -0
- package/agent/docs-md/change-request.md +166 -0
- package/agent/docs-md/chart-area.md +87 -0
- package/agent/docs-md/chart-bar.md +100 -0
- package/agent/docs-md/chart-box-plot.md +88 -0
- package/agent/docs-md/chart-bullet.md +89 -0
- package/agent/docs-md/chart-candlestick.md +112 -0
- package/agent/docs-md/chart-card-line.md +120 -0
- package/agent/docs-md/chart-donut.md +90 -0
- package/agent/docs-md/chart-drill-down.md +72 -0
- package/agent/docs-md/chart-funnel.md +71 -0
- package/agent/docs-md/chart-heatmap.md +76 -0
- package/agent/docs-md/chart-histogram.md +81 -0
- package/agent/docs-md/chart-map.md +165 -0
- package/agent/docs-md/chart-mixed.md +88 -0
- package/agent/docs-md/chart-price.md +92 -0
- package/agent/docs-md/chart-radial-bars.md +109 -0
- package/agent/docs-md/chart-radial-lines.md +111 -0
- package/agent/docs-md/chart-sankey.md +104 -0
- package/agent/docs-md/chart-scatter.md +87 -0
- package/agent/docs-md/chart-share-bar.md +89 -0
- package/agent/docs-md/chart-treemap.md +98 -0
- package/agent/docs-md/chart-waterfall.md +93 -0
- package/agent/docs-md/checkbox.md +131 -0
- package/agent/docs-md/choosing-selection-control.md +71 -0
- package/agent/docs-md/citations-sources.md +79 -0
- package/agent/docs-md/citing-sources.md +63 -0
- package/agent/docs-md/clarify-before-acting.md +69 -0
- package/agent/docs-md/clarifying-question.md +92 -0
- package/agent/docs-md/code-block.md +174 -0
- package/agent/docs-md/colours.md +87 -0
- package/agent/docs-md/columns-menu.md +140 -0
- package/agent/docs-md/combobox.md +161 -0
- package/agent/docs-md/command-palette.md +126 -0
- package/agent/docs-md/confidence-note.md +87 -0
- package/agent/docs-md/configurable-dashboard.md +76 -0
- package/agent/docs-md/confirmation-dialog.md +93 -0
- package/agent/docs-md/connected-tools.md +80 -0
- package/agent/docs-md/connector-picker.md +127 -0
- package/agent/docs-md/consistency.md +53 -0
- package/agent/docs-md/content-density.md +61 -0
- package/agent/docs-md/conversation-history.md +78 -0
- package/agent/docs-md/create-record.md +80 -0
- package/agent/docs-md/csv-import.md +88 -0
- package/agent/docs-md/dashboard-items.md +78 -0
- package/agent/docs-md/data-export.md +61 -0
- package/agent/docs-md/data-grid.md +137 -0
- package/agent/docs-md/data-vis-colours.md +76 -0
- package/agent/docs-md/data-visualisation.md +76 -0
- package/agent/docs-md/date-picker.md +178 -0
- package/agent/docs-md/delete-record.md +75 -0
- package/agent/docs-md/dense-table.md +495 -0
- package/agent/docs-md/design-tokens.md +53 -0
- package/agent/docs-md/disabled-read-only.md +75 -0
- package/agent/docs-md/drag-and-drop.md +74 -0
- package/agent/docs-md/dropdown-menu.md +137 -0
- package/agent/docs-md/edit-record.md +73 -0
- package/agent/docs-md/empty-loading-error.md +78 -0
- package/agent/docs-md/empty-state.md +128 -0
- package/agent/docs-md/error-messages.md +75 -0
- package/agent/docs-md/error-state.md +123 -0
- package/agent/docs-md/export-menu.md +86 -0
- package/agent/docs-md/feedback-prompt.md +88 -0
- package/agent/docs-md/field-mapping.md +78 -0
- package/agent/docs-md/file-drop.md +110 -0
- package/agent/docs-md/filter-bar.md +138 -0
- package/agent/docs-md/filter-panel.md +103 -0
- package/agent/docs-md/filtering-search.md +79 -0
- package/agent/docs-md/follow-ups-starters.md +79 -0
- package/agent/docs-md/form-validation.md +95 -0
- package/agent/docs-md/generated-columns.md +65 -0
- package/agent/docs-md/generated-drafts-files.md +71 -0
- package/agent/docs-md/grouped-list.md +89 -0
- package/agent/docs-md/guide-cue.md +170 -0
- package/agent/docs-md/help-panel.md +103 -0
- package/agent/docs-md/help-system.md +74 -0
- package/agent/docs-md/iconography.md +49 -0
- package/agent/docs-md/inbox.md +108 -0
- package/agent/docs-md/inline-editing-validation.md +80 -0
- package/agent/docs-md/inline-input-in-answer.md +70 -0
- package/agent/docs-md/items-palette.md +116 -0
- package/agent/docs-md/keyboard-model.md +47 -0
- package/agent/docs-md/keyboard-navigation.md +68 -0
- package/agent/docs-md/keyboard-shortcut-hint.md +87 -0
- package/agent/docs-md/keyboard-shortcut-sheet.md +90 -0
- package/agent/docs-md/labelling-ai-output.md +66 -0
- package/agent/docs-md/layout.md +47 -0
- package/agent/docs-md/list-table.md +254 -0
- package/agent/docs-md/loading-skeleton.md +91 -0
- package/agent/docs-md/managing-agents.md +71 -0
- package/agent/docs-md/message-composer.md +105 -0
- package/agent/docs-md/migrating.md +49 -0
- package/agent/docs-md/motion.md +93 -0
- package/agent/docs-md/navigation.md +76 -0
- package/agent/docs-md/notification-channels.md +65 -0
- package/agent/docs-md/notifications-decision.md +100 -0
- package/agent/docs-md/onboarding-step.md +114 -0
- package/agent/docs-md/order-book.md +108 -0
- package/agent/docs-md/page-header.md +96 -0
- package/agent/docs-md/pagination.md +88 -0
- package/agent/docs-md/pane-layout.md +105 -0
- package/agent/docs-md/period-comparison.md +66 -0
- package/agent/docs-md/plan-card.md +120 -0
- package/agent/docs-md/popover-rules.md +88 -0
- package/agent/docs-md/prompt-editor.md +90 -0
- package/agent/docs-md/propose-apply.md +65 -0
- package/agent/docs-md/provider-logo.md +97 -0
- package/agent/docs-md/radio.md +83 -0
- package/agent/docs-md/ranked-list.md +102 -0
- package/agent/docs-md/reasoning-progress.md +72 -0
- package/agent/docs-md/record-detail.md +71 -0
- package/agent/docs-md/regenerating-answers.md +70 -0
- package/agent/docs-md/run-status-bar.md +94 -0
- package/agent/docs-md/saved-tasks-schedules.md +63 -0
- package/agent/docs-md/saved-views.md +149 -0
- package/agent/docs-md/saving-views.md +68 -0
- package/agent/docs-md/scheduler.md +258 -0
- package/agent/docs-md/secondary-panels.md +72 -0
- package/agent/docs-md/segmented-control.md +88 -0
- package/agent/docs-md/selection-bulk-actions.md +70 -0
- package/agent/docs-md/separator.md +75 -0
- package/agent/docs-md/setup-checklist.md +92 -0
- package/agent/docs-md/shape-elevation.md +55 -0
- package/agent/docs-md/sheet-grid.md +211 -0
- package/agent/docs-md/side-panel.md +134 -0
- package/agent/docs-md/sign-in.md +114 -0
- package/agent/docs-md/spacing.md +55 -0
- package/agent/docs-md/split-button.md +100 -0
- package/agent/docs-md/stat-compare.md +82 -0
- package/agent/docs-md/static-dashboard.md +75 -0
- package/agent/docs-md/status-badge.md +140 -0
- package/agent/docs-md/step-card.md +75 -0
- package/agent/docs-md/stepper.md +92 -0
- package/agent/docs-md/suggested-changes.md +91 -0
- package/agent/docs-md/switch.md +78 -0
- package/agent/docs-md/table-settings.md +81 -0
- package/agent/docs-md/tabs.md +85 -0
- package/agent/docs-md/tag-input.md +108 -0
- package/agent/docs-md/tag.md +79 -0
- package/agent/docs-md/task-builder.md +87 -0
- package/agent/docs-md/team-instructions.md +72 -0
- package/agent/docs-md/templates-gallery.md +85 -0
- package/agent/docs-md/text-input.md +160 -0
- package/agent/docs-md/thinking-steps.md +89 -0
- package/agent/docs-md/timeline.md +189 -0
- package/agent/docs-md/timestamp.md +84 -0
- package/agent/docs-md/timestamps.md +70 -0
- package/agent/docs-md/toast.md +117 -0
- package/agent/docs-md/tooltip.md +90 -0
- package/agent/docs-md/typography.md +62 -0
- package/agent/docs-md/undo-destructive.md +66 -0
- package/agent/docs-md/unsaved-changes.md +71 -0
- package/agent/docs-md/usage-meter.md +80 -0
- package/agent/docs-md/user-feedback.md +71 -0
- package/agent/docs-md/voice-and-tone.md +60 -0
- package/agent/docs-md/why-choice.md +93 -0
- package/agent/docs-md/workspace-onboarding.md +74 -0
- package/agent/docs-md/writing.md +48 -0
- package/agent/llms-full.txt +18369 -0
- package/agent/llms.txt +198 -0
- package/agent/skills/twoux-audit/SKILL.md +49 -0
- package/agent/skills/twoux-build/SKILL.md +39 -0
- package/agent/skills/twoux-design/SKILL.md +54 -0
- package/agent/skills/twoux-write/SKILL.md +32 -0
- package/bin/check.mjs +123 -0
- package/bin/docs.mjs +24 -0
- package/bin/guard.mjs +27 -0
- package/bin/init.mjs +113 -0
- package/bin/knowledge.mjs +87 -0
- package/bin/mcp.mjs +116 -0
- package/bin/theme.mjs +168 -0
- package/bin/twoux.mjs +25 -0
- package/package.json +80 -3
- package/registry/jobs.json +1028 -0
- package/registry/palette.json +770 -0
- package/registry/rules.json +913 -0
- package/src/components/agent-review.tsx +364 -0
- package/src/components/ai-basics.tsx +212 -0
- package/src/components/ai-work.tsx +304 -0
- package/src/components/ai.tsx +227 -0
- package/src/components/alert-dialog.tsx +203 -0
- package/src/components/alert.tsx +86 -0
- package/src/components/avatar.tsx +114 -0
- package/src/components/badge.tsx +59 -0
- package/src/components/board.tsx +397 -0
- package/src/components/breadcrumb.tsx +114 -0
- package/src/components/button-group.tsx +90 -0
- package/src/components/button.tsx +109 -0
- package/src/components/calendar.tsx +247 -0
- package/src/components/card.tsx +102 -0
- package/src/components/chart-map.tsx +336 -0
- package/src/components/charts-more.tsx +1331 -0
- package/src/components/charts-radial.tsx +328 -0
- package/src/components/charts.tsx +390 -0
- package/src/components/checkbox.tsx +40 -0
- package/src/components/code.tsx +139 -0
- package/src/components/collapsible.tsx +37 -0
- package/src/components/combobox.tsx +339 -0
- package/src/components/command-extras.tsx +11 -0
- package/src/components/command.tsx +196 -0
- package/src/components/data-grid.tsx +213 -0
- package/src/components/data-table.tsx +334 -0
- package/src/components/data-views.tsx +740 -0
- package/src/components/date-picker.tsx +686 -0
- package/src/components/dense-table.tsx +207 -0
- package/src/components/dialog.tsx +162 -0
- package/src/components/dropdown-menu.tsx +264 -0
- package/src/components/empty.tsx +114 -0
- package/src/components/feedback-prompt.tsx +80 -0
- package/src/components/field.tsx +254 -0
- package/src/components/fields.tsx +112 -0
- package/src/components/flow.tsx +840 -0
- package/src/components/guide-cue.tsx +273 -0
- package/src/components/inbox.tsx +113 -0
- package/src/components/input-group.tsx +176 -0
- package/src/components/input.tsx +26 -0
- package/src/components/kbd.tsx +34 -0
- package/src/components/label.tsx +27 -0
- package/src/components/labels.tsx +176 -0
- package/src/components/motion.tsx +136 -0
- package/src/components/onboarding.tsx +454 -0
- package/src/components/order-book.tsx +185 -0
- package/src/components/pane-layout.tsx +417 -0
- package/src/components/popover.tsx +96 -0
- package/src/components/provider-logos.data.ts +49 -0
- package/src/components/radio-group.tsx +52 -0
- package/src/components/scheduler.tsx +997 -0
- package/src/components/segmented-control.tsx +28 -0
- package/src/components/select.tsx +195 -0
- package/src/components/separator.tsx +31 -0
- package/src/components/sheet.tsx +148 -0
- package/src/components/shell.tsx +426 -0
- package/src/components/shortcut-sheet.tsx +83 -0
- package/src/components/skeleton.tsx +18 -0
- package/src/components/sonner.tsx +107 -0
- package/src/components/spinner.tsx +13 -0
- package/src/components/split-button.tsx +58 -0
- package/src/components/stepper.tsx +78 -0
- package/src/components/switch.tsx +43 -0
- package/src/components/table.tsx +126 -0
- package/src/components/tabs.tsx +118 -0
- package/src/components/tag-input.tsx +253 -0
- package/src/components/textarea.tsx +21 -0
- package/src/components/theme.tsx +80 -0
- package/src/components/timeline.tsx +408 -0
- package/src/components/toggle-group.tsx +87 -0
- package/src/components/toggle.tsx +54 -0
- package/src/components/tooltip.tsx +65 -0
- package/src/components/workspace-actions.tsx +294 -0
- package/src/components/workspace-import.tsx +465 -0
- package/src/components/workspace.tsx +1884 -0
- package/src/index.ts +80 -0
- package/src/lib/active-indicator.tsx +53 -0
- package/src/lib/chart-kit.tsx +72 -0
- package/src/lib/cn.ts +6 -0
- package/src/lib/shortcuts.tsx +61 -0
- package/src/lib/workspace.tsx +10 -0
- package/src/shadcn/alert-dialog.tsx +196 -0
- package/src/shadcn/alert.tsx +65 -0
- package/src/shadcn/avatar.tsx +108 -0
- package/src/shadcn/badge.tsx +47 -0
- package/src/shadcn/breadcrumb.tsx +108 -0
- package/src/shadcn/button-group.tsx +83 -0
- package/src/shadcn/button.tsx +63 -0
- package/src/shadcn/calendar.tsx +220 -0
- package/src/shadcn/card.tsx +91 -0
- package/src/shadcn/checkbox.tsx +31 -0
- package/src/shadcn/collapsible.tsx +33 -0
- package/src/shadcn/command.tsx +184 -0
- package/src/shadcn/dialog.tsx +158 -0
- package/src/shadcn/dropdown-menu.tsx +256 -0
- package/src/shadcn/empty.tsx +103 -0
- package/src/shadcn/field.tsx +248 -0
- package/src/shadcn/input-group.tsx +170 -0
- package/src/shadcn/input.tsx +20 -0
- package/src/shadcn/kbd.tsx +28 -0
- package/src/shadcn/label.tsx +23 -0
- package/src/shadcn/popover.tsx +88 -0
- package/src/shadcn/radio-group.tsx +44 -0
- package/src/shadcn/select.tsx +189 -0
- package/src/shadcn/separator.tsx +27 -0
- package/src/shadcn/sheet.tsx +142 -0
- package/src/shadcn/skeleton.tsx +13 -0
- package/src/shadcn/sonner.tsx +40 -0
- package/src/shadcn/switch.tsx +34 -0
- package/src/shadcn/table.tsx +115 -0
- package/src/shadcn/tabs.tsx +90 -0
- package/src/shadcn/textarea.tsx +17 -0
- package/src/shadcn/toggle-group.tsx +83 -0
- package/src/shadcn/toggle.tsx +46 -0
- package/src/shadcn/tooltip.tsx +56 -0
- package/src/styles/palette.css +127 -0
- package/src/styles/theme.css +35 -0
- package/src/styles/twoux.css +236 -0
- package/theme.json +14 -0
- 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
|
+
}
|