@seekalfred/primitives 0.5.0 → 0.5.1
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/dist/accordion/accordion.d.ts +5 -5
- package/dist/accordion/accordion.js +13 -8
- package/dist/accordion/accordion.js.map +1 -1
- package/dist/alert/alert.d.ts +1 -1
- package/dist/alert/alert.js +4 -2
- package/dist/alert/alert.js.map +1 -1
- package/dist/alert-dialog/alert-dialog.d.ts +1 -1
- package/dist/alert-dialog/alert-dialog.js +4 -2
- package/dist/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/avatar/avatar.d.ts +1 -1
- package/dist/avatar/avatar.js +6 -4
- package/dist/avatar/avatar.js.map +1 -1
- package/dist/badge/badge.d.ts +3 -3
- package/dist/badge/badge.js +4 -2
- package/dist/badge/badge.js.map +1 -1
- package/dist/breadcrumb/breadcrumb.d.ts +3 -3
- package/dist/breadcrumb/breadcrumb.js +7 -4
- package/dist/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/button/button.d.ts +3 -3
- package/dist/button/button.js +4 -2
- package/dist/button/button.js.map +1 -1
- package/dist/calendar/calendar.d.ts +2 -2
- package/dist/calendar/calendar.js +7 -5
- package/dist/calendar/calendar.js.map +1 -1
- package/dist/card/card.d.ts +6 -6
- package/dist/card/card.js +19 -12
- package/dist/card/card.js.map +1 -1
- package/dist/checkbox/checkbox.d.ts +2 -2
- package/dist/checkbox/checkbox.js +4 -2
- package/dist/checkbox/checkbox.js.map +1 -1
- package/dist/dialog/dialog.d.ts +3 -3
- package/dist/dialog/dialog.js +7 -4
- package/dist/dialog/dialog.js.map +1 -1
- package/dist/input/input.d.ts +1 -1
- package/dist/input/input.js +1 -1
- package/dist/label/label.d.ts +1 -1
- package/dist/label/label.js +4 -2
- package/dist/label/label.js.map +1 -1
- package/dist/lib/merge-refs.js +22 -0
- package/dist/lib/merge-refs.js.map +1 -0
- package/dist/menu/menu.d.ts +5 -5
- package/dist/menu/menu.js +10 -6
- package/dist/menu/menu.js.map +1 -1
- package/dist/popover/popover.d.ts +2 -2
- package/dist/popover/popover.js +4 -2
- package/dist/popover/popover.js.map +1 -1
- package/dist/progress/progress.d.ts +2 -2
- package/dist/progress/progress.js +4 -2
- package/dist/progress/progress.js.map +1 -1
- package/dist/radio-group/radio-group.d.ts +3 -3
- package/dist/radio-group/radio-group.js +7 -4
- package/dist/radio-group/radio-group.js.map +1 -1
- package/dist/scroll-area/scroll-area.d.ts +7 -6
- package/dist/scroll-area/scroll-area.js +6 -4
- package/dist/scroll-area/scroll-area.js.map +1 -1
- package/dist/select/select.d.ts +3 -3
- package/dist/select/select.js +7 -4
- package/dist/select/select.js.map +1 -1
- package/dist/separator/separator.d.ts +1 -1
- package/dist/separator/separator.js +4 -2
- package/dist/separator/separator.js.map +1 -1
- package/dist/sheet/sheet.d.ts +1 -1
- package/dist/sheet/sheet.js +4 -2
- package/dist/sheet/sheet.js.map +1 -1
- package/dist/skeleton/skeleton.d.ts +1 -1
- package/dist/skeleton/skeleton.js +4 -2
- package/dist/skeleton/skeleton.js.map +1 -1
- package/dist/slider/slider.d.ts +2 -2
- package/dist/slider/slider.js +4 -2
- package/dist/slider/slider.js.map +1 -1
- package/dist/spinner/spinner.d.ts +1 -1
- package/dist/spinner/spinner.js +4 -2
- package/dist/spinner/spinner.js.map +1 -1
- package/dist/switch/switch.d.ts +2 -2
- package/dist/switch/switch.js +4 -2
- package/dist/switch/switch.js.map +1 -1
- package/dist/table/table.d.ts +4 -4
- package/dist/table/table.js +4 -3
- package/dist/table/table.js.map +1 -1
- package/dist/tabs/tabs.d.ts +4 -4
- package/dist/tabs/tabs.js +13 -8
- package/dist/tabs/tabs.js.map +1 -1
- package/dist/textarea/textarea.d.ts +1 -1
- package/dist/textarea/textarea.js +4 -2
- package/dist/textarea/textarea.js.map +1 -1
- package/dist/toast/toast.d.ts +2 -2
- package/dist/toast/toast.js +4 -2
- package/dist/toast/toast.js.map +1 -1
- package/dist/tooltip/tooltip.d.ts +2 -2
- package/dist/tooltip/tooltip.js +4 -2
- package/dist/tooltip/tooltip.js.map +1 -1
- package/package.json +3 -3
package/dist/button/button.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VariantProps } from "class-variance-authority";
|
|
2
|
-
import { ButtonProps } from "react-aria-components";
|
|
3
2
|
import { ReactNode } from "react";
|
|
3
|
+
import { ButtonProps } from "react-aria-components";
|
|
4
4
|
//#region src/button/button.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* Variant classes, exported so a consumer can reuse the exact classes we ship
|
|
@@ -21,7 +21,7 @@ import { ReactNode } from "react";
|
|
|
21
21
|
* touch and keyboard uniformly. The original had no pressed state at all.
|
|
22
22
|
*/
|
|
23
23
|
export declare const buttonVariants: (props?: ({
|
|
24
|
-
variant?: "primary" | "
|
|
24
|
+
variant?: "primary" | "outline" | "link" | "secondary" | "outlineNeutral" | "ghost" | "destructive" | null | undefined;
|
|
25
25
|
size?: "sm" | "md" | "lg" | "icon" | null | undefined;
|
|
26
26
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
27
27
|
/**
|
|
@@ -73,7 +73,7 @@ interface ButtonProps$1 extends Omit<ButtonProps, "className" | "style">, Varian
|
|
|
73
73
|
* <Button endIcon={<ChevronIcon aria-hidden />}>Continue</Button>
|
|
74
74
|
* <Button variant="outline" size="icon" aria-label="Close"><XIcon /></Button>
|
|
75
75
|
*/
|
|
76
|
-
declare
|
|
76
|
+
declare const Button$1: import("react").ForwardRefExoticComponent<ButtonProps$1 & import("react").RefAttributes<HTMLButtonElement>>;
|
|
77
77
|
//#endregion
|
|
78
78
|
export { Button$1 as Button, ButtonProps$1 as ButtonProps };
|
|
79
79
|
//# sourceMappingURL=button.d.ts.map
|
package/dist/button/button.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
|
+
import { forwardRef } from "react";
|
|
4
5
|
import { Button } from "react-aria-components";
|
|
5
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
//#region src/button/button.tsx
|
|
@@ -106,8 +107,9 @@ const buttonVariants = cva([
|
|
|
106
107
|
* <Button endIcon={<ChevronIcon aria-hidden />}>Continue</Button>
|
|
107
108
|
* <Button variant="outline" size="icon" aria-label="Close"><XIcon /></Button>
|
|
108
109
|
*/
|
|
109
|
-
|
|
110
|
+
const Button$1 = forwardRef(function Button$2({ className, variant, size, startIcon, endIcon, children, ...props }, ref) {
|
|
110
111
|
return /* @__PURE__ */ jsx(Button, {
|
|
112
|
+
ref,
|
|
111
113
|
...props,
|
|
112
114
|
"data-slot": "button",
|
|
113
115
|
className: cn(buttonVariants({
|
|
@@ -120,7 +122,7 @@ function Button$1({ className, variant, size, startIcon, endIcon, children, ...p
|
|
|
120
122
|
endIcon
|
|
121
123
|
] })
|
|
122
124
|
});
|
|
123
|
-
}
|
|
125
|
+
});
|
|
124
126
|
//#endregion
|
|
125
127
|
export { Button$1 as Button, buttonVariants };
|
|
126
128
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","names":["Button","AriaButton"],"sources":["../../src/button/button.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport type { ReactNode } from \"react\";\nimport { Button as AriaButton, type ButtonProps as AriaButtonProps } from \"react-aria-components\";\n\nimport { cn } from \"../lib/cn.js\";\n\n/**\n * Variant classes, exported so a consumer can reuse the exact classes we ship\n * rather than guessing at them. This is also the supported answer for the\n * link-shaped cases React Aria's Button cannot cover: it never renders an\n * anchor, so `<a className={buttonVariants({ variant: \"outline\" })}>` is how a\n * real navigation target gets button styling until the Link primitive lands.\n *\n * Ported from the legacy shadcn Button. The variant and size vocabulary is\n * deliberately identical so existing call sites migrate by rename, with six\n * corrections that the Alfred contracts require -- each marked below.\n *\n * Every string here is a STATIC literal. Tailwind scans source text, so a class\n * assembled at runtime is invisible to it and would simply never be emitted.\n *\n * State comes from React Aria data attributes rather than pseudo-classes:\n * data-[focus-visible] is keyboard focus only, and data-[pressed] covers mouse,\n * touch and keyboard uniformly. The original had no pressed state at all.\n */\nexport const buttonVariants = cva(\n [\n \"inline-flex items-center justify-center gap-(--density-control-gap) shrink-0 whitespace-nowrap\",\n // No leading-* here on purpose. tailwind-merge treats a later text-* class\n // as owning line-height (a Tailwind v3 assumption, where text-base carried\n // one), so a leading-* in the base string is silently STRIPPED by cn() once\n // a size variant adds text-base. It is not needed either: the control has a\n // fixed height and centres with flex, so line-height cannot overflow it.\n // A component with auto height must put leading-* AFTER its text-* class.\n \"rounded-md font-sans font-medium\",\n \"cursor-pointer select-none\",\n\n // font-sans above is part of the same problem: a <button> does not inherit\n // the page font, so without a reset it renders in the user-agent face\n // (Arial in Chromium) rather than the design system's. The same applies to\n // bg-transparent: an unstyled <button> paints the user-agent ButtonFace\n // grey -- which is what surfaces the moment a fill class fails to resolve,\n // and is why the paint stories compare against tokens rather than checking\n // for transparency.\n //\n // The reset in @seekalfred/styles is OPT-IN, so a consumer may never load\n // one. A bare <button> then keeps its user-agent border (2px, black, in\n // Chromium) and inline padding, which is a black box around every variant\n // that does not set a border of its own. The original inherited a zeroed\n // border from Tailwind Preflight in the app; a library component cannot\n // assume the consumer supplied one.\n \"border-(length:--border-width) border-transparent bg-transparent\",\n\n // Icon handling, ported verbatim: an svg child is sized unless the caller\n // already said otherwise, and never swallows the press.\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0\",\n \"[&_svg:not([class*='size-'])]:size-(--icon-sm)\",\n\n // CORRECTION 1 -- the original focused with `ring-[3px]`, which is a\n // box-shadow. Box-shadows are discarded under forced-colors, taking the\n // only focus indication with them, and axe has no rule that would catch it\n // (ARCHITECTURE section 5, rule 6). A real outline survives.\n //\n // outline-solid on the focus variant is load-bearing, not decoration.\n // `outline-none` sets BOTH outline-style:none and --tw-outline-style:none,\n // and Tailwind's outline-width utility resolves its style from that same\n // variable -- so the focus variant applied a width and a colour while\n // faithfully re-applying style:none, and painted nothing. The button was\n // keyboard-focusable with no visible ring. axe has no focus-indicator\n // rule, so every automated gate stayed green; the KeyboardFocus story now\n // asserts outlineStyle directly.\n \"outline-none\",\n \"data-[focus-visible]:outline-solid\",\n \"data-[focus-visible]:outline-(length:--focus-ring-width)\",\n \"data-[focus-visible]:outline-offset-(--focus-ring-offset)\",\n \"data-[focus-visible]:outline-(--color-ring)\",\n\n // CORRECTION 2 -- `disabled:pointer-events-none` also kills the cursor, so\n // the control reads as inert rather than as unavailable. React Aria already\n // blocks activation; this only has to say so.\n \"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-(--opacity-disabled)\",\n\n // React Aria's own pending state. The original had no equivalent.\n \"data-[pending]:cursor-progress\",\n ],\n {\n variants: {\n variant: {\n // CORRECTION 3 -- the legacy button filled this variant with the brand\n // gradient. It is flat here, because the brand system caps\n // --gradient-brand at one intentional element per view and keeps that\n // budget for the logo and progress bars: \"a gradient on every button\n // spends that budget everywhere. Ours is the flat primary.\"\n //\n // CORRECTION 4 -- the label is ink, not white. Brand orange #FF8431\n // carries white at 2.44:1; ink clears it at 8.35:1, which is the brand\n // system's own --text-on-orange rule. Its Button ships white only as a\n // dated, individually signed-off exception, and this library's contrast\n // contract is build-failing with no exemption mechanism to inherit it.\n //\n // CORRECTION 7 -- hover and pressed are their own TOKENS, not opacity\n // modifiers on the fill. `bg-primary/90` lightened the button toward the\n // page, which reads as receding rather than interactive and was nearly\n // invisible; it also made the label pair unmeasurable, because an alpha\n // composite depends on whatever happens to sit behind it. The brand system\n // steps DOWN its ramp instead -- 500 rest, 600 hover, 700 pressed -- and\n // every one of those fills is now in the contrast contract.\n primary: [\n \"bg-primary text-primary-foreground shadow-surface\",\n \"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard\",\n \"data-[hovered]:bg-primary-hover\",\n \"data-[pressed]:bg-primary-pressed\",\n ],\n secondary: [\n \"bg-secondary text-secondary-foreground shadow-surface\",\n \"motion-safe:transition-colors\",\n \"data-[hovered]:bg-secondary-hover\",\n \"data-[pressed]:bg-secondary-pressed\",\n ],\n // primary-strong, never primary: the brand orange is 2.44:1 on the page\n // and cannot legally be a label OR a border. That is the whole reason\n // the token exists.\n outline: [\n \"bg-background text-primary-strong border-(length:--border-width) border-primary-strong shadow-surface\",\n \"motion-safe:transition-colors\",\n \"data-[hovered]:bg-muted\",\n \"data-[pressed]:bg-muted data-[pressed]:border-foreground\",\n ],\n /*\n * The NEUTRAL outline, and the product's single most-used button:\n * 99 call sites against 32 for the brand-coloured one.\n *\n * It exists because `outline` above is brand-toned -- orange border,\n * orange label -- which is what the product calls `secondaryOutline`.\n * Its plain `outline` is this: a grey border and ordinary body text,\n * for a button that must not compete with the primary action next to\n * it. One name could not cover both, and renaming `outline` would have\n * silently repainted every existing call site of ours instead.\n *\n * `border` rather than `primary-strong`: --color-border is the token\n * already held to the 3:1 non-text floor of WCAG 1.4.11, which is what\n * a border separating a control from the page has to clear.\n */\n outlineNeutral: [\n \"bg-background text-foreground border-(length:--border-width) border-border shadow-surface\",\n \"motion-safe:transition-colors\",\n \"data-[hovered]:bg-muted\",\n \"data-[pressed]:bg-muted data-[pressed]:border-foreground\",\n ],\n ghost: [\n \"bg-transparent text-primary-strong\",\n \"motion-safe:transition-colors\",\n \"data-[hovered]:bg-muted\",\n // CORRECTION 5 -- pressed must not be background-only. A ghost button\n // has no border at rest, so the pressed border is the non-colour cue\n // that survives forced-colors (rule 6 again).\n \"data-[pressed]:bg-muted data-[pressed]:border-primary-strong\",\n ],\n destructive: [\n \"bg-destructive text-destructive-foreground shadow-surface\",\n \"motion-safe:transition-colors\",\n \"data-[hovered]:bg-destructive-hover\",\n \"data-[pressed]:bg-destructive-pressed\",\n ],\n link: [\n \"bg-transparent text-primary-strong underline-offset-(--underline-offset)\",\n \"data-[hovered]:underline\",\n \"data-[pressed]:underline\",\n ],\n },\n size: {\n // Height, padding and label size all come from the control scale, so\n // data-density moves them together. The icon-only variant is square at\n // the md height. The legacy shadcn rule that tightened padding when a\n // child was an icon is gone: it needed three more magic numbers, the\n // brand system has no equivalent, and the gap token now owns icon\n // spacing.\n sm: \"h-(--density-control-h-sm) px-(--density-control-pad-sm) text-sm\",\n md: \"h-(--density-control-h-md) px-(--density-control-pad-md) text-base\",\n lg: \"h-(--density-control-h-lg) px-(--density-control-pad-lg) text-lg\",\n // text-base even though there is no visible label: without it the\n // user-agent default (13.33px in Chromium) leaks in and sizes any\n // em-based child against the wrong root.\n icon: \"size-(--density-control-h-md) px-0 text-base\",\n },\n },\n defaultVariants: {\n variant: \"primary\",\n size: \"md\",\n },\n },\n);\n\n/**\n * Props.\n *\n * CORRECTION 6 -- the legacy Button was a plain `<button>`, so it took\n * `onClick`, `disabled` and Radix's `asChild`. React Aria's Button has none of\n * those: `ButtonProps` explicitly omits `onClick` and `href`. The replacements\n * are `onPress`, `isDisabled`, and `buttonVariants()` on the consumer's own\n * element. See the migration table in the package README.\n *\n * Deliberately NOT intersected with ComponentPropsWithoutRef<\"button\">: that\n * would advertise disabled, tabIndex and role, which React Aria does not\n * implement and silently ignores. React Aria already forwards the native event\n * surface, so nothing is lost.\n */\nexport interface ButtonProps\n extends Omit<AriaButtonProps, \"className\" | \"style\">, VariantProps<typeof buttonVariants> {\n /** Extra classes. Merged last, so they win conflicts with ours. */\n className?: string;\n /**\n * Icon rendered before the label.\n *\n * Mark the glyph `aria-hidden` -- the label is the accessible name, and a\n * second name source only makes the button announce twice. It is sized by the\n * base `[&_svg]` rule at `--icon-sm` unless it carries a `size-*` class of\n * its own, and spaced by `--density-control-gap`.\n *\n * Two named slots rather than one `icon` plus a position prop: a button can\n * legitimately carry a leading glyph AND a trailing affordance, which one\n * icon and a position cannot express.\n *\n * NOT the route for `size=\"icon\"`. An icon-only button passes its glyph as\n * `children`, which is what gives it its single centred child.\n */\n startIcon?: ReactNode;\n /** Icon rendered after the label. Same rules as {@link ButtonProps.startIcon}. */\n endIcon?: ReactNode;\n}\n\n/**\n * A button.\n *\n * `size=\"icon\"` renders a square button with no visible text, so it **must**\n * carry an `aria-label` -- otherwise it has no accessible name and fails axe's\n * `button-name` rule. The IconOnly story is the guard on that.\n *\n * @example\n * <Button onPress={save}>Save changes</Button>\n * <Button startIcon={<SaveIcon aria-hidden />}>Save changes</Button>\n * <Button endIcon={<ChevronIcon aria-hidden />}>Continue</Button>\n * <Button variant=\"outline\" size=\"icon\" aria-label=\"Close\"><XIcon /></Button>\n */\nexport function Button({\n className,\n variant,\n size,\n startIcon,\n endIcon,\n children,\n ...props\n}: ButtonProps) {\n return (\n <AriaButton\n {...props}\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size }), className)}\n >\n {/*\n * children passes through UNTOUCHED when neither slot is used, so a\n * button with no icon renders byte-identical DOM to before this prop\n * existed. That is what keeps this an additive change rather than a\n * structural one -- and the childOrder assertions in the stories are what\n * hold it true, since they read the button's direct children.\n *\n * The slot branch has to be a render function because React Aria's\n * children are ChildrenOrFunction<ButtonRenderProps>: a consumer may pass\n * a function to read isPressed or isPending, and wrapping the node\n * directly would silently render that function as nothing. The fragment\n * adds no element of its own.\n */}\n {startIcon === undefined && endIcon === undefined\n ? children\n : (renderProps) => (\n <>\n {startIcon}\n {typeof children === \"function\" ? children(renderProps) : children}\n {endIcon}\n </>\n )}\n </AriaButton>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAa,iBAAiB,IAC5B;CACE;CAOA;CACA;CAgBA;CAIA;CACA;CAeA;CACA;CACA;CACA;CACA;CAKA;CAGA;AACF,GACA;CACE,UAAU;EACR,SAAS;GAoBP,SAAS;IACP;IACA;IACA;IACA;GACF;GACA,WAAW;IACT;IACA;IACA;IACA;GACF;GAIA,SAAS;IACP;IACA;IACA;IACA;GACF;GAgBA,gBAAgB;IACd;IACA;IACA;IACA;GACF;GACA,OAAO;IACL;IACA;IACA;IAIA;GACF;GACA,aAAa;IACX;IACA;IACA;IACA;GACF;GACA,MAAM;IACJ;IACA;IACA;GACF;EACF;EACA,MAAM;GAOJ,IAAI;GACJ,IAAI;GACJ,IAAI;GAIJ,MAAM;EACR;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CACF;;;;;;;;;;;;;;AAqDA,SAAgBA,SAAO,EACrB,WACA,SACA,MACA,WACA,SACA,UACA,GAAG,SACW;CACd,OACE,oBAACC,QAAD;EACE,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,eAAe;GAAE;GAAS;EAAK,CAAC,GAAG,SAAS;EAezD,UAAA,cAAc,KAAA,KAAa,YAAY,KAAA,IACpC,YACC,gBACC,qBAAA,UAAA,EAAA,UAAA;GACG;GACA,OAAO,aAAa,aAAa,SAAS,WAAW,IAAI;GACzD;EACD,EAAA,CAAA;CAEE,CAAA;AAEhB"}
|
|
1
|
+
{"version":3,"file":"button.js","names":["Button","AriaButton"],"sources":["../../src/button/button.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { forwardRef, type ReactNode } from \"react\";\nimport { Button as AriaButton, type ButtonProps as AriaButtonProps } from \"react-aria-components\";\n\nimport { cn } from \"../lib/cn.js\";\n\n/**\n * Variant classes, exported so a consumer can reuse the exact classes we ship\n * rather than guessing at them. This is also the supported answer for the\n * link-shaped cases React Aria's Button cannot cover: it never renders an\n * anchor, so `<a className={buttonVariants({ variant: \"outline\" })}>` is how a\n * real navigation target gets button styling until the Link primitive lands.\n *\n * Ported from the legacy shadcn Button. The variant and size vocabulary is\n * deliberately identical so existing call sites migrate by rename, with six\n * corrections that the Alfred contracts require -- each marked below.\n *\n * Every string here is a STATIC literal. Tailwind scans source text, so a class\n * assembled at runtime is invisible to it and would simply never be emitted.\n *\n * State comes from React Aria data attributes rather than pseudo-classes:\n * data-[focus-visible] is keyboard focus only, and data-[pressed] covers mouse,\n * touch and keyboard uniformly. The original had no pressed state at all.\n */\nexport const buttonVariants = cva(\n [\n \"inline-flex items-center justify-center gap-(--density-control-gap) shrink-0 whitespace-nowrap\",\n // No leading-* here on purpose. tailwind-merge treats a later text-* class\n // as owning line-height (a Tailwind v3 assumption, where text-base carried\n // one), so a leading-* in the base string is silently STRIPPED by cn() once\n // a size variant adds text-base. It is not needed either: the control has a\n // fixed height and centres with flex, so line-height cannot overflow it.\n // A component with auto height must put leading-* AFTER its text-* class.\n \"rounded-md font-sans font-medium\",\n \"cursor-pointer select-none\",\n\n // font-sans above is part of the same problem: a <button> does not inherit\n // the page font, so without a reset it renders in the user-agent face\n // (Arial in Chromium) rather than the design system's. The same applies to\n // bg-transparent: an unstyled <button> paints the user-agent ButtonFace\n // grey -- which is what surfaces the moment a fill class fails to resolve,\n // and is why the paint stories compare against tokens rather than checking\n // for transparency.\n //\n // The reset in @seekalfred/styles is OPT-IN, so a consumer may never load\n // one. A bare <button> then keeps its user-agent border (2px, black, in\n // Chromium) and inline padding, which is a black box around every variant\n // that does not set a border of its own. The original inherited a zeroed\n // border from Tailwind Preflight in the app; a library component cannot\n // assume the consumer supplied one.\n \"border-(length:--border-width) border-transparent bg-transparent\",\n\n // Icon handling, ported verbatim: an svg child is sized unless the caller\n // already said otherwise, and never swallows the press.\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0\",\n \"[&_svg:not([class*='size-'])]:size-(--icon-sm)\",\n\n // CORRECTION 1 -- the original focused with `ring-[3px]`, which is a\n // box-shadow. Box-shadows are discarded under forced-colors, taking the\n // only focus indication with them, and axe has no rule that would catch it\n // (ARCHITECTURE section 5, rule 6). A real outline survives.\n //\n // outline-solid on the focus variant is load-bearing, not decoration.\n // `outline-none` sets BOTH outline-style:none and --tw-outline-style:none,\n // and Tailwind's outline-width utility resolves its style from that same\n // variable -- so the focus variant applied a width and a colour while\n // faithfully re-applying style:none, and painted nothing. The button was\n // keyboard-focusable with no visible ring. axe has no focus-indicator\n // rule, so every automated gate stayed green; the KeyboardFocus story now\n // asserts outlineStyle directly.\n \"outline-none\",\n \"data-[focus-visible]:outline-solid\",\n \"data-[focus-visible]:outline-(length:--focus-ring-width)\",\n \"data-[focus-visible]:outline-offset-(--focus-ring-offset)\",\n \"data-[focus-visible]:outline-(--color-ring)\",\n\n // CORRECTION 2 -- `disabled:pointer-events-none` also kills the cursor, so\n // the control reads as inert rather than as unavailable. React Aria already\n // blocks activation; this only has to say so.\n \"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-(--opacity-disabled)\",\n\n // React Aria's own pending state. The original had no equivalent.\n \"data-[pending]:cursor-progress\",\n ],\n {\n variants: {\n variant: {\n // CORRECTION 3 -- the legacy button filled this variant with the brand\n // gradient. It is flat here, because the brand system caps\n // --gradient-brand at one intentional element per view and keeps that\n // budget for the logo and progress bars: \"a gradient on every button\n // spends that budget everywhere. Ours is the flat primary.\"\n //\n // CORRECTION 4 -- the label is ink, not white. Brand orange #FF8431\n // carries white at 2.44:1; ink clears it at 8.35:1, which is the brand\n // system's own --text-on-orange rule. Its Button ships white only as a\n // dated, individually signed-off exception, and this library's contrast\n // contract is build-failing with no exemption mechanism to inherit it.\n //\n // CORRECTION 7 -- hover and pressed are their own TOKENS, not opacity\n // modifiers on the fill. `bg-primary/90` lightened the button toward the\n // page, which reads as receding rather than interactive and was nearly\n // invisible; it also made the label pair unmeasurable, because an alpha\n // composite depends on whatever happens to sit behind it. The brand system\n // steps DOWN its ramp instead -- 500 rest, 600 hover, 700 pressed -- and\n // every one of those fills is now in the contrast contract.\n primary: [\n \"bg-primary text-primary-foreground shadow-surface\",\n \"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard\",\n \"data-[hovered]:bg-primary-hover\",\n \"data-[pressed]:bg-primary-pressed\",\n ],\n secondary: [\n \"bg-secondary text-secondary-foreground shadow-surface\",\n \"motion-safe:transition-colors\",\n \"data-[hovered]:bg-secondary-hover\",\n \"data-[pressed]:bg-secondary-pressed\",\n ],\n // primary-strong, never primary: the brand orange is 2.44:1 on the page\n // and cannot legally be a label OR a border. That is the whole reason\n // the token exists.\n outline: [\n \"bg-background text-primary-strong border-(length:--border-width) border-primary-strong shadow-surface\",\n \"motion-safe:transition-colors\",\n \"data-[hovered]:bg-muted\",\n \"data-[pressed]:bg-muted data-[pressed]:border-foreground\",\n ],\n /*\n * The NEUTRAL outline, and the product's single most-used button:\n * 99 call sites against 32 for the brand-coloured one.\n *\n * It exists because `outline` above is brand-toned -- orange border,\n * orange label -- which is what the product calls `secondaryOutline`.\n * Its plain `outline` is this: a grey border and ordinary body text,\n * for a button that must not compete with the primary action next to\n * it. One name could not cover both, and renaming `outline` would have\n * silently repainted every existing call site of ours instead.\n *\n * `border` rather than `primary-strong`: --color-border is the token\n * already held to the 3:1 non-text floor of WCAG 1.4.11, which is what\n * a border separating a control from the page has to clear.\n */\n outlineNeutral: [\n \"bg-background text-foreground border-(length:--border-width) border-border shadow-surface\",\n \"motion-safe:transition-colors\",\n \"data-[hovered]:bg-muted\",\n \"data-[pressed]:bg-muted data-[pressed]:border-foreground\",\n ],\n ghost: [\n \"bg-transparent text-primary-strong\",\n \"motion-safe:transition-colors\",\n \"data-[hovered]:bg-muted\",\n // CORRECTION 5 -- pressed must not be background-only. A ghost button\n // has no border at rest, so the pressed border is the non-colour cue\n // that survives forced-colors (rule 6 again).\n \"data-[pressed]:bg-muted data-[pressed]:border-primary-strong\",\n ],\n destructive: [\n \"bg-destructive text-destructive-foreground shadow-surface\",\n \"motion-safe:transition-colors\",\n \"data-[hovered]:bg-destructive-hover\",\n \"data-[pressed]:bg-destructive-pressed\",\n ],\n link: [\n \"bg-transparent text-primary-strong underline-offset-(--underline-offset)\",\n \"data-[hovered]:underline\",\n \"data-[pressed]:underline\",\n ],\n },\n size: {\n // Height, padding and label size all come from the control scale, so\n // data-density moves them together. The icon-only variant is square at\n // the md height. The legacy shadcn rule that tightened padding when a\n // child was an icon is gone: it needed three more magic numbers, the\n // brand system has no equivalent, and the gap token now owns icon\n // spacing.\n sm: \"h-(--density-control-h-sm) px-(--density-control-pad-sm) text-sm\",\n md: \"h-(--density-control-h-md) px-(--density-control-pad-md) text-base\",\n lg: \"h-(--density-control-h-lg) px-(--density-control-pad-lg) text-lg\",\n // text-base even though there is no visible label: without it the\n // user-agent default (13.33px in Chromium) leaks in and sizes any\n // em-based child against the wrong root.\n icon: \"size-(--density-control-h-md) px-0 text-base\",\n },\n },\n defaultVariants: {\n variant: \"primary\",\n size: \"md\",\n },\n },\n);\n\n/**\n * Props.\n *\n * CORRECTION 6 -- the legacy Button was a plain `<button>`, so it took\n * `onClick`, `disabled` and Radix's `asChild`. React Aria's Button has none of\n * those: `ButtonProps` explicitly omits `onClick` and `href`. The replacements\n * are `onPress`, `isDisabled`, and `buttonVariants()` on the consumer's own\n * element. See the migration table in the package README.\n *\n * Deliberately NOT intersected with ComponentPropsWithoutRef<\"button\">: that\n * would advertise disabled, tabIndex and role, which React Aria does not\n * implement and silently ignores. React Aria already forwards the native event\n * surface, so nothing is lost.\n */\nexport interface ButtonProps\n extends Omit<AriaButtonProps, \"className\" | \"style\">, VariantProps<typeof buttonVariants> {\n /** Extra classes. Merged last, so they win conflicts with ours. */\n className?: string;\n /**\n * Icon rendered before the label.\n *\n * Mark the glyph `aria-hidden` -- the label is the accessible name, and a\n * second name source only makes the button announce twice. It is sized by the\n * base `[&_svg]` rule at `--icon-sm` unless it carries a `size-*` class of\n * its own, and spaced by `--density-control-gap`.\n *\n * Two named slots rather than one `icon` plus a position prop: a button can\n * legitimately carry a leading glyph AND a trailing affordance, which one\n * icon and a position cannot express.\n *\n * NOT the route for `size=\"icon\"`. An icon-only button passes its glyph as\n * `children`, which is what gives it its single centred child.\n */\n startIcon?: ReactNode;\n /** Icon rendered after the label. Same rules as {@link ButtonProps.startIcon}. */\n endIcon?: ReactNode;\n}\n\n/**\n * A button.\n *\n * `size=\"icon\"` renders a square button with no visible text, so it **must**\n * carry an `aria-label` -- otherwise it has no accessible name and fails axe's\n * `button-name` rule. The IconOnly story is the guard on that.\n *\n * @example\n * <Button onPress={save}>Save changes</Button>\n * <Button startIcon={<SaveIcon aria-hidden />}>Save changes</Button>\n * <Button endIcon={<ChevronIcon aria-hidden />}>Continue</Button>\n * <Button variant=\"outline\" size=\"icon\" aria-label=\"Close\"><XIcon /></Button>\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n { className, variant, size, startIcon, endIcon, children, ...props },\n ref,\n) {\n return (\n <AriaButton\n ref={ref}\n {...props}\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size }), className)}\n >\n {/*\n * children passes through UNTOUCHED when neither slot is used, so a\n * button with no icon renders byte-identical DOM to before this prop\n * existed. That is what keeps this an additive change rather than a\n * structural one -- and the childOrder assertions in the stories are what\n * hold it true, since they read the button's direct children.\n *\n * The slot branch has to be a render function because React Aria's\n * children are ChildrenOrFunction<ButtonRenderProps>: a consumer may pass\n * a function to read isPressed or isPending, and wrapping the node\n * directly would silently render that function as nothing. The fragment\n * adds no element of its own.\n */}\n {startIcon === undefined && endIcon === undefined\n ? children\n : (renderProps) => (\n <>\n {startIcon}\n {typeof children === \"function\" ? children(renderProps) : children}\n {endIcon}\n </>\n )}\n </AriaButton>\n );\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAa,iBAAiB,IAC5B;CACE;CAOA;CACA;CAgBA;CAIA;CACA;CAeA;CACA;CACA;CACA;CACA;CAKA;CAGA;AACF,GACA;CACE,UAAU;EACR,SAAS;GAoBP,SAAS;IACP;IACA;IACA;IACA;GACF;GACA,WAAW;IACT;IACA;IACA;IACA;GACF;GAIA,SAAS;IACP;IACA;IACA;IACA;GACF;GAgBA,gBAAgB;IACd;IACA;IACA;IACA;GACF;GACA,OAAO;IACL;IACA;IACA;IAIA;GACF;GACA,aAAa;IACX;IACA;IACA;IACA;GACF;GACA,MAAM;IACJ;IACA;IACA;GACF;EACF;EACA,MAAM;GAOJ,IAAI;GACJ,IAAI;GACJ,IAAI;GAIJ,MAAM;EACR;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CACF;;;;;;;;;;;;;;AAqDA,MAAaA,WAAS,WAA2C,SAASA,SACxE,EAAE,WAAW,SAAS,MAAM,WAAW,SAAS,UAAU,GAAG,SAC7D,KACA;CACA,OACE,oBAACC,QAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,eAAe;GAAE;GAAS;EAAK,CAAC,GAAG,SAAS;EAezD,UAAA,cAAc,KAAA,KAAa,YAAY,KAAA,IACpC,YACC,gBACC,qBAAA,UAAA,EAAA,UAAA;GACG;GACA,OAAO,aAAa,aAAa,SAAS,WAAW,IAAI;GACzD;EACD,EAAA,CAAA;CAEE,CAAA;AAEhB,CAAC"}
|
|
@@ -138,7 +138,7 @@ export interface CalendarRangeProps extends Omit<RangeCalendarProps<DateValue>,
|
|
|
138
138
|
* @example
|
|
139
139
|
* <Calendar label="Report date" value={date} onChange={setDate} clearable />
|
|
140
140
|
*/
|
|
141
|
-
declare
|
|
141
|
+
declare const Calendar$1: import("react").ForwardRefExoticComponent<CalendarProps$1 & import("react").RefAttributes<HTMLDivElement>>;
|
|
142
142
|
/**
|
|
143
143
|
* A calendar for picking a contiguous date range.
|
|
144
144
|
*
|
|
@@ -148,7 +148,7 @@ declare function Calendar$1({ className, label, labelHidden, visibleMonths, clea
|
|
|
148
148
|
* <CalendarRange label="Period" visibleMonths={3}
|
|
149
149
|
* value={range} onChange={setRange} clearable />
|
|
150
150
|
*/
|
|
151
|
-
export declare
|
|
151
|
+
export declare const CalendarRange: import("react").ForwardRefExoticComponent<CalendarRangeProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
152
152
|
//#endregion
|
|
153
153
|
export { Calendar$1 as Calendar, CalendarProps$1 as CalendarProps };
|
|
154
154
|
//# sourceMappingURL=calendar.d.ts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
|
+
import { forwardRef, useContext } from "react";
|
|
4
5
|
import { Button, Calendar, CalendarCell, CalendarGrid, CalendarGridBody, CalendarGridHeader, CalendarHeaderCell, CalendarHeading, CalendarStateContext, RangeCalendar, RangeCalendarStateContext } from "react-aria-components";
|
|
5
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
-
import { useContext } from "react";
|
|
7
7
|
//#region src/calendar/calendar.tsx
|
|
8
8
|
/**
|
|
9
9
|
* Calendar, built on React Aria's Calendar and RangeCalendar.
|
|
@@ -225,8 +225,9 @@ function CalendarBody({ visibleMonths, clearable, clearLabel, previousLabel, nex
|
|
|
225
225
|
* @example
|
|
226
226
|
* <Calendar label="Report date" value={date} onChange={setDate} clearable />
|
|
227
227
|
*/
|
|
228
|
-
|
|
228
|
+
const Calendar$1 = forwardRef(function Calendar$2({ className, label, labelHidden = false, visibleMonths = 1, clearable = false, clearLabel = "Clear", previousLabel = "Previous month", nextLabel = "Next month", ...props }, ref) {
|
|
229
229
|
return /* @__PURE__ */ jsxs(Calendar, {
|
|
230
|
+
ref,
|
|
230
231
|
...props,
|
|
231
232
|
"aria-label": label,
|
|
232
233
|
visibleDuration: { months: visibleMonths },
|
|
@@ -245,7 +246,7 @@ function Calendar$1({ className, label, labelHidden = false, visibleMonths = 1,
|
|
|
245
246
|
selection: "single"
|
|
246
247
|
})]
|
|
247
248
|
});
|
|
248
|
-
}
|
|
249
|
+
});
|
|
249
250
|
/**
|
|
250
251
|
* A calendar for picking a contiguous date range.
|
|
251
252
|
*
|
|
@@ -255,8 +256,9 @@ function Calendar$1({ className, label, labelHidden = false, visibleMonths = 1,
|
|
|
255
256
|
* <CalendarRange label="Period" visibleMonths={3}
|
|
256
257
|
* value={range} onChange={setRange} clearable />
|
|
257
258
|
*/
|
|
258
|
-
function CalendarRange({ className, label, labelHidden = false, visibleMonths = 1, clearable = false, clearLabel = "Clear", previousLabel = "Previous month", nextLabel = "Next month", ...props }) {
|
|
259
|
+
const CalendarRange = forwardRef(function CalendarRange({ className, label, labelHidden = false, visibleMonths = 1, clearable = false, clearLabel = "Clear", previousLabel = "Previous month", nextLabel = "Next month", ...props }, ref) {
|
|
259
260
|
return /* @__PURE__ */ jsxs(RangeCalendar, {
|
|
261
|
+
ref,
|
|
260
262
|
...props,
|
|
261
263
|
"aria-label": label,
|
|
262
264
|
visibleDuration: { months: visibleMonths },
|
|
@@ -275,7 +277,7 @@ function CalendarRange({ className, label, labelHidden = false, visibleMonths =
|
|
|
275
277
|
selection: "range"
|
|
276
278
|
})]
|
|
277
279
|
});
|
|
278
|
-
}
|
|
280
|
+
});
|
|
279
281
|
//#endregion
|
|
280
282
|
export { Calendar$1 as Calendar, CalendarRange, calendarCellVariants, calendarClearVariants, calendarGridVariants, calendarHeaderCellVariants, calendarHeaderVariants, calendarHeadingVariants, calendarLabelVariants, calendarMonthsVariants, calendarNavVariants, calendarVariants };
|
|
281
283
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar.js","names":["AriaButton","AriaCalendarHeading","AriaCalendarGrid","AriaCalendarGridHeader","AriaCalendarHeaderCell","AriaCalendarGridBody","AriaCalendarCell","Calendar","AriaCalendar","AriaRangeCalendar"],"sources":["../../src/calendar/calendar.tsx"],"sourcesContent":["\"use client\";\n\nimport type { DateValue } from \"@internationalized/date\";\nimport { cva } from \"class-variance-authority\";\nimport { useContext } from \"react\";\nimport {\n Button as AriaButton,\n Calendar as AriaCalendar,\n CalendarCell as AriaCalendarCell,\n CalendarGrid as AriaCalendarGrid,\n CalendarGridBody as AriaCalendarGridBody,\n CalendarGridHeader as AriaCalendarGridHeader,\n CalendarHeaderCell as AriaCalendarHeaderCell,\n CalendarHeading as AriaCalendarHeading,\n CalendarStateContext,\n RangeCalendar as AriaRangeCalendar,\n RangeCalendarStateContext,\n type CalendarProps as AriaCalendarProps,\n type RangeCalendarProps as AriaRangeCalendarProps,\n} from \"react-aria-components\";\n\nimport { cn } from \"../lib/cn.js\";\n\n/**\n * Calendar, built on React Aria's Calendar and RangeCalendar.\n *\n * Values are `DateValue` objects from `@internationalized/date`, NOT JS\n * `Date`. ADR 0006 names that package the one allowed public type dependency\n * precisely here: a calendar day has no time zone, so modelling it as a\n * timestamp is what costs you a day at a DST boundary. The import is\n * `import type` only — nothing at runtime needs a constructor from it, so the\n * package contributes zero bytes to the bundle.\n *\n * Every string below is a STATIC literal. Tailwind scans source text, so a\n * class assembled at runtime is invisible to it and would simply never be\n * emitted — the component would render unstyled, with no error anywhere.\n *\n * State comes from React Aria's data attributes rather than pseudo-classes:\n * `data-[focus-visible]` is keyboard focus only, and `data-[hovered]` /\n * `data-[pressed]` cover pointer, touch and keyboard uniformly.\n */\nexport const calendarVariants = cva([\n \"flex w-fit flex-col gap-(--density-gap) box-border\",\n \"font-sans text-sm leading-(--leading-normal) text-foreground\",\n]);\n\nexport const calendarLabelVariants = cva([\"text-sm font-medium text-foreground\"]);\n\nexport const calendarHeaderVariants = cva([\n \"flex items-center justify-between gap-(--density-control-gap)\",\n]);\n\n/**\n * The month/prev/next buttons.\n *\n * Deliberately NOT `buttonVariants` from ../button. That would put a\n * cross-component import in the bundle for one caller and six classes, and\n * DRY extracts at two callers, not one.\n */\nexport const calendarNavVariants = cva([\n \"inline-flex shrink-0 items-center justify-center\",\n \"size-(--density-control-h-sm) rounded-md\",\n // A library consumer may load no reset at all, so a bare <button> keeps its\n // user-agent border and ButtonFace grey without these two.\n \"border-(length:--border-width) border-transparent bg-transparent\",\n \"cursor-pointer select-none text-foreground outline-none\",\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0\",\n \"[&_svg:not([class*='size-'])]:size-(--icon-sm)\",\n // The glyph is directional where the BEHAVIOUR is logical: React Aria maps\n // slot=\"previous\" to the correct month either way, so only the arrow flips.\n \"[&_svg]:rtl:-scale-x-100\",\n \"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard\",\n \"data-[hovered]:bg-muted data-[pressed]:bg-muted\",\n \"data-[focus-visible]:outline-solid data-[focus-visible]:outline-(length:--focus-ring-width)\",\n \"data-[focus-visible]:outline-offset-(--focus-ring-offset) data-[focus-visible]:outline-(--color-ring)\",\n \"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-(--opacity-disabled)\",\n]);\n\nexport const calendarMonthsVariants = cva([\n \"flex flex-col gap-(--density-gap) sm:flex-row sm:items-start\",\n]);\n\nexport const calendarHeadingVariants = cva([\n \"mb-1 text-center text-sm font-semibold text-foreground\",\n]);\n\nexport const calendarGridVariants = cva([\n // Without this a bare <table> falls back to user-agent border spacing and\n // the range band shows gaps between cells.\n \"border-collapse\",\n]);\n\nexport const calendarHeaderCellVariants = cva([\n \"w-(--density-control-h-sm) pb-1\",\n \"text-center text-2xs font-medium text-muted-foreground\",\n]);\n\nexport const calendarClearVariants = cva([\n \"self-end rounded-md px-2 py-1\",\n \"border-(length:--border-width) border-transparent bg-transparent\",\n \"cursor-pointer select-none text-sm text-muted-foreground outline-none\",\n \"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard\",\n \"data-[hovered]:bg-muted data-[hovered]:text-foreground\",\n \"data-[focus-visible]:outline-solid data-[focus-visible]:outline-(length:--focus-ring-width)\",\n \"data-[focus-visible]:outline-offset-(--focus-ring-offset) data-[focus-visible]:outline-(--color-ring)\",\n]);\n\n/**\n * A day.\n *\n * Sized from `--density-control-h-sm` rather than a new\n * `--density-calendar-cell`: the density contract test requires every scope to\n * declare every token name, so a new one is three file edits — and this one is\n * already 30/36/42px, all clear of the 24px floor that WCAG 2.2 SC 2.5.8 sets.\n *\n * ARCHITECTURE section 5 rule 6 — no state is carried by colour alone, because\n * every author colour is replaced under forced-colors and the distinction\n * would vanish. Selected adds weight, the range ends add SHAPE, today is an\n * underline (not an outline, which would fight the focus ring) and unavailable\n * is a strikethrough.\n */\nexport const calendarCellVariants = cva(\n [\n \"flex items-center justify-center box-border\",\n \"size-(--density-control-h-sm) rounded-md\",\n \"text-sm leading-(--leading-normal) text-foreground\",\n \"cursor-pointer select-none outline-none\",\n \"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard\",\n \"data-[hovered]:bg-muted\",\n \"data-[today]:font-semibold data-[today]:underline data-[today]:underline-offset-4\",\n \"data-[outside-month]:text-muted-foreground data-[outside-month]:opacity-(--opacity-disabled)\",\n // Unavailable dates stay FOCUSABLE, so ADR 0007 holds them to 4.5:1 — this\n // dims to muted-foreground, which the contrast contract grades, never below.\n \"data-[unavailable]:cursor-not-allowed data-[unavailable]:text-muted-foreground\",\n \"data-[unavailable]:line-through\",\n \"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-(--opacity-disabled)\",\n \"data-[focus-visible]:outline-solid data-[focus-visible]:outline-(length:--focus-ring-width)\",\n \"data-[focus-visible]:outline-offset-(--focus-ring-offset) data-[focus-visible]:outline-(--color-ring)\",\n ],\n {\n variants: {\n /**\n * A variant axis rather than a boolean prop, because the two modes are\n * mutually exclusive visual treatments of the same element — which is\n * exactly what OCP asks a variant to model.\n */\n selection: {\n single: [\n \"data-[selected]:bg-primary data-[selected]:text-primary-foreground\",\n \"data-[selected]:font-semibold\",\n ],\n range: [\n // The band is `muted` — a pair the contrast contract already grades\n // at 4.5:1, so the range needs no new contrast-pairs.json entry.\n \"data-[selected]:rounded-none data-[selected]:bg-muted data-[selected]:text-foreground\",\n \"data-[selection-start]:rounded-s-md data-[selection-start]:bg-primary\",\n \"data-[selection-start]:font-semibold data-[selection-start]:text-primary-foreground\",\n \"data-[selection-end]:rounded-e-md data-[selection-end]:bg-primary\",\n \"data-[selection-end]:font-semibold data-[selection-end]:text-primary-foreground\",\n ],\n },\n },\n defaultVariants: { selection: \"single\" },\n },\n);\n\nfunction ChevronPrevious() {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n );\n}\n\nfunction ChevronNext() {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n );\n}\n\n/**\n * Resets the selection to null.\n *\n * It reads the calendar state from React Aria's context and calls\n * `setValue(null)`, which runs through `useControlledState` — so it fires\n * `onChange` for a controlled parent AND updates uncontrolled state, with no\n * mirrored state here. That is the whole reason there is no `onClear` prop:\n * from inside the provider tree the reset is free, and from outside it it\n * would force every consumer to own the value.\n *\n * The two states are narrowed separately rather than through a union, because\n * `setValue` has a different parameter type on each and the union call is not\n * assignable to either.\n *\n * `slot={null}` opts out of the Button context: inside a Calendar that context\n * carries the previous/next slots, and an unslotted Button would claim one.\n */\nfunction ClearButton({ label }: { label: string }) {\n const calendarState = useContext(CalendarStateContext);\n const rangeState = useContext(RangeCalendarStateContext);\n\n /*\n * Inherit the calendar's own inert states.\n *\n * Without this the Clear button stayed focusable and announced as enabled\n * inside an `isDisabled` calendar — every cell and both nav buttons were\n * inert, and one control in the middle of them was not. `isReadOnly` is the\n * same argument: \"the value is immutable\" has to include clearing it.\n */\n const state = calendarState ?? rangeState;\n const isInert = Boolean(state?.isDisabled ?? false) || Boolean(state?.isReadOnly ?? false);\n\n return (\n <AriaButton\n slot={null}\n data-slot=\"calendar-clear\"\n isDisabled={isInert}\n className={calendarClearVariants()}\n // Stays enabled when there is nothing to clear. Disabling it on press\n // moves focus to <body>, which silently strands a keyboard user mid-grid.\n onPress={() => {\n if (calendarState) calendarState.setValue(null);\n else rangeState?.setValue(null);\n }}\n >\n {label}\n </AriaButton>\n );\n}\n\ninterface CalendarBodyProps {\n visibleMonths: number;\n clearable: boolean;\n clearLabel: string;\n previousLabel: string;\n nextLabel: string;\n selection: \"single\" | \"range\";\n}\n\n/** Header, grids and Clear — identical under both calendar roots. */\nfunction CalendarBody({\n visibleMonths,\n clearable,\n clearLabel,\n previousLabel,\n nextLabel,\n selection,\n}: CalendarBodyProps) {\n return (\n <>\n <header data-slot=\"calendar-header\" className={calendarHeaderVariants()}>\n <AriaButton slot=\"previous\" aria-label={previousLabel} className={calendarNavVariants()}>\n <ChevronPrevious />\n </AriaButton>\n <AriaButton slot=\"next\" aria-label={nextLabel} className={calendarNavVariants()}>\n <ChevronNext />\n </AriaButton>\n </header>\n\n <div data-slot=\"calendar-months\" className={calendarMonthsVariants()}>\n {Array.from({ length: visibleMonths }, (_, offset) => (\n <div key={offset} data-slot=\"calendar-month\">\n {/* Per grid, so three months are three named columns rather than\n one combined range nobody can map back to a column. */}\n <AriaCalendarHeading\n offset={{ months: offset }}\n className={calendarHeadingVariants()}\n />\n <AriaCalendarGrid offset={{ months: offset }} className={calendarGridVariants()}>\n <AriaCalendarGridHeader>\n {(weekday) => (\n <AriaCalendarHeaderCell className={calendarHeaderCellVariants()}>\n {weekday}\n </AriaCalendarHeaderCell>\n )}\n </AriaCalendarGridHeader>\n <AriaCalendarGridBody>\n {(date) => (\n <AriaCalendarCell\n date={date}\n data-slot=\"calendar-cell\"\n className={calendarCellVariants({ selection })}\n />\n )}\n </AriaCalendarGridBody>\n </AriaCalendarGrid>\n </div>\n ))}\n </div>\n\n {clearable ? <ClearButton label={clearLabel} /> : null}\n </>\n );\n}\n\ninterface CalendarSharedProps {\n /**\n * Accessible name for the calendar.\n *\n * REQUIRED. React Aria renders the root as `role=\"application\"`, which has\n * no implicit name, so without this every calendar announces as an unnamed\n * application — the same finding that made `label` required on Select,\n * Progress, Slider and ScrollArea.\n */\n label: string;\n /**\n * Hide the label visually while leaving it on the accessibility tree. Pass\n * this when the surrounding UI already names the control.\n *\n * @default false\n */\n labelHidden?: boolean;\n /**\n * Number of months displayed side by side. Maps to React Aria's\n * `visibleDuration`, which is omitted from the public surface so the two\n * cannot disagree.\n *\n * @default 1\n */\n visibleMonths?: number;\n /**\n * Render a Clear button that resets the selection to `null`.\n *\n * Works controlled and uncontrolled: the button calls React Aria's\n * `setValue(null)` through context, so `onChange` fires either way and there\n * is no `onClear` for a consumer to wire up.\n *\n * @default false\n */\n clearable?: boolean;\n /**\n * Visible text of the Clear button.\n *\n * A prop rather than a literal because `ARCHITECTURE.md` §7 rule 9 forbids\n * hard-coded user-visible strings and says it cannot be retrofitted.\n * `useMessages()` does not exist yet, so this follows Dialog's `closeLabel`.\n *\n * @default \"Clear\"\n */\n clearLabel?: string;\n /**\n * Accessible name for the previous-month button, which is icon-only. Same\n * reasoning as {@link CalendarSharedProps.clearLabel}.\n *\n * @default \"Previous month\"\n */\n previousLabel?: string;\n /**\n * Accessible name for the next-month button. Same reasoning as\n * {@link CalendarSharedProps.clearLabel}.\n *\n * @default \"Next month\"\n */\n nextLabel?: string;\n /** Extra classes. Merged last through `cn()`, so the consumer wins. */\n className?: string;\n}\n\n/**\n * Props for {@link Calendar}.\n *\n * Extends the React Aria type via `Omit` rather than\n * `ComponentPropsWithoutRef`, matching every other React Aria-backed component\n * here and recorded in ADR 0008. Intersecting would advertise DOM props that\n * React Aria ignores silently.\n */\nexport interface CalendarProps\n extends Omit<\n AriaCalendarProps<DateValue>,\n \"className\" | \"style\" | \"children\" | \"visibleDuration\"\n >,\n CalendarSharedProps {}\n\n/** Props for {@link CalendarRange}. */\nexport interface CalendarRangeProps\n extends Omit<\n AriaRangeCalendarProps<DateValue>,\n \"className\" | \"style\" | \"children\" | \"visibleDuration\"\n >,\n CalendarSharedProps {}\n\n/**\n * A calendar for picking a single date.\n *\n * Maturity: **experimental**. `ARCHITECTURE.md` §7 rule 8's metadata mechanism\n * does not exist yet, and ADR 0006 blocks `stable` until a WebKit test\n * instance lands regardless.\n *\n * `onChange` hands back a `DateValue`; `String(value)` is its `YYYY-MM-DD`\n * form, which is what an API filter or query parameter wants.\n *\n * @example\n * <Calendar label=\"Report date\" value={date} onChange={setDate} clearable />\n */\nexport function Calendar({\n className,\n label,\n labelHidden = false,\n visibleMonths = 1,\n clearable = false,\n clearLabel = \"Clear\",\n previousLabel = \"Previous month\",\n nextLabel = \"Next month\",\n ...props\n}: CalendarProps) {\n return (\n <AriaCalendar\n {...props}\n aria-label={label}\n visibleDuration={{ months: visibleMonths }}\n data-slot=\"calendar\"\n className={cn(calendarVariants(), className)}\n >\n {labelHidden ? null : (\n <span data-slot=\"calendar-label\" className={calendarLabelVariants()}>\n {label}\n </span>\n )}\n <CalendarBody\n visibleMonths={visibleMonths}\n clearable={clearable}\n clearLabel={clearLabel}\n previousLabel={previousLabel}\n nextLabel={nextLabel}\n selection=\"single\"\n />\n </AriaCalendar>\n );\n}\n\n/**\n * A calendar for picking a contiguous date range.\n *\n * `onChange` hands back `{ start, end }`, both `DateValue`.\n *\n * @example\n * <CalendarRange label=\"Period\" visibleMonths={3}\n * value={range} onChange={setRange} clearable />\n */\nexport function CalendarRange({\n className,\n label,\n labelHidden = false,\n visibleMonths = 1,\n clearable = false,\n clearLabel = \"Clear\",\n previousLabel = \"Previous month\",\n nextLabel = \"Next month\",\n ...props\n}: CalendarRangeProps) {\n return (\n <AriaRangeCalendar\n {...props}\n aria-label={label}\n visibleDuration={{ months: visibleMonths }}\n data-slot=\"calendar\"\n className={cn(calendarVariants(), className)}\n >\n {labelHidden ? null : (\n <span data-slot=\"calendar-label\" className={calendarLabelVariants()}>\n {label}\n </span>\n )}\n <CalendarBody\n visibleMonths={visibleMonths}\n clearable={clearable}\n clearLabel={clearLabel}\n previousLabel={previousLabel}\n nextLabel={nextLabel}\n selection=\"range\"\n />\n </AriaRangeCalendar>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"calendar.js","names":["AriaButton","AriaCalendarHeading","AriaCalendarGrid","AriaCalendarGridHeader","AriaCalendarHeaderCell","AriaCalendarGridBody","AriaCalendarCell","Calendar","AriaCalendar","AriaRangeCalendar"],"sources":["../../src/calendar/calendar.tsx"],"sourcesContent":["\"use client\";\n\nimport type { DateValue } from \"@internationalized/date\";\nimport { cva } from \"class-variance-authority\";\nimport { forwardRef, useContext } from \"react\";\nimport {\n Button as AriaButton,\n Calendar as AriaCalendar,\n CalendarCell as AriaCalendarCell,\n CalendarGrid as AriaCalendarGrid,\n CalendarGridBody as AriaCalendarGridBody,\n CalendarGridHeader as AriaCalendarGridHeader,\n CalendarHeaderCell as AriaCalendarHeaderCell,\n CalendarHeading as AriaCalendarHeading,\n CalendarStateContext,\n RangeCalendar as AriaRangeCalendar,\n RangeCalendarStateContext,\n type CalendarProps as AriaCalendarProps,\n type RangeCalendarProps as AriaRangeCalendarProps,\n} from \"react-aria-components\";\n\nimport { cn } from \"../lib/cn.js\";\n\n/**\n * Calendar, built on React Aria's Calendar and RangeCalendar.\n *\n * Values are `DateValue` objects from `@internationalized/date`, NOT JS\n * `Date`. ADR 0006 names that package the one allowed public type dependency\n * precisely here: a calendar day has no time zone, so modelling it as a\n * timestamp is what costs you a day at a DST boundary. The import is\n * `import type` only — nothing at runtime needs a constructor from it, so the\n * package contributes zero bytes to the bundle.\n *\n * Every string below is a STATIC literal. Tailwind scans source text, so a\n * class assembled at runtime is invisible to it and would simply never be\n * emitted — the component would render unstyled, with no error anywhere.\n *\n * State comes from React Aria's data attributes rather than pseudo-classes:\n * `data-[focus-visible]` is keyboard focus only, and `data-[hovered]` /\n * `data-[pressed]` cover pointer, touch and keyboard uniformly.\n */\nexport const calendarVariants = cva([\n \"flex w-fit flex-col gap-(--density-gap) box-border\",\n \"font-sans text-sm leading-(--leading-normal) text-foreground\",\n]);\n\nexport const calendarLabelVariants = cva([\"text-sm font-medium text-foreground\"]);\n\nexport const calendarHeaderVariants = cva([\n \"flex items-center justify-between gap-(--density-control-gap)\",\n]);\n\n/**\n * The month/prev/next buttons.\n *\n * Deliberately NOT `buttonVariants` from ../button. That would put a\n * cross-component import in the bundle for one caller and six classes, and\n * DRY extracts at two callers, not one.\n */\nexport const calendarNavVariants = cva([\n \"inline-flex shrink-0 items-center justify-center\",\n \"size-(--density-control-h-sm) rounded-md\",\n // A library consumer may load no reset at all, so a bare <button> keeps its\n // user-agent border and ButtonFace grey without these two.\n \"border-(length:--border-width) border-transparent bg-transparent\",\n \"cursor-pointer select-none text-foreground outline-none\",\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0\",\n \"[&_svg:not([class*='size-'])]:size-(--icon-sm)\",\n // The glyph is directional where the BEHAVIOUR is logical: React Aria maps\n // slot=\"previous\" to the correct month either way, so only the arrow flips.\n \"[&_svg]:rtl:-scale-x-100\",\n \"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard\",\n \"data-[hovered]:bg-muted data-[pressed]:bg-muted\",\n \"data-[focus-visible]:outline-solid data-[focus-visible]:outline-(length:--focus-ring-width)\",\n \"data-[focus-visible]:outline-offset-(--focus-ring-offset) data-[focus-visible]:outline-(--color-ring)\",\n \"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-(--opacity-disabled)\",\n]);\n\nexport const calendarMonthsVariants = cva([\n \"flex flex-col gap-(--density-gap) sm:flex-row sm:items-start\",\n]);\n\nexport const calendarHeadingVariants = cva([\n \"mb-1 text-center text-sm font-semibold text-foreground\",\n]);\n\nexport const calendarGridVariants = cva([\n // Without this a bare <table> falls back to user-agent border spacing and\n // the range band shows gaps between cells.\n \"border-collapse\",\n]);\n\nexport const calendarHeaderCellVariants = cva([\n \"w-(--density-control-h-sm) pb-1\",\n \"text-center text-2xs font-medium text-muted-foreground\",\n]);\n\nexport const calendarClearVariants = cva([\n \"self-end rounded-md px-2 py-1\",\n \"border-(length:--border-width) border-transparent bg-transparent\",\n \"cursor-pointer select-none text-sm text-muted-foreground outline-none\",\n \"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard\",\n \"data-[hovered]:bg-muted data-[hovered]:text-foreground\",\n \"data-[focus-visible]:outline-solid data-[focus-visible]:outline-(length:--focus-ring-width)\",\n \"data-[focus-visible]:outline-offset-(--focus-ring-offset) data-[focus-visible]:outline-(--color-ring)\",\n]);\n\n/**\n * A day.\n *\n * Sized from `--density-control-h-sm` rather than a new\n * `--density-calendar-cell`: the density contract test requires every scope to\n * declare every token name, so a new one is three file edits — and this one is\n * already 30/36/42px, all clear of the 24px floor that WCAG 2.2 SC 2.5.8 sets.\n *\n * ARCHITECTURE section 5 rule 6 — no state is carried by colour alone, because\n * every author colour is replaced under forced-colors and the distinction\n * would vanish. Selected adds weight, the range ends add SHAPE, today is an\n * underline (not an outline, which would fight the focus ring) and unavailable\n * is a strikethrough.\n */\nexport const calendarCellVariants = cva(\n [\n \"flex items-center justify-center box-border\",\n \"size-(--density-control-h-sm) rounded-md\",\n \"text-sm leading-(--leading-normal) text-foreground\",\n \"cursor-pointer select-none outline-none\",\n \"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard\",\n \"data-[hovered]:bg-muted\",\n \"data-[today]:font-semibold data-[today]:underline data-[today]:underline-offset-4\",\n \"data-[outside-month]:text-muted-foreground data-[outside-month]:opacity-(--opacity-disabled)\",\n // Unavailable dates stay FOCUSABLE, so ADR 0007 holds them to 4.5:1 — this\n // dims to muted-foreground, which the contrast contract grades, never below.\n \"data-[unavailable]:cursor-not-allowed data-[unavailable]:text-muted-foreground\",\n \"data-[unavailable]:line-through\",\n \"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-(--opacity-disabled)\",\n \"data-[focus-visible]:outline-solid data-[focus-visible]:outline-(length:--focus-ring-width)\",\n \"data-[focus-visible]:outline-offset-(--focus-ring-offset) data-[focus-visible]:outline-(--color-ring)\",\n ],\n {\n variants: {\n /**\n * A variant axis rather than a boolean prop, because the two modes are\n * mutually exclusive visual treatments of the same element — which is\n * exactly what OCP asks a variant to model.\n */\n selection: {\n single: [\n \"data-[selected]:bg-primary data-[selected]:text-primary-foreground\",\n \"data-[selected]:font-semibold\",\n ],\n range: [\n // The band is `muted` — a pair the contrast contract already grades\n // at 4.5:1, so the range needs no new contrast-pairs.json entry.\n \"data-[selected]:rounded-none data-[selected]:bg-muted data-[selected]:text-foreground\",\n \"data-[selection-start]:rounded-s-md data-[selection-start]:bg-primary\",\n \"data-[selection-start]:font-semibold data-[selection-start]:text-primary-foreground\",\n \"data-[selection-end]:rounded-e-md data-[selection-end]:bg-primary\",\n \"data-[selection-end]:font-semibold data-[selection-end]:text-primary-foreground\",\n ],\n },\n },\n defaultVariants: { selection: \"single\" },\n },\n);\n\nfunction ChevronPrevious() {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n );\n}\n\nfunction ChevronNext() {\n return (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n );\n}\n\n/**\n * Resets the selection to null.\n *\n * It reads the calendar state from React Aria's context and calls\n * `setValue(null)`, which runs through `useControlledState` — so it fires\n * `onChange` for a controlled parent AND updates uncontrolled state, with no\n * mirrored state here. That is the whole reason there is no `onClear` prop:\n * from inside the provider tree the reset is free, and from outside it it\n * would force every consumer to own the value.\n *\n * The two states are narrowed separately rather than through a union, because\n * `setValue` has a different parameter type on each and the union call is not\n * assignable to either.\n *\n * `slot={null}` opts out of the Button context: inside a Calendar that context\n * carries the previous/next slots, and an unslotted Button would claim one.\n */\nfunction ClearButton({ label }: { label: string }) {\n const calendarState = useContext(CalendarStateContext);\n const rangeState = useContext(RangeCalendarStateContext);\n\n /*\n * Inherit the calendar's own inert states.\n *\n * Without this the Clear button stayed focusable and announced as enabled\n * inside an `isDisabled` calendar — every cell and both nav buttons were\n * inert, and one control in the middle of them was not. `isReadOnly` is the\n * same argument: \"the value is immutable\" has to include clearing it.\n */\n const state = calendarState ?? rangeState;\n const isInert = Boolean(state?.isDisabled ?? false) || Boolean(state?.isReadOnly ?? false);\n\n return (\n <AriaButton\n slot={null}\n data-slot=\"calendar-clear\"\n isDisabled={isInert}\n className={calendarClearVariants()}\n // Stays enabled when there is nothing to clear. Disabling it on press\n // moves focus to <body>, which silently strands a keyboard user mid-grid.\n onPress={() => {\n if (calendarState) calendarState.setValue(null);\n else rangeState?.setValue(null);\n }}\n >\n {label}\n </AriaButton>\n );\n}\n\ninterface CalendarBodyProps {\n visibleMonths: number;\n clearable: boolean;\n clearLabel: string;\n previousLabel: string;\n nextLabel: string;\n selection: \"single\" | \"range\";\n}\n\n/** Header, grids and Clear — identical under both calendar roots. */\nfunction CalendarBody({\n visibleMonths,\n clearable,\n clearLabel,\n previousLabel,\n nextLabel,\n selection,\n}: CalendarBodyProps) {\n return (\n <>\n <header data-slot=\"calendar-header\" className={calendarHeaderVariants()}>\n <AriaButton slot=\"previous\" aria-label={previousLabel} className={calendarNavVariants()}>\n <ChevronPrevious />\n </AriaButton>\n <AriaButton slot=\"next\" aria-label={nextLabel} className={calendarNavVariants()}>\n <ChevronNext />\n </AriaButton>\n </header>\n\n <div data-slot=\"calendar-months\" className={calendarMonthsVariants()}>\n {Array.from({ length: visibleMonths }, (_, offset) => (\n <div key={offset} data-slot=\"calendar-month\">\n {/* Per grid, so three months are three named columns rather than\n one combined range nobody can map back to a column. */}\n <AriaCalendarHeading\n offset={{ months: offset }}\n className={calendarHeadingVariants()}\n />\n <AriaCalendarGrid offset={{ months: offset }} className={calendarGridVariants()}>\n <AriaCalendarGridHeader>\n {(weekday) => (\n <AriaCalendarHeaderCell className={calendarHeaderCellVariants()}>\n {weekday}\n </AriaCalendarHeaderCell>\n )}\n </AriaCalendarGridHeader>\n <AriaCalendarGridBody>\n {(date) => (\n <AriaCalendarCell\n date={date}\n data-slot=\"calendar-cell\"\n className={calendarCellVariants({ selection })}\n />\n )}\n </AriaCalendarGridBody>\n </AriaCalendarGrid>\n </div>\n ))}\n </div>\n\n {clearable ? <ClearButton label={clearLabel} /> : null}\n </>\n );\n}\n\ninterface CalendarSharedProps {\n /**\n * Accessible name for the calendar.\n *\n * REQUIRED. React Aria renders the root as `role=\"application\"`, which has\n * no implicit name, so without this every calendar announces as an unnamed\n * application — the same finding that made `label` required on Select,\n * Progress, Slider and ScrollArea.\n */\n label: string;\n /**\n * Hide the label visually while leaving it on the accessibility tree. Pass\n * this when the surrounding UI already names the control.\n *\n * @default false\n */\n labelHidden?: boolean;\n /**\n * Number of months displayed side by side. Maps to React Aria's\n * `visibleDuration`, which is omitted from the public surface so the two\n * cannot disagree.\n *\n * @default 1\n */\n visibleMonths?: number;\n /**\n * Render a Clear button that resets the selection to `null`.\n *\n * Works controlled and uncontrolled: the button calls React Aria's\n * `setValue(null)` through context, so `onChange` fires either way and there\n * is no `onClear` for a consumer to wire up.\n *\n * @default false\n */\n clearable?: boolean;\n /**\n * Visible text of the Clear button.\n *\n * A prop rather than a literal because `ARCHITECTURE.md` §7 rule 9 forbids\n * hard-coded user-visible strings and says it cannot be retrofitted.\n * `useMessages()` does not exist yet, so this follows Dialog's `closeLabel`.\n *\n * @default \"Clear\"\n */\n clearLabel?: string;\n /**\n * Accessible name for the previous-month button, which is icon-only. Same\n * reasoning as {@link CalendarSharedProps.clearLabel}.\n *\n * @default \"Previous month\"\n */\n previousLabel?: string;\n /**\n * Accessible name for the next-month button. Same reasoning as\n * {@link CalendarSharedProps.clearLabel}.\n *\n * @default \"Next month\"\n */\n nextLabel?: string;\n /** Extra classes. Merged last through `cn()`, so the consumer wins. */\n className?: string;\n}\n\n/**\n * Props for {@link Calendar}.\n *\n * Extends the React Aria type via `Omit` rather than\n * `ComponentPropsWithoutRef`, matching every other React Aria-backed component\n * here and recorded in ADR 0008. Intersecting would advertise DOM props that\n * React Aria ignores silently.\n */\nexport interface CalendarProps\n extends Omit<\n AriaCalendarProps<DateValue>,\n \"className\" | \"style\" | \"children\" | \"visibleDuration\"\n >,\n CalendarSharedProps {}\n\n/** Props for {@link CalendarRange}. */\nexport interface CalendarRangeProps\n extends Omit<\n AriaRangeCalendarProps<DateValue>,\n \"className\" | \"style\" | \"children\" | \"visibleDuration\"\n >,\n CalendarSharedProps {}\n\n/**\n * A calendar for picking a single date.\n *\n * Maturity: **experimental**. `ARCHITECTURE.md` §7 rule 8's metadata mechanism\n * does not exist yet, and ADR 0006 blocks `stable` until a WebKit test\n * instance lands regardless.\n *\n * `onChange` hands back a `DateValue`; `String(value)` is its `YYYY-MM-DD`\n * form, which is what an API filter or query parameter wants.\n *\n * @example\n * <Calendar label=\"Report date\" value={date} onChange={setDate} clearable />\n */\nexport const Calendar = forwardRef<HTMLDivElement, CalendarProps>(function Calendar(\n {\n className,\n label,\n labelHidden = false,\n visibleMonths = 1,\n clearable = false,\n clearLabel = \"Clear\",\n previousLabel = \"Previous month\",\n nextLabel = \"Next month\",\n ...props\n },\n ref,\n) {\n return (\n <AriaCalendar\n ref={ref}\n {...props}\n aria-label={label}\n visibleDuration={{ months: visibleMonths }}\n data-slot=\"calendar\"\n className={cn(calendarVariants(), className)}\n >\n {labelHidden ? null : (\n <span data-slot=\"calendar-label\" className={calendarLabelVariants()}>\n {label}\n </span>\n )}\n <CalendarBody\n visibleMonths={visibleMonths}\n clearable={clearable}\n clearLabel={clearLabel}\n previousLabel={previousLabel}\n nextLabel={nextLabel}\n selection=\"single\"\n />\n </AriaCalendar>\n );\n});\n\n/**\n * A calendar for picking a contiguous date range.\n *\n * `onChange` hands back `{ start, end }`, both `DateValue`.\n *\n * @example\n * <CalendarRange label=\"Period\" visibleMonths={3}\n * value={range} onChange={setRange} clearable />\n */\nexport const CalendarRange = forwardRef<HTMLDivElement, CalendarRangeProps>(function CalendarRange(\n {\n className,\n label,\n labelHidden = false,\n visibleMonths = 1,\n clearable = false,\n clearLabel = \"Clear\",\n previousLabel = \"Previous month\",\n nextLabel = \"Next month\",\n ...props\n },\n ref,\n) {\n return (\n <AriaRangeCalendar\n ref={ref}\n {...props}\n aria-label={label}\n visibleDuration={{ months: visibleMonths }}\n data-slot=\"calendar\"\n className={cn(calendarVariants(), className)}\n >\n {labelHidden ? null : (\n <span data-slot=\"calendar-label\" className={calendarLabelVariants()}>\n {label}\n </span>\n )}\n <CalendarBody\n visibleMonths={visibleMonths}\n clearable={clearable}\n clearLabel={clearLabel}\n previousLabel={previousLabel}\n nextLabel={nextLabel}\n selection=\"range\"\n />\n </AriaRangeCalendar>\n );\n});\n"],"mappings":"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"}
|
package/dist/card/card.d.ts
CHANGED
|
@@ -54,10 +54,10 @@ export declare const cardFooterVariants: (props?: import("class-variance-authori
|
|
|
54
54
|
* </Card>
|
|
55
55
|
*/
|
|
56
56
|
export type CardProps = ComponentPropsWithoutRef<"div">;
|
|
57
|
-
export declare
|
|
57
|
+
export declare const Card: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
58
58
|
/** Title and description, stacked. */
|
|
59
59
|
export type CardHeaderProps = ComponentPropsWithoutRef<"div">;
|
|
60
|
-
export declare
|
|
60
|
+
export declare const CardHeader: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
61
61
|
/**
|
|
62
62
|
* The card's heading.
|
|
63
63
|
*
|
|
@@ -79,15 +79,15 @@ export interface CardTitleProps extends ComponentPropsWithoutRef<"h3"> {
|
|
|
79
79
|
*/
|
|
80
80
|
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
81
81
|
}
|
|
82
|
-
export declare
|
|
82
|
+
export declare const CardTitle: import("react").ForwardRefExoticComponent<CardTitleProps & import("react").RefAttributes<HTMLHeadingElement>>;
|
|
83
83
|
/** Secondary text under the title. */
|
|
84
84
|
export type CardDescriptionProps = ComponentPropsWithoutRef<"div">;
|
|
85
|
-
export declare
|
|
85
|
+
export declare const CardDescription: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
86
86
|
/** The card's body. */
|
|
87
87
|
export type CardContentProps = ComponentPropsWithoutRef<"div">;
|
|
88
|
-
export declare
|
|
88
|
+
export declare const CardContent: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
89
89
|
/** Actions or metadata at the foot of the card. */
|
|
90
90
|
export type CardFooterProps = ComponentPropsWithoutRef<"div">;
|
|
91
|
-
export declare
|
|
91
|
+
export declare const CardFooter: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
92
92
|
//#endregion
|
|
93
93
|
//# sourceMappingURL=card.d.ts.map
|
package/dist/card/card.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
|
+
import { forwardRef } from "react";
|
|
4
5
|
import { jsx } from "react/jsx-runtime";
|
|
5
6
|
//#region src/card/card.tsx
|
|
6
7
|
/**
|
|
@@ -49,21 +50,23 @@ const cardTitleVariants = cva(["text-base leading-(--leading-none) font-semibold
|
|
|
49
50
|
const cardDescriptionVariants = cva(["text-sm leading-(--leading-normal) text-muted-foreground"]);
|
|
50
51
|
const cardContentVariants = cva("px-6");
|
|
51
52
|
const cardFooterVariants = cva("flex items-center px-6");
|
|
52
|
-
function Card({ className, ...props }) {
|
|
53
|
+
const Card = forwardRef(function Card({ className, ...props }, ref) {
|
|
53
54
|
return /* @__PURE__ */ jsx("div", {
|
|
55
|
+
ref,
|
|
54
56
|
...props,
|
|
55
57
|
"data-slot": "card",
|
|
56
58
|
className: cn(cardVariants(), className)
|
|
57
59
|
});
|
|
58
|
-
}
|
|
59
|
-
function CardHeader({ className, ...props }) {
|
|
60
|
+
});
|
|
61
|
+
const CardHeader = forwardRef(function CardHeader({ className, ...props }, ref) {
|
|
60
62
|
return /* @__PURE__ */ jsx("div", {
|
|
63
|
+
ref,
|
|
61
64
|
...props,
|
|
62
65
|
"data-slot": "card-header",
|
|
63
66
|
className: cn(cardHeaderVariants(), className)
|
|
64
67
|
});
|
|
65
|
-
}
|
|
66
|
-
function CardTitle({ className, level = 3, ...props }) {
|
|
68
|
+
});
|
|
69
|
+
const CardTitle = forwardRef(function CardTitle({ className, level = 3, ...props }, ref) {
|
|
67
70
|
const Heading = {
|
|
68
71
|
1: "h1",
|
|
69
72
|
2: "h2",
|
|
@@ -73,32 +76,36 @@ function CardTitle({ className, level = 3, ...props }) {
|
|
|
73
76
|
6: "h6"
|
|
74
77
|
}[level];
|
|
75
78
|
return /* @__PURE__ */ jsx(Heading, {
|
|
79
|
+
ref,
|
|
76
80
|
...props,
|
|
77
81
|
"data-slot": "card-title",
|
|
78
82
|
className: cn(cardTitleVariants(), className)
|
|
79
83
|
});
|
|
80
|
-
}
|
|
81
|
-
function CardDescription({ className, ...props }) {
|
|
84
|
+
});
|
|
85
|
+
const CardDescription = forwardRef(function CardDescription({ className, ...props }, ref) {
|
|
82
86
|
return /* @__PURE__ */ jsx("div", {
|
|
87
|
+
ref,
|
|
83
88
|
...props,
|
|
84
89
|
"data-slot": "card-description",
|
|
85
90
|
className: cn(cardDescriptionVariants(), className)
|
|
86
91
|
});
|
|
87
|
-
}
|
|
88
|
-
function CardContent({ className, ...props }) {
|
|
92
|
+
});
|
|
93
|
+
const CardContent = forwardRef(function CardContent({ className, ...props }, ref) {
|
|
89
94
|
return /* @__PURE__ */ jsx("div", {
|
|
95
|
+
ref,
|
|
90
96
|
...props,
|
|
91
97
|
"data-slot": "card-content",
|
|
92
98
|
className: cn(cardContentVariants(), className)
|
|
93
99
|
});
|
|
94
|
-
}
|
|
95
|
-
function CardFooter({ className, ...props }) {
|
|
100
|
+
});
|
|
101
|
+
const CardFooter = forwardRef(function CardFooter({ className, ...props }, ref) {
|
|
96
102
|
return /* @__PURE__ */ jsx("div", {
|
|
103
|
+
ref,
|
|
97
104
|
...props,
|
|
98
105
|
"data-slot": "card-footer",
|
|
99
106
|
className: cn(cardFooterVariants(), className)
|
|
100
107
|
});
|
|
101
|
-
}
|
|
108
|
+
});
|
|
102
109
|
//#endregion
|
|
103
110
|
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, cardContentVariants, cardDescriptionVariants, cardFooterVariants, cardHeaderVariants, cardTitleVariants, cardVariants };
|
|
104
111
|
|
package/dist/card/card.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.js","names":[],"sources":["../../src/card/card.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport type
|
|
1
|
+
{"version":3,"file":"card.js","names":[],"sources":["../../src/card/card.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport { forwardRef, type ComponentPropsWithoutRef } from \"react\";\n\nimport { cn } from \"../lib/cn.js\";\n\n/**\n * Card, ported from the legacy shadcn component.\n *\n * Presentational, so there is no React Aria base -- React Aria ships no card,\n * and a container that is not focusable, selectable or interactive needs no\n * behaviour to inherit.\n *\n * Five parts, from six. The census (24 consumer files, the most-used\n * container in the app) reads: Card 55, CardContent 40, CardHeader 21,\n * CardTitle 19, CardDescription 8, CardFooter 2, **CardAction 0**.\n *\n * Dropping `CardAction` takes three things with it, which is most of the\n * legacy header's complexity: the `grid`, the `grid-rows-[auto_auto]`, and\n * the `has-data-[slot=card-action]:grid-cols-[1fr_auto]` rule that existed\n * only to reserve a column for it. With no action to place, a header is a\n * stack.\n *\n * Two more legacy rules are gone. `[.border-b]:pb-6` and `[.border-t]:pt-6`\n * added padding when the CONSUMER happened to add a border class -- clever,\n * but action at a distance through a class name we do not own, and the census\n * found zero application call sites relying on it (one call site passes\n * `border-b-0`, which removes a border it never had). `@container/card-header`\n * named a container nothing queried.\n *\n * Every string in the cva blocks below is a STATIC literal. Tailwind scans\n * source text, so a class assembled at runtime is invisible to it and would\n * simply never be emitted.\n */\nexport const cardVariants = cva([\n \"flex flex-col gap-6\",\n \"rounded-xl border-(length:--border-width) border-border py-6\",\n \"bg-card text-card-foreground shadow-surface\",\n\n // box-border and font-sans are not boilerplate. The reset in\n // @seekalfred/styles is OPT-IN, so a consumer may load none: content-box\n // would add the padding to any width they set (the Alert shipped\n // overflowing its container by 46px), and an unstyled document renders\n // text in a serif (the Accordion shipped its panel that way). Declaring\n // the family HERE rather than on each part means one declaration covers\n // the whole subtree by inheritance.\n \"box-border font-sans\",\n]);\n\n/**\n * Padding is inline-only on the sections and block-only on the shell.\n *\n * That split is load-bearing rather than stylistic: it is what lets a\n * consumer run a divider or a full-bleed image edge to edge, which a single\n * `p-6` on the shell would make impossible.\n */\nexport const cardHeaderVariants = cva(\"flex flex-col gap-1.5 px-6\");\n\nexport const cardTitleVariants = cva([\n // leading-* AFTER text-*: tailwind-merge treats a later text-* as owning\n // line-height and silently strips a leading-* that precedes it.\n \"text-base leading-(--leading-none) font-semibold\",\n // The user-agent <h3> ships a 1em block margin and font-size 1.17em. The\n // legacy component was a <div> and never met either.\n \"m-0\",\n]);\n\nexport const cardDescriptionVariants = cva([\n \"text-sm leading-(--leading-normal) text-muted-foreground\",\n]);\n\nexport const cardContentVariants = cva(\"px-6\");\n\nexport const cardFooterVariants = cva(\"flex items-center px-6\");\n\n/**\n * A content container.\n *\n * @example\n * <Card>\n * <CardHeader>\n * <CardTitle>Learning Progress</CardTitle>\n * <CardDescription>Across all active courses.</CardDescription>\n * </CardHeader>\n * <CardContent>Twelve of eighteen modules complete.</CardContent>\n * </Card>\n */\nexport type CardProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const Card = forwardRef<HTMLDivElement, CardProps>(function Card(\n { className, ...props },\n ref,\n) {\n return (\n <div ref={ref} {...props} data-slot=\"card\" className={cn(cardVariants(), className)} />\n );\n});\n\n/** Title and description, stacked. */\nexport type CardHeaderProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const CardHeader = forwardRef<HTMLDivElement, CardHeaderProps>(function CardHeader(\n { className, ...props },\n ref,\n) {\n return (\n <div\n ref={ref}\n {...props}\n data-slot=\"card-header\"\n className={cn(cardHeaderVariants(), className)}\n />\n );\n});\n\n/**\n * The card's heading.\n *\n * A REAL heading, unlike the legacy `<div class=\"font-semibold\">`. None of\n * the 19 legacy call sites wrapped one, so 19 card titles were invisible to\n * screen-reader heading navigation -- the same shape of finding as the Avatar\n * port's missing `alt`, and the migration is when it gets answered.\n */\nexport interface CardTitleProps extends ComponentPropsWithoutRef<\"h3\"> {\n /**\n * Heading level.\n *\n * `3` by default, because a card almost always sits under a section\n * heading. It is a prop rather than a constant because the correct level\n * is a fact about the PAGE, and a fixed one would be wrong somewhere; the\n * level changes semantics only, never the rendered size.\n *\n * @default 3\n */\n level?: 1 | 2 | 3 | 4 | 5 | 6;\n}\n\nexport const CardTitle = forwardRef<HTMLHeadingElement, CardTitleProps>(function CardTitle(\n { className, level = 3, ...props },\n ref,\n) {\n // Static union, not a template literal: `h${level}` is a string React\n // accepts but TypeScript cannot narrow to an intrinsic element, and the\n // cast that silences it would also accept `h7`.\n const Heading = ({ 1: \"h1\", 2: \"h2\", 3: \"h3\", 4: \"h4\", 5: \"h5\", 6: \"h6\" } as const)[level];\n\n return (\n <Heading\n ref={ref}\n {...props}\n data-slot=\"card-title\"\n className={cn(cardTitleVariants(), className)}\n />\n );\n});\n\n/** Secondary text under the title. */\nexport type CardDescriptionProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const CardDescription = forwardRef<HTMLDivElement, CardDescriptionProps>(\n function CardDescription({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n {...props}\n data-slot=\"card-description\"\n className={cn(cardDescriptionVariants(), className)}\n />\n );\n },\n);\n\n/** The card's body. */\nexport type CardContentProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const CardContent = forwardRef<HTMLDivElement, CardContentProps>(function CardContent(\n { className, ...props },\n ref,\n) {\n return (\n <div\n ref={ref}\n {...props}\n data-slot=\"card-content\"\n className={cn(cardContentVariants(), className)}\n />\n );\n});\n\n/** Actions or metadata at the foot of the card. */\nexport type CardFooterProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const CardFooter = forwardRef<HTMLDivElement, CardFooterProps>(function CardFooter(\n { className, ...props },\n ref,\n) {\n return (\n <div\n ref={ref}\n {...props}\n data-slot=\"card-footer\"\n className={cn(cardFooterVariants(), className)}\n />\n );\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,MAAa,eAAe,IAAI;CAC9B;CACA;CACA;CASA;AACF,CAAC;;;;;;;;AASD,MAAa,qBAAqB,IAAI,4BAA4B;AAElE,MAAa,oBAAoB,IAAI,CAGnC,oDAGA,KACF,CAAC;AAED,MAAa,0BAA0B,IAAI,CACzC,0DACF,CAAC;AAED,MAAa,sBAAsB,IAAI,MAAM;AAE7C,MAAa,qBAAqB,IAAI,wBAAwB;AAgB9D,MAAa,OAAO,WAAsC,SAAS,KACjE,EAAE,WAAW,GAAG,SAChB,KACA;CACA,OACE,oBAAC,OAAD;EAAU;EAAK,GAAI;EAAO,aAAU;EAAO,WAAW,GAAG,aAAa,GAAG,SAAS;CAAI,CAAA;AAE1F,CAAC;AAKD,MAAa,aAAa,WAA4C,SAAS,WAC7E,EAAE,WAAW,GAAG,SAChB,KACA;CACA,OACE,oBAAC,OAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,mBAAmB,GAAG,SAAS;CAC9C,CAAA;AAEL,CAAC;AAwBD,MAAa,YAAY,WAA+C,SAAS,UAC/E,EAAE,WAAW,QAAQ,GAAG,GAAG,SAC3B,KACA;CAIA,MAAM,UAAW;EAAE,GAAG;EAAM,GAAG;EAAM,GAAG;EAAM,GAAG;EAAM,GAAG;EAAM,GAAG;CAAK,EAAY;CAEpF,OACE,oBAAC,SAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,kBAAkB,GAAG,SAAS;CAC7C,CAAA;AAEL,CAAC;AAKD,MAAa,kBAAkB,WAC7B,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAS,KAAK;CACrD,OACE,oBAAC,OAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,wBAAwB,GAAG,SAAS;CACnD,CAAA;AAEL,CACF;AAKA,MAAa,cAAc,WAA6C,SAAS,YAC/E,EAAE,WAAW,GAAG,SAChB,KACA;CACA,OACE,oBAAC,OAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,oBAAoB,GAAG,SAAS;CAC/C,CAAA;AAEL,CAAC;AAKD,MAAa,aAAa,WAA4C,SAAS,WAC7E,EAAE,WAAW,GAAG,SAChB,KACA;CACA,OACE,oBAAC,OAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,mBAAmB,GAAG,SAAS;CAC9C,CAAA;AAEL,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CheckboxProps } from "react-aria-components";
|
|
2
1
|
import { ReactNode } from "react";
|
|
2
|
+
import { CheckboxProps } from "react-aria-components";
|
|
3
3
|
//#region src/checkbox/checkbox.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Checkbox, rebuilt on React Aria.
|
|
@@ -57,7 +57,7 @@ interface CheckboxProps$1 extends Omit<CheckboxProps, "className" | "style" | "c
|
|
|
57
57
|
/** Extra classes for the label. Merged last, so they win conflicts. */
|
|
58
58
|
className?: string;
|
|
59
59
|
}
|
|
60
|
-
declare
|
|
60
|
+
declare const Checkbox$1: import("react").ForwardRefExoticComponent<CheckboxProps$1 & import("react").RefAttributes<HTMLInputElement>>;
|
|
61
61
|
//#endregion
|
|
62
62
|
export { Checkbox$1 as Checkbox, CheckboxProps$1 as CheckboxProps };
|
|
63
63
|
//# sourceMappingURL=checkbox.d.ts.map
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
3
|
import { selectionLabelVariants, selectionRingVariants } from "../lib/selection-control.js";
|
|
4
4
|
import { cva } from "class-variance-authority";
|
|
5
|
+
import { forwardRef } from "react";
|
|
5
6
|
import { Checkbox } from "react-aria-components";
|
|
6
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
8
|
//#region src/checkbox/checkbox.tsx
|
|
@@ -53,9 +54,10 @@ const checkboxBoxVariants = cva([
|
|
|
53
54
|
"group-data-[indeterminate]:text-primary-foreground",
|
|
54
55
|
selectionRingVariants()
|
|
55
56
|
]);
|
|
56
|
-
|
|
57
|
+
const Checkbox$1 = forwardRef(function Checkbox$2({ className, children, ...props }, ref) {
|
|
57
58
|
return /* @__PURE__ */ jsx(Checkbox, {
|
|
58
59
|
...props,
|
|
60
|
+
inputRef: ref,
|
|
59
61
|
"data-slot": "checkbox",
|
|
60
62
|
className: cn(checkboxVariants(), className),
|
|
61
63
|
children: ({ isSelected, isIndeterminate }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
@@ -87,7 +89,7 @@ function Checkbox$1({ className, children, ...props }) {
|
|
|
87
89
|
children
|
|
88
90
|
})] })
|
|
89
91
|
});
|
|
90
|
-
}
|
|
92
|
+
});
|
|
91
93
|
//#endregion
|
|
92
94
|
export { Checkbox$1 as Checkbox, checkboxBoxVariants, checkboxVariants };
|
|
93
95
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox.js","names":["Checkbox","AriaCheckbox"],"sources":["../../src/checkbox/checkbox.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport type
|
|
1
|
+
{"version":3,"file":"checkbox.js","names":["Checkbox","AriaCheckbox"],"sources":["../../src/checkbox/checkbox.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport { forwardRef, type ReactNode } from \"react\";\nimport {\n Checkbox as AriaCheckbox,\n type CheckboxProps as AriaCheckboxProps,\n} from \"react-aria-components\";\n\nimport { cn } from \"../lib/cn.js\";\nimport { selectionLabelVariants, selectionRingVariants } from \"../lib/selection-control.js\";\n\n/**\n * Checkbox, rebuilt on React Aria.\n *\n * THE CENSUS FOUND ZERO CALL SITES. It is ported anyway because forms and\n * table row selection are unbuildable without it, but that fact changes what\n * this is: with no usage to be faithful to and no call site to break, it is a\n * rewrite rather than a restyling. Four things the legacy component got\n * wrong are therefore simply fixed rather than carried:\n *\n * - **No accessible name.** It rendered a bare `<input type=\"checkbox\">` with\n * no label, no `aria-label` and no `id`, so every use was an axe `label`\n * violation. Here the label is `children`, and React Aria wraps the input\n * in it.\n * - **The fill never showed.** `checked:bg-primary` on a native input with no\n * `appearance-none` is painted over by the user-agent checkbox.\n * - **`border-primary` cannot be a boundary.** Brand orange is 2.44:1 on\n * white, under even the 3:1 non-text floor (WCAG 1.4.11).\n * - **`focus-visible:ring-2` is a box-shadow**, which forced-colors discards,\n * taking the only focus indication with it.\n *\n * React Aria renders a `<label>` around a visually-hidden real `<input>` and\n * NOTHING else -- there is no visual box in the box. Drawing one, and keeping\n * it in step with `data-selected` / `data-indeterminate`, is what this\n * component owns.\n *\n * Every string in the cva blocks below is a STATIC literal. Tailwind scans\n * source text, so a class assembled at runtime is invisible to it and would\n * simply never be emitted.\n */\n/**\n * The label geometry now lives in lib/selection-control.ts, shared with\n * Radio and Switch. Three controls with the same 24px target and the same\n * typography is the Rule of Three, and this migration has twice found a\n * legacy pair that styled one surface twice and silently drifted.\n */\nexport const checkboxVariants = cva([selectionLabelVariants()]);\n\nexport const checkboxBoxVariants = cva([\n \"inline-flex size-4 shrink-0 items-center justify-center\",\n // rounded-2xs, not rounded-sm. --radius-sm is 8px, which on a 16px box\n // is exactly half its width -- a circle, indistinguishable from a radio\n // button. A screenshot caught that; no assertion in this suite did, which\n // is why NotACircle now exists. --radius-xs (6px) is still 75% of the way\n // there, so the scale gained a 4px step rather than this reaching for a\n // bracket value that check:hardcoding would rightly reject.\n \"rounded-2xs border-(length:--border-width)\",\n\n // box-border: content-box would add the border to the 16px box and make it\n // 18, which is the same opt-in-reset exposure as everywhere else.\n \"box-border\",\n\n // Unselected: a neutral boundary, NOT the legacy border-primary. Brand\n // orange is 2.44:1 on white and cannot legally be the only thing describing\n // a control's edge.\n \"bg-background border-border\",\n\n \"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard\",\n\n // Selected and indeterminate paint the same: both mean \"this control has a\n // value\", and the glyph inside says which.\n //\n // primary-strong on the border, not primary: a filled orange box is 2.44:1\n // against the page, so the FILL cannot satisfy 1.4.11 and the boundary has\n // to. Same reasoning, and the same token, as the Button's outline variant.\n \"group-data-[selected]:bg-primary group-data-[selected]:border-primary-strong\",\n \"group-data-[selected]:text-primary-foreground\",\n \"group-data-[indeterminate]:bg-primary group-data-[indeterminate]:border-primary-strong\",\n \"group-data-[indeterminate]:text-primary-foreground\",\n\n // Shared with Radio and Switch. The ring goes on the BOX rather than the\n // input, because React Aria's input is visually hidden.\n selectionRingVariants(),\n]);\n\n/**\n * A checkbox.\n *\n * @example\n * <Checkbox defaultSelected>Email me about new courses</Checkbox>\n * <Checkbox aria-label=\"Select row\" />\n */\nexport interface CheckboxProps\n extends Omit<AriaCheckboxProps, \"className\" | \"style\" | \"children\"> {\n /**\n * The label, and the control's accessible name.\n *\n * Omit it only for a genuinely label-less checkbox -- a table row selector\n * -- and pass `aria-label` instead. A checkbox with neither has no\n * accessible name, which is what every legacy call site would have been.\n */\n children?: ReactNode;\n /** Extra classes for the label. Merged last, so they win conflicts. */\n className?: string;\n}\n\nexport const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(\n { className, children, ...props },\n ref,\n) {\n return (\n <AriaCheckbox\n {...props}\n // inputRef, not ref: AriaCheckbox's own ref targets the label it\n // renders around a visually-hidden native input, and a label cannot\n // be focused -- ref.current.focus() would silently no-op. inputRef is\n // React Aria's own escape hatch to the real control.\n inputRef={ref}\n data-slot=\"checkbox\"\n // `group` is load-bearing: React Aria puts data-selected,\n // data-indeterminate and data-focus-visible on the LABEL, and CSS\n // cannot look upward from the box to them.\n className={cn(checkboxVariants(), className)}\n >\n {({ isSelected, isIndeterminate }) => (\n <>\n {/*\n aria-hidden: the real <input> already carries the state. A\n decorative box announced as well would say everything twice.\n */}\n <span aria-hidden=\"true\" data-slot=\"checkbox-box\" className={checkboxBoxVariants()}>\n {/*\n Chosen in JS rather than toggled with CSS. Two rules that both\n apply -- show-when-selected and hide-when-indeterminate -- have\n equal specificity, so which wins comes down to the order\n Tailwind happened to emit them in. Rendering one glyph makes\n the precedence explicit and puts it in the DOM, where a test\n can read it.\n\n Indeterminate wins: both states can be true at once (a \"select\n all\" box that has been partially cleared), and a tick there\n would say the opposite of the aria-checked=\"mixed\" beside it.\n */}\n {isIndeterminate ? (\n <svg\n data-slot=\"checkbox-indeterminate\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n className=\"size-3\"\n >\n <path d=\"M4 8h8\" />\n </svg>\n ) : isSelected ? (\n <svg\n data-slot=\"checkbox-check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"size-3\"\n >\n <path d=\"m3.5 8.5 3 3 6-6\" />\n </svg>\n ) : null}\n </span>\n {children == null ? null : <span data-slot=\"checkbox-label\">{children}</span>}\n </>\n )}\n </AriaCheckbox>\n );\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,MAAa,mBAAmB,IAAI,CAAC,uBAAuB,CAAC,CAAC;AAE9D,MAAa,sBAAsB,IAAI;CACrC;CAOA;CAIA;CAKA;CAEA;CAQA;CACA;CACA;CACA;CAIA,sBAAsB;AACxB,CAAC;AAuBD,MAAaA,aAAW,WAA4C,SAASA,WAC3E,EAAE,WAAW,UAAU,GAAG,SAC1B,KACA;CACA,OACE,oBAACC,UAAD;EACE,GAAI;EAKJ,UAAU;EACV,aAAU;EAIV,WAAW,GAAG,iBAAiB,GAAG,SAAS;EAEzC,WAAA,EAAE,YAAY,sBACd,qBAAA,UAAA,EAAA,UAAA,CAKE,oBAAC,QAAD;GAAM,eAAY;GAAO,aAAU;GAAe,WAAW,oBAAoB;GAa9E,UAAA,kBACC,oBAAC,OAAD;IACE,aAAU;IACV,SAAQ;IACR,MAAK;IACL,QAAO;IACP,aAAY;IACZ,eAAc;IACd,WAAU;IAEV,UAAA,oBAAC,QAAD,EAAM,GAAE,SAAU,CAAA;GACf,CAAA,IACH,aACF,oBAAC,OAAD;IACE,aAAU;IACV,SAAQ;IACR,MAAK;IACL,QAAO;IACP,aAAY;IACZ,eAAc;IACd,gBAAe;IACf,WAAU;IAEV,UAAA,oBAAC,QAAD,EAAM,GAAE,mBAAoB,CAAA;GACzB,CAAA,IACH;EACA,CAAA,GACL,YAAY,OAAO,OAAO,oBAAC,QAAD;GAAM,aAAU;GAAkB;EAAe,CAAA,CAC5E,EAAA,CAAA;CAEQ,CAAA;AAElB,CAAC"}
|
package/dist/dialog/dialog.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DialogTrigger, ModalOverlayProps } from "react-aria-components";
|
|
2
1
|
import { ReactNode } from "react";
|
|
2
|
+
import { DialogTrigger, ModalOverlayProps } from "react-aria-components";
|
|
3
3
|
//#region src/dialog/dialog.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Dialog, ported from the legacy shadcn/Radix component onto React Aria's
|
|
@@ -120,7 +120,7 @@ export interface DialogProps extends Omit<ModalOverlayProps, "className" | "styl
|
|
|
120
120
|
*/
|
|
121
121
|
isDismissable?: boolean;
|
|
122
122
|
}
|
|
123
|
-
declare
|
|
123
|
+
declare const Dialog$1: import("react").ForwardRefExoticComponent<DialogProps & import("react").RefAttributes<HTMLElement>>;
|
|
124
124
|
/**
|
|
125
125
|
* Actions at the foot of a dialog.
|
|
126
126
|
*
|
|
@@ -134,7 +134,7 @@ export interface DialogFooterProps {
|
|
|
134
134
|
children?: ReactNode;
|
|
135
135
|
className?: string;
|
|
136
136
|
}
|
|
137
|
-
export declare
|
|
137
|
+
export declare const DialogFooter: import("react").ForwardRefExoticComponent<DialogFooterProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
138
138
|
//#endregion
|
|
139
139
|
export { Dialog$1 as Dialog, DialogTrigger };
|
|
140
140
|
//# sourceMappingURL=dialog.d.ts.map
|