@devalok/shilp-sutra 0.49.5 → 0.50.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/AGENTS.md +12 -4
- package/MIGRATION.md +6 -0
- package/dist/_chunks/badge-group.js +4 -4
- package/dist/_chunks/badge-group.js.map +1 -1
- package/dist/_chunks/block-shell.js +1 -1
- package/dist/_chunks/block-shell.js.map +1 -1
- package/dist/_chunks/chat.js +18 -18
- package/dist/_chunks/chat.js.map +1 -1
- package/dist/_chunks/document-preview.js +1 -1
- package/dist/_chunks/document-preview.js.map +1 -1
- package/dist/_chunks/emoji-suggestion.js +1 -1
- package/dist/_chunks/emoji-suggestion.js.map +1 -1
- package/dist/_chunks/grid-lines.js +2 -2
- package/dist/_chunks/grid-lines.js.map +1 -1
- package/dist/_chunks/image-preview.js +1 -1
- package/dist/_chunks/image-preview.js.map +1 -1
- package/dist/_chunks/mention-suggestion.js +2 -2
- package/dist/_chunks/mention-suggestion.js.map +1 -1
- package/dist/_chunks/oauth-button.js +8 -8
- package/dist/_chunks/oauth-button.js.map +1 -1
- package/dist/_chunks/shared.js +2 -2
- package/dist/_chunks/shared.js.map +1 -1
- package/dist/_chunks/success.js +5 -5
- package/dist/_chunks/success.js.map +1 -1
- package/dist/_chunks/tiptap.js +3956 -1796
- package/dist/_chunks/tiptap.js.map +1 -1
- package/dist/_chunks/tooltip.js +2 -2
- package/dist/_chunks/tooltip.js.map +1 -1
- package/dist/_chunks/tree-view.js +2 -2
- package/dist/_chunks/tree-view.js.map +1 -1
- package/dist/_chunks/use-calendar.js +3 -3
- package/dist/_chunks/use-calendar.js.map +1 -1
- package/dist/ai/block-renderer.js +1 -1
- package/dist/ai/block-renderer.js.map +1 -1
- package/dist/ai/blocks/error.js +1 -1
- package/dist/ai/blocks/error.js.map +1 -1
- package/dist/ai/command-bar.js +15 -15
- package/dist/ai/command-bar.js.map +1 -1
- package/dist/ai/conversation.js +6 -6
- package/dist/ai/conversation.js.map +1 -1
- package/dist/composed/activity-feed.js +4 -4
- package/dist/composed/activity-feed.js.map +1 -1
- package/dist/composed/avatar-group.js +6 -6
- package/dist/composed/avatar-group.js.map +1 -1
- package/dist/composed/bulk-action-bar.js +1 -1
- package/dist/composed/bulk-action-bar.js.map +1 -1
- package/dist/composed/command-palette.js +12 -12
- package/dist/composed/command-palette.js.map +1 -1
- package/dist/composed/content-card.js +1 -1
- package/dist/composed/content-card.js.map +1 -1
- package/dist/composed/date-picker/index.js +17 -17
- package/dist/composed/date-picker/index.js.map +1 -1
- package/dist/composed/deadline-indicator.js +2 -2
- package/dist/composed/deadline-indicator.js.map +1 -1
- package/dist/composed/diff.d.ts +108 -0
- package/dist/composed/diff.d.ts.map +1 -0
- package/dist/composed/diff.js +1004 -0
- package/dist/composed/diff.js.map +1 -0
- package/dist/composed/emoji-picker.js +6 -6
- package/dist/composed/emoji-picker.js.map +1 -1
- package/dist/composed/empty-state.js +2 -2
- package/dist/composed/empty-state.js.map +1 -1
- package/dist/composed/error-boundary.js +6 -6
- package/dist/composed/error-boundary.js.map +1 -1
- package/dist/composed/file-preview.js +5 -5
- package/dist/composed/file-preview.js.map +1 -1
- package/dist/composed/filter-bar.js +3 -3
- package/dist/composed/filter-bar.js.map +1 -1
- package/dist/composed/form-section.js +2 -2
- package/dist/composed/form-section.js.map +1 -1
- package/dist/composed/inline-edit.d.ts +1 -1
- package/dist/composed/inline-edit.d.ts.map +1 -1
- package/dist/composed/inline-edit.js.map +1 -1
- package/dist/composed/loading-skeleton.js +3 -3
- package/dist/composed/loading-skeleton.js.map +1 -1
- package/dist/composed/markdown-viewer.js +11 -11
- package/dist/composed/markdown-viewer.js.map +1 -1
- package/dist/composed/master-detail.js +1 -1
- package/dist/composed/master-detail.js.map +1 -1
- package/dist/composed/member-picker.js +2 -2
- package/dist/composed/member-picker.js.map +1 -1
- package/dist/composed/multi-select-popover.js +5 -5
- package/dist/composed/multi-select-popover.js.map +1 -1
- package/dist/composed/page-header.js +3 -3
- package/dist/composed/page-header.js.map +1 -1
- package/dist/composed/page-skeletons.js +4 -4
- package/dist/composed/page-skeletons.js.map +1 -1
- package/dist/composed/priority-indicator.js +1 -1
- package/dist/composed/priority-indicator.js.map +1 -1
- package/dist/composed/responsive-modal.js +2 -2
- package/dist/composed/responsive-modal.js.map +1 -1
- package/dist/composed/rich-chat-input.js +27 -27
- package/dist/composed/rich-chat-input.js.map +1 -1
- package/dist/composed/rich-text-editor.d.ts +81 -6
- package/dist/composed/rich-text-editor.d.ts.map +1 -1
- package/dist/composed/rich-text-editor.js +365 -210
- package/dist/composed/rich-text-editor.js.map +1 -1
- package/dist/composed/schedule-view.js +4 -4
- package/dist/composed/schedule-view.js.map +1 -1
- package/dist/shell/bottom-navbar.js +4 -4
- package/dist/shell/bottom-navbar.js.map +1 -1
- package/dist/shell/notification-center.js +13 -13
- package/dist/shell/notification-center.js.map +1 -1
- package/dist/shell/notification-preferences.js +10 -10
- package/dist/shell/notification-preferences.js.map +1 -1
- package/dist/shell/sidebar.js +9 -9
- package/dist/shell/sidebar.js.map +1 -1
- package/dist/shell/top-bar.js +8 -8
- package/dist/shell/top-bar.js.map +1 -1
- package/dist/tokens/semantic.css +6 -1
- package/dist/tokens/typography-semantic.css +6 -6
- package/dist/tokens/utilities.css +8 -0
- package/dist/ui/accordion.js +2 -2
- package/dist/ui/accordion.js.map +1 -1
- package/dist/ui/alert-dialog.js +4 -4
- package/dist/ui/alert-dialog.js.map +1 -1
- package/dist/ui/alert.js +1 -1
- package/dist/ui/alert.js.map +1 -1
- package/dist/ui/autocomplete.js +3 -3
- package/dist/ui/autocomplete.js.map +1 -1
- package/dist/ui/avatar.js +5 -5
- package/dist/ui/avatar.js.map +1 -1
- package/dist/ui/banner.js +1 -1
- package/dist/ui/banner.js.map +1 -1
- package/dist/ui/breadcrumb.js +1 -1
- package/dist/ui/breadcrumb.js.map +1 -1
- package/dist/ui/button.js +7 -7
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/card.d.ts +1 -1
- package/dist/ui/card.js +1 -1
- package/dist/ui/card.js.map +1 -1
- package/dist/ui/charts/gauge-chart.js +2 -2
- package/dist/ui/charts/gauge-chart.js.map +1 -1
- package/dist/ui/charts/pie-chart.js +1 -1
- package/dist/ui/charts/pie-chart.js.map +1 -1
- package/dist/ui/charts/radar-chart.d.ts +19 -1
- package/dist/ui/charts/radar-chart.d.ts.map +1 -1
- package/dist/ui/charts/radar-chart.js +80 -42
- package/dist/ui/charts/radar-chart.js.map +1 -1
- package/dist/ui/code.js +2 -2
- package/dist/ui/code.js.map +1 -1
- package/dist/ui/color-input.js +9 -9
- package/dist/ui/color-input.js.map +1 -1
- package/dist/ui/combobox.js +16 -16
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/context-menu.js +6 -6
- package/dist/ui/context-menu.js.map +1 -1
- package/dist/ui/data-table-body.js +1 -1
- package/dist/ui/data-table-body.js.map +1 -1
- package/dist/ui/data-table-bulk-actions.js +1 -1
- package/dist/ui/data-table-bulk-actions.js.map +1 -1
- package/dist/ui/data-table-card.js +1 -1
- package/dist/ui/data-table-card.js.map +1 -1
- package/dist/ui/data-table-header.js +1 -1
- package/dist/ui/data-table-header.js.map +1 -1
- package/dist/ui/data-table-pagination.js +3 -3
- package/dist/ui/data-table-pagination.js.map +1 -1
- package/dist/ui/data-table-toolbar.js +1 -1
- package/dist/ui/data-table-toolbar.js.map +1 -1
- package/dist/ui/data-table.js +1 -1
- package/dist/ui/data-table.js.map +1 -1
- package/dist/ui/dialog.js +2 -2
- package/dist/ui/dialog.js.map +1 -1
- package/dist/ui/dot.js +4 -4
- package/dist/ui/dot.js.map +1 -1
- package/dist/ui/dropdown-menu.js +6 -6
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/dist/ui/file-upload.js +5 -5
- package/dist/ui/file-upload.js.map +1 -1
- package/dist/ui/form.js +1 -1
- package/dist/ui/form.js.map +1 -1
- package/dist/ui/input-otp.d.ts.map +1 -1
- package/dist/ui/input-otp.js +3 -3
- package/dist/ui/input-otp.js.map +1 -1
- package/dist/ui/input.js +8 -8
- package/dist/ui/input.js.map +1 -1
- package/dist/ui/label.js +1 -1
- package/dist/ui/label.js.map +1 -1
- package/dist/ui/lib/utils.d.ts.map +1 -1
- package/dist/ui/lib/utils.js +42 -13
- package/dist/ui/lib/utils.js.map +1 -1
- package/dist/ui/menubar.js +7 -7
- package/dist/ui/menubar.js.map +1 -1
- package/dist/ui/navigation-menu.js +1 -1
- package/dist/ui/navigation-menu.js.map +1 -1
- package/dist/ui/number-input.js +4 -4
- package/dist/ui/number-input.js.map +1 -1
- package/dist/ui/pagination.js +1 -1
- package/dist/ui/pagination.js.map +1 -1
- package/dist/ui/progress-ring.js +3 -3
- package/dist/ui/progress-ring.js.map +1 -1
- package/dist/ui/progress.js +2 -2
- package/dist/ui/progress.js.map +1 -1
- package/dist/ui/segmented-control.js +3 -3
- package/dist/ui/segmented-control.js.map +1 -1
- package/dist/ui/select.js +6 -6
- package/dist/ui/select.js.map +1 -1
- package/dist/ui/sheet.js +2 -2
- package/dist/ui/sheet.js.map +1 -1
- package/dist/ui/sidebar.js +7 -7
- package/dist/ui/sidebar.js.map +1 -1
- package/dist/ui/split-button.js +6 -6
- package/dist/ui/split-button.js.map +1 -1
- package/dist/ui/stat-card.d.ts +1 -1
- package/dist/ui/stat-card.js +7 -7
- package/dist/ui/stat-card.js.map +1 -1
- package/dist/ui/stepper.js +3 -3
- package/dist/ui/stepper.js.map +1 -1
- package/dist/ui/table.js +3 -3
- package/dist/ui/table.js.map +1 -1
- package/dist/ui/tabs.js +3 -3
- package/dist/ui/tabs.js.map +1 -1
- package/dist/ui/text.d.ts.map +1 -1
- package/dist/ui/text.js.map +1 -1
- package/dist/ui/textarea.js +4 -4
- package/dist/ui/textarea.js.map +1 -1
- package/dist/ui/toast.js +11 -11
- package/dist/ui/toast.js.map +1 -1
- package/dist/ui/toggle.js +3 -3
- package/dist/ui/toggle.js.map +1 -1
- package/dist/ui/tooltip.js +1 -1
- package/dist/ui/tooltip.js.map +1 -1
- package/docs/components/composed/diff.md +50 -0
- package/llms.txt +2 -1
- package/mcp-manifest.json +145 -1
- package/package.json +8 -1
- package/skill/SKILL.md +1 -1
- package/skill/references/components.md +2 -1
package/dist/ui/stepper.js
CHANGED
|
@@ -42,7 +42,7 @@ var u = i.createContext({
|
|
|
42
42
|
});
|
|
43
43
|
}), f = i.forwardRef(({ label: t, description: c, icon: l, className: d, ...f }, p) => {
|
|
44
44
|
let { _index: m = 0, ...h } = f, { activeStep: g, orientation: _, stepperId: v, onStepClick: y } = i.useContext(u), b = m < g ? "completed" : m === g ? "active" : "pending", x = b === "completed" && !!y, S = /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o("div", {
|
|
45
|
-
className: n("relative shrink-0 flex items-center justify-center w-ds-sm h-ds-sm rounded-pill text-
|
|
45
|
+
className: n("relative shrink-0 flex items-center justify-center w-ds-sm h-ds-sm rounded-pill text-body-sm font-semibold", "transition-[background-color,border-color,color] duration-moderate-01 ease-productive-standard", b === "completed" && "bg-accent-9 text-accent-fg", b === "active" && "bg-accent-9 text-accent-fg", b === "pending" && "bg-surface-raised text-surface-fg-subtle border border-surface-border-strong"),
|
|
46
46
|
children: l ? /* @__PURE__ */ o(e, {
|
|
47
47
|
size: "sm",
|
|
48
48
|
children: r(l)
|
|
@@ -59,10 +59,10 @@ var u = i.createContext({
|
|
|
59
59
|
}), /* @__PURE__ */ s("div", {
|
|
60
60
|
className: "flex flex-col",
|
|
61
61
|
children: [/* @__PURE__ */ o("span", {
|
|
62
|
-
className: n("text-
|
|
62
|
+
className: n("text-body-md font-medium leading-ds-snug", b === "pending" ? "text-surface-fg-subtle" : "text-surface-fg"),
|
|
63
63
|
children: t
|
|
64
64
|
}), c && /* @__PURE__ */ o("span", {
|
|
65
|
-
className: "text-
|
|
65
|
+
className: "text-body-sm text-surface-fg-muted leading-ds-relaxed",
|
|
66
66
|
children: c
|
|
67
67
|
})]
|
|
68
68
|
})] });
|
package/dist/ui/stepper.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stepper.js","names":[],"sources":["../../src/ui/stepper.tsx"],"sourcesContent":["'use client'\n\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { IconProvider } from './icon-context'\nimport type { IconInput } from './lib/icon-input'\nimport { springs } from './lib/motion'\nimport { normalizeIcon } from './lib/normalize-icon'\nimport { cn } from './lib/utils'\n\ntype StepState = 'completed' | 'active' | 'pending'\n\ntype StepperContextValue = {\n activeStep: number\n orientation: 'horizontal' | 'vertical'\n stepperId: string\n onStepClick?: (stepIndex: number) => void\n}\n\nconst StepperContext = React.createContext<StepperContextValue>({\n activeStep: 0,\n orientation: 'horizontal',\n stepperId: '',\n})\n\n/**\n * Props for Stepper — a multi-step progress indicator that renders a connected series of `<Step>`\n * children with connector lines, showing completed/active/pending states automatically.\n *\n * **`activeStep`:** 0-indexed. Step at `activeStep` is \"active\", steps before it are \"completed\",\n * steps after it are \"pending\". Update this value to advance the stepper.\n *\n * **Orientation:** `'horizontal'` (default, left-to-right) | `'vertical'` (top-to-bottom, for sidebars).\n *\n * **Children:** Must be `<Step>` components. The Stepper injects `_index` into each child automatically.\n *\n * @example\n * // Horizontal 3-step form wizard:\n * <Stepper activeStep={currentStep}>\n * <Step label=\"Account\" description=\"Create your credentials\" />\n * <Step label=\"Profile\" description=\"Add your details\" />\n * <Step label=\"Review\" description=\"Confirm and submit\" />\n * </Stepper>\n *\n * @example\n * // Vertical onboarding checklist in a sidebar:\n * <Stepper activeStep={completedSteps} orientation=\"vertical\">\n * <Step label=\"Connect workspace\" />\n * <Step label=\"Invite teammates\" />\n * <Step label=\"Set up billing\" />\n * </Stepper>\n *\n * @example\n * // Clickable completed steps — user can navigate back:\n * <Stepper activeStep={step} onStepClick={(i) => setStep(i)}>\n * <Step label=\"Account\" />\n * <Step label=\"Profile\" />\n * <Step label=\"Review\" />\n * </Stepper>\n * // These are just a few ways — feel free to combine props creatively!\n */\ninterface StepperProps extends React.HTMLAttributes<HTMLDivElement> {\n activeStep: number\n orientation?: 'horizontal' | 'vertical'\n /** Called when a completed step is clicked. Receives the 0-based step index. */\n onStepClick?: (stepIndex: number) => void\n children: React.ReactNode\n}\n\nconst Stepper = React.forwardRef<HTMLDivElement, StepperProps>(\n ({ activeStep, orientation = 'horizontal', onStepClick, className, children, ...props }, ref) => {\n const steps = React.Children.toArray(children)\n const stepperId = React.useId()\n const contextValue = React.useMemo(\n () => ({ activeStep, orientation, stepperId, onStepClick }),\n [activeStep, orientation, stepperId, onStepClick],\n )\n return (\n <StepperContext.Provider value={contextValue}>\n <div\n ref={ref}\n className={cn(\n 'flex gap-ds-02',\n orientation === 'vertical' ? 'flex-col' : 'flex-row items-center',\n className,\n )}\n role=\"list\"\n {...props}\n >\n {steps.map((child, index) => (\n <React.Fragment key={index}>\n {React.isValidElement<StepInternalProps>(child)\n ? React.cloneElement(child, { _index: index })\n : child}\n {index < steps.length - 1 && (\n <div\n className={cn(\n 'relative flex-1 overflow-hidden',\n orientation === 'vertical'\n ? 'ml-ds-04 w-ds-01 min-h-ds-05'\n : 'h-ds-01 min-w-ds-05',\n 'bg-surface-border',\n )}\n aria-hidden=\"true\"\n >\n {/* Filled portion — smooth CSS transition */}\n <div\n className={cn(\n 'absolute inset-0 bg-accent-9 transition-transform duration-moderate-02 ease-productive-standard',\n orientation === 'vertical' ? 'origin-top' : 'origin-left',\n )}\n style={{\n transform: `${orientation === 'vertical' ? 'scaleY' : 'scaleX'}(${index < activeStep ? 1 : 0})`,\n }}\n />\n </div>\n )}\n </React.Fragment>\n ))}\n </div>\n </StepperContext.Provider>\n )\n },\n)\n\n/**\n * Props for Step — a single step within a `<Stepper>`. The visual state (completed/active/pending)\n * is derived from the parent Stepper's `activeStep` and this step's position — you don't set it manually.\n *\n * @example\n * // Basic step with label and description:\n * <Step label=\"Payment\" description=\"Enter your card details\" />\n *\n * @example\n * // Step with a custom icon (overrides the default number/checkmark):\n * <Step label=\"Verified\" icon={<IconShieldCheck className=\"h-ico-sm w-ico-sm\" />} />\n */\ninterface StepProps extends React.HTMLAttributes<HTMLDivElement> {\n label: string\n description?: string\n icon?: IconInput\n}\n\ntype StepInternalProps = StepProps & { _index?: number }\n\nconst Step = React.forwardRef<HTMLDivElement, StepProps>(\n ({ label, description, icon, className, ...props }, ref) => {\n const { _index = 0, ...restProps } = props as StepInternalProps\n const { activeStep, orientation, stepperId, onStepClick } = React.useContext(StepperContext)\n const state: StepState = _index < activeStep ? 'completed' : _index === activeStep ? 'active' : 'pending'\n const isClickable = state === 'completed' && !!onStepClick\n\n const stepContent = (\n <>\n <div\n className={cn(\n 'relative shrink-0 flex items-center justify-center w-ds-sm h-ds-sm rounded-pill text-ds-sm font-semibold',\n 'transition-[background-color,border-color,color] duration-moderate-01 ease-productive-standard',\n state === 'completed' && 'bg-accent-9 text-accent-fg',\n state === 'active' && 'bg-accent-9 text-accent-fg',\n state === 'pending' && 'bg-surface-raised text-surface-fg-subtle border border-surface-border-strong',\n )}\n >\n {icon ? <IconProvider size=\"sm\">{normalizeIcon(icon)}</IconProvider> : (state === 'completed' ? (\n <svg\n className=\"w-ico-sm h-ico-sm\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n ) : (\n _index + 1\n ))}\n </div>\n <div className=\"flex flex-col\">\n <span\n className={cn(\n 'text-ds-md font-medium leading-ds-snug',\n state === 'pending'\n ? 'text-surface-fg-subtle'\n : 'text-surface-fg',\n )}\n >\n {label}\n </span>\n {description && (\n <span className=\"text-ds-sm text-surface-fg-muted leading-ds-relaxed\">\n {description}\n </span>\n )}\n </div>\n </>\n )\n\n if (isClickable) {\n return (\n <div\n ref={ref}\n data-step=\"\"\n data-state={state}\n role=\"listitem\"\n className={cn(\n orientation === 'vertical' && 'py-ds-02',\n className,\n )}\n {...restProps}\n >\n <button\n type=\"button\"\n tabIndex={0}\n aria-label={`Go to step ${_index + 1}: ${label}`}\n onClick={() => onStepClick(_index)}\n className={cn(\n 'flex items-center gap-ds-03 cursor-pointer select-none',\n 'rounded-control px-ds-02 py-ds-01 -mx-ds-02 -my-ds-01',\n 'bg-transparent border-0',\n 'hover:bg-surface-raised-hover active:bg-surface-raised-active',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-8 focus-visible:ring-offset-2',\n 'transition-colors duration-fast-01 ease-productive-standard',\n )}\n >\n {stepContent}\n </button>\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n data-step=\"\"\n data-state={state}\n role=\"listitem\"\n aria-current={state === 'active' ? 'step' : undefined}\n aria-label={`Step ${_index + 1}: ${label}, ${state === 'completed' ? 'completed' : state === 'active' ? 'current' : 'upcoming'}`}\n className={cn(\n 'flex items-center gap-ds-03',\n orientation === 'vertical' && 'py-ds-02',\n className,\n )}\n {...restProps}\n >\n {stepContent}\n </div>\n )\n },\n)\n\n/**\n * Props for StepperContent — wraps the content panel for the active step, animating\n * slide transitions when `activeStep` changes. Detects forward vs backward navigation\n * and slides content accordingly.\n *\n * @example\n * <StepperContent activeStep={currentStep}>\n * {currentStep === 0 && <AccountForm />}\n * {currentStep === 1 && <ProfileForm />}\n * {currentStep === 2 && <ReviewPanel />}\n * </StepperContent>\n */\ninterface StepperContentProps {\n activeStep: number\n children: React.ReactNode\n className?: string\n}\n\nconst SLIDE_OFFSET = 40\n\nconst stepContentVariants = {\n enter: (direction: number) => ({\n opacity: 0,\n x: direction * SLIDE_OFFSET,\n }),\n center: {\n opacity: 1,\n x: 0,\n },\n exit: (direction: number) => ({\n opacity: 0,\n x: direction * -SLIDE_OFFSET,\n }),\n}\n\nfunction StepperContent({ activeStep, children, className }: StepperContentProps) {\n const prevStepRef = React.useRef(activeStep)\n const direction = activeStep >= prevStepRef.current ? 1 : -1\n\n React.useEffect(() => {\n prevStepRef.current = activeStep\n }, [activeStep])\n\n return (\n <div className={cn('relative overflow-hidden', className)}>\n <AnimatePresence mode=\"wait\" custom={direction}>\n <motion.div\n key={activeStep}\n custom={direction}\n variants={stepContentVariants}\n initial=\"enter\"\n animate=\"center\"\n exit=\"exit\"\n transition={springs.smooth}\n >\n {children}\n </motion.div>\n </AnimatePresence>\n </div>\n )\n}\n\nStepper.displayName = 'Stepper'\nStep.displayName = 'Step'\nStepperContent.displayName = 'StepperContent'\n\nexport { Step, Stepper, StepperContent, type StepperContentProps,type StepperProps, type StepProps }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stepper.js","names":[],"sources":["../../src/ui/stepper.tsx"],"sourcesContent":["'use client'\n\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { IconProvider } from './icon-context'\nimport type { IconInput } from './lib/icon-input'\nimport { springs } from './lib/motion'\nimport { normalizeIcon } from './lib/normalize-icon'\nimport { cn } from './lib/utils'\n\ntype StepState = 'completed' | 'active' | 'pending'\n\ntype StepperContextValue = {\n activeStep: number\n orientation: 'horizontal' | 'vertical'\n stepperId: string\n onStepClick?: (stepIndex: number) => void\n}\n\nconst StepperContext = React.createContext<StepperContextValue>({\n activeStep: 0,\n orientation: 'horizontal',\n stepperId: '',\n})\n\n/**\n * Props for Stepper — a multi-step progress indicator that renders a connected series of `<Step>`\n * children with connector lines, showing completed/active/pending states automatically.\n *\n * **`activeStep`:** 0-indexed. Step at `activeStep` is \"active\", steps before it are \"completed\",\n * steps after it are \"pending\". Update this value to advance the stepper.\n *\n * **Orientation:** `'horizontal'` (default, left-to-right) | `'vertical'` (top-to-bottom, for sidebars).\n *\n * **Children:** Must be `<Step>` components. The Stepper injects `_index` into each child automatically.\n *\n * @example\n * // Horizontal 3-step form wizard:\n * <Stepper activeStep={currentStep}>\n * <Step label=\"Account\" description=\"Create your credentials\" />\n * <Step label=\"Profile\" description=\"Add your details\" />\n * <Step label=\"Review\" description=\"Confirm and submit\" />\n * </Stepper>\n *\n * @example\n * // Vertical onboarding checklist in a sidebar:\n * <Stepper activeStep={completedSteps} orientation=\"vertical\">\n * <Step label=\"Connect workspace\" />\n * <Step label=\"Invite teammates\" />\n * <Step label=\"Set up billing\" />\n * </Stepper>\n *\n * @example\n * // Clickable completed steps — user can navigate back:\n * <Stepper activeStep={step} onStepClick={(i) => setStep(i)}>\n * <Step label=\"Account\" />\n * <Step label=\"Profile\" />\n * <Step label=\"Review\" />\n * </Stepper>\n * // These are just a few ways — feel free to combine props creatively!\n */\ninterface StepperProps extends React.HTMLAttributes<HTMLDivElement> {\n activeStep: number\n orientation?: 'horizontal' | 'vertical'\n /** Called when a completed step is clicked. Receives the 0-based step index. */\n onStepClick?: (stepIndex: number) => void\n children: React.ReactNode\n}\n\nconst Stepper = React.forwardRef<HTMLDivElement, StepperProps>(\n ({ activeStep, orientation = 'horizontal', onStepClick, className, children, ...props }, ref) => {\n const steps = React.Children.toArray(children)\n const stepperId = React.useId()\n const contextValue = React.useMemo(\n () => ({ activeStep, orientation, stepperId, onStepClick }),\n [activeStep, orientation, stepperId, onStepClick],\n )\n return (\n <StepperContext.Provider value={contextValue}>\n <div\n ref={ref}\n className={cn(\n 'flex gap-ds-02',\n orientation === 'vertical' ? 'flex-col' : 'flex-row items-center',\n className,\n )}\n role=\"list\"\n {...props}\n >\n {steps.map((child, index) => (\n <React.Fragment key={index}>\n {React.isValidElement<StepInternalProps>(child)\n ? React.cloneElement(child, { _index: index })\n : child}\n {index < steps.length - 1 && (\n <div\n className={cn(\n 'relative flex-1 overflow-hidden',\n orientation === 'vertical'\n ? 'ml-ds-04 w-ds-01 min-h-ds-05'\n : 'h-ds-01 min-w-ds-05',\n 'bg-surface-border',\n )}\n aria-hidden=\"true\"\n >\n {/* Filled portion — smooth CSS transition */}\n <div\n className={cn(\n 'absolute inset-0 bg-accent-9 transition-transform duration-moderate-02 ease-productive-standard',\n orientation === 'vertical' ? 'origin-top' : 'origin-left',\n )}\n style={{\n transform: `${orientation === 'vertical' ? 'scaleY' : 'scaleX'}(${index < activeStep ? 1 : 0})`,\n }}\n />\n </div>\n )}\n </React.Fragment>\n ))}\n </div>\n </StepperContext.Provider>\n )\n },\n)\n\n/**\n * Props for Step — a single step within a `<Stepper>`. The visual state (completed/active/pending)\n * is derived from the parent Stepper's `activeStep` and this step's position — you don't set it manually.\n *\n * @example\n * // Basic step with label and description:\n * <Step label=\"Payment\" description=\"Enter your card details\" />\n *\n * @example\n * // Step with a custom icon (overrides the default number/checkmark):\n * <Step label=\"Verified\" icon={<IconShieldCheck className=\"h-ico-sm w-ico-sm\" />} />\n */\ninterface StepProps extends React.HTMLAttributes<HTMLDivElement> {\n label: string\n description?: string\n icon?: IconInput\n}\n\ntype StepInternalProps = StepProps & { _index?: number }\n\nconst Step = React.forwardRef<HTMLDivElement, StepProps>(\n ({ label, description, icon, className, ...props }, ref) => {\n const { _index = 0, ...restProps } = props as StepInternalProps\n const { activeStep, orientation, stepperId, onStepClick } = React.useContext(StepperContext)\n const state: StepState = _index < activeStep ? 'completed' : _index === activeStep ? 'active' : 'pending'\n const isClickable = state === 'completed' && !!onStepClick\n\n const stepContent = (\n <>\n <div\n className={cn(\n 'relative shrink-0 flex items-center justify-center w-ds-sm h-ds-sm rounded-pill text-body-sm font-semibold',\n 'transition-[background-color,border-color,color] duration-moderate-01 ease-productive-standard',\n state === 'completed' && 'bg-accent-9 text-accent-fg',\n state === 'active' && 'bg-accent-9 text-accent-fg',\n state === 'pending' && 'bg-surface-raised text-surface-fg-subtle border border-surface-border-strong',\n )}\n >\n {icon ? <IconProvider size=\"sm\">{normalizeIcon(icon)}</IconProvider> : (state === 'completed' ? (\n <svg\n className=\"w-ico-sm h-ico-sm\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n ) : (\n _index + 1\n ))}\n </div>\n <div className=\"flex flex-col\">\n <span\n className={cn(\n 'text-body-md font-medium leading-ds-snug',\n state === 'pending'\n ? 'text-surface-fg-subtle'\n : 'text-surface-fg',\n )}\n >\n {label}\n </span>\n {description && (\n <span className=\"text-body-sm text-surface-fg-muted leading-ds-relaxed\">\n {description}\n </span>\n )}\n </div>\n </>\n )\n\n if (isClickable) {\n return (\n <div\n ref={ref}\n data-step=\"\"\n data-state={state}\n role=\"listitem\"\n className={cn(\n orientation === 'vertical' && 'py-ds-02',\n className,\n )}\n {...restProps}\n >\n <button\n type=\"button\"\n tabIndex={0}\n aria-label={`Go to step ${_index + 1}: ${label}`}\n onClick={() => onStepClick(_index)}\n className={cn(\n 'flex items-center gap-ds-03 cursor-pointer select-none',\n 'rounded-control px-ds-02 py-ds-01 -mx-ds-02 -my-ds-01',\n 'bg-transparent border-0',\n 'hover:bg-surface-raised-hover active:bg-surface-raised-active',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-8 focus-visible:ring-offset-2',\n 'transition-colors duration-fast-01 ease-productive-standard',\n )}\n >\n {stepContent}\n </button>\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n data-step=\"\"\n data-state={state}\n role=\"listitem\"\n aria-current={state === 'active' ? 'step' : undefined}\n aria-label={`Step ${_index + 1}: ${label}, ${state === 'completed' ? 'completed' : state === 'active' ? 'current' : 'upcoming'}`}\n className={cn(\n 'flex items-center gap-ds-03',\n orientation === 'vertical' && 'py-ds-02',\n className,\n )}\n {...restProps}\n >\n {stepContent}\n </div>\n )\n },\n)\n\n/**\n * Props for StepperContent — wraps the content panel for the active step, animating\n * slide transitions when `activeStep` changes. Detects forward vs backward navigation\n * and slides content accordingly.\n *\n * @example\n * <StepperContent activeStep={currentStep}>\n * {currentStep === 0 && <AccountForm />}\n * {currentStep === 1 && <ProfileForm />}\n * {currentStep === 2 && <ReviewPanel />}\n * </StepperContent>\n */\ninterface StepperContentProps {\n activeStep: number\n children: React.ReactNode\n className?: string\n}\n\nconst SLIDE_OFFSET = 40\n\nconst stepContentVariants = {\n enter: (direction: number) => ({\n opacity: 0,\n x: direction * SLIDE_OFFSET,\n }),\n center: {\n opacity: 1,\n x: 0,\n },\n exit: (direction: number) => ({\n opacity: 0,\n x: direction * -SLIDE_OFFSET,\n }),\n}\n\nfunction StepperContent({ activeStep, children, className }: StepperContentProps) {\n const prevStepRef = React.useRef(activeStep)\n const direction = activeStep >= prevStepRef.current ? 1 : -1\n\n React.useEffect(() => {\n prevStepRef.current = activeStep\n }, [activeStep])\n\n return (\n <div className={cn('relative overflow-hidden', className)}>\n <AnimatePresence mode=\"wait\" custom={direction}>\n <motion.div\n key={activeStep}\n custom={direction}\n variants={stepContentVariants}\n initial=\"enter\"\n animate=\"center\"\n exit=\"exit\"\n transition={springs.smooth}\n >\n {children}\n </motion.div>\n </AnimatePresence>\n </div>\n )\n}\n\nStepper.displayName = 'Stepper'\nStep.displayName = 'Step'\nStepperContent.displayName = 'StepperContent'\n\nexport { Step, Stepper, StepperContent, type StepperContentProps,type StepperProps, type StepProps }\n"],"mappings":"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"}
|
package/dist/ui/table.js
CHANGED
|
@@ -10,7 +10,7 @@ var r = {
|
|
|
10
10
|
className: "relative w-full overflow-auto",
|
|
11
11
|
children: /* @__PURE__ */ n("table", {
|
|
12
12
|
ref: s,
|
|
13
|
-
className: e("w-full caption-bottom text-
|
|
13
|
+
className: e("w-full caption-bottom text-body-md overflow-x-clip [--table-edge:var(--card-spacing,var(--spacing-ds-04))]", r[i], a && "[&_tbody_tr:nth-child(even)]:bg-surface-base", t),
|
|
14
14
|
...o
|
|
15
15
|
})
|
|
16
16
|
}));
|
|
@@ -42,7 +42,7 @@ c.displayName = "TableRow";
|
|
|
42
42
|
var l = t.forwardRef(({ className: t, numeric: r, ...i }, a) => /* @__PURE__ */ n("th", {
|
|
43
43
|
ref: a,
|
|
44
44
|
scope: "col",
|
|
45
|
-
className: e("py-(--table-py) px-ds-04 first:pl-(--table-edge) last:pr-(--table-edge) text-left align-middle text-
|
|
45
|
+
className: e("py-(--table-py) px-ds-04 first:pl-(--table-edge) last:pr-(--table-edge) text-left align-middle text-body-sm font-medium text-surface-fg-muted [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", r && "text-right", t),
|
|
46
46
|
...i
|
|
47
47
|
}));
|
|
48
48
|
l.displayName = "TableHead";
|
|
@@ -60,7 +60,7 @@ var d = t.forwardRef(({ className: t, persist: r, ...i }, a) => /* @__PURE__ */
|
|
|
60
60
|
d.displayName = "TableRowActions";
|
|
61
61
|
var f = t.forwardRef(({ className: t, ...r }, i) => /* @__PURE__ */ n("caption", {
|
|
62
62
|
ref: i,
|
|
63
|
-
className: e("mt-ds-05 text-
|
|
63
|
+
className: e("mt-ds-05 text-body-md text-surface-fg-muted", t),
|
|
64
64
|
...r
|
|
65
65
|
}));
|
|
66
66
|
f.displayName = "TableCaption";
|
package/dist/ui/table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","names":[],"sources":["../../src/ui/table.tsx"],"sourcesContent":["// @server-safe\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\n\n/** Row density — sets --table-py, which header and body cells both read. */\ntype TableDensity = 'compact' | 'standard' | 'comfortable'\n\n// One variable pair drives the table's spacing (same pattern as Card):\n// --table-py vertical cell padding per density (4 / 8 / 12px → rows ≈ 29 / 37 / 45px)\n// --table-edge first/last-cell inline padding — inherits --card-spacing when the table\n// sits inside a Card, so edge columns align with the card's slots;\n// falls back to ds-04 (12px) standalone.\nconst densityClasses: Record<TableDensity, string> = {\n compact: '[--table-py:var(--spacing-ds-02)]',\n standard: '[--table-py:var(--spacing-ds-03)]',\n comfortable: '[--table-py:var(--spacing-ds-04)]',\n}\n\nexport interface TableCellBaseProps {\n /**\n * Quantitative column: right-aligns and uses tabular figures so digits line up.\n * Keep decimal places consistent per column; identifier-numbers (dates, phones,\n * IDs) stay left-aligned — they're names, not quantities.\n */\n numeric?: boolean\n}\n\nexport interface TableProps extends React.HTMLAttributes<HTMLTableElement> {\n /** Row density — vertical cell padding for header + body. @default 'standard' */\n density?: TableDensity\n /**\n * Zebra striping (even body rows get the faintest surface step). Opt-in only —\n * for very wide/dense tables; hairline separators are the default row cue.\n */\n striped?: boolean\n}\n\nconst Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, density = 'standard', striped, ...props }, ref) => (\n <div className=\"relative w-full overflow-auto\">\n <table\n ref={ref}\n className={cn(\n // overflow-x-clip contains TableRowLink's 100vw stretch pseudo-element\n // without creating a horizontal scrollbar (the wrapper owns scrolling).\n \"w-full caption-bottom text-
|
|
1
|
+
{"version":3,"file":"table.js","names":[],"sources":["../../src/ui/table.tsx"],"sourcesContent":["// @server-safe\nimport * as React from \"react\"\n\nimport { cn } from \"./lib/utils\"\n\n/** Row density — sets --table-py, which header and body cells both read. */\ntype TableDensity = 'compact' | 'standard' | 'comfortable'\n\n// One variable pair drives the table's spacing (same pattern as Card):\n// --table-py vertical cell padding per density (4 / 8 / 12px → rows ≈ 29 / 37 / 45px)\n// --table-edge first/last-cell inline padding — inherits --card-spacing when the table\n// sits inside a Card, so edge columns align with the card's slots;\n// falls back to ds-04 (12px) standalone.\nconst densityClasses: Record<TableDensity, string> = {\n compact: '[--table-py:var(--spacing-ds-02)]',\n standard: '[--table-py:var(--spacing-ds-03)]',\n comfortable: '[--table-py:var(--spacing-ds-04)]',\n}\n\nexport interface TableCellBaseProps {\n /**\n * Quantitative column: right-aligns and uses tabular figures so digits line up.\n * Keep decimal places consistent per column; identifier-numbers (dates, phones,\n * IDs) stay left-aligned — they're names, not quantities.\n */\n numeric?: boolean\n}\n\nexport interface TableProps extends React.HTMLAttributes<HTMLTableElement> {\n /** Row density — vertical cell padding for header + body. @default 'standard' */\n density?: TableDensity\n /**\n * Zebra striping (even body rows get the faintest surface step). Opt-in only —\n * for very wide/dense tables; hairline separators are the default row cue.\n */\n striped?: boolean\n}\n\nconst Table = React.forwardRef<HTMLTableElement, TableProps>(\n ({ className, density = 'standard', striped, ...props }, ref) => (\n <div className=\"relative w-full overflow-auto\">\n <table\n ref={ref}\n className={cn(\n // overflow-x-clip contains TableRowLink's 100vw stretch pseudo-element\n // without creating a horizontal scrollbar (the wrapper owns scrolling).\n \"w-full caption-bottom text-body-md overflow-x-clip [--table-edge:var(--card-spacing,var(--spacing-ds-04))]\",\n densityClasses[density],\n striped && \"[&_tbody_tr:nth-child(even)]:bg-surface-base\",\n className,\n )}\n {...props}\n />\n </div>\n ),\n)\nTable.displayName = \"Table\"\n\nconst TableHeader = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <thead ref={ref} className={cn(\"[&_tr]:border-b [&_tr]:border-surface-border-subtle\", className)} {...props} />\n))\nTableHeader.displayName = \"TableHeader\"\n\nconst TableBody = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tbody\n ref={ref}\n className={cn(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n))\nTableBody.displayName = \"TableBody\"\n\nconst TableFooter = React.forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>(({ className, ...props }, ref) => (\n <tfoot\n ref={ref}\n className={cn(\n // surface-base band, not raised@50% — the footer must read against the\n // card surface the table lives on (same mis-mapped shadcn muted/50 family\n // as the row-hover bug).\n \"border-t border-surface-border-subtle bg-surface-base font-medium [&>tr]:last:border-b-0\",\n className\n )}\n {...props}\n />\n))\nTableFooter.displayName = \"TableFooter\"\n\nconst TableRow = React.forwardRef<\n HTMLTableRowElement,\n React.HTMLAttributes<HTMLTableRowElement>\n>(({ className, ...props }, ref) => (\n <tr\n ref={ref}\n className={cn(\n // raised-hover, NOT raised — tables live on cards (surface-raised), so a\n // surface-raised hover would be invisible (the 0.44-era port bug).\n // selected+hover gets its own explicit step — without it the hover and\n // selected classes tie on specificity and stylesheet order decides.\n // `group/row` lets TableRowActions reveal on row hover/focus; the has-[]\n // rule draws a row-level focus ring when a TableRowLink inside is\n // keyboard-focused (the anchor itself suppresses its own ring).\n \"group/row border-b border-surface-border-subtle transition-colors hover:bg-surface-raised-hover data-[state=selected]:bg-accent-3 data-[state=selected]:hover:bg-accent-4\",\n \"has-[[data-slot=row-link]:focus-visible]:outline-2 has-[[data-slot=row-link]:focus-visible]:outline-accent-9 has-[[data-slot=row-link]:focus-visible]:-outline-offset-2\",\n className,\n )}\n {...props}\n />\n))\nTableRow.displayName = \"TableRow\"\n\nconst TableHead = React.forwardRef<\n HTMLTableCellElement,\n React.ThHTMLAttributes<HTMLTableCellElement> & TableCellBaseProps\n>(({ className, numeric, ...props }, ref) => (\n <th\n ref={ref}\n scope=\"col\"\n className={cn(\n // Header is quieter than the data: one step smaller, medium, muted.\n // Height tracks density via the same --table-py the body cells read.\n \"py-(--table-py) px-ds-04 first:pl-(--table-edge) last:pr-(--table-edge) text-left align-middle text-body-sm font-medium text-surface-fg-muted [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\",\n numeric && \"text-right\",\n className,\n )}\n {...props}\n />\n))\nTableHead.displayName = \"TableHead\"\n\nconst TableCell = React.forwardRef<\n HTMLTableCellElement,\n React.TdHTMLAttributes<HTMLTableCellElement> & TableCellBaseProps\n>(({ className, numeric, ...props }, ref) => (\n <td\n ref={ref}\n className={cn(\n \"py-(--table-py) px-ds-04 first:pl-(--table-edge) last:pr-(--table-edge) align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\",\n numeric && \"text-right tabular-nums\",\n className,\n )}\n {...props}\n />\n))\nTableCell.displayName = \"TableCell\"\n\nexport interface TableRowActionsProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Always show the actions instead of revealing on row hover/focus. Use for\n * tables where actions must be permanently discoverable (the GitLab stance),\n * or when the row has few columns and the density win doesn't matter.\n */\n persist?: boolean\n}\n\n/**\n * Right-aligned action cluster for a table row, revealed on row hover — and,\n * critically, on keyboard focus: the buttons stay in the tab order permanently\n * (opacity reveal, never display:none) and appear the moment focus enters the\n * row (WCAG 1.4.13). On touch devices (no hover) they are always visible.\n *\n * Give the actions column a visually-hidden header: `<TableHead><span className=\"sr-only\">Actions</span></TableHead>`.\n *\n * @example\n * <TableCell>\n * <TableRowActions>\n * <IconButton size=\"xs\" variant=\"ghost\" aria-label={`Download ${name}`} icon={<IconDownload />} />\n * <IconButton size=\"xs\" variant=\"ghost\" aria-label={`Delete ${name}`} icon={<IconTrash />} />\n * </TableRowActions>\n * </TableCell>\n */\nconst TableRowActions = React.forwardRef<HTMLDivElement, TableRowActionsProps>(\n ({ className, persist, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n \"flex items-center justify-end gap-ds-01 transition-opacity duration-fast-01 ease-productive-standard\",\n persist\n ? \"opacity-100\"\n : \"opacity-0 group-hover/row:opacity-100 group-focus-within/row:opacity-100 pointer-coarse:opacity-100\",\n className,\n )}\n {...props}\n />\n ),\n)\nTableRowActions.displayName = \"TableRowActions\"\n\nconst TableCaption = React.forwardRef<\n HTMLTableCaptionElement,\n React.HTMLAttributes<HTMLTableCaptionElement>\n>(({ className, ...props }, ref) => (\n <caption\n ref={ref}\n className={cn(\"mt-ds-05 text-body-md text-surface-fg-muted\", className)}\n {...props}\n />\n))\nTableCaption.displayName = \"TableCaption\"\n\nexport type TableRowProps = React.HTMLAttributes<HTMLTableRowElement>\nexport type TableCellProps = React.TdHTMLAttributes<HTMLTableCellElement>\nexport type { TableDensity }\n\nexport {\n Table,\n TableBody,\n TableCaption,\n TableCell,\n TableFooter,\n TableHead,\n TableHeader,\n TableRow,\n TableRowActions,\n}\n"],"mappings":";;;;AAaA,IAAM,IAA+C;CACnD,SAAS;CACT,UAAU;CACV,aAAa;AACf,GAqBM,IAAQ,EAAM,YACjB,EAAE,cAAW,aAAU,YAAY,YAAS,GAAG,KAAS,MACvD,kBAAC,OAAD;CAAK,WAAU;WACb,kBAAC,SAAD;EACO;EACL,WAAW,EAGT,8GACA,EAAe,IACf,KAAW,gDACX,CACF;EACA,GAAI;CACL,CAAA;AACE,CAAA,CAET;AACA,EAAM,cAAc;AAEpB,IAAM,IAAc,EAAM,YAGvB,EAAE,cAAW,GAAG,KAAS,MAC1B,kBAAC,SAAD;CAAY;CAAK,WAAW,EAAG,uDAAuD,CAAS;CAAG,GAAI;AAAQ,CAAA,CAC/G;AACD,EAAY,cAAc;AAE1B,IAAM,IAAY,EAAM,YAGrB,EAAE,cAAW,GAAG,KAAS,MAC1B,kBAAC,SAAD;CACO;CACL,WAAW,EAAG,8BAA8B,CAAS;CACrD,GAAI;AACL,CAAA,CACF;AACD,EAAU,cAAc;AAExB,IAAM,IAAc,EAAM,YAGvB,EAAE,cAAW,GAAG,KAAS,MAC1B,kBAAC,SAAD;CACO;CACL,WAAW,EAIT,4FACA,CACF;CACA,GAAI;AACL,CAAA,CACF;AACD,EAAY,cAAc;AAE1B,IAAM,IAAW,EAAM,YAGpB,EAAE,cAAW,GAAG,KAAS,MAC1B,kBAAC,MAAD;CACO;CACL,WAAW,EAQT,6KACA,2KACA,CACF;CACA,GAAI;AACL,CAAA,CACF;AACD,EAAS,cAAc;AAEvB,IAAM,IAAY,EAAM,YAGrB,EAAE,cAAW,YAAS,GAAG,KAAS,MACnC,kBAAC,MAAD;CACO;CACL,OAAM;CACN,WAAW,EAGT,qNACA,KAAW,cACX,CACF;CACA,GAAI;AACL,CAAA,CACF;AACD,EAAU,cAAc;AAExB,IAAM,IAAY,EAAM,YAGrB,EAAE,cAAW,YAAS,GAAG,KAAS,MACnC,kBAAC,MAAD;CACO;CACL,WAAW,EACT,4JACA,KAAW,2BACX,CACF;CACA,GAAI;AACL,CAAA,CACF;AACD,EAAU,cAAc;AA2BxB,IAAM,IAAkB,EAAM,YAC3B,EAAE,cAAW,YAAS,GAAG,KAAS,MACjC,kBAAC,OAAD;CACO;CACL,WAAW,EACT,wGACA,IACI,gBACA,uGACJ,CACF;CACA,GAAI;AACL,CAAA,CAEL;AACA,EAAgB,cAAc;AAE9B,IAAM,IAAe,EAAM,YAGxB,EAAE,cAAW,GAAG,KAAS,MAC1B,kBAAC,WAAD;CACO;CACL,WAAW,EAAG,+CAA+C,CAAS;CACtE,GAAI;AACL,CAAA,CACF;AACD,EAAa,cAAc"}
|
package/dist/ui/tabs.js
CHANGED
|
@@ -78,9 +78,9 @@ var g = c.createContext({
|
|
|
78
78
|
]
|
|
79
79
|
},
|
|
80
80
|
size: {
|
|
81
|
-
sm: "px-ds-03 py-ds-02 text-
|
|
82
|
-
md: "px-ds-05 py-ds-03 text-
|
|
83
|
-
lg: "px-ds-06 py-ds-04 text-
|
|
81
|
+
sm: "px-ds-03 py-ds-02 text-body-xs",
|
|
82
|
+
md: "px-ds-05 py-ds-03 text-body-sm",
|
|
83
|
+
lg: "px-ds-06 py-ds-04 text-body-md"
|
|
84
84
|
}
|
|
85
85
|
},
|
|
86
86
|
defaultVariants: {
|
package/dist/ui/tabs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs.js","names":[],"sources":["../../src/ui/tabs.tsx"],"sourcesContent":["'use client'\n\nimport * as TabsPrimitive from '@primitives/react-tabs'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { LayoutGroup,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { springs, tweens } from './lib/motion'\nimport { cn } from './lib/utils'\n\n/* ── Active-value context (drives layoutId indicator) ────── */\ntype TabsOrientation = 'horizontal' | 'vertical'\nconst TabsValueContext = React.createContext<string | undefined>(undefined)\nconst TabsOrientationContext = React.createContext<TabsOrientation>('horizontal')\n\n/**\n * Tabs compound component — accessible tabbed navigation with keyboard support and two visual\n * variants (line underline and contained pill styles).\n *\n * **Parts (in composition order):**\n * - `Tabs` — manages active tab state (this root; takes `defaultValue`, `value`, `onValueChange`)\n * - `TabsList` — tab bar container (takes `variant=\"line\"|\"contained\"`, default `\"line\"`)\n * - `TabsTrigger` — individual tab button (requires `value`; inherits `variant` from TabsList via context)\n * - `TabsContent` — the panel shown when its tab is active (requires `value` matching a TabsTrigger)\n *\n * **Critical behavior:** `variant` set on `TabsList` propagates automatically via React context to\n * all `TabsTrigger` children. You do NOT need to repeat `variant` on each trigger — but you CAN\n * override it per-trigger if needed.\n *\n * The active tab indicator animates between tabs using Framer Motion `layoutId`. Line variant\n * shows a sliding underline; contained variant shows a sliding pill background.\n *\n * @compound\n * @example\n * // Default line variant:\n * <Tabs defaultValue=\"overview\">\n * <TabsList>\n * <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n * <TabsTrigger value=\"activity\">Activity</TabsTrigger>\n * <TabsTrigger value=\"settings\">Settings</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"overview\">Overview content</TabsContent>\n * <TabsContent value=\"activity\">Activity content</TabsContent>\n * <TabsContent value=\"settings\">Settings content</TabsContent>\n * </Tabs>\n *\n * @example\n * // Contained pill variant (controlled):\n * const [tab, setTab] = useState('members')\n * <Tabs value={tab} onValueChange={setTab}>\n * <TabsList variant=\"contained\">\n * <TabsTrigger value=\"members\">Members</TabsTrigger>\n * <TabsTrigger value=\"roles\">Roles</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"members\">Members list here.</TabsContent>\n * <TabsContent value=\"roles\">Roles list here.</TabsContent>\n * </Tabs>\n */\nconst Tabs = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>\n>(({ value: valueProp, defaultValue, onValueChange, orientation, ...props }, ref) => {\n // Track the active value so TabsTrigger can conditionally render the motion indicator.\n // For controlled usage, mirror the prop; for uncontrolled, manage internal state.\n const [activeValue, setActiveValue] = React.useState(valueProp ?? defaultValue ?? '')\n\n // Sync controlled value\n React.useEffect(() => {\n if (valueProp !== undefined) setActiveValue(valueProp)\n }, [valueProp])\n\n const handleValueChange = React.useCallback(\n (newValue: string) => {\n setActiveValue(newValue)\n onValueChange?.(newValue)\n },\n [onValueChange],\n )\n\n const resolvedOrientation: TabsOrientation = orientation ?? 'horizontal'\n\n return (\n <TabsValueContext.Provider value={activeValue}>\n <TabsOrientationContext.Provider value={resolvedOrientation}>\n <TabsPrimitive.Root\n ref={ref}\n value={valueProp}\n defaultValue={valueProp === undefined ? defaultValue : undefined}\n onValueChange={handleValueChange}\n orientation={orientation}\n {...props}\n className={cn(\n resolvedOrientation === 'vertical' && 'flex flex-row gap-ds-05',\n props.className,\n )}\n />\n </TabsOrientationContext.Provider>\n </TabsValueContext.Provider>\n )\n})\nTabs.displayName = 'Tabs'\n\n/** Props for the Tabs root (defaultValue, value, onValueChange, etc.). */\nexport type TabsProps = React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>\n\ntype TabsVariant = 'line' | 'contained'\ntype TabsSize = 'sm' | 'md' | 'lg'\ntype TabsColor = 'accent' | 'neutral'\n\ninterface TabsListContextValue {\n variant: TabsVariant\n size: TabsSize\n color: TabsColor\n layoutId: string\n}\n\nconst TabsListContext = React.createContext<TabsListContextValue>({\n variant: 'line',\n size: 'md',\n color: 'accent',\n layoutId: 'tab-indicator',\n})\n\nconst tabsListVariants = cva('inline-flex items-center', {\n variants: {\n variant: {\n line: 'border-b border-surface-border-strong w-full gap-0',\n contained:\n 'bg-surface-raised p-ds-02 rounded-surface gap-ds-02',\n },\n size: {\n sm: 'h-8',\n md: 'h-10',\n lg: 'h-12',\n },\n orientation: {\n horizontal: '',\n vertical: 'flex-col',\n },\n },\n compoundVariants: [\n // Vertical line: left border instead of bottom, fixed width, auto height\n { variant: 'line', orientation: 'vertical', class: 'border-b-0 border-l border-surface-border-strong w-48 shrink-0 h-auto gap-0' },\n // Vertical contained: column layout, fixed width, auto height\n { variant: 'contained', orientation: 'vertical', class: 'h-auto w-48 shrink-0' },\n ],\n defaultVariants: { variant: 'line', size: 'md', orientation: 'horizontal' },\n})\n\nconst tabsTriggerVariants = cva(\n 'relative inline-flex items-center justify-center gap-ds-02 whitespace-nowrap font-sans font-medium transition-colors duration-100 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-1 disabled:pointer-events-none disabled:opacity-action-disabled',\n {\n variants: {\n variant: {\n line: [\n '-mb-px',\n 'text-surface-fg-muted hover:text-surface-fg',\n ],\n contained: [\n 'rounded-control',\n 'text-surface-fg-muted hover:text-surface-fg',\n 'data-[state=active]:text-surface-fg',\n ],\n },\n size: {\n sm: 'px-ds-03 py-ds-02 text-ds-xs',\n md: 'px-ds-05 py-ds-03 text-ds-sm',\n lg: 'px-ds-06 py-ds-04 text-ds-md',\n },\n },\n defaultVariants: { variant: 'line', size: 'md' },\n },\n)\n\n/**\n * TabsList — container for tab triggers. Sets `variant` for all child TabsTriggers via context.\n *\n * **Compound structure — variant propagates automatically:**\n * ```tsx\n * <Tabs defaultValue=\"overview\">\n * <TabsList variant=\"contained\">\n * <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n * <TabsTrigger value=\"activity\">Activity</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"overview\">Overview content</TabsContent>\n * <TabsContent value=\"activity\">Activity content</TabsContent>\n * </Tabs>\n * ```\n *\n * `variant` on `TabsList` flows to all `TabsTrigger` children via React context.\n * You do NOT need to repeat `variant` on each `TabsTrigger`.\n */\nexport interface TabsListProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>,\n VariantProps<typeof tabsListVariants> {\n /** Color axis — affects active tab indicator and text color. @default \"accent\" */\n color?: TabsColor\n}\n\nconst TabsList = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.List>,\n TabsListProps\n>(({ className, variant, size, color, ...props }, ref) => {\n const orientation = React.useContext(TabsOrientationContext)\n const resolvedVariant: TabsVariant = variant ?? 'line'\n const resolvedSize: TabsSize = size ?? 'md'\n const resolvedColor: TabsColor = color ?? 'accent'\n const layoutId = React.useId()\n const contextValue = React.useMemo(\n () => ({\n variant: resolvedVariant,\n size: resolvedSize,\n color: resolvedColor,\n layoutId: `tab-indicator-${layoutId}`,\n }),\n [resolvedVariant, resolvedSize, resolvedColor, layoutId],\n )\n return (\n <TabsListContext.Provider value={contextValue}>\n <LayoutGroup>\n <TabsPrimitive.List\n ref={ref}\n className={cn(tabsListVariants({ variant: resolvedVariant, size: resolvedSize, orientation }), className)}\n {...props}\n />\n </LayoutGroup>\n </TabsListContext.Provider>\n )\n})\nTabsList.displayName = TabsPrimitive.List.displayName\n\nexport interface TabsTriggerProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>,\n VariantProps<typeof tabsTriggerVariants> {}\n\n/* ── Color classes for active state ────── */\nconst lineActiveColorMap: Record<TabsColor, string> = {\n accent: 'data-[state=active]:text-accent-11',\n neutral: 'data-[state=active]:text-surface-fg',\n}\n\nconst lineIndicatorColorMap: Record<TabsColor, string> = {\n accent: 'bg-accent-9',\n neutral: 'bg-surface-fg',\n}\n\nconst TabsTrigger = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Trigger>,\n TabsTriggerProps\n>(({ className, variant: variantProp, children, ...props }, ref) => {\n const listContext = React.useContext(TabsListContext)\n const activeValue = React.useContext(TabsValueContext)\n const orientation = React.useContext(TabsOrientationContext)\n const variant = variantProp ?? listContext.variant\n const size = listContext.size\n const color = listContext.color\n const isActive = props.value === activeValue\n const isVertical = orientation === 'vertical'\n\n return (\n <TabsPrimitive.Trigger\n ref={ref}\n className={cn(\n tabsTriggerVariants({ variant, size }),\n variant === 'line' && lineActiveColorMap[color],\n // Vertical: full width triggers, left margin instead of bottom\n isVertical && 'w-full justify-start',\n variant === 'line' && isVertical && '-ml-px -mb-0',\n className,\n )}\n {...props}\n >\n {/* Contained variant: sliding pill background */}\n {variant === 'contained' && isActive && (\n <motion.span\n layoutId={`${listContext.layoutId}-contained`}\n className=\"absolute inset-0 rounded-control bg-surface-overlay shadow-raised\"\n transition={springs.smooth}\n />\n )}\n {/* Content sits above the indicator */}\n <span className=\"relative z-[1] inline-flex min-w-0 items-center gap-ds-02\">\n <span className=\"truncate\">{children}</span>\n </span>\n {/* Line variant: sliding indicator -- bottom underline (horizontal) or left bar (vertical) */}\n {variant === 'line' && isActive && (\n <motion.span\n layoutId={`${listContext.layoutId}-line`}\n className={cn(\n 'absolute',\n isVertical\n ? 'left-0 top-0 bottom-0 w-0.5'\n : 'bottom-0 left-0 right-0 h-0.5',\n lineIndicatorColorMap[color],\n )}\n transition={springs.smooth}\n />\n )}\n </TabsPrimitive.Trigger>\n )\n})\nTabsTrigger.displayName = TabsPrimitive.Trigger.displayName\n\nconst TabsContent = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n>(({ className, children, ...props }, ref) => {\n const orientation = React.useContext(TabsOrientationContext)\n const isVertical = orientation === 'vertical'\n\n return (\n <TabsPrimitive.Content\n ref={ref}\n className={cn(\n 'ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2',\n isVertical ? 'mt-0 flex-1 min-w-0' : 'mt-ds-05',\n className,\n )}\n {...props}\n >\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweens.fade}\n >\n {children}\n </motion.div>\n </TabsPrimitive.Content>\n )\n})\nTabsContent.displayName = TabsPrimitive.Content.displayName\n\n/** Props for TabsContent. The `value` prop must match a TabsTrigger's `value`. */\nexport type TabsContentProps = React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n\nexport { Tabs, TabsContent,TabsList, TabsTrigger }\nexport type { TabsColor, TabsOrientation,TabsSize }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tabs.js","names":[],"sources":["../../src/ui/tabs.tsx"],"sourcesContent":["'use client'\n\nimport * as TabsPrimitive from '@primitives/react-tabs'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { LayoutGroup,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { springs, tweens } from './lib/motion'\nimport { cn } from './lib/utils'\n\n/* ── Active-value context (drives layoutId indicator) ────── */\ntype TabsOrientation = 'horizontal' | 'vertical'\nconst TabsValueContext = React.createContext<string | undefined>(undefined)\nconst TabsOrientationContext = React.createContext<TabsOrientation>('horizontal')\n\n/**\n * Tabs compound component — accessible tabbed navigation with keyboard support and two visual\n * variants (line underline and contained pill styles).\n *\n * **Parts (in composition order):**\n * - `Tabs` — manages active tab state (this root; takes `defaultValue`, `value`, `onValueChange`)\n * - `TabsList` — tab bar container (takes `variant=\"line\"|\"contained\"`, default `\"line\"`)\n * - `TabsTrigger` — individual tab button (requires `value`; inherits `variant` from TabsList via context)\n * - `TabsContent` — the panel shown when its tab is active (requires `value` matching a TabsTrigger)\n *\n * **Critical behavior:** `variant` set on `TabsList` propagates automatically via React context to\n * all `TabsTrigger` children. You do NOT need to repeat `variant` on each trigger — but you CAN\n * override it per-trigger if needed.\n *\n * The active tab indicator animates between tabs using Framer Motion `layoutId`. Line variant\n * shows a sliding underline; contained variant shows a sliding pill background.\n *\n * @compound\n * @example\n * // Default line variant:\n * <Tabs defaultValue=\"overview\">\n * <TabsList>\n * <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n * <TabsTrigger value=\"activity\">Activity</TabsTrigger>\n * <TabsTrigger value=\"settings\">Settings</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"overview\">Overview content</TabsContent>\n * <TabsContent value=\"activity\">Activity content</TabsContent>\n * <TabsContent value=\"settings\">Settings content</TabsContent>\n * </Tabs>\n *\n * @example\n * // Contained pill variant (controlled):\n * const [tab, setTab] = useState('members')\n * <Tabs value={tab} onValueChange={setTab}>\n * <TabsList variant=\"contained\">\n * <TabsTrigger value=\"members\">Members</TabsTrigger>\n * <TabsTrigger value=\"roles\">Roles</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"members\">Members list here.</TabsContent>\n * <TabsContent value=\"roles\">Roles list here.</TabsContent>\n * </Tabs>\n */\nconst Tabs = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>\n>(({ value: valueProp, defaultValue, onValueChange, orientation, ...props }, ref) => {\n // Track the active value so TabsTrigger can conditionally render the motion indicator.\n // For controlled usage, mirror the prop; for uncontrolled, manage internal state.\n const [activeValue, setActiveValue] = React.useState(valueProp ?? defaultValue ?? '')\n\n // Sync controlled value\n React.useEffect(() => {\n if (valueProp !== undefined) setActiveValue(valueProp)\n }, [valueProp])\n\n const handleValueChange = React.useCallback(\n (newValue: string) => {\n setActiveValue(newValue)\n onValueChange?.(newValue)\n },\n [onValueChange],\n )\n\n const resolvedOrientation: TabsOrientation = orientation ?? 'horizontal'\n\n return (\n <TabsValueContext.Provider value={activeValue}>\n <TabsOrientationContext.Provider value={resolvedOrientation}>\n <TabsPrimitive.Root\n ref={ref}\n value={valueProp}\n defaultValue={valueProp === undefined ? defaultValue : undefined}\n onValueChange={handleValueChange}\n orientation={orientation}\n {...props}\n className={cn(\n resolvedOrientation === 'vertical' && 'flex flex-row gap-ds-05',\n props.className,\n )}\n />\n </TabsOrientationContext.Provider>\n </TabsValueContext.Provider>\n )\n})\nTabs.displayName = 'Tabs'\n\n/** Props for the Tabs root (defaultValue, value, onValueChange, etc.). */\nexport type TabsProps = React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>\n\ntype TabsVariant = 'line' | 'contained'\ntype TabsSize = 'sm' | 'md' | 'lg'\ntype TabsColor = 'accent' | 'neutral'\n\ninterface TabsListContextValue {\n variant: TabsVariant\n size: TabsSize\n color: TabsColor\n layoutId: string\n}\n\nconst TabsListContext = React.createContext<TabsListContextValue>({\n variant: 'line',\n size: 'md',\n color: 'accent',\n layoutId: 'tab-indicator',\n})\n\nconst tabsListVariants = cva('inline-flex items-center', {\n variants: {\n variant: {\n line: 'border-b border-surface-border-strong w-full gap-0',\n contained:\n 'bg-surface-raised p-ds-02 rounded-surface gap-ds-02',\n },\n size: {\n sm: 'h-8',\n md: 'h-10',\n lg: 'h-12',\n },\n orientation: {\n horizontal: '',\n vertical: 'flex-col',\n },\n },\n compoundVariants: [\n // Vertical line: left border instead of bottom, fixed width, auto height\n { variant: 'line', orientation: 'vertical', class: 'border-b-0 border-l border-surface-border-strong w-48 shrink-0 h-auto gap-0' },\n // Vertical contained: column layout, fixed width, auto height\n { variant: 'contained', orientation: 'vertical', class: 'h-auto w-48 shrink-0' },\n ],\n defaultVariants: { variant: 'line', size: 'md', orientation: 'horizontal' },\n})\n\nconst tabsTriggerVariants = cva(\n 'relative inline-flex items-center justify-center gap-ds-02 whitespace-nowrap font-sans font-medium transition-colors duration-100 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-1 disabled:pointer-events-none disabled:opacity-action-disabled',\n {\n variants: {\n variant: {\n line: [\n '-mb-px',\n 'text-surface-fg-muted hover:text-surface-fg',\n ],\n contained: [\n 'rounded-control',\n 'text-surface-fg-muted hover:text-surface-fg',\n 'data-[state=active]:text-surface-fg',\n ],\n },\n size: {\n sm: 'px-ds-03 py-ds-02 text-body-xs',\n md: 'px-ds-05 py-ds-03 text-body-sm',\n lg: 'px-ds-06 py-ds-04 text-body-md',\n },\n },\n defaultVariants: { variant: 'line', size: 'md' },\n },\n)\n\n/**\n * TabsList — container for tab triggers. Sets `variant` for all child TabsTriggers via context.\n *\n * **Compound structure — variant propagates automatically:**\n * ```tsx\n * <Tabs defaultValue=\"overview\">\n * <TabsList variant=\"contained\">\n * <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n * <TabsTrigger value=\"activity\">Activity</TabsTrigger>\n * </TabsList>\n * <TabsContent value=\"overview\">Overview content</TabsContent>\n * <TabsContent value=\"activity\">Activity content</TabsContent>\n * </Tabs>\n * ```\n *\n * `variant` on `TabsList` flows to all `TabsTrigger` children via React context.\n * You do NOT need to repeat `variant` on each `TabsTrigger`.\n */\nexport interface TabsListProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>,\n VariantProps<typeof tabsListVariants> {\n /** Color axis — affects active tab indicator and text color. @default \"accent\" */\n color?: TabsColor\n}\n\nconst TabsList = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.List>,\n TabsListProps\n>(({ className, variant, size, color, ...props }, ref) => {\n const orientation = React.useContext(TabsOrientationContext)\n const resolvedVariant: TabsVariant = variant ?? 'line'\n const resolvedSize: TabsSize = size ?? 'md'\n const resolvedColor: TabsColor = color ?? 'accent'\n const layoutId = React.useId()\n const contextValue = React.useMemo(\n () => ({\n variant: resolvedVariant,\n size: resolvedSize,\n color: resolvedColor,\n layoutId: `tab-indicator-${layoutId}`,\n }),\n [resolvedVariant, resolvedSize, resolvedColor, layoutId],\n )\n return (\n <TabsListContext.Provider value={contextValue}>\n <LayoutGroup>\n <TabsPrimitive.List\n ref={ref}\n className={cn(tabsListVariants({ variant: resolvedVariant, size: resolvedSize, orientation }), className)}\n {...props}\n />\n </LayoutGroup>\n </TabsListContext.Provider>\n )\n})\nTabsList.displayName = TabsPrimitive.List.displayName\n\nexport interface TabsTriggerProps\n extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>,\n VariantProps<typeof tabsTriggerVariants> {}\n\n/* ── Color classes for active state ────── */\nconst lineActiveColorMap: Record<TabsColor, string> = {\n accent: 'data-[state=active]:text-accent-11',\n neutral: 'data-[state=active]:text-surface-fg',\n}\n\nconst lineIndicatorColorMap: Record<TabsColor, string> = {\n accent: 'bg-accent-9',\n neutral: 'bg-surface-fg',\n}\n\nconst TabsTrigger = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Trigger>,\n TabsTriggerProps\n>(({ className, variant: variantProp, children, ...props }, ref) => {\n const listContext = React.useContext(TabsListContext)\n const activeValue = React.useContext(TabsValueContext)\n const orientation = React.useContext(TabsOrientationContext)\n const variant = variantProp ?? listContext.variant\n const size = listContext.size\n const color = listContext.color\n const isActive = props.value === activeValue\n const isVertical = orientation === 'vertical'\n\n return (\n <TabsPrimitive.Trigger\n ref={ref}\n className={cn(\n tabsTriggerVariants({ variant, size }),\n variant === 'line' && lineActiveColorMap[color],\n // Vertical: full width triggers, left margin instead of bottom\n isVertical && 'w-full justify-start',\n variant === 'line' && isVertical && '-ml-px -mb-0',\n className,\n )}\n {...props}\n >\n {/* Contained variant: sliding pill background */}\n {variant === 'contained' && isActive && (\n <motion.span\n layoutId={`${listContext.layoutId}-contained`}\n className=\"absolute inset-0 rounded-control bg-surface-overlay shadow-raised\"\n transition={springs.smooth}\n />\n )}\n {/* Content sits above the indicator */}\n <span className=\"relative z-[1] inline-flex min-w-0 items-center gap-ds-02\">\n <span className=\"truncate\">{children}</span>\n </span>\n {/* Line variant: sliding indicator -- bottom underline (horizontal) or left bar (vertical) */}\n {variant === 'line' && isActive && (\n <motion.span\n layoutId={`${listContext.layoutId}-line`}\n className={cn(\n 'absolute',\n isVertical\n ? 'left-0 top-0 bottom-0 w-0.5'\n : 'bottom-0 left-0 right-0 h-0.5',\n lineIndicatorColorMap[color],\n )}\n transition={springs.smooth}\n />\n )}\n </TabsPrimitive.Trigger>\n )\n})\nTabsTrigger.displayName = TabsPrimitive.Trigger.displayName\n\nconst TabsContent = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n>(({ className, children, ...props }, ref) => {\n const orientation = React.useContext(TabsOrientationContext)\n const isVertical = orientation === 'vertical'\n\n return (\n <TabsPrimitive.Content\n ref={ref}\n className={cn(\n 'ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2',\n isVertical ? 'mt-0 flex-1 min-w-0' : 'mt-ds-05',\n className,\n )}\n {...props}\n >\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweens.fade}\n >\n {children}\n </motion.div>\n </TabsPrimitive.Content>\n )\n})\nTabsContent.displayName = TabsPrimitive.Content.displayName\n\n/** Props for TabsContent. The `value` prop must match a TabsTrigger's `value`. */\nexport type TabsContentProps = React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n\nexport { Tabs, TabsContent,TabsList, TabsTrigger }\nexport type { TabsColor, TabsOrientation,TabsSize }\n"],"mappings":"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"}
|
package/dist/ui/text.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/ui/text.tsx"],"names":[],"mappings":"AACA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/ui/text.tsx"],"names":[],"mappings":"AACA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,QAAA,MAAM,YAAY;;8EA4BhB,CAAA;AAEF,KAAK,WAAW,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;AAyB5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,KAAK,SAAS,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,GAAG,GAAG,IAAI;IAClD,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,EAAE,CAAC,EAAE,CAAC,CAAA;IACN,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC,CAAA;AAOrF,KAAK,aAAa,GAAG,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,GAAG,GAAG,EACtD,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;CAAE,KAClE,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAc1D,QAAA,MAAM,IAAI,EAA0B,aAAa,CAAA;AAEjD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAC,YAAY,EAAE,CAAA"}
|
package/dist/ui/text.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","names":[],"sources":["../../src/ui/text.tsx"],"sourcesContent":["// @server-safe\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from './lib/utils'\n\nconst textVariants = cva('font-sans', {\n variants: {\n variant: {\n 'heading-2xl': 'font-display text-[length:var(--typo-heading-2xl-size)] font-[number:var(--typo-heading-2xl-weight)] leading-[var(--typo-heading-2xl-leading)] tracking-[var(--typo-heading-2xl-tracking)]',\n 'heading-xl': 'font-display text-[length:var(--typo-heading-xl-size)] font-[number:var(--typo-heading-xl-weight)] leading-[var(--typo-heading-xl-leading)] tracking-[var(--typo-heading-xl-tracking)]',\n 'heading-lg': 'font-display text-[length:var(--typo-heading-lg-size)] font-[number:var(--typo-heading-lg-weight)] leading-[var(--typo-heading-lg-leading)] tracking-[var(--typo-heading-lg-tracking)]',\n 'heading-md': 'font-display text-[length:var(--typo-heading-md-size)] font-[number:var(--typo-heading-md-weight)] leading-[var(--typo-heading-md-leading)] tracking-[var(--typo-heading-md-tracking)]',\n 'heading-sm': 'font-display text-[length:var(--typo-heading-sm-size)] font-[number:var(--typo-heading-sm-weight)] leading-[var(--typo-heading-sm-leading)] tracking-[var(--typo-heading-sm-tracking)]',\n 'heading-xs': 'font-display text-[length:var(--typo-heading-xs-size)] font-[number:var(--typo-heading-xs-weight)] leading-[var(--typo-heading-xs-leading)] tracking-[var(--typo-heading-xs-tracking)]',\n 'body-lg': 'text-[length:var(--typo-body-lg-size)] font-[number:var(--typo-body-lg-weight)] leading-[var(--typo-body-lg-leading)] tracking-[var(--typo-body-lg-tracking)]',\n 'body-md': 'text-[length:var(--typo-body-md-size)] font-[number:var(--typo-body-md-weight)] leading-[var(--typo-body-md-leading)] tracking-[var(--typo-body-md-tracking)]',\n 'body-sm': 'text-[length:var(--typo-body-sm-size)] font-[number:var(--typo-body-sm-weight)] leading-[var(--typo-body-sm-leading)] tracking-[var(--typo-body-sm-tracking)]',\n 'body-xs': 'text-[length:var(--typo-body-xs-size)] font-[number:var(--typo-body-xs-weight)] leading-[var(--typo-body-xs-leading)] tracking-[var(--typo-body-xs-tracking)]',\n 'label-lg': 'text-[length:var(--typo-label-lg-size)] font-[number:var(--typo-label-lg-weight)] leading-[var(--typo-label-lg-leading)] tracking-[var(--typo-label-lg-tracking)] uppercase',\n 'label-md': 'text-[length:var(--typo-label-md-size)] font-[number:var(--typo-label-md-weight)] leading-[var(--typo-label-md-leading)] tracking-[var(--typo-label-md-tracking)] uppercase',\n 'label-sm': 'text-[length:var(--typo-label-sm-size)] font-[number:var(--typo-label-sm-weight)] leading-[var(--typo-label-sm-leading)] tracking-[var(--typo-label-sm-tracking)] uppercase',\n 'label-xs': 'text-[length:var(--typo-label-xs-size)] font-[number:var(--typo-label-xs-weight)] leading-[var(--typo-label-xs-leading)] tracking-[var(--typo-label-xs-tracking)] uppercase',\n caption: 'text-[length:var(--typo-caption-size)] font-[number:var(--typo-caption-weight)] leading-[var(--typo-caption-leading)] tracking-[var(--typo-caption-tracking)]',\n overline: 'text-[length:var(--typo-overline-size)] font-[number:var(--typo-overline-weight)] leading-[var(--typo-overline-leading)] tracking-[var(--typo-overline-tracking)] uppercase',\n code: 'text-[length:var(--typo-code-size)] font-[number:var(--typo-code-weight)] leading-[var(--typo-code-leading)] tracking-[var(--typo-code-tracking)] font-mono',\n 'label-plain-lg': 'text-[length:var(--typo-label-plain-lg-size)] font-[number:var(--typo-label-plain-lg-weight)] leading-[var(--typo-label-plain-lg-leading)] tracking-[var(--typo-label-plain-lg-tracking)]',\n 'label-plain-md': 'text-[length:var(--typo-label-plain-md-size)] font-[number:var(--typo-label-plain-md-weight)] leading-[var(--typo-label-plain-md-leading)] tracking-[var(--typo-label-plain-md-tracking)]',\n 'label-plain-sm': 'text-[length:var(--typo-label-plain-sm-size)] font-[number:var(--typo-label-plain-sm-weight)] leading-[var(--typo-label-plain-sm-leading)] tracking-[var(--typo-label-plain-sm-tracking)]',\n },\n },\n defaultVariants: {\n variant: 'body-md',\n },\n})\n\ntype TextVariant = NonNullable<VariantProps<typeof textVariants>['variant']>\n\nconst defaultElementMap: Record<TextVariant, keyof React.JSX.IntrinsicElements> = {\n 'heading-2xl': 'h1',\n 'heading-xl': 'h2',\n 'heading-lg': 'h3',\n 'heading-md': 'h4',\n 'heading-sm': 'h5',\n 'heading-xs': 'h6',\n 'body-lg': 'p',\n 'body-md': 'p',\n 'body-sm': 'p',\n 'body-xs': 'p',\n 'label-lg': 'span',\n 'label-md': 'span',\n 'label-sm': 'span',\n 'label-xs': 'span',\n caption: 'span',\n overline: 'span',\n code: 'code',\n 'label-plain-lg': 'span',\n 'label-plain-md': 'span',\n 'label-plain-sm': 'span',\n}\n\n/**\n * Props for Text — a polymorphic typography component covering the full type scale:\n * headings, body, labels, captions, and overlines — with automatic semantic HTML element selection.\n *\n * **Variants (grouped):**\n * - Headings: `heading-2xl` → `h1`, `heading-xl` → `h2`, `heading-lg` → `h3`, etc.\n * - Body: `body-lg` | `body-md` (default) | `body-sm` | `body-xs` → `<p>`\n * - Labels: `label-lg` | `label-md` | `label-sm` | `label-xs` → `<span>` (uppercase)\n * - Misc: `caption` | `overline` → `<span>` (overline is uppercase)\n *\n * **`as` prop:** Override the rendered element. E.g. `<Text variant=\"heading-lg\" as=\"div\">` renders\n * `<div class=\"text-heading-lg ...\">` — useful when you need heading styles on a non-heading element.\n *\n * @example\n * // Page heading:\n * <Text variant=\"heading-2xl\">Welcome to Shilp Sutra</Text>\n *\n * @example\n * // Section label (uppercase, small):\n * <Text variant=\"label-sm\" className=\"text-surface-fg-muted\">Recent activity</Text>\n *\n * @example\n * // Body copy with custom element (renders as <span> for inline use):\n * <Text variant=\"body-sm\" as=\"span\" className=\"text-surface-fg-muted\">\n * Last updated 3 hours ago\n * </Text>\n *\n * @example\n * // Caption under an image or figure:\n * <Text variant=\"caption\" className=\"text-surface-fg-subtle\">Figure 1: System architecture</Text>\n * // These are just a few ways — feel free to combine props creatively!\n */\ntype TextProps<T extends React.ElementType = 'p'> = {\n variant?: TextVariant\n as?: T\n className?: string\n children?: React.ReactNode\n} & Omit<React.ComponentPropsWithRef<T>, 'as' | 'variant' | 'className' | 'children'>\n\n// Polymorphic component type — preserves T across the call site so element-\n// specific props (e.g. `htmlFor` on `as=\"label\"`, `href` on `as=\"a\"`) typecheck.\n// React.forwardRef can't keep a generic parameter live at its export, so we\n// type the implementation loosely and cast the public export to a generic\n// callable. Standard polymorphic-component pattern (same shape as Radix).\ntype TextComponent = (<T extends React.ElementType = 'p'>(\n props: TextProps<T> & { ref?: React.ComponentPropsWithRef<T>['ref'] },\n) => React.ReactElement | null) & { displayName?: string }\n\nconst TextImpl = React.forwardRef<HTMLElement, TextProps>(\n ({ variant = 'body-md', as, className, children, ...props }, ref) => {\n const Component = as || defaultElementMap[variant] || 'p'\n return React.createElement(\n Component,\n { ref, className: cn(textVariants({ variant }), className), ...props },\n children,\n )\n },\n)\nTextImpl.displayName = 'Text'\n\nconst Text = TextImpl as unknown as TextComponent\n\nexport { Text, type TextProps, type TextVariant,textVariants }\n"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"text.js","names":[],"sources":["../../src/ui/text.tsx"],"sourcesContent":["// @server-safe\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from './lib/utils'\n\n// slop-allow: caps-overuse — this primitive DEFINES the uppercase label-* variants; not on-surface caps overuse\nconst textVariants = cva('font-sans', {\n variants: {\n variant: {\n 'heading-2xl': 'font-display text-[length:var(--typo-heading-2xl-size)] font-[number:var(--typo-heading-2xl-weight)] leading-[var(--typo-heading-2xl-leading)] tracking-[var(--typo-heading-2xl-tracking)]',\n 'heading-xl': 'font-display text-[length:var(--typo-heading-xl-size)] font-[number:var(--typo-heading-xl-weight)] leading-[var(--typo-heading-xl-leading)] tracking-[var(--typo-heading-xl-tracking)]',\n 'heading-lg': 'font-display text-[length:var(--typo-heading-lg-size)] font-[number:var(--typo-heading-lg-weight)] leading-[var(--typo-heading-lg-leading)] tracking-[var(--typo-heading-lg-tracking)]',\n 'heading-md': 'font-display text-[length:var(--typo-heading-md-size)] font-[number:var(--typo-heading-md-weight)] leading-[var(--typo-heading-md-leading)] tracking-[var(--typo-heading-md-tracking)]',\n 'heading-sm': 'font-display text-[length:var(--typo-heading-sm-size)] font-[number:var(--typo-heading-sm-weight)] leading-[var(--typo-heading-sm-leading)] tracking-[var(--typo-heading-sm-tracking)]',\n 'heading-xs': 'font-display text-[length:var(--typo-heading-xs-size)] font-[number:var(--typo-heading-xs-weight)] leading-[var(--typo-heading-xs-leading)] tracking-[var(--typo-heading-xs-tracking)]',\n 'body-lg': 'text-[length:var(--typo-body-lg-size)] font-[number:var(--typo-body-lg-weight)] leading-[var(--typo-body-lg-leading)] tracking-[var(--typo-body-lg-tracking)]',\n 'body-md': 'text-[length:var(--typo-body-md-size)] font-[number:var(--typo-body-md-weight)] leading-[var(--typo-body-md-leading)] tracking-[var(--typo-body-md-tracking)]',\n 'body-sm': 'text-[length:var(--typo-body-sm-size)] font-[number:var(--typo-body-sm-weight)] leading-[var(--typo-body-sm-leading)] tracking-[var(--typo-body-sm-tracking)]',\n 'body-xs': 'text-[length:var(--typo-body-xs-size)] font-[number:var(--typo-body-xs-weight)] leading-[var(--typo-body-xs-leading)] tracking-[var(--typo-body-xs-tracking)]',\n 'label-lg': 'text-[length:var(--typo-label-lg-size)] font-[number:var(--typo-label-lg-weight)] leading-[var(--typo-label-lg-leading)] tracking-[var(--typo-label-lg-tracking)] uppercase',\n 'label-md': 'text-[length:var(--typo-label-md-size)] font-[number:var(--typo-label-md-weight)] leading-[var(--typo-label-md-leading)] tracking-[var(--typo-label-md-tracking)] uppercase',\n 'label-sm': 'text-[length:var(--typo-label-sm-size)] font-[number:var(--typo-label-sm-weight)] leading-[var(--typo-label-sm-leading)] tracking-[var(--typo-label-sm-tracking)] uppercase',\n 'label-xs': 'text-[length:var(--typo-label-xs-size)] font-[number:var(--typo-label-xs-weight)] leading-[var(--typo-label-xs-leading)] tracking-[var(--typo-label-xs-tracking)] uppercase',\n caption: 'text-[length:var(--typo-caption-size)] font-[number:var(--typo-caption-weight)] leading-[var(--typo-caption-leading)] tracking-[var(--typo-caption-tracking)]',\n overline: 'text-[length:var(--typo-overline-size)] font-[number:var(--typo-overline-weight)] leading-[var(--typo-overline-leading)] tracking-[var(--typo-overline-tracking)] uppercase',\n code: 'text-[length:var(--typo-code-size)] font-[number:var(--typo-code-weight)] leading-[var(--typo-code-leading)] tracking-[var(--typo-code-tracking)] font-mono',\n 'label-plain-lg': 'text-[length:var(--typo-label-plain-lg-size)] font-[number:var(--typo-label-plain-lg-weight)] leading-[var(--typo-label-plain-lg-leading)] tracking-[var(--typo-label-plain-lg-tracking)]',\n 'label-plain-md': 'text-[length:var(--typo-label-plain-md-size)] font-[number:var(--typo-label-plain-md-weight)] leading-[var(--typo-label-plain-md-leading)] tracking-[var(--typo-label-plain-md-tracking)]',\n 'label-plain-sm': 'text-[length:var(--typo-label-plain-sm-size)] font-[number:var(--typo-label-plain-sm-weight)] leading-[var(--typo-label-plain-sm-leading)] tracking-[var(--typo-label-plain-sm-tracking)]',\n },\n },\n defaultVariants: {\n variant: 'body-md',\n },\n})\n\ntype TextVariant = NonNullable<VariantProps<typeof textVariants>['variant']>\n\nconst defaultElementMap: Record<TextVariant, keyof React.JSX.IntrinsicElements> = {\n 'heading-2xl': 'h1',\n 'heading-xl': 'h2',\n 'heading-lg': 'h3',\n 'heading-md': 'h4',\n 'heading-sm': 'h5',\n 'heading-xs': 'h6',\n 'body-lg': 'p',\n 'body-md': 'p',\n 'body-sm': 'p',\n 'body-xs': 'p',\n 'label-lg': 'span',\n 'label-md': 'span',\n 'label-sm': 'span',\n 'label-xs': 'span',\n caption: 'span',\n overline: 'span',\n code: 'code',\n 'label-plain-lg': 'span',\n 'label-plain-md': 'span',\n 'label-plain-sm': 'span',\n}\n\n/**\n * Props for Text — a polymorphic typography component covering the full type scale:\n * headings, body, labels, captions, and overlines — with automatic semantic HTML element selection.\n *\n * **Variants (grouped):**\n * - Headings: `heading-2xl` → `h1`, `heading-xl` → `h2`, `heading-lg` → `h3`, etc.\n * - Body: `body-lg` | `body-md` (default) | `body-sm` | `body-xs` → `<p>`\n * - Labels: `label-lg` | `label-md` | `label-sm` | `label-xs` → `<span>` (uppercase)\n * - Misc: `caption` | `overline` → `<span>` (overline is uppercase)\n *\n * **`as` prop:** Override the rendered element. E.g. `<Text variant=\"heading-lg\" as=\"div\">` renders\n * `<div class=\"text-heading-lg ...\">` — useful when you need heading styles on a non-heading element.\n *\n * @example\n * // Page heading:\n * <Text variant=\"heading-2xl\">Welcome to Shilp Sutra</Text>\n *\n * @example\n * // Section label (uppercase, small):\n * <Text variant=\"label-sm\" className=\"text-surface-fg-muted\">Recent activity</Text>\n *\n * @example\n * // Body copy with custom element (renders as <span> for inline use):\n * <Text variant=\"body-sm\" as=\"span\" className=\"text-surface-fg-muted\">\n * Last updated 3 hours ago\n * </Text>\n *\n * @example\n * // Caption under an image or figure:\n * <Text variant=\"caption\" className=\"text-surface-fg-subtle\">Figure 1: System architecture</Text>\n * // These are just a few ways — feel free to combine props creatively!\n */\ntype TextProps<T extends React.ElementType = 'p'> = {\n variant?: TextVariant\n as?: T\n className?: string\n children?: React.ReactNode\n} & Omit<React.ComponentPropsWithRef<T>, 'as' | 'variant' | 'className' | 'children'>\n\n// Polymorphic component type — preserves T across the call site so element-\n// specific props (e.g. `htmlFor` on `as=\"label\"`, `href` on `as=\"a\"`) typecheck.\n// React.forwardRef can't keep a generic parameter live at its export, so we\n// type the implementation loosely and cast the public export to a generic\n// callable. Standard polymorphic-component pattern (same shape as Radix).\ntype TextComponent = (<T extends React.ElementType = 'p'>(\n props: TextProps<T> & { ref?: React.ComponentPropsWithRef<T>['ref'] },\n) => React.ReactElement | null) & { displayName?: string }\n\nconst TextImpl = React.forwardRef<HTMLElement, TextProps>(\n ({ variant = 'body-md', as, className, children, ...props }, ref) => {\n const Component = as || defaultElementMap[variant] || 'p'\n return React.createElement(\n Component,\n { ref, className: cn(textVariants({ variant }), className), ...props },\n children,\n )\n },\n)\nTextImpl.displayName = 'Text'\n\nconst Text = TextImpl as unknown as TextComponent\n\nexport { Text, type TextProps, type TextVariant,textVariants }\n"],"mappings":";;;;AAOA,IAAM,IAAe,EAAI,aAAa;CACpC,UAAU,EACR,SAAS;EACP,eAAe;EACf,cAAe;EACf,cAAe;EACf,cAAe;EACf,cAAe;EACf,cAAe;EACf,WAAe;EACf,WAAe;EACf,WAAe;EACf,WAAe;EACf,YAAe;EACf,YAAe;EACf,YAAe;EACf,YAAe;EACf,SAAe;EACf,UAAe;EACf,MAAmB;EACnB,kBAAmB;EACnB,kBAAmB;EACnB,kBAAmB;CACrB,EACF;CACA,iBAAiB,EACf,SAAS,UACX;AACF,CAAC,GAIK,IAA4E;CAChF,eAAe;CACf,cAAe;CACf,cAAe;CACf,cAAe;CACf,cAAe;CACf,cAAe;CACf,WAAe;CACf,WAAe;CACf,WAAe;CACf,WAAe;CACf,YAAe;CACf,YAAe;CACf,YAAe;CACf,YAAe;CACf,SAAe;CACf,UAAe;CACf,MAAmB;CACnB,kBAAmB;CACnB,kBAAmB;CACnB,kBAAmB;AACrB,GAkDM,IAAW,EAAM,YACpB,EAAE,aAAU,WAAW,OAAI,cAAW,aAAU,GAAG,KAAS,MAAQ;CACnE,IAAM,IAAY,KAAM,EAAkB,MAAY;CACtD,OAAO,EAAM,cACX,GACA;EAAE;EAAK,WAAW,EAAG,EAAa,EAAE,WAAQ,CAAC,GAAG,CAAS;EAAG,GAAG;CAAM,GACrE,CACF;AACF,CACF;AACA,EAAS,cAAc;AAEvB,IAAM,IAAO"}
|
package/dist/ui/textarea.js
CHANGED
|
@@ -20,10 +20,10 @@ var c = t([
|
|
|
20
20
|
"read-only:bg-surface-raised read-only:cursor-default"
|
|
21
21
|
], {
|
|
22
22
|
variants: { size: {
|
|
23
|
-
xs: "min-h-ds-09 text-
|
|
24
|
-
sm: "min-h-[60px] text-
|
|
25
|
-
md: "min-h-ds-11 text-
|
|
26
|
-
lg: "min-h-[120px] text-
|
|
23
|
+
xs: "min-h-ds-09 text-body-sm px-ds-02 py-ds-02",
|
|
24
|
+
sm: "min-h-[60px] text-body-sm px-ds-03 py-ds-02",
|
|
25
|
+
md: "min-h-ds-11 text-body-md px-ds-04 py-ds-03",
|
|
26
|
+
lg: "min-h-[120px] text-body-md px-ds-05 py-ds-04"
|
|
27
27
|
} },
|
|
28
28
|
defaultVariants: { size: "md" }
|
|
29
29
|
}), l = a.forwardRef(({ className: t, state: a, size: l, ...u }, d) => {
|
package/dist/ui/textarea.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textarea.js","names":[],"sources":["../../src/ui/textarea.tsx"],"sourcesContent":["'use client'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { useFormField } from './form'\nimport { type FieldState, resolveFieldState } from './lib/field-state'\nimport { motionProps } from './lib/motion'\nimport { cn } from './lib/utils'\n\nconst textareaVariants = cva(\n [\n 'flex w-full font-sans resize-y',\n 'bg-surface-raised-hover text-surface-fg',\n 'border border-surface-border-strong rounded-control',\n 'placeholder:text-surface-fg-subtle',\n 'hover:bg-surface-raised-active',\n 'transition-colors duration-fast-01 ease-productive-standard',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2 focus-visible:border-accent-7',\n 'disabled:cursor-not-allowed disabled:opacity-action-disabled',\n 'read-only:bg-surface-raised read-only:cursor-default',\n ],\n {\n variants: {\n // Min-height ramp 48/60/80/120: 48/80 map to spacing tokens (ds-09/ds-11);\n // 60/120 have no exact token so stay arbitrary (allowed). Rendered sizes unchanged.\n size: {\n xs: 'min-h-ds-09 text-
|
|
1
|
+
{"version":3,"file":"textarea.js","names":[],"sources":["../../src/ui/textarea.tsx"],"sourcesContent":["'use client'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { useFormField } from './form'\nimport { type FieldState, resolveFieldState } from './lib/field-state'\nimport { motionProps } from './lib/motion'\nimport { cn } from './lib/utils'\n\nconst textareaVariants = cva(\n [\n 'flex w-full font-sans resize-y',\n 'bg-surface-raised-hover text-surface-fg',\n 'border border-surface-border-strong rounded-control',\n 'placeholder:text-surface-fg-subtle',\n 'hover:bg-surface-raised-active',\n 'transition-colors duration-fast-01 ease-productive-standard',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2 focus-visible:border-accent-7',\n 'disabled:cursor-not-allowed disabled:opacity-action-disabled',\n 'read-only:bg-surface-raised read-only:cursor-default',\n ],\n {\n variants: {\n // Min-height ramp 48/60/80/120: 48/80 map to spacing tokens (ds-09/ds-11);\n // 60/120 have no exact token so stay arbitrary (allowed). Rendered sizes unchanged.\n size: {\n xs: 'min-h-ds-09 text-body-sm px-ds-02 py-ds-02',\n sm: 'min-h-[60px] text-body-sm px-ds-03 py-ds-02',\n md: 'min-h-ds-11 text-body-md px-ds-04 py-ds-03',\n lg: 'min-h-[120px] text-body-md px-ds-05 py-ds-04',\n },\n },\n defaultVariants: { size: 'md' },\n },\n)\n\n/**\n * Props for Textarea — a resizable multi-line text input with size variants and validation state coloring,\n * sharing the same `FieldState` type as every form control.\n *\n * **Sizes:** `sm` (min 60px) | `md` (min 80px, default) | `lg` (min 120px) — all are vertically resizable.\n *\n * **Validation states:** `state=\"error\"` | `\"warning\"` | `\"success\"` — changes border color and focus ring.\n * HTML's native `size` attribute is omitted; use `rows` for initial height or CSS `min-height`.\n *\n * **Pair with FormField:** Use inside `<FormField>` to get a label, helper text, and associated `state`.\n *\n * @example\n * // Basic description textarea in a form:\n * <Textarea placeholder=\"Describe the issue...\" rows={4} />\n *\n * @example\n * // Error state when validation fails:\n * <Textarea state=\"error\" value={bio} onChange={(e) => setBio(e.target.value)} />\n *\n * @example\n * // Large textarea for a full email draft composer:\n * <Textarea size=\"lg\" placeholder=\"Write your message...\" className=\"min-h-[200px]\" />\n *\n * @example\n * // Read-only view of a previously submitted note:\n * <Textarea readOnly value={submission.notes} size=\"md\" />\n * // These are just a few ways — feel free to combine props creatively!\n */\nexport interface TextareaProps\n extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'size'>,\n VariantProps<typeof textareaVariants> {\n state?: FieldState\n}\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, state: stateProp, size, ...props }, ref) => {\n const fieldCtx = useFormField()\n // Merge FormField context — explicit props always win (shared precedence)\n const state = resolveFieldState(stateProp, fieldCtx.state)\n const ariaDescribedBy = props['aria-describedby'] ?? fieldCtx.helperTextId\n const ariaRequired = props['aria-required'] ?? fieldCtx.required\n // Explicit id wins; otherwise adopt FormField's inputId so <Label htmlFor> resolves.\n const textareaId = props.id ?? fieldCtx.inputId\n\n return (\n <motion.textarea\n aria-invalid={state === 'error' || undefined}\n aria-describedby={ariaDescribedBy}\n aria-required={ariaRequired || undefined}\n className={cn(\n textareaVariants({ size }),\n state === 'error' && 'border-error-7 focus-visible:ring-error-7',\n state === 'warning' && 'border-warning-7 focus-visible:ring-warning-7',\n state === 'success' && 'border-success-7 focus-visible:ring-success-7',\n className,\n )}\n ref={ref}\n {...motionProps(props)}\n id={textareaId}\n />\n )\n },\n)\nTextarea.displayName = 'Textarea'\n\nexport { Textarea, textareaVariants }\n"],"mappings":";;;;;;;;;;AAWA,IAAM,IAAmB,EACvB;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GACA;CACE,UAAU,EAGR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EAAE,MAAM,KAAK;AAChC,CACF,GAoCM,IAAW,EAAM,YACpB,EAAE,cAAW,OAAO,GAAW,SAAM,GAAG,KAAS,MAAQ;CACxD,IAAM,IAAW,EAAa,GAExB,IAAQ,EAAkB,GAAW,EAAS,KAAK,GACnD,IAAkB,EAAM,uBAAuB,EAAS,cACxD,IAAe,EAAM,oBAAoB,EAAS,UAElD,IAAa,EAAM,MAAM,EAAS;CAExC,OACE,kBAAC,EAAO,UAAR;EACE,gBAAc,MAAU,WAAW,KAAA;EACnC,oBAAkB;EAClB,iBAAe,KAAgB,KAAA;EAC/B,WAAW,EACT,EAAiB,EAAE,QAAK,CAAC,GACzB,MAAU,WAAW,6CACrB,MAAU,aAAa,iDACvB,MAAU,aAAa,iDACvB,CACF;EACK;EACL,GAAI,EAAY,CAAK;EACrB,IAAI;CACL,CAAA;AAEL,CACF;AACA,EAAS,cAAc"}
|
package/dist/ui/toast.js
CHANGED
|
@@ -143,11 +143,11 @@ function k({ type: a, title: o, description: u, action: d, cancel: f, duration:
|
|
|
143
143
|
className: "min-w-0 flex-1",
|
|
144
144
|
children: [
|
|
145
145
|
o && /* @__PURE__ */ c("p", {
|
|
146
|
-
className: "text-
|
|
146
|
+
className: "text-body-md font-semibold text-surface-fg",
|
|
147
147
|
children: o
|
|
148
148
|
}),
|
|
149
149
|
u && /* @__PURE__ */ c("p", {
|
|
150
|
-
className: n("text-
|
|
150
|
+
className: n("text-body-sm text-surface-fg-muted", o && "mt-0.5"),
|
|
151
151
|
children: u
|
|
152
152
|
}),
|
|
153
153
|
(d || f) && /* @__PURE__ */ l("div", {
|
|
@@ -155,12 +155,12 @@ function k({ type: a, title: o, description: u, action: d, cancel: f, duration:
|
|
|
155
155
|
children: [d && /* @__PURE__ */ c("button", {
|
|
156
156
|
type: "button",
|
|
157
157
|
onClick: d.onClick,
|
|
158
|
-
className: "text-
|
|
158
|
+
className: "text-body-sm font-medium text-accent-11 underline-offset-2 hover:underline hover:bg-surface-raised-hover rounded-control-inner px-ds-02 py-ds-01 transition-[color,background-color] duration-fast-01 ease-productive-standard focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:rounded-control-inner",
|
|
159
159
|
children: d.label
|
|
160
160
|
}), f && /* @__PURE__ */ c("button", {
|
|
161
161
|
type: "button",
|
|
162
162
|
onClick: f.onClick,
|
|
163
|
-
className: "text-
|
|
163
|
+
className: "text-body-sm text-surface-fg-muted hover:text-surface-fg focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:rounded-control-inner",
|
|
164
164
|
children: f.label
|
|
165
165
|
})]
|
|
166
166
|
})
|
|
@@ -302,7 +302,7 @@ function F({ file: n, onRetry: o, onRemove: s }) {
|
|
|
302
302
|
})
|
|
303
303
|
}),
|
|
304
304
|
/* @__PURE__ */ c("span", {
|
|
305
|
-
className: "min-w-0 flex-1 truncate text-
|
|
305
|
+
className: "min-w-0 flex-1 truncate text-body-xs text-surface-fg",
|
|
306
306
|
children: n.name
|
|
307
307
|
}),
|
|
308
308
|
p ? /* @__PURE__ */ l("div", {
|
|
@@ -313,17 +313,17 @@ function F({ file: n, onRetry: o, onRemove: s }) {
|
|
|
313
313
|
value: N(n),
|
|
314
314
|
className: "flex-1"
|
|
315
315
|
}), n.progress !== void 0 && /* @__PURE__ */ l("span", {
|
|
316
|
-
className: "shrink-0 text-
|
|
316
|
+
className: "shrink-0 text-caption tabular-nums text-surface-fg-muted",
|
|
317
317
|
children: [n.progress, "%"]
|
|
318
318
|
})]
|
|
319
319
|
}) : n.status === "complete" ? /* @__PURE__ */ c("span", {
|
|
320
|
-
className: "text-
|
|
320
|
+
className: "text-body-xs text-success-11",
|
|
321
321
|
children: "Done"
|
|
322
322
|
}) : n.status === "error" ? /* @__PURE__ */ c("span", {
|
|
323
|
-
className: "max-w-[60px] truncate text-
|
|
323
|
+
className: "max-w-[60px] truncate text-body-xs text-error-11",
|
|
324
324
|
children: n.error || "Failed"
|
|
325
325
|
}) : /* @__PURE__ */ c("span", {
|
|
326
|
-
className: "text-
|
|
326
|
+
className: "text-caption text-surface-fg-muted",
|
|
327
327
|
children: P(n.size)
|
|
328
328
|
}),
|
|
329
329
|
n.status === "error" && o && /* @__PURE__ */ c("button", {
|
|
@@ -435,12 +435,12 @@ function I({ files: r, onRetry: a, onRemove: o, selfDismissId: d, showAccent: p
|
|
|
435
435
|
})
|
|
436
436
|
}, "upload-icon")
|
|
437
437
|
}), /* @__PURE__ */ c("p", {
|
|
438
|
-
className: "text-
|
|
438
|
+
className: "text-body-md font-semibold text-surface-fg",
|
|
439
439
|
children: T ? w > 0 ? `${b} of ${r.length} uploaded` : `${r.length} file${r.length > 1 ? "s" : ""} uploaded` : `Uploading ${r.length} file${r.length > 1 ? "s" : ""}`
|
|
440
440
|
})]
|
|
441
441
|
}),
|
|
442
442
|
!T && /* @__PURE__ */ l("p", {
|
|
443
|
-
className: "mt-0.5 text-
|
|
443
|
+
className: "mt-0.5 text-caption text-surface-fg-muted",
|
|
444
444
|
children: [
|
|
445
445
|
b,
|
|
446
446
|
" of ",
|