@seekalfred/primitives 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +950 -13
- package/dist/accordion/accordion.d.ts +107 -0
- package/dist/accordion/accordion.js +84 -0
- package/dist/accordion/accordion.js.map +1 -0
- package/dist/accordion/index.d.ts +2 -0
- package/dist/accordion/index.js +2 -0
- package/dist/alert/alert.d.ts +68 -0
- package/dist/alert/alert.js +67 -0
- package/dist/alert/alert.js.map +1 -0
- package/dist/alert/index.d.ts +2 -0
- package/dist/alert/index.js +2 -0
- package/dist/alert-dialog/alert-dialog.d.ts +53 -0
- package/dist/alert-dialog/alert-dialog.js +16 -0
- package/dist/alert-dialog/alert-dialog.js.map +1 -0
- package/dist/alert-dialog/index.d.ts +2 -0
- package/dist/alert-dialog/index.js +2 -0
- package/dist/avatar/avatar.d.ts +50 -0
- package/dist/avatar/avatar.js +91 -0
- package/dist/avatar/avatar.js.map +1 -0
- package/dist/avatar/index.d.ts +2 -0
- package/dist/avatar/index.js +2 -0
- package/dist/badge/badge.d.ts +47 -0
- package/dist/badge/badge.js +189 -0
- package/dist/badge/badge.js.map +1 -0
- package/dist/badge/index.d.ts +2 -0
- package/dist/badge/index.js +2 -0
- package/dist/breadcrumb/breadcrumb.d.ts +98 -0
- package/dist/breadcrumb/breadcrumb.js +93 -0
- package/dist/breadcrumb/breadcrumb.js.map +1 -0
- package/dist/breadcrumb/index.d.ts +2 -0
- package/dist/breadcrumb/index.js +2 -0
- package/dist/button/button.d.ts +1 -1
- package/dist/button/button.js +7 -0
- package/dist/button/button.js.map +1 -1
- package/dist/calendar/calendar.d.ts +154 -0
- package/dist/calendar/calendar.js +282 -0
- package/dist/calendar/calendar.js.map +1 -0
- package/dist/calendar/index.d.ts +2 -0
- package/dist/calendar/index.js +2 -0
- package/dist/card/card.d.ts +93 -0
- package/dist/card/card.js +105 -0
- package/dist/card/card.js.map +1 -0
- package/dist/card/index.d.ts +2 -0
- package/dist/card/index.js +2 -0
- package/dist/checkbox/checkbox.d.ts +63 -0
- package/dist/checkbox/checkbox.js +94 -0
- package/dist/checkbox/checkbox.js.map +1 -0
- package/dist/checkbox/index.d.ts +2 -0
- package/dist/checkbox/index.js +2 -0
- package/dist/dialog/dialog.d.ts +140 -0
- package/dist/dialog/dialog.js +127 -0
- package/dist/dialog/dialog.js.map +1 -0
- package/dist/dialog/index.d.ts +2 -0
- package/dist/dialog/index.js +2 -0
- package/dist/index.d.ts +30 -1
- package/dist/index.js +30 -1
- package/dist/input/index.d.ts +2 -0
- package/dist/input/index.js +2 -0
- package/dist/input/input.d.ts +64 -0
- package/dist/input/input.js +94 -0
- package/dist/input/input.js.map +1 -0
- package/dist/label/index.d.ts +2 -0
- package/dist/label/index.js +2 -0
- package/dist/label/label.d.ts +41 -0
- package/dist/label/label.js +44 -0
- package/dist/label/label.js.map +1 -0
- package/dist/lib/field-surface.js +40 -0
- package/dist/lib/field-surface.js.map +1 -0
- package/dist/lib/selection-control.js +57 -0
- package/dist/lib/selection-control.js.map +1 -0
- package/dist/menu/index.d.ts +2 -0
- package/dist/menu/index.js +2 -0
- package/dist/menu/menu.d.ts +98 -0
- package/dist/menu/menu.js +99 -0
- package/dist/menu/menu.js.map +1 -0
- package/dist/popover/index.d.ts +2 -0
- package/dist/popover/index.js +2 -0
- package/dist/popover/popover.d.ts +50 -0
- package/dist/popover/popover.js +46 -0
- package/dist/popover/popover.js.map +1 -0
- package/dist/progress/index.d.ts +2 -0
- package/dist/progress/index.js +2 -0
- package/dist/progress/progress.d.ts +82 -0
- package/dist/progress/progress.js +82 -0
- package/dist/progress/progress.js.map +1 -0
- package/dist/radio-group/index.d.ts +2 -0
- package/dist/radio-group/index.js +2 -0
- package/dist/radio-group/radio-group.d.ts +53 -0
- package/dist/radio-group/radio-group.js +65 -0
- package/dist/radio-group/radio-group.js.map +1 -0
- package/dist/scroll-area/index.d.ts +2 -0
- package/dist/scroll-area/index.js +2 -0
- package/dist/scroll-area/scroll-area.d.ts +74 -0
- package/dist/scroll-area/scroll-area.js +63 -0
- package/dist/scroll-area/scroll-area.js.map +1 -0
- package/dist/select/index.d.ts +2 -0
- package/dist/select/index.js +2 -0
- package/dist/select/select.d.ts +93 -0
- package/dist/select/select.js +132 -0
- package/dist/select/select.js.map +1 -0
- package/dist/separator/index.d.ts +2 -0
- package/dist/separator/index.js +2 -0
- package/dist/separator/separator.d.ts +42 -0
- package/dist/separator/separator.js +49 -0
- package/dist/separator/separator.js.map +1 -0
- package/dist/sheet/index.d.ts +2 -0
- package/dist/sheet/index.js +2 -0
- package/dist/sheet/sheet.d.ts +96 -0
- package/dist/sheet/sheet.js +98 -0
- package/dist/sheet/sheet.js.map +1 -0
- package/dist/skeleton/index.d.ts +2 -0
- package/dist/skeleton/index.js +2 -0
- package/dist/skeleton/skeleton.d.ts +33 -0
- package/dist/skeleton/skeleton.js +42 -0
- package/dist/skeleton/skeleton.js.map +1 -0
- package/dist/slider/index.d.ts +2 -0
- package/dist/slider/index.js +2 -0
- package/dist/slider/slider.d.ts +70 -0
- package/dist/slider/slider.js +92 -0
- package/dist/slider/slider.js.map +1 -0
- package/dist/spinner/index.d.ts +2 -0
- package/dist/spinner/index.js +2 -0
- package/dist/spinner/spinner.d.ts +75 -0
- package/dist/spinner/spinner.js +68 -0
- package/dist/spinner/spinner.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/switch/index.d.ts +2 -0
- package/dist/switch/index.js +2 -0
- package/dist/switch/switch.d.ts +50 -0
- package/dist/switch/switch.js +66 -0
- package/dist/switch/switch.js.map +1 -0
- package/dist/table/index.d.ts +2 -0
- package/dist/table/index.js +2 -0
- package/dist/table/table.d.ts +288 -0
- package/dist/table/table.js +513 -0
- package/dist/table/table.js.map +1 -0
- package/dist/tabs/index.d.ts +2 -0
- package/dist/tabs/index.js +2 -0
- package/dist/tabs/tabs.d.ts +79 -0
- package/dist/tabs/tabs.js +103 -0
- package/dist/tabs/tabs.js.map +1 -0
- package/dist/textarea/index.d.ts +2 -0
- package/dist/textarea/index.js +2 -0
- package/dist/textarea/textarea.d.ts +27 -0
- package/dist/textarea/textarea.js +37 -0
- package/dist/textarea/textarea.js.map +1 -0
- package/dist/toast/index.d.ts +2 -0
- package/dist/toast/index.js +2 -0
- package/dist/toast/toast.d.ts +93 -0
- package/dist/toast/toast.js +145 -0
- package/dist/toast/toast.js.map +1 -0
- package/dist/tooltip/index.d.ts +2 -0
- package/dist/tooltip/index.js +2 -0
- package/dist/tooltip/tooltip.d.ts +70 -0
- package/dist/tooltip/tooltip.js +65 -0
- package/dist/tooltip/tooltip.js.map +1 -0
- package/package.json +125 -7
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/card/card.tsx
|
|
6
|
+
/**
|
|
7
|
+
* Card, ported from the legacy shadcn component.
|
|
8
|
+
*
|
|
9
|
+
* Presentational, so there is no React Aria base -- React Aria ships no card,
|
|
10
|
+
* and a container that is not focusable, selectable or interactive needs no
|
|
11
|
+
* behaviour to inherit.
|
|
12
|
+
*
|
|
13
|
+
* Five parts, from six. The census (24 consumer files, the most-used
|
|
14
|
+
* container in the app) reads: Card 55, CardContent 40, CardHeader 21,
|
|
15
|
+
* CardTitle 19, CardDescription 8, CardFooter 2, **CardAction 0**.
|
|
16
|
+
*
|
|
17
|
+
* Dropping `CardAction` takes three things with it, which is most of the
|
|
18
|
+
* legacy header's complexity: the `grid`, the `grid-rows-[auto_auto]`, and
|
|
19
|
+
* the `has-data-[slot=card-action]:grid-cols-[1fr_auto]` rule that existed
|
|
20
|
+
* only to reserve a column for it. With no action to place, a header is a
|
|
21
|
+
* stack.
|
|
22
|
+
*
|
|
23
|
+
* Two more legacy rules are gone. `[.border-b]:pb-6` and `[.border-t]:pt-6`
|
|
24
|
+
* added padding when the CONSUMER happened to add a border class -- clever,
|
|
25
|
+
* but action at a distance through a class name we do not own, and the census
|
|
26
|
+
* found zero application call sites relying on it (one call site passes
|
|
27
|
+
* `border-b-0`, which removes a border it never had). `@container/card-header`
|
|
28
|
+
* named a container nothing queried.
|
|
29
|
+
*
|
|
30
|
+
* Every string in the cva blocks below is a STATIC literal. Tailwind scans
|
|
31
|
+
* source text, so a class assembled at runtime is invisible to it and would
|
|
32
|
+
* simply never be emitted.
|
|
33
|
+
*/
|
|
34
|
+
const cardVariants = cva([
|
|
35
|
+
"flex flex-col gap-6",
|
|
36
|
+
"rounded-xl border-(length:--border-width) border-border py-6",
|
|
37
|
+
"bg-card text-card-foreground shadow-surface",
|
|
38
|
+
"box-border font-sans"
|
|
39
|
+
]);
|
|
40
|
+
/**
|
|
41
|
+
* Padding is inline-only on the sections and block-only on the shell.
|
|
42
|
+
*
|
|
43
|
+
* That split is load-bearing rather than stylistic: it is what lets a
|
|
44
|
+
* consumer run a divider or a full-bleed image edge to edge, which a single
|
|
45
|
+
* `p-6` on the shell would make impossible.
|
|
46
|
+
*/
|
|
47
|
+
const cardHeaderVariants = cva("flex flex-col gap-1.5 px-6");
|
|
48
|
+
const cardTitleVariants = cva(["text-base leading-(--leading-none) font-semibold", "m-0"]);
|
|
49
|
+
const cardDescriptionVariants = cva(["text-sm leading-(--leading-normal) text-muted-foreground"]);
|
|
50
|
+
const cardContentVariants = cva("px-6");
|
|
51
|
+
const cardFooterVariants = cva("flex items-center px-6");
|
|
52
|
+
function Card({ className, ...props }) {
|
|
53
|
+
return /* @__PURE__ */ jsx("div", {
|
|
54
|
+
...props,
|
|
55
|
+
"data-slot": "card",
|
|
56
|
+
className: cn(cardVariants(), className)
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function CardHeader({ className, ...props }) {
|
|
60
|
+
return /* @__PURE__ */ jsx("div", {
|
|
61
|
+
...props,
|
|
62
|
+
"data-slot": "card-header",
|
|
63
|
+
className: cn(cardHeaderVariants(), className)
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function CardTitle({ className, level = 3, ...props }) {
|
|
67
|
+
const Heading = {
|
|
68
|
+
1: "h1",
|
|
69
|
+
2: "h2",
|
|
70
|
+
3: "h3",
|
|
71
|
+
4: "h4",
|
|
72
|
+
5: "h5",
|
|
73
|
+
6: "h6"
|
|
74
|
+
}[level];
|
|
75
|
+
return /* @__PURE__ */ jsx(Heading, {
|
|
76
|
+
...props,
|
|
77
|
+
"data-slot": "card-title",
|
|
78
|
+
className: cn(cardTitleVariants(), className)
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function CardDescription({ className, ...props }) {
|
|
82
|
+
return /* @__PURE__ */ jsx("div", {
|
|
83
|
+
...props,
|
|
84
|
+
"data-slot": "card-description",
|
|
85
|
+
className: cn(cardDescriptionVariants(), className)
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function CardContent({ className, ...props }) {
|
|
89
|
+
return /* @__PURE__ */ jsx("div", {
|
|
90
|
+
...props,
|
|
91
|
+
"data-slot": "card-content",
|
|
92
|
+
className: cn(cardContentVariants(), className)
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function CardFooter({ className, ...props }) {
|
|
96
|
+
return /* @__PURE__ */ jsx("div", {
|
|
97
|
+
...props,
|
|
98
|
+
"data-slot": "card-footer",
|
|
99
|
+
className: cn(cardFooterVariants(), className)
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, cardContentVariants, cardDescriptionVariants, cardFooterVariants, cardHeaderVariants, cardTitleVariants, cardVariants };
|
|
104
|
+
|
|
105
|
+
//# sourceMappingURL=card.js.map
|
|
@@ -0,0 +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 { 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 function Card({ className, ...props }: CardProps) {\n return <div {...props} data-slot=\"card\" className={cn(cardVariants(), className)} />;\n}\n\n/** Title and description, stacked. */\nexport type CardHeaderProps = ComponentPropsWithoutRef<\"div\">;\n\nexport function CardHeader({ className, ...props }: CardHeaderProps) {\n return (\n <div {...props} data-slot=\"card-header\" className={cn(cardHeaderVariants(), className)} />\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 function CardTitle({ className, level = 3, ...props }: CardTitleProps) {\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 {...props} data-slot=\"card-title\" className={cn(cardTitleVariants(), className)} />\n );\n}\n\n/** Secondary text under the title. */\nexport type CardDescriptionProps = ComponentPropsWithoutRef<\"div\">;\n\nexport function CardDescription({ className, ...props }: CardDescriptionProps) {\n return (\n <div\n {...props}\n data-slot=\"card-description\"\n className={cn(cardDescriptionVariants(), className)}\n />\n );\n}\n\n/** The card's body. */\nexport type CardContentProps = ComponentPropsWithoutRef<\"div\">;\n\nexport function CardContent({ className, ...props }: CardContentProps) {\n return (\n <div {...props} data-slot=\"card-content\" className={cn(cardContentVariants(), className)} />\n );\n}\n\n/** Actions or metadata at the foot of the card. */\nexport type CardFooterProps = ComponentPropsWithoutRef<\"div\">;\n\nexport function CardFooter({ className, ...props }: CardFooterProps) {\n return (\n <div {...props} data-slot=\"card-footer\" className={cn(cardFooterVariants(), className)} />\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,SAAgB,KAAK,EAAE,WAAW,GAAG,SAAoB;CACvD,OAAO,oBAAC,OAAD;EAAK,GAAI;EAAO,aAAU;EAAO,WAAW,GAAG,aAAa,GAAG,SAAS;CAAI,CAAA;AACrF;AAKA,SAAgB,WAAW,EAAE,WAAW,GAAG,SAA0B;CACnE,OACE,oBAAC,OAAD;EAAK,GAAI;EAAO,aAAU;EAAc,WAAW,GAAG,mBAAmB,GAAG,SAAS;CAAI,CAAA;AAE7F;AAwBA,SAAgB,UAAU,EAAE,WAAW,QAAQ,GAAG,GAAG,SAAyB;CAI5E,MAAM,UAAW;EAAE,GAAG;EAAM,GAAG;EAAM,GAAG;EAAM,GAAG;EAAM,GAAG;EAAM,GAAG;CAAK,EAAY;CAEpF,OACE,oBAAC,SAAD;EAAS,GAAI;EAAO,aAAU;EAAa,WAAW,GAAG,kBAAkB,GAAG,SAAS;CAAI,CAAA;AAE/F;AAKA,SAAgB,gBAAgB,EAAE,WAAW,GAAG,SAA+B;CAC7E,OACE,oBAAC,OAAD;EACE,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,wBAAwB,GAAG,SAAS;CACnD,CAAA;AAEL;AAKA,SAAgB,YAAY,EAAE,WAAW,GAAG,SAA2B;CACrE,OACE,oBAAC,OAAD;EAAK,GAAI;EAAO,aAAU;EAAe,WAAW,GAAG,oBAAoB,GAAG,SAAS;CAAI,CAAA;AAE/F;AAKA,SAAgB,WAAW,EAAE,WAAW,GAAG,SAA0B;CACnE,OACE,oBAAC,OAAD;EAAK,GAAI;EAAO,aAAU;EAAc,WAAW,GAAG,mBAAmB,GAAG,SAAS;CAAI,CAAA;AAE7F"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Card, CardContent, CardContentProps, CardDescription, CardDescriptionProps, CardFooter, CardFooterProps, CardHeader, CardHeaderProps, CardProps, CardTitle, CardTitleProps, cardContentVariants, cardDescriptionVariants, cardFooterVariants, cardHeaderVariants, cardTitleVariants, cardVariants } from "./card.js";
|
|
2
|
+
export { Card, CardContent, type CardContentProps, CardDescription, type CardDescriptionProps, CardFooter, type CardFooterProps, CardHeader, type CardHeaderProps, type CardProps, CardTitle, type CardTitleProps, cardContentVariants, cardDescriptionVariants, cardFooterVariants, cardHeaderVariants, cardTitleVariants, cardVariants };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, cardContentVariants, cardDescriptionVariants, cardFooterVariants, cardHeaderVariants, cardTitleVariants, cardVariants } from "./card.js";
|
|
2
|
+
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, cardContentVariants, cardDescriptionVariants, cardFooterVariants, cardHeaderVariants, cardTitleVariants, cardVariants };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { CheckboxProps } from "react-aria-components";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
//#region src/checkbox/checkbox.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Checkbox, rebuilt on React Aria.
|
|
6
|
+
*
|
|
7
|
+
* THE CENSUS FOUND ZERO CALL SITES. It is ported anyway because forms and
|
|
8
|
+
* table row selection are unbuildable without it, but that fact changes what
|
|
9
|
+
* this is: with no usage to be faithful to and no call site to break, it is a
|
|
10
|
+
* rewrite rather than a restyling. Four things the legacy component got
|
|
11
|
+
* wrong are therefore simply fixed rather than carried:
|
|
12
|
+
*
|
|
13
|
+
* - **No accessible name.** It rendered a bare `<input type="checkbox">` with
|
|
14
|
+
* no label, no `aria-label` and no `id`, so every use was an axe `label`
|
|
15
|
+
* violation. Here the label is `children`, and React Aria wraps the input
|
|
16
|
+
* in it.
|
|
17
|
+
* - **The fill never showed.** `checked:bg-primary` on a native input with no
|
|
18
|
+
* `appearance-none` is painted over by the user-agent checkbox.
|
|
19
|
+
* - **`border-primary` cannot be a boundary.** Brand orange is 2.44:1 on
|
|
20
|
+
* white, under even the 3:1 non-text floor (WCAG 1.4.11).
|
|
21
|
+
* - **`focus-visible:ring-2` is a box-shadow**, which forced-colors discards,
|
|
22
|
+
* taking the only focus indication with it.
|
|
23
|
+
*
|
|
24
|
+
* React Aria renders a `<label>` around a visually-hidden real `<input>` and
|
|
25
|
+
* NOTHING else -- there is no visual box in the box. Drawing one, and keeping
|
|
26
|
+
* it in step with `data-selected` / `data-indeterminate`, is what this
|
|
27
|
+
* component owns.
|
|
28
|
+
*
|
|
29
|
+
* Every string in the cva blocks below is a STATIC literal. Tailwind scans
|
|
30
|
+
* source text, so a class assembled at runtime is invisible to it and would
|
|
31
|
+
* simply never be emitted.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* The label geometry now lives in lib/selection-control.ts, shared with
|
|
35
|
+
* Radio and Switch. Three controls with the same 24px target and the same
|
|
36
|
+
* typography is the Rule of Three, and this migration has twice found a
|
|
37
|
+
* legacy pair that styled one surface twice and silently drifted.
|
|
38
|
+
*/
|
|
39
|
+
export declare const checkboxVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
40
|
+
export declare const checkboxBoxVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
41
|
+
/**
|
|
42
|
+
* A checkbox.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* <Checkbox defaultSelected>Email me about new courses</Checkbox>
|
|
46
|
+
* <Checkbox aria-label="Select row" />
|
|
47
|
+
*/
|
|
48
|
+
interface CheckboxProps$1 extends Omit<CheckboxProps, "className" | "style" | "children"> {
|
|
49
|
+
/**
|
|
50
|
+
* The label, and the control's accessible name.
|
|
51
|
+
*
|
|
52
|
+
* Omit it only for a genuinely label-less checkbox -- a table row selector
|
|
53
|
+
* -- and pass `aria-label` instead. A checkbox with neither has no
|
|
54
|
+
* accessible name, which is what every legacy call site would have been.
|
|
55
|
+
*/
|
|
56
|
+
children?: ReactNode;
|
|
57
|
+
/** Extra classes for the label. Merged last, so they win conflicts. */
|
|
58
|
+
className?: string;
|
|
59
|
+
}
|
|
60
|
+
declare function Checkbox$1({ className, children, ...props }: CheckboxProps$1): import("react").JSX.Element;
|
|
61
|
+
//#endregion
|
|
62
|
+
export { Checkbox$1 as Checkbox, CheckboxProps$1 as CheckboxProps };
|
|
63
|
+
//# sourceMappingURL=checkbox.d.ts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { selectionLabelVariants, selectionRingVariants } from "../lib/selection-control.js";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
import { Checkbox } from "react-aria-components";
|
|
6
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/checkbox/checkbox.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Checkbox, rebuilt on React Aria.
|
|
10
|
+
*
|
|
11
|
+
* THE CENSUS FOUND ZERO CALL SITES. It is ported anyway because forms and
|
|
12
|
+
* table row selection are unbuildable without it, but that fact changes what
|
|
13
|
+
* this is: with no usage to be faithful to and no call site to break, it is a
|
|
14
|
+
* rewrite rather than a restyling. Four things the legacy component got
|
|
15
|
+
* wrong are therefore simply fixed rather than carried:
|
|
16
|
+
*
|
|
17
|
+
* - **No accessible name.** It rendered a bare `<input type="checkbox">` with
|
|
18
|
+
* no label, no `aria-label` and no `id`, so every use was an axe `label`
|
|
19
|
+
* violation. Here the label is `children`, and React Aria wraps the input
|
|
20
|
+
* in it.
|
|
21
|
+
* - **The fill never showed.** `checked:bg-primary` on a native input with no
|
|
22
|
+
* `appearance-none` is painted over by the user-agent checkbox.
|
|
23
|
+
* - **`border-primary` cannot be a boundary.** Brand orange is 2.44:1 on
|
|
24
|
+
* white, under even the 3:1 non-text floor (WCAG 1.4.11).
|
|
25
|
+
* - **`focus-visible:ring-2` is a box-shadow**, which forced-colors discards,
|
|
26
|
+
* taking the only focus indication with it.
|
|
27
|
+
*
|
|
28
|
+
* React Aria renders a `<label>` around a visually-hidden real `<input>` and
|
|
29
|
+
* NOTHING else -- there is no visual box in the box. Drawing one, and keeping
|
|
30
|
+
* it in step with `data-selected` / `data-indeterminate`, is what this
|
|
31
|
+
* component owns.
|
|
32
|
+
*
|
|
33
|
+
* Every string in the cva blocks below is a STATIC literal. Tailwind scans
|
|
34
|
+
* source text, so a class assembled at runtime is invisible to it and would
|
|
35
|
+
* simply never be emitted.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* The label geometry now lives in lib/selection-control.ts, shared with
|
|
39
|
+
* Radio and Switch. Three controls with the same 24px target and the same
|
|
40
|
+
* typography is the Rule of Three, and this migration has twice found a
|
|
41
|
+
* legacy pair that styled one surface twice and silently drifted.
|
|
42
|
+
*/
|
|
43
|
+
const checkboxVariants = cva([selectionLabelVariants()]);
|
|
44
|
+
const checkboxBoxVariants = cva([
|
|
45
|
+
"inline-flex size-4 shrink-0 items-center justify-center",
|
|
46
|
+
"rounded-2xs border-(length:--border-width)",
|
|
47
|
+
"box-border",
|
|
48
|
+
"bg-background border-border",
|
|
49
|
+
"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard",
|
|
50
|
+
"group-data-[selected]:bg-primary group-data-[selected]:border-primary-strong",
|
|
51
|
+
"group-data-[selected]:text-primary-foreground",
|
|
52
|
+
"group-data-[indeterminate]:bg-primary group-data-[indeterminate]:border-primary-strong",
|
|
53
|
+
"group-data-[indeterminate]:text-primary-foreground",
|
|
54
|
+
selectionRingVariants()
|
|
55
|
+
]);
|
|
56
|
+
function Checkbox$1({ className, children, ...props }) {
|
|
57
|
+
return /* @__PURE__ */ jsx(Checkbox, {
|
|
58
|
+
...props,
|
|
59
|
+
"data-slot": "checkbox",
|
|
60
|
+
className: cn(checkboxVariants(), className),
|
|
61
|
+
children: ({ isSelected, isIndeterminate }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
62
|
+
"aria-hidden": "true",
|
|
63
|
+
"data-slot": "checkbox-box",
|
|
64
|
+
className: checkboxBoxVariants(),
|
|
65
|
+
children: isIndeterminate ? /* @__PURE__ */ jsx("svg", {
|
|
66
|
+
"data-slot": "checkbox-indeterminate",
|
|
67
|
+
viewBox: "0 0 16 16",
|
|
68
|
+
fill: "none",
|
|
69
|
+
stroke: "currentColor",
|
|
70
|
+
strokeWidth: "2.5",
|
|
71
|
+
strokeLinecap: "round",
|
|
72
|
+
className: "size-3",
|
|
73
|
+
children: /* @__PURE__ */ jsx("path", { d: "M4 8h8" })
|
|
74
|
+
}) : isSelected ? /* @__PURE__ */ jsx("svg", {
|
|
75
|
+
"data-slot": "checkbox-check",
|
|
76
|
+
viewBox: "0 0 16 16",
|
|
77
|
+
fill: "none",
|
|
78
|
+
stroke: "currentColor",
|
|
79
|
+
strokeWidth: "2.5",
|
|
80
|
+
strokeLinecap: "round",
|
|
81
|
+
strokeLinejoin: "round",
|
|
82
|
+
className: "size-3",
|
|
83
|
+
children: /* @__PURE__ */ jsx("path", { d: "m3.5 8.5 3 3 6-6" })
|
|
84
|
+
}) : null
|
|
85
|
+
}), children == null ? null : /* @__PURE__ */ jsx("span", {
|
|
86
|
+
"data-slot": "checkbox-label",
|
|
87
|
+
children
|
|
88
|
+
})] })
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
92
|
+
export { Checkbox$1 as Checkbox, checkboxBoxVariants, checkboxVariants };
|
|
93
|
+
|
|
94
|
+
//# sourceMappingURL=checkbox.js.map
|
|
@@ -0,0 +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 { 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 function Checkbox({ className, children, ...props }: CheckboxProps) {\n return (\n <AriaCheckbox\n {...props}\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,SAAgBA,WAAS,EAAE,WAAW,UAAU,GAAG,SAAwB;CACzE,OACE,oBAACC,UAAD;EACE,GAAI;EACJ,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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { DialogTrigger, ModalOverlayProps } from "react-aria-components";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
//#region src/dialog/dialog.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Dialog, ported from the legacy shadcn/Radix component onto React Aria's
|
|
6
|
+
* Modal primitives.
|
|
7
|
+
*
|
|
8
|
+
* FOUR LEGACY PARTS COLLAPSE INTO TWO PROPS. The census (9 importing files,
|
|
9
|
+
* but only **7** that render anything -- header.tsx and PollQuizCreator.tsx
|
|
10
|
+
* import the parts and use none) reads: DialogContent 9, DialogTitle 8,
|
|
11
|
+
* DialogHeader 7, DialogDescription 2. Those four always appear in the same
|
|
12
|
+
* shape, so `title` and `description` are props of the dialog itself.
|
|
13
|
+
*
|
|
14
|
+
* That is not tidying. `title` is REQUIRED, which makes an unnamed dialog
|
|
15
|
+
* impossible to write -- and the legacy shipped one: LiveQAOverlay.tsx
|
|
16
|
+
* renders a DialogContent with no DialogTitle, so its `aria-labelledby`
|
|
17
|
+
* points at an id that matches no element and the dialog is announced with
|
|
18
|
+
* no name.
|
|
19
|
+
*
|
|
20
|
+
* It also fixes the dangling-description defect for free. Radix set
|
|
21
|
+
* `aria-describedby` unconditionally from a `useId`, so seven of the nine
|
|
22
|
+
* legacy dialogs referenced an id that did not exist. React Aria wires it
|
|
23
|
+
* only when a description slot is actually rendered.
|
|
24
|
+
*
|
|
25
|
+
* `DialogPortal` and `DialogOverlay` are not ported: zero external call
|
|
26
|
+
* sites, and React Aria's ModalOverlay does both jobs.
|
|
27
|
+
*
|
|
28
|
+
* NOT PORTED, and deliberately: the enter/exit animation. The legacy leans
|
|
29
|
+
* on tailwindcss-animate's `animate-in` / `zoom-in-95` utilities, which this
|
|
30
|
+
* repo does not ship, and the motion tokens are a separate task. React Aria
|
|
31
|
+
* exposes `data-entering` / `data-exiting` for whoever adds them.
|
|
32
|
+
*
|
|
33
|
+
* Every string in the cva blocks below is a STATIC literal. Tailwind scans
|
|
34
|
+
* source text, so a class assembled at runtime is invisible to it and would
|
|
35
|
+
* simply never be emitted.
|
|
36
|
+
*/
|
|
37
|
+
export declare const dialogOverlayVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
38
|
+
export declare const dialogPanelVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
39
|
+
export declare const dialogTitleVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
40
|
+
export declare const dialogDescriptionVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
41
|
+
export declare const dialogFooterVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
42
|
+
/**
|
|
43
|
+
* A modal dialog.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* <Dialog isOpen={open} onOpenChange={setOpen} title="Delete user"
|
|
47
|
+
* description="This cannot be undone.">
|
|
48
|
+
* <DialogFooter>
|
|
49
|
+
* <Button slot="close" variant="ghost">Cancel</Button>
|
|
50
|
+
* <Button variant="destructive" onPress={remove}>Delete</Button>
|
|
51
|
+
* </DialogFooter>
|
|
52
|
+
* </Dialog>
|
|
53
|
+
*/
|
|
54
|
+
export interface DialogProps extends Omit<ModalOverlayProps, "className" | "style" | "children"> {
|
|
55
|
+
/**
|
|
56
|
+
* The dialog's heading, and its accessible name.
|
|
57
|
+
*
|
|
58
|
+
* **Required.** The legacy allowed a dialog with no title and one call
|
|
59
|
+
* site shipped that, producing an `aria-labelledby` pointing at nothing.
|
|
60
|
+
* Making it a required prop turns that into something you cannot express.
|
|
61
|
+
*/
|
|
62
|
+
title: ReactNode;
|
|
63
|
+
/**
|
|
64
|
+
* Rendered ABOVE the heading, inside the panel.
|
|
65
|
+
*
|
|
66
|
+
* Exists for Sheet's back control. A panel that replaces its own contents
|
|
67
|
+
* rather than stacking a second modal needs a way back, and that control
|
|
68
|
+
* cannot live in `title`: React Aria wires aria-labelledby to the heading,
|
|
69
|
+
* so a button inside it becomes part of the dialog's accessible name --
|
|
70
|
+
* "Back Campaign details" instead of "Campaign details".
|
|
71
|
+
*/
|
|
72
|
+
beforeTitle?: ReactNode;
|
|
73
|
+
/** Optional supporting text, wired to `aria-describedby` when present. */
|
|
74
|
+
description?: ReactNode;
|
|
75
|
+
/** The dialog body. */
|
|
76
|
+
children?: ReactNode;
|
|
77
|
+
/** Extra classes for the panel. Merged last, so they win conflicts. */
|
|
78
|
+
className?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Extra classes for the scrim, merged last.
|
|
81
|
+
*
|
|
82
|
+
* A centred modal never needs this. A Sheet does: it has to replace the
|
|
83
|
+
* overlay's centring with an edge alignment, and it is the only way to
|
|
84
|
+
* do that without a second copy of the whole overlay.
|
|
85
|
+
*/
|
|
86
|
+
overlayClassName?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Whether to render the corner close button.
|
|
89
|
+
*
|
|
90
|
+
* `true` by default. An `alertdialog` sets it `false`: a confirmation must
|
|
91
|
+
* be answered, not dismissed silently.
|
|
92
|
+
*/
|
|
93
|
+
closeButton?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Accessible name for the close button.
|
|
96
|
+
*
|
|
97
|
+
* A prop because the legacy hard-coded the English string `Close` in an
|
|
98
|
+
* `sr-only` span with no way to override it, which makes the component
|
|
99
|
+
* unlocalisable.
|
|
100
|
+
*
|
|
101
|
+
* @default "Close"
|
|
102
|
+
*/
|
|
103
|
+
closeLabel?: string;
|
|
104
|
+
/** `alertdialog` for a destructive confirmation. @default "dialog" */
|
|
105
|
+
role?: "dialog" | "alertdialog";
|
|
106
|
+
/**
|
|
107
|
+
* Whether clicking outside closes the dialog.
|
|
108
|
+
*
|
|
109
|
+
* `true`, which is NOT React Aria's default. React Aria ships
|
|
110
|
+
* `isDismissable = false` (useOverlay.mjs:26); Radix, which the legacy
|
|
111
|
+
* component wraps, closes on outside click unless told otherwise. Taking
|
|
112
|
+
* the headless default here would have silently changed the behaviour of
|
|
113
|
+
* all seven legacy call sites, and nothing in the suite would have
|
|
114
|
+
* noticed.
|
|
115
|
+
*
|
|
116
|
+
* An `alertdialog` should set this `false`: a confirmation must be
|
|
117
|
+
* answered, not clicked away.
|
|
118
|
+
*
|
|
119
|
+
* @default true
|
|
120
|
+
*/
|
|
121
|
+
isDismissable?: boolean;
|
|
122
|
+
}
|
|
123
|
+
declare function Dialog$1({ title, beforeTitle, description, children, className, closeButton, closeLabel, role, isDismissable, overlayClassName, ...props }: DialogProps): import("react").JSX.Element;
|
|
124
|
+
/**
|
|
125
|
+
* Actions at the foot of a dialog.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* <DialogFooter>
|
|
129
|
+
* <Button slot="close" variant="ghost">Cancel</Button>
|
|
130
|
+
* <Button variant="destructive" onPress={remove}>Delete</Button>
|
|
131
|
+
* </DialogFooter>
|
|
132
|
+
*/
|
|
133
|
+
export interface DialogFooterProps {
|
|
134
|
+
children?: ReactNode;
|
|
135
|
+
className?: string;
|
|
136
|
+
}
|
|
137
|
+
export declare function DialogFooter({ children, className }: DialogFooterProps): import("react").JSX.Element;
|
|
138
|
+
//#endregion
|
|
139
|
+
export { Dialog$1 as Dialog, DialogTrigger };
|
|
140
|
+
//# sourceMappingURL=dialog.d.ts.map
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import { Button, Dialog, DialogTrigger, Heading, Modal, ModalOverlay, Text } from "react-aria-components";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/dialog/dialog.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Dialog, ported from the legacy shadcn/Radix component onto React Aria's
|
|
9
|
+
* Modal primitives.
|
|
10
|
+
*
|
|
11
|
+
* FOUR LEGACY PARTS COLLAPSE INTO TWO PROPS. The census (9 importing files,
|
|
12
|
+
* but only **7** that render anything -- header.tsx and PollQuizCreator.tsx
|
|
13
|
+
* import the parts and use none) reads: DialogContent 9, DialogTitle 8,
|
|
14
|
+
* DialogHeader 7, DialogDescription 2. Those four always appear in the same
|
|
15
|
+
* shape, so `title` and `description` are props of the dialog itself.
|
|
16
|
+
*
|
|
17
|
+
* That is not tidying. `title` is REQUIRED, which makes an unnamed dialog
|
|
18
|
+
* impossible to write -- and the legacy shipped one: LiveQAOverlay.tsx
|
|
19
|
+
* renders a DialogContent with no DialogTitle, so its `aria-labelledby`
|
|
20
|
+
* points at an id that matches no element and the dialog is announced with
|
|
21
|
+
* no name.
|
|
22
|
+
*
|
|
23
|
+
* It also fixes the dangling-description defect for free. Radix set
|
|
24
|
+
* `aria-describedby` unconditionally from a `useId`, so seven of the nine
|
|
25
|
+
* legacy dialogs referenced an id that did not exist. React Aria wires it
|
|
26
|
+
* only when a description slot is actually rendered.
|
|
27
|
+
*
|
|
28
|
+
* `DialogPortal` and `DialogOverlay` are not ported: zero external call
|
|
29
|
+
* sites, and React Aria's ModalOverlay does both jobs.
|
|
30
|
+
*
|
|
31
|
+
* NOT PORTED, and deliberately: the enter/exit animation. The legacy leans
|
|
32
|
+
* on tailwindcss-animate's `animate-in` / `zoom-in-95` utilities, which this
|
|
33
|
+
* repo does not ship, and the motion tokens are a separate task. React Aria
|
|
34
|
+
* exposes `data-entering` / `data-exiting` for whoever adds them.
|
|
35
|
+
*
|
|
36
|
+
* Every string in the cva blocks below is a STATIC literal. Tailwind scans
|
|
37
|
+
* source text, so a class assembled at runtime is invisible to it and would
|
|
38
|
+
* simply never be emitted.
|
|
39
|
+
*/
|
|
40
|
+
const dialogOverlayVariants = cva([
|
|
41
|
+
"fixed inset-0 z-50 flex items-center justify-center",
|
|
42
|
+
"p-4",
|
|
43
|
+
"bg-scrim"
|
|
44
|
+
]);
|
|
45
|
+
const dialogPanelVariants = cva([
|
|
46
|
+
"relative w-full max-w-128",
|
|
47
|
+
"rounded-xl border-(length:--border-width) border-border p-6",
|
|
48
|
+
"bg-card text-card-foreground shadow-modal",
|
|
49
|
+
"flex flex-col gap-4",
|
|
50
|
+
"box-border font-sans",
|
|
51
|
+
"outline-none",
|
|
52
|
+
"max-h-full overflow-y-auto"
|
|
53
|
+
]);
|
|
54
|
+
const dialogTitleVariants = cva(["text-lg leading-(--leading-tight) font-semibold", "m-0"]);
|
|
55
|
+
const dialogDescriptionVariants = cva(["text-sm leading-(--leading-normal) text-muted-foreground", "m-0"]);
|
|
56
|
+
const dialogFooterVariants = cva(["flex flex-wrap items-center justify-end gap-2"]);
|
|
57
|
+
const dialogCloseVariants = cva([
|
|
58
|
+
"absolute end-4 top-4 inline-flex size-6 items-center justify-center",
|
|
59
|
+
"rounded-2xs box-border cursor-pointer",
|
|
60
|
+
"border-(length:--border-width) border-transparent bg-transparent",
|
|
61
|
+
"text-muted-foreground",
|
|
62
|
+
"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard",
|
|
63
|
+
"data-[hovered]:text-foreground",
|
|
64
|
+
"outline-none",
|
|
65
|
+
"data-[focus-visible]:outline-solid",
|
|
66
|
+
"data-[focus-visible]:outline-(length:--focus-ring-width)",
|
|
67
|
+
"data-[focus-visible]:outline-offset-(--focus-ring-offset)",
|
|
68
|
+
"data-[focus-visible]:outline-(--color-ring)",
|
|
69
|
+
"[&_svg]:pointer-events-none [&_svg]:size-4"
|
|
70
|
+
]);
|
|
71
|
+
function Dialog$1({ title, beforeTitle, description, children, className, closeButton = true, closeLabel = "Close", role = "dialog", isDismissable = true, overlayClassName, ...props }) {
|
|
72
|
+
return /* @__PURE__ */ jsx(ModalOverlay, {
|
|
73
|
+
...props,
|
|
74
|
+
isDismissable,
|
|
75
|
+
"data-slot": "dialog-overlay",
|
|
76
|
+
className: cn(dialogOverlayVariants(), overlayClassName),
|
|
77
|
+
children: /* @__PURE__ */ jsx(Modal, {
|
|
78
|
+
className: "contents",
|
|
79
|
+
children: /* @__PURE__ */ jsxs(Dialog, {
|
|
80
|
+
role,
|
|
81
|
+
"data-slot": "dialog",
|
|
82
|
+
className: cn(dialogPanelVariants(), className),
|
|
83
|
+
children: [
|
|
84
|
+
beforeTitle,
|
|
85
|
+
/* @__PURE__ */ jsx(Heading, {
|
|
86
|
+
slot: "title",
|
|
87
|
+
"data-slot": "dialog-title",
|
|
88
|
+
className: dialogTitleVariants(),
|
|
89
|
+
children: title
|
|
90
|
+
}),
|
|
91
|
+
description == null ? null : /* @__PURE__ */ jsx(Text, {
|
|
92
|
+
slot: "description",
|
|
93
|
+
"data-slot": "dialog-description",
|
|
94
|
+
className: dialogDescriptionVariants(),
|
|
95
|
+
children: description
|
|
96
|
+
}),
|
|
97
|
+
children,
|
|
98
|
+
closeButton ? /* @__PURE__ */ jsx(Button, {
|
|
99
|
+
slot: "close",
|
|
100
|
+
"aria-label": closeLabel,
|
|
101
|
+
className: dialogCloseVariants(),
|
|
102
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
103
|
+
"aria-hidden": "true",
|
|
104
|
+
viewBox: "0 0 16 16",
|
|
105
|
+
fill: "none",
|
|
106
|
+
stroke: "currentColor",
|
|
107
|
+
strokeWidth: "1.75",
|
|
108
|
+
strokeLinecap: "round",
|
|
109
|
+
children: /* @__PURE__ */ jsx("path", { d: "m4 4 8 8M12 4l-8 8" })
|
|
110
|
+
})
|
|
111
|
+
}) : null
|
|
112
|
+
]
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function DialogFooter({ children, className }) {
|
|
118
|
+
return /* @__PURE__ */ jsx("div", {
|
|
119
|
+
"data-slot": "dialog-footer",
|
|
120
|
+
className: cn(dialogFooterVariants(), className),
|
|
121
|
+
children
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//#endregion
|
|
125
|
+
export { Dialog$1 as Dialog, DialogFooter, DialogTrigger, dialogDescriptionVariants, dialogFooterVariants, dialogOverlayVariants, dialogPanelVariants, dialogTitleVariants };
|
|
126
|
+
|
|
127
|
+
//# sourceMappingURL=dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.js","names":["Dialog","AriaModalOverlay","AriaModal","AriaDialog","AriaHeading","AriaText","AriaButton"],"sources":["../../src/dialog/dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport type { ReactNode } from \"react\";\nimport {\n Button as AriaButton,\n Dialog as AriaDialog,\n Heading as AriaHeading,\n Modal as AriaModal,\n ModalOverlay as AriaModalOverlay,\n Text as AriaText,\n type ModalOverlayProps as AriaModalOverlayProps,\n} from \"react-aria-components\";\n\nimport { cn } from \"../lib/cn.js\";\n\n/**\n * Dialog, ported from the legacy shadcn/Radix component onto React Aria's\n * Modal primitives.\n *\n * FOUR LEGACY PARTS COLLAPSE INTO TWO PROPS. The census (9 importing files,\n * but only **7** that render anything -- header.tsx and PollQuizCreator.tsx\n * import the parts and use none) reads: DialogContent 9, DialogTitle 8,\n * DialogHeader 7, DialogDescription 2. Those four always appear in the same\n * shape, so `title` and `description` are props of the dialog itself.\n *\n * That is not tidying. `title` is REQUIRED, which makes an unnamed dialog\n * impossible to write -- and the legacy shipped one: LiveQAOverlay.tsx\n * renders a DialogContent with no DialogTitle, so its `aria-labelledby`\n * points at an id that matches no element and the dialog is announced with\n * no name.\n *\n * It also fixes the dangling-description defect for free. Radix set\n * `aria-describedby` unconditionally from a `useId`, so seven of the nine\n * legacy dialogs referenced an id that did not exist. React Aria wires it\n * only when a description slot is actually rendered.\n *\n * `DialogPortal` and `DialogOverlay` are not ported: zero external call\n * sites, and React Aria's ModalOverlay does both jobs.\n *\n * NOT PORTED, and deliberately: the enter/exit animation. The legacy leans\n * on tailwindcss-animate's `animate-in` / `zoom-in-95` utilities, which this\n * repo does not ship, and the motion tokens are a separate task. React Aria\n * exposes `data-entering` / `data-exiting` for whoever adds them.\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 dialogOverlayVariants = cva([\n // Centring by flex, not by `top-1/2 left-1/2 -translate-1/2`. The legacy's\n // translate pair is a bracket value that check:hardcoding rejects, and\n // flex centring needs no transform to undo.\n \"fixed inset-0 z-50 flex items-center justify-center\",\n // The inset that keeps a full-width panel off the viewport edge. The\n // legacy did this with max-w-[calc(100%-2rem)] -- also a bracket value.\n \"p-4\",\n \"bg-scrim\",\n]);\n\nexport const dialogPanelVariants = cva([\n // max-w-128 (32rem), NOT max-w-lg. `--container-lg` does not exist in this\n // repo -- the container scale holds only page-shell widths (max 75rem,\n // wide 90rem) -- so `max-w-lg` compiles to NOTHING and the panel spans the\n // viewport. It emitted no rule at all, tsc and ESLint were both blind to\n // it, and a screenshot is what caught it. 128 spacing units is 32rem,\n // exactly the legacy sm:max-w-lg.\n \"relative w-full max-w-128\",\n \"rounded-xl border-(length:--border-width) border-border p-6\",\n // bg-card, not bg-background: a dialog is a raised surface, and card is\n // the role that already steps up the ink ramp on dark, where a shadow made\n // of ink is invisible. Its contrast pairs are in the contract already.\n \"bg-card text-card-foreground shadow-modal\",\n \"flex flex-col gap-4\",\n // The reset in @seekalfred/styles is OPT-IN, so a consumer may load none:\n // content-box would add the 24px padding to max-w-lg, and an unstyled\n // document renders text in a serif. The Accordion shipped its panel that\n // way and the Alert overflowed by 46px.\n \"box-border font-sans\",\n // React Aria gives the dialog tabindex=-1 and focuses it when nothing\n // inside is autofocused, so it can receive a visible focus ring it does\n // not want.\n \"outline-none\",\n // A dialog taller than the viewport has to scroll, or its footer is\n // unreachable. max-h is on the panel rather than the overlay so the\n // padding above stays visible.\n \"max-h-full overflow-y-auto\",\n]);\n\nexport const dialogTitleVariants = 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-lg leading-(--leading-tight) font-semibold\",\n // The user-agent <h2> ships a 1em block margin. The legacy was inside a\n // Preflight'd app and never met it.\n \"m-0\",\n]);\n\nexport const dialogDescriptionVariants = cva([\n \"text-sm leading-(--leading-normal) text-muted-foreground\",\n // Same: the user-agent <p> block margin.\n \"m-0\",\n]);\n\nexport const dialogFooterVariants = cva([\n // NOT flex-col-reverse. The legacy reversed the footer below `sm`, so a\n // DOM order of Cancel-then-Confirm rendered Confirm-then-Cancel on a\n // phone -- WCAG 1.3.2 Meaningful Sequence, and both alert-dialog call\n // sites hit it. Wrapping keeps narrow viewports working without lying\n // about the order.\n \"flex flex-wrap items-center justify-end gap-2\",\n]);\n\nconst dialogCloseVariants = cva([\n \"absolute end-4 top-4 inline-flex size-6 items-center justify-center\",\n \"rounded-2xs box-border cursor-pointer\",\n \"border-(length:--border-width) border-transparent bg-transparent\",\n \"text-muted-foreground\",\n \"motion-safe:transition-colors motion-safe:duration-(--duration-fast) motion-safe:ease-standard\",\n // The legacy sat at opacity-70 until hover, dimming the only close\n // affordance below its already-marginal contrast. A token that is legible\n // at rest does the same job without that.\n \"data-[hovered]:text-foreground\",\n // outline-solid is load-bearing: outline-none sets --tw-outline-style:none,\n // and the width utility resolves its style from that variable, so a focus\n // rule can apply a width and a colour and paint nothing. Button shipped\n // exactly that.\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 \"[&_svg]:pointer-events-none [&_svg]:size-4\",\n]);\n\n/**\n * A modal dialog.\n *\n * @example\n * <Dialog isOpen={open} onOpenChange={setOpen} title=\"Delete user\"\n * description=\"This cannot be undone.\">\n * <DialogFooter>\n * <Button slot=\"close\" variant=\"ghost\">Cancel</Button>\n * <Button variant=\"destructive\" onPress={remove}>Delete</Button>\n * </DialogFooter>\n * </Dialog>\n */\nexport interface DialogProps\n extends Omit<AriaModalOverlayProps, \"className\" | \"style\" | \"children\"> {\n /**\n * The dialog's heading, and its accessible name.\n *\n * **Required.** The legacy allowed a dialog with no title and one call\n * site shipped that, producing an `aria-labelledby` pointing at nothing.\n * Making it a required prop turns that into something you cannot express.\n */\n title: ReactNode;\n /**\n * Rendered ABOVE the heading, inside the panel.\n *\n * Exists for Sheet's back control. A panel that replaces its own contents\n * rather than stacking a second modal needs a way back, and that control\n * cannot live in `title`: React Aria wires aria-labelledby to the heading,\n * so a button inside it becomes part of the dialog's accessible name --\n * \"Back Campaign details\" instead of \"Campaign details\".\n */\n beforeTitle?: ReactNode;\n /** Optional supporting text, wired to `aria-describedby` when present. */\n description?: ReactNode;\n /** The dialog body. */\n children?: ReactNode;\n /** Extra classes for the panel. Merged last, so they win conflicts. */\n className?: string;\n /**\n * Extra classes for the scrim, merged last.\n *\n * A centred modal never needs this. A Sheet does: it has to replace the\n * overlay's centring with an edge alignment, and it is the only way to\n * do that without a second copy of the whole overlay.\n */\n overlayClassName?: string;\n /**\n * Whether to render the corner close button.\n *\n * `true` by default. An `alertdialog` sets it `false`: a confirmation must\n * be answered, not dismissed silently.\n */\n closeButton?: boolean;\n /**\n * Accessible name for the close button.\n *\n * A prop because the legacy hard-coded the English string `Close` in an\n * `sr-only` span with no way to override it, which makes the component\n * unlocalisable.\n *\n * @default \"Close\"\n */\n closeLabel?: string;\n /** `alertdialog` for a destructive confirmation. @default \"dialog\" */\n role?: \"dialog\" | \"alertdialog\";\n /**\n * Whether clicking outside closes the dialog.\n *\n * `true`, which is NOT React Aria's default. React Aria ships\n * `isDismissable = false` (useOverlay.mjs:26); Radix, which the legacy\n * component wraps, closes on outside click unless told otherwise. Taking\n * the headless default here would have silently changed the behaviour of\n * all seven legacy call sites, and nothing in the suite would have\n * noticed.\n *\n * An `alertdialog` should set this `false`: a confirmation must be\n * answered, not clicked away.\n *\n * @default true\n */\n isDismissable?: boolean;\n}\n\nexport function Dialog({\n title,\n beforeTitle,\n description,\n children,\n className,\n closeButton = true,\n closeLabel = \"Close\",\n role = \"dialog\",\n isDismissable = true,\n overlayClassName,\n ...props\n}: DialogProps) {\n return (\n // ModalOverlay explicitly, not a bare <Modal>. A bare Modal still renders\n // an overlay div, but className lands on the INNER element -- so the\n // scrim would be unstyleable and would paint nothing at all.\n <AriaModalOverlay\n {...props}\n isDismissable={isDismissable}\n data-slot=\"dialog-overlay\"\n className={cn(dialogOverlayVariants(), overlayClassName)}\n >\n <AriaModal className=\"contents\">\n <AriaDialog\n role={role}\n data-slot=\"dialog\"\n className={cn(dialogPanelVariants(), className)}\n >\n {/*\n Above the heading, not inside it. Sheet's back control lives here:\n folding it into `title` would put a button inside the <h2> React\n Aria wires aria-labelledby to, so the dialog's accessible name\n would become \"Back Campaign details\".\n */}\n {beforeTitle}\n {/*\n slot=\"title\" is what React Aria wires aria-labelledby to. A plain\n <h2> here would render identically and leave the dialog unnamed.\n */}\n <AriaHeading slot=\"title\" data-slot=\"dialog-title\" className={dialogTitleVariants()}>\n {title}\n </AriaHeading>\n {description == null ? null : (\n <AriaText\n slot=\"description\"\n data-slot=\"dialog-description\"\n className={dialogDescriptionVariants()}\n >\n {description}\n </AriaText>\n )}\n {children}\n {closeButton ? (\n // slot=\"close\" is React Aria's own dismiss wiring; an onPress\n // that called onOpenChange by hand would not work inside an\n // uncontrolled DialogTrigger.\n <AriaButton slot=\"close\" aria-label={closeLabel} className={dialogCloseVariants()}>\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n >\n <path d=\"m4 4 8 8M12 4l-8 8\" />\n </svg>\n </AriaButton>\n ) : null}\n </AriaDialog>\n </AriaModal>\n </AriaModalOverlay>\n );\n}\n\n/**\n * Actions at the foot of a dialog.\n *\n * @example\n * <DialogFooter>\n * <Button slot=\"close\" variant=\"ghost\">Cancel</Button>\n * <Button variant=\"destructive\" onPress={remove}>Delete</Button>\n * </DialogFooter>\n */\nexport interface DialogFooterProps {\n children?: ReactNode;\n className?: string;\n}\n\nexport function DialogFooter({ children, className }: DialogFooterProps) {\n return (\n <div data-slot=\"dialog-footer\" className={cn(dialogFooterVariants(), className)}>\n {children}\n </div>\n );\n}\n\n/**\n * Pairs a trigger with a dialog and owns the open state.\n *\n * Re-exported from React Aria unchanged. Only 3 of the 9 legacy call sites\n * use a trigger at all -- the rest drive `isOpen` themselves -- so wrapping\n * it would add a layer with nothing to do.\n */\nexport { DialogTrigger } from \"react-aria-components\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,MAAa,wBAAwB,IAAI;CAIvC;CAGA;CACA;AACF,CAAC;AAED,MAAa,sBAAsB,IAAI;CAOrC;CACA;CAIA;CACA;CAKA;CAIA;CAIA;AACF,CAAC;AAED,MAAa,sBAAsB,IAAI,CAGrC,mDAGA,KACF,CAAC;AAED,MAAa,4BAA4B,IAAI,CAC3C,4DAEA,KACF,CAAC;AAED,MAAa,uBAAuB,IAAI,CAMtC,+CACF,CAAC;AAED,MAAM,sBAAsB,IAAI;CAC9B;CACA;CACA;CACA;CACA;CAIA;CAKA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAqFD,SAAgBA,SAAO,EACrB,OACA,aACA,aACA,UACA,WACA,cAAc,MACd,aAAa,SACb,OAAO,UACP,gBAAgB,MAChB,kBACA,GAAG,SACW;CACd,OAIE,oBAACC,cAAD;EACE,GAAI;EACW;EACf,aAAU;EACV,WAAW,GAAG,sBAAsB,GAAG,gBAAgB;EAEvD,UAAA,oBAACC,OAAD;GAAW,WAAU;GACnB,UAAA,qBAACC,QAAD;IACQ;IACN,aAAU;IACV,WAAW,GAAG,oBAAoB,GAAG,SAAS;IAHhD,UAAA;KAWG;KAKD,oBAACC,SAAD;MAAa,MAAK;MAAQ,aAAU;MAAe,WAAW,oBAAoB;MAC/E,UAAA;KACU,CAAA;KACZ,eAAe,OAAO,OACrB,oBAACC,MAAD;MACE,MAAK;MACL,aAAU;MACV,WAAW,0BAA0B;MAEpC,UAAA;KACO,CAAA;KAEX;KACA,cAIC,oBAACC,QAAD;MAAY,MAAK;MAAQ,cAAY;MAAY,WAAW,oBAAoB;MAC9E,UAAA,oBAAC,OAAD;OACE,eAAY;OACZ,SAAQ;OACR,MAAK;OACL,QAAO;OACP,aAAY;OACZ,eAAc;OAEd,UAAA,oBAAC,QAAD,EAAM,GAAE,qBAAsB,CAAA;MAC3B,CAAA;KACK,CAAA,IACV;IACM;;EACH,CAAA;CACK,CAAA;AAEtB;AAgBA,SAAgB,aAAa,EAAE,UAAU,aAAgC;CACvE,OACE,oBAAC,OAAD;EAAK,aAAU;EAAgB,WAAW,GAAG,qBAAqB,GAAG,SAAS;EAC3E;CACE,CAAA;AAET"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Dialog, DialogFooter, DialogFooterProps, DialogProps, DialogTrigger, dialogDescriptionVariants, dialogFooterVariants, dialogOverlayVariants, dialogPanelVariants, dialogTitleVariants } from "./dialog.js";
|
|
2
|
+
export { Dialog, DialogFooter, type DialogFooterProps, type DialogProps, DialogTrigger, dialogDescriptionVariants, dialogFooterVariants, dialogOverlayVariants, dialogPanelVariants, dialogTitleVariants };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Dialog, DialogFooter, DialogTrigger, dialogDescriptionVariants, dialogFooterVariants, dialogOverlayVariants, dialogPanelVariants, dialogTitleVariants } from "./dialog.js";
|
|
2
|
+
export { Dialog, DialogFooter, DialogTrigger, dialogDescriptionVariants, dialogFooterVariants, dialogOverlayVariants, dialogPanelVariants, dialogTitleVariants };
|