@kanzo-tech/ui 0.14.0 → 0.15.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/analytics.d.ts +1 -1
- package/dist/analytics.d.ts.map +1 -1
- package/dist/analytics.js +35 -36
- package/dist/composites/CodeEditor.d.ts +1 -1
- package/dist/composites/CodeEditor.d.ts.map +1 -1
- package/dist/composites/CodeEditor.js +79 -78
- package/dist/composites/CodeEditor.js.map +1 -1
- package/dist/composites/MadeWith.d.ts +2 -3
- package/dist/composites/MadeWith.d.ts.map +1 -1
- package/dist/composites/MadeWith.js.map +1 -1
- package/dist/composites/Preferences.js.map +1 -1
- package/dist/composites/theme-notice.d.ts +2 -2
- package/dist/composites/theme-notice.js.map +1 -1
- package/dist/guard-corpus.d.ts +21 -5
- package/dist/guard-corpus.d.ts.map +1 -1
- package/dist/simples/Link.d.ts +2 -2
- package/dist/simples/Link.js.map +1 -1
- package/dist/simples/button.js +21 -21
- package/dist/simples/button.js.map +1 -1
- package/dist/simples/command.js +1 -1
- package/dist/simples/command.js.map +1 -1
- package/dist/simples/dialog.js +1 -1
- package/dist/simples/dialog.js.map +1 -1
- package/dist/simples/hover-card.js +4 -4
- package/dist/simples/hover-card.js.map +1 -1
- package/dist/simples/input-group.js +1 -1
- package/dist/simples/input-group.js.map +1 -1
- package/dist/simples/menu.js +5 -5
- package/dist/simples/menu.js.map +1 -1
- package/dist/simples/popover.js +1 -1
- package/dist/simples/popover.js.map +1 -1
- package/package.json +3 -3
- package/src/tailwind.css +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-notice.js","sources":["../../src/composites/theme-notice.tsx"],"sourcesContent":["\"use client\";\n\nimport type { CreateToasterReturn } from \"@ark-ui/react/toast\";\nimport * as React from \"react\";\nimport { toast as sharedToaster } from \"../simples/toast.js\";\nimport { useKanzoTheme } from \"../theme/KanzoThemeProvider.js\";\n\n/**\n * The copy for \"the theme you chose is no longer published\", shared by the two surfaces that\n * say it: this toast, and the `Alert` inside `
|
|
1
|
+
{"version":3,"file":"theme-notice.js","sources":["../../src/composites/theme-notice.tsx"],"sourcesContent":["\"use client\";\n\nimport type { CreateToasterReturn } from \"@ark-ui/react/toast\";\nimport * as React from \"react\";\nimport { toast as sharedToaster } from \"../simples/toast.js\";\nimport { useKanzoTheme } from \"../theme/KanzoThemeProvider.js\";\n\n/**\n * The copy for \"the theme you chose is no longer published\", shared by the two surfaces that\n * say it: this toast, and the `Alert` inside `PreferencesColor`. One state, said once.\n *\n * Both strings are **library-authored English**, which is exactly the distinction `PreferencesColor`'s `formatSide`\n * draws with its `formatName`: the library wrote \"Light\" and \"Dark\", so a caller who translates the\n * app has to be able to translate them. A theme's `label` is the opposite case — the client\n * authored it, at runtime — and takes no formatter, because a formatter over it would only let a\n * host decorate someone else's brand name.\n */\nexport interface ThemeRetiredCopy {\n /** Heading (i18n). */\n title?: string;\n /**\n * Compose the body. The default frame is English; a caller who translates `title` needs this\n * too, or the notice is half-translated.\n *\n * `theme` is the retired **name**, not a label: what the tenant withdrew is gone from\n * `identities`, so its label went with it. A host that keeps its own table of retired names is\n * the reason this is a function rather than a string.\n */\n formatDescription?: (parts: { theme: string }) => string;\n}\n\nconst DEFAULT_TITLE = \"Brand updated\";\nconst DEFAULT_DESCRIPTION = ({ theme }: { theme: string }) =>\n `“${theme}” is no longer offered here. You are seeing the default.`;\n\n/** Resolve the copy once, so the toast and the panel's Alert cannot drift into two wordings. */\nexport function themeRetiredCopy(\n { title = DEFAULT_TITLE, formatDescription = DEFAULT_DESCRIPTION }: ThemeRetiredCopy,\n theme: string,\n): { title: string; description: string } {\n return { title, description: formatDescription({ theme }) };\n}\n\nexport interface ThemeNoticeProps extends ThemeRetiredCopy {\n /** Feed a second, separately-placed viewport. Defaults to the shared `toast` instance. */\n toaster?: CreateToasterReturn;\n}\n\n/**\n * ThemeNotice — says, once, that the identity this user chose is no longer published.\n *\n * **Opt-in, and it renders nothing itself.** `KanzoThemeProvider` detects the retirement, clears\n * the preference and holds the id in `retiredTheme`; it draws no surface, because a themer that\n * draws its own surface is what `KanzoTheme` was deleted for (`index.test.ts` keeps it deleted).\n * So mount this beside the host's own `<Toaster />` — it feeds that viewport and returns `null`.\n *\n * Why it is worth saying at all: the cascade already handled the colour. An attribute selector with\n * no matching rule is inert, so a withdrawn id falls through to `:root`, which is the default\n * identity. What is left is that somebody chose gold and is looking at blue, and silence makes that\n * read as a bug in our product rather than a change in their client's.\n *\n * The panel says the same thing in `PreferencesColor`, from the same state — and cannot always\n * say it: that section hides itself below two published themes, so a tenant who retired their way\n * down to one has this as the only surface left.\n */\nexport const ThemeNotice = ({ toaster = sharedToaster, ...copy }: ThemeNoticeProps = {}) => {\n const { retiredTheme } = useKanzoTheme();\n const { title, description } = themeRetiredCopy(copy, retiredTheme ?? \"\");\n\n // Keyed on the id rather than a boolean: the provider's own ref guarantees it *detects* a\n // retirement once, not that this effect runs once. Two things still reach it — StrictMode's\n // double invocation when this mounts AFTER the detection (a host that renders the notice behind\n // a route), and an inline `formatDescription`, which is a new function on every render and so a\n // changed dep. Neither is the \"once per session\" question, which storage already answered.\n const said = React.useRef<string | null>(null);\n React.useEffect(() => {\n if (!retiredTheme || said.current === retiredTheme) return;\n said.current = retiredTheme;\n toaster.create({ title, description, type: \"info\" });\n }, [retiredTheme, title, description, toaster]);\n\n return null;\n};\n"],"names":[],"mappings":";;;;AA+BA;AAKO;AAIL;AACF;AAwBO;AACL;AASA;AACE;AAEmD;AAIvD;;;;;"}
|
package/dist/guard-corpus.d.ts
CHANGED
|
@@ -5,13 +5,29 @@ export interface Root {
|
|
|
5
5
|
/** Absolute path to that package's `src/`. */
|
|
6
6
|
readonly src: string;
|
|
7
7
|
}
|
|
8
|
+
/** Every package the idiom scans cover, derived from the workspace rather than hard-coded. */
|
|
9
|
+
export declare const ROOTS: readonly Root[];
|
|
8
10
|
/**
|
|
9
|
-
*
|
|
11
|
+
* The population for the one rule that is not about the idiom: **a custom property that is read
|
|
12
|
+
* has to exist.** Every shipped package's `src/`, and `docs/`.
|
|
13
|
+
*
|
|
14
|
+
* The idiom filter above is right for the rules about how a recipe is written and wrong for this
|
|
15
|
+
* one, and the failure that proved it is the reason this constant exists: `graph-canvas.tsx`
|
|
16
|
+
* filled the lasso with `var(--brand-a5)`, a token the theme refoundation deleted, and it drew
|
|
17
|
+
* BLACK in keasy — an undefined property makes an SVG `fill` invalid, and `fill`'s initial value is
|
|
18
|
+
* black. `graph` writes no `tv()` recipe, so no guard read a line of it. What a file reads from the
|
|
19
|
+
* theme does not depend on how it spells its classes.
|
|
10
20
|
*
|
|
11
|
-
* `
|
|
12
|
-
*
|
|
21
|
+
* **`docs` is in, and only here.** The showcases and examples are what a consumer copies, and two of
|
|
22
|
+
* them were teaching deleted names (`bg-base-a5`, `var(--brand-a3)`) — a page that paints nothing
|
|
23
|
+
* is a defect whether or not it ships in a tarball. It stays out of {@link ROOTS}: a showcase
|
|
24
|
+
* deliberately hand-rolls what a recipe would own, and the idiom rules would be arguing with the
|
|
25
|
+
* one place that is allowed to.
|
|
26
|
+
*
|
|
27
|
+
* `theme` is in as well, although it declares the vocabulary: its `src/` is TypeScript that READS
|
|
28
|
+
* names (`categoricalColor` returns `var(--chart-N)`), and a read there resolves like any other.
|
|
13
29
|
*/
|
|
14
|
-
export declare const
|
|
30
|
+
export declare const READERS: readonly Root[];
|
|
15
31
|
/** `/Users/…/packages/ai/src/message.tsx` → `ai/message.tsx`. Throws rather than guessing. */
|
|
16
32
|
export declare function label(file: string): string;
|
|
17
33
|
/** The inverse, so a pinned list in a guard is spelled the way that guard's failures are. */
|
|
@@ -22,7 +38,7 @@ export declare function resolvePath(reported: string): string;
|
|
|
22
38
|
* Tests are excluded: they quote the very spellings the rules ban, on purpose, and several of them
|
|
23
39
|
* assemble one at runtime to keep it out of Tailwind's scan.
|
|
24
40
|
*/
|
|
25
|
-
export declare function sourceFiles(extensions?: RegExp): string[];
|
|
41
|
+
export declare function sourceFiles(extensions?: RegExp, roots?: readonly Root[]): string[];
|
|
26
42
|
/**
|
|
27
43
|
* Every subtree a scan has to reach, spelled as a path prefix: `ui/simples/`, `ui/charts/`, `ai/`.
|
|
28
44
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard-corpus.d.ts","sourceRoot":"","sources":["../src/guard-corpus.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"guard-corpus.d.ts","sourceRoot":"","sources":["../src/guard-corpus.ts"],"names":[],"mappings":"AAyEA,eAAO,MAAM,IAAI,QAA4B,CAAC;AAE9C,MAAM,WAAW,IAAI;IACnB,kGAAkG;IAClG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AA4CD,8FAA8F;AAC9F,eAAO,MAAM,KAAK,EAAE,SAAS,IAAI,EAIS,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,OAAO,EAAE,SAAS,IAAI,EAGlC,CAAC;AA+BF,8FAA8F;AAC9F,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI1C;AAED,6FAA6F;AAC7F,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUpD;AAKD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,UAAU,SAAY,EAAE,KAAK,GAAE,SAAS,IAAI,EAAU,GAAG,MAAM,EAAE,CAY5F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,IAAI,MAAM,EAAE,CAYnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAKjF;AASD;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,MAAM,CAAC;AAEhC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/simples/Link.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { VariantProps } from 'tailwind-variants';
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
/**
|
|
4
4
|
* Link — a token-styled anchor, and the only component in the library emitting
|
|
5
|
-
* `data-slot="link"`. `variant` picks the treatment
|
|
6
|
-
*
|
|
5
|
+
* `data-slot="link"`. `variant` picks the treatment. It takes no `asChild`, so a router's link
|
|
6
|
+
* cannot wear it yet. (Generic layout stays in the product via Tailwind — the DS
|
|
7
7
|
* ships no `Flex`/`Box`/`Grid`.)
|
|
8
8
|
*
|
|
9
9
|
* `linkVariants` is module-level and deliberately not on the barrel, which is where every other
|
package/dist/simples/Link.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.js","sources":["../../src/simples/Link.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn.js\";\n\n/**\n * Link — a token-styled anchor, and the only component in the library emitting\n * `data-slot=\"link\"`. `variant` picks the treatment
|
|
1
|
+
{"version":3,"file":"Link.js","sources":["../../src/simples/Link.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn.js\";\n\n/**\n * Link — a token-styled anchor, and the only component in the library emitting\n * `data-slot=\"link\"`. `variant` picks the treatment. It takes no `asChild`, so a router's link\n * cannot wear it yet. (Generic layout stays in the product via Tailwind — the DS\n * ships no `Flex`/`Box`/`Grid`.)\n *\n * `linkVariants` is module-level and deliberately not on the barrel, which is where every other\n * recipe with no cross-module importer sits: exported, a variant object freezes a class list as\n * API. `index.test.ts` pins that.\n */\nexport const linkVariants = tv({\n base: \"rounded-sm underline-offset-4 outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring\",\n variants: {\n variant: {\n default: \"text-primary hover:underline\",\n subtle: \"text-muted-foreground hover:text-foreground hover:underline\",\n plain: \"text-inherit no-underline hover:underline\",\n },\n },\n defaultVariants: { variant: \"default\" },\n});\n\nexport interface LinkProps extends React.ComponentProps<\"a\">, VariantProps<typeof linkVariants> {}\n\nexport function Link({ variant, className, ref, slot, ...rest }: LinkProps) {\n return <a ref={ref} className={cn(linkVariants({ variant }), className)} {...rest} data-slot={slot ?? \"link\"} />;\n}\nLink.displayName = \"Link\";\n"],"names":["linkVariants","tv","Link","variant","className","ref","slot","rest","cn"],"mappings":";;;;AAcO,MAAMA,IAAeC,EAAG;AAAA,EAC7B,MAAM;AAAA,EACN,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA,IAAA;AAAA,EACT;AAAA,EAEF,iBAAiB,EAAE,SAAS,UAAA;AAC9B,CAAC;AAIM,SAASC,EAAK,EAAE,SAAAC,GAAS,WAAAC,GAAW,KAAAC,GAAK,MAAAC,GAAM,GAAGC,KAAmB;AAC1E,2BAAQ,KAAA,EAAE,KAAAF,GAAU,WAAWG,EAAGR,EAAa,EAAE,SAAAG,EAAA,CAAS,GAAGC,CAAS,GAAI,GAAGG,GAAM,aAAWD,KAAQ,QAAQ;AAChH;AACAJ,EAAK,cAAc;"}
|
package/dist/simples/button.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsx as r, jsxs as v, Fragment as
|
|
2
|
-
import { ark as
|
|
1
|
+
import { jsx as r, jsxs as v, Fragment as g } from "react/jsx-runtime";
|
|
2
|
+
import { ark as p } from "@ark-ui/react/factory";
|
|
3
3
|
import { tv as f } from "tailwind-variants";
|
|
4
4
|
import { cn as u } from "../lib/cn.js";
|
|
5
5
|
import { controlSizes as e, controlHeight as m } from "../lib/control-size.js";
|
|
@@ -14,18 +14,18 @@ const z = f({
|
|
|
14
14
|
// that assigns `--btn-bd`, while all six assign the fill and the ink. A default for those two
|
|
15
15
|
// would be a line that is overwritten every single render.
|
|
16
16
|
"[--btn-bd:transparent]",
|
|
17
|
-
// Derived, never assigned by a variant. `--
|
|
17
|
+
// Derived, never assigned by a variant. `--relief: 0` collapses the edge and the lift to
|
|
18
18
|
// nothing, which is what the library looks like today; `1` gives it relief. Same classes.
|
|
19
19
|
//
|
|
20
20
|
// daisyUI darkens a fill with `color-mix(in oklab, var(--btn-bg), #000 5%)`. Mixing toward
|
|
21
21
|
// `--foreground` instead is a divergence taken on a reason: `black` is only "darker" in a light
|
|
22
22
|
// theme, and on a dark one the hover of a pale button should move toward white. One formula
|
|
23
23
|
// reads as "push this fill away from the page and toward the ink" in both, and it follows a
|
|
24
|
-
// tenant's document instead of a constant — which is also why `--
|
|
24
|
+
// tenant's document instead of a constant — which is also why `--relief` can be a single number.
|
|
25
25
|
// Their half-pixel inset gloss needs a colour that is toward the light side in both modes and
|
|
26
26
|
// neither `--foreground` nor `--background` is that, so it waits for a reason to exist.
|
|
27
|
-
"[--btn-edge:color-mix(in_oklab,var(--btn-bd),var(--foreground)_calc(var(--
|
|
28
|
-
"[--btn-lift:color-mix(in_oklab,var(--btn-bg)_calc(var(--
|
|
27
|
+
"[--btn-edge:color-mix(in_oklab,var(--btn-bd),var(--foreground)_calc(var(--relief)*8%))]",
|
|
28
|
+
"[--btn-lift:color-mix(in_oklab,var(--btn-bg)_calc(var(--relief)*30%),transparent)]",
|
|
29
29
|
"bg-(--btn-bg) text-(--btn-fg)",
|
|
30
30
|
// The grain, and the whole of the conditional that switches it off: at `--noise: 0` the layer
|
|
31
31
|
// is sized to zero and never painted, at `1` it tiles. No variant — which is the property that
|
|
@@ -39,7 +39,7 @@ const z = f({
|
|
|
39
39
|
// caller. An arbitrary value is in a group the merge does know.
|
|
40
40
|
"border-[length:var(--stroke)] border-(--btn-edge) rounded-[var(--radius-field)]",
|
|
41
41
|
// As `shadow-*` rather than a raw `box-shadow`, so it composes with `focus-visible:ring-[3px]`
|
|
42
|
-
// through Tailwind's shadow chain instead of being replaced by it. At `--
|
|
42
|
+
// through Tailwind's shadow chain instead of being replaced by it. At `--relief: 0` the lift is
|
|
43
43
|
// transparent and nothing is drawn either way, which is why that was invisible before.
|
|
44
44
|
"shadow-[0_3px_2px_-2px_var(--btn-lift),0_4px_3px_-2px_var(--btn-lift)]",
|
|
45
45
|
// One hover and one active for every variant, solid and transparent alike — and the transparent
|
|
@@ -77,7 +77,7 @@ const z = f({
|
|
|
77
77
|
outline: [
|
|
78
78
|
"[--btn-bg:transparent]",
|
|
79
79
|
"[--btn-fg:var(--foreground)]",
|
|
80
|
-
"[--btn-bd:var(--input)]",
|
|
80
|
+
"[--btn-bd:var(--input,var(--border))]",
|
|
81
81
|
"focus-visible:border-primary"
|
|
82
82
|
],
|
|
83
83
|
destructive: [
|
|
@@ -89,7 +89,7 @@ const z = f({
|
|
|
89
89
|
],
|
|
90
90
|
secondary: [
|
|
91
91
|
"[--btn-bg:var(--secondary)]",
|
|
92
|
-
"[--btn-fg:var(--secondary-foreground)]",
|
|
92
|
+
"[--btn-fg:var(--secondary-foreground,var(--foreground))]",
|
|
93
93
|
"focus-visible:border-primary"
|
|
94
94
|
],
|
|
95
95
|
ghost: [
|
|
@@ -160,36 +160,36 @@ const z = f({
|
|
|
160
160
|
}
|
|
161
161
|
}), j = (s) => {
|
|
162
162
|
const {
|
|
163
|
-
variant:
|
|
163
|
+
variant: t = "default",
|
|
164
164
|
size: n = "md",
|
|
165
165
|
clickEffect: o = !0,
|
|
166
|
-
pill:
|
|
166
|
+
pill: l = !1,
|
|
167
167
|
isLoading: a = !1,
|
|
168
|
-
className:
|
|
169
|
-
children:
|
|
168
|
+
className: d,
|
|
169
|
+
children: i,
|
|
170
170
|
slot: b,
|
|
171
171
|
...c
|
|
172
172
|
} = s;
|
|
173
173
|
return /* @__PURE__ */ r(
|
|
174
|
-
|
|
174
|
+
p.button,
|
|
175
175
|
{
|
|
176
176
|
className: u(
|
|
177
|
-
z({ variant:
|
|
178
|
-
|
|
177
|
+
z({ variant: t, size: n, clickEffect: o, pill: l }),
|
|
178
|
+
d
|
|
179
179
|
),
|
|
180
180
|
"data-size": n,
|
|
181
181
|
"data-state": a ? "loading" : "idle",
|
|
182
|
-
"data-variant":
|
|
182
|
+
"data-variant": t,
|
|
183
183
|
type: "button",
|
|
184
184
|
...c,
|
|
185
185
|
"data-slot": b ?? "button",
|
|
186
186
|
"aria-busy": a,
|
|
187
187
|
"aria-disabled": a,
|
|
188
|
-
children: a ? /* @__PURE__ */ v(
|
|
189
|
-
/* @__PURE__ */ r("span", { "aria-hidden": !0, className: "invisible", children:
|
|
190
|
-
/* @__PURE__ */ r("span", { className: "sr-only", children:
|
|
188
|
+
children: a ? /* @__PURE__ */ v(g, { children: [
|
|
189
|
+
/* @__PURE__ */ r("span", { "aria-hidden": !0, className: "invisible", children: i }),
|
|
190
|
+
/* @__PURE__ */ r("span", { className: "sr-only", children: i }),
|
|
191
191
|
/* @__PURE__ */ r("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ r(x, { "aria-hidden": !0 }) })
|
|
192
|
-
] }) :
|
|
192
|
+
] }) : i
|
|
193
193
|
}
|
|
194
194
|
);
|
|
195
195
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","sources":["../../src/simples/button.tsx"],"sourcesContent":["import { ark } from \"@ark-ui/react/factory\";\nimport type React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\nimport { controlHeight, controlSizes } from \"../lib/control-size\";\nimport { Spinner } from \"./spinner\";\n\n/**\n * The whole control: the fill, the ink, the edge, the lift, both washes and the height, all on the\n * `base` and all written once in terms of three locals a variant assigns.\n *\n * **The shape is daisyUI's.** Their `.btn-primary` is two custom-property assignments over a `.btn`\n * that derives every state; ours was six variants of five to six utilities each, naming eight\n * different tokens between them, with the hover of each written separately. A hover rule that lives\n * in six places is a hover rule that drifts in six places.\n *\n * **The placement is daisyUI's too, and that half arrived late.** The derivations sat in\n * the stylesheet under `[data-slot=\"button\"]`, which is the one attribute this library invites a\n * caller to RENAME — every part takes `slot?: string`. So every component of ours that renames a\n * `Button` got the variant's three assignments and no rule that read them: `AlertDialogAction` and\n * `AlertDialogCancel` reported their `data-variant` correctly and `background-color:\n * rgba(0, 0, 0, 0)` in a live document, and twenty-nine more call sites sat on the same fault.\n * `05f3a0a` had already moved the *height* here for exactly this reason and left the colour behind,\n * on the argument that losing a colour on a rename is a caller asking for a different look — which\n * is true of a caller and was never true of us. `no-paint-on-a-renameable-slot.test.ts` holds it.\n *\n * What a variant may set: `--btn-bg`, `--btn-fg`, `--btn-bd`. Nothing else here paints.\n */\nexport const buttonVariants = tv({\n base: [\n \"relative\",\n // Nothing below may be keyed on `data-slot`. See the docblock: `--size` was moved here first,\n // in `05f3a0a`, and the paint followed it once the same rename was measured against the colour.\n controlHeight,\n // The only one of the three locals a variant may leave unset — `outline` is the sole variant\n // that assigns `--btn-bd`, while all six assign the fill and the ink. A default for those two\n // would be a line that is overwritten every single render.\n \"[--btn-bd:transparent]\",\n // Derived, never assigned by a variant. `--depth: 0` collapses the edge and the lift to\n // nothing, which is what the library looks like today; `1` gives it relief. Same classes.\n //\n // daisyUI darkens a fill with `color-mix(in oklab, var(--btn-bg), #000 5%)`. Mixing toward\n // `--foreground` instead is a divergence taken on a reason: `black` is only \"darker\" in a light\n // theme, and on a dark one the hover of a pale button should move toward white. One formula\n // reads as \"push this fill away from the page and toward the ink\" in both, and it follows a\n // tenant's document instead of a constant — which is also why `--depth` can be a single number.\n // Their half-pixel inset gloss needs a colour that is toward the light side in both modes and\n // neither `--foreground` nor `--background` is that, so it waits for a reason to exist.\n \"[--btn-edge:color-mix(in_oklab,var(--btn-bd),var(--foreground)_calc(var(--depth)*8%))]\",\n \"[--btn-lift:color-mix(in_oklab,var(--btn-bg)_calc(var(--depth)*30%),transparent)]\",\n \"bg-(--btn-bg) text-(--btn-fg)\",\n // The grain, and the whole of the conditional that switches it off: at `--noise: 0` the layer\n // is sized to zero and never painted, at `1` it tiles. No variant — which is the property that\n // lets it be a value a tenant sets rather than a look somebody has to write. It defaults to `0`\n // here rather than in every theme, because a theme that wants no texture is saying nothing.\n \"bg-(image:--fx-noise) bg-size-[calc(var(--noise,0)*100%)]\",\n // `rounded-[var(--radius-field)]` and not `rounded-field`, which is the same radius and the\n // spelling every other recipe here uses: `tailwind-merge` knows nothing about a theme key it\n // was never configured with, so `rounded-field` and a caller's `rounded-full` both survive the\n // merge and the winner is whichever Tailwind happened to emit last. The `pill` variant is that\n // caller. An arbitrary value is in a group the merge does know.\n \"border-[length:var(--stroke)] border-(--btn-edge) rounded-[var(--radius-field)]\",\n // As `shadow-*` rather than a raw `box-shadow`, so it composes with `focus-visible:ring-[3px]`\n // through Tailwind's shadow chain instead of being replaced by it. At `--depth: 0` the lift is\n // transparent and nothing is drawn either way, which is why that was invisible before.\n \"shadow-[0_3px_2px_-2px_var(--btn-lift),0_4px_3px_-2px_var(--btn-lift)]\",\n // One hover and one active for every variant, solid and transparent alike — and the transparent\n // case is the tell that the formula is right. Mixing `transparent` with the foreground at 10%\n // IS the foreground at 10% alpha, which is exactly the wash a ghost button wants.\n //\n // The CSS rule guarded these with `:not(:disabled, [aria-disabled=\"true\"], [data-disabled])`.\n // All three spellings already carry `pointer-events-none` on this same base and an element with\n // `pointer-events: none` can match neither `:hover` nor `:active`, so the guard was\n // belt-and-braces. Dropping it is not tidiness: with the plain modifier, `tailwind-merge` can\n // see a variant's own `hover:bg-*` as the same utility and let it win — which is how `link`\n // opts out in one class, instead of losing to a longer selector on specificity.\n \"hover:bg-[color-mix(in_oklab,var(--btn-bg),var(--foreground)_10%)]\",\n \"active:bg-[color-mix(in_oklab,var(--btn-bg),var(--foreground)_16%)]\",\n \"inline-flex shrink-0 items-center justify-center gap-2\",\n \"whitespace-nowrap font-medium text-sm\",\n \"border-solid\",\n \"transition-all\",\n \"outline-none focus-visible:ring-[3px] focus-visible:ring-ring\",\n \"disabled:pointer-events-none disabled:opacity-64\",\n \"data-disabled:pointer-events-none data-disabled:opacity-64\",\n \"aria-disabled:pointer-events-none aria-disabled:opacity-64\",\n \"data-[state=loading]:pointer-events-none\",\n \"aria-invalid:border-destructive aria-invalid:ring-destructive/24\",\n \"[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n \"motion-reduce:transition-none!\",\n ],\n variants: {\n variant: {\n default: [\n \"[--btn-bg:var(--primary)]\",\n \"[--btn-fg:var(--primary-foreground)]\",\n \"focus-visible:border-background\",\n ],\n outline: [\n \"[--btn-bg:transparent]\",\n \"[--btn-fg:var(--foreground)]\",\n \"[--btn-bd:var(--input)]\",\n \"focus-visible:border-primary\",\n ],\n destructive: [\n \"[--btn-bg:var(--destructive)]\",\n // Was `text-white` at 3.81 on red-500. The fill moved to `-600` and the ink became a token,\n // because no choice of ink rescued red-500: white 3.81, near-black 4.15, AA needs 4.5.\n \"[--btn-fg:var(--destructive-content)]\",\n \"focus-visible:border-background focus-visible:ring-destructive-foreground/32\",\n ],\n secondary: [\n \"[--btn-bg:var(--secondary)]\",\n \"[--btn-fg:var(--secondary-foreground)]\",\n \"focus-visible:border-primary\",\n ],\n ghost: [\n \"[--btn-bg:transparent]\",\n \"[--btn-fg:var(--foreground)]\",\n \"focus-visible:border-primary\",\n ],\n // The one variant that opts OUT of the shared hover, because a link's hover is an underline\n // and not a wash. Same modifier and same utility group as the base's wash, so\n // `tailwind-variants` merges the two and the variant wins — which is what makes opting out\n // one class rather than an exception somewhere else.\n link: [\n \"[--btn-bg:transparent]\",\n \"[--btn-fg:var(--primary)]\",\n \"underline-offset-4\",\n \"hover:bg-transparent hover:underline active:bg-transparent\",\n \"focus-visible:border-primary\",\n ],\n },\n /**\n * Padding, gaps and icon sizes. A size variant only **moves `--size`** — the height that reads\n * it is on the `base` — so a tenant can ask for compact controls, through `--size-field`,\n * without asking for tighter text.\n *\n * The floor is still measured rather than chosen. `xs` and `icon-xs` were both `1.5rem`, and\n * every size is a `rem` against a root the density axis sets — 16px default, 14px compact, 18px\n * comfortable — so they measured **21px in compact**, under the 24×24 WCAG 2.5.8 states in CSS\n * pixels. `sm` is the smallest size that clears the bar in all three densities. No call site was\n * failing: the spacing exception saves a clustered control, and every measured `xs` was in a\n * cluster. The variant went because its NAME promised a size it could not deliver at one\n * density, and nothing was published to break.\n */\n size: {\n sm: [controlSizes.sm, \"px-2.5\", \"gap-1.5\", \"[&_svg:not([class*='size-'])]:size-3.5\"],\n md: [controlSizes.md, \"px-3\", \"py-2\"],\n lg: [controlSizes.lg, \"px-3.5\"],\n xl: [\"[--size:calc(var(--size-field)*10)]\", \"text-base\", \"px-4\"],\n // Square, and the width is stated rather than left to `aspect-ratio`: a caller who writes\n // `w-fit` on top of an aspect ratio gets the icon's own width and a control twice as tall.\n \"icon-sm\": [controlSizes.sm, \"w-(--size)\", \"px-0\"],\n \"icon-md\": [controlSizes.md, \"w-(--size)\", \"px-0\"],\n \"icon-lg\": [controlSizes.lg, \"w-(--size)\", \"px-0\"],\n \"icon-xl\": [\n \"[--size:calc(var(--size-field)*10)]\",\n \"w-(--size)\",\n \"px-0\",\n \"[&_svg:not([class*='size-'])]:size-5\",\n ],\n },\n clickEffect: {\n true: \"active:not-aria-[haspopup]:scale-[0.98]\",\n },\n pill: {\n true: [\n \"rounded-full\",\n \"has-[>svg]:data-[size=sm]:pe-3.5\",\n \"has-[>svg]:data-[size=md]:pe-4\",\n \"has-[>svg]:data-[size=lg]:pe-4.5\",\n \"has-[>svg]:data-[size=xl]:pe-5\",\n ],\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"md\",\n clickEffect: true,\n pill: false,\n },\n});\n\nexport interface ButtonProps\n extends React.ComponentProps<typeof ark.button>,\n VariantProps<typeof buttonVariants> {\n /**\n * Apply a click effect to the button\n *\n * @default true\n */\n clickEffect?: boolean;\n /**\n * Show a loading indicator\n *\n * @default false\n */\n isLoading?: boolean;\n}\n\nexport const Button = (props: ButtonProps) => {\n const {\n variant = \"default\",\n size = \"md\",\n clickEffect = true,\n pill = false,\n isLoading = false,\n className,\n children,\n slot,\n ...rest\n } = props;\n\n return (\n <ark.button\n className={cn(\n buttonVariants({ variant, size, clickEffect, pill }),\n className\n )}\n data-size={size}\n data-state={isLoading ? \"loading\" : \"idle\"}\n data-variant={variant}\n type=\"button\"\n {...rest}\n data-slot={slot ?? \"button\"}\n aria-busy={isLoading}\n aria-disabled={isLoading}\n >\n {isLoading ? (\n <>\n <span aria-hidden className=\"invisible\">\n {children}\n </span>\n\n <span className=\"sr-only\">{children}</span>\n\n <span className=\"absolute inset-0 flex items-center justify-center\">\n <Spinner aria-hidden />\n </span>\n </>\n ) : (\n children\n )}\n </ark.button>\n );\n};\n"],"names":["buttonVariants","tv","controlHeight","controlSizes","Button","props","variant","size","clickEffect","pill","isLoading","className","children","slot","rest","jsx","ark","cn","jsxs","Fragment","Spinner"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"button.js","sources":["../../src/simples/button.tsx"],"sourcesContent":["import { ark } from \"@ark-ui/react/factory\";\nimport type React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\nimport { controlHeight, controlSizes } from \"../lib/control-size\";\nimport { Spinner } from \"./spinner\";\n\n/**\n * The whole control: the fill, the ink, the edge, the lift, both washes and the height, all on the\n * `base` and all written once in terms of three locals a variant assigns.\n *\n * **The shape is daisyUI's.** Their `.btn-primary` is two custom-property assignments over a `.btn`\n * that derives every state; ours was six variants of five to six utilities each, naming eight\n * different tokens between them, with the hover of each written separately. A hover rule that lives\n * in six places is a hover rule that drifts in six places.\n *\n * **The placement is daisyUI's too, and that half arrived late.** The derivations sat in\n * the stylesheet under `[data-slot=\"button\"]`, which is the one attribute this library invites a\n * caller to RENAME — every part takes `slot?: string`. So every component of ours that renames a\n * `Button` got the variant's three assignments and no rule that read them: `AlertDialogAction` and\n * `AlertDialogCancel` reported their `data-variant` correctly and `background-color:\n * rgba(0, 0, 0, 0)` in a live document, and twenty-nine more call sites sat on the same fault.\n * `05f3a0a` had already moved the *height* here for exactly this reason and left the colour behind,\n * on the argument that losing a colour on a rename is a caller asking for a different look — which\n * is true of a caller and was never true of us. `no-paint-on-a-renameable-slot.test.ts` holds it.\n *\n * What a variant may set: `--btn-bg`, `--btn-fg`, `--btn-bd`. Nothing else here paints.\n */\nexport const buttonVariants = tv({\n base: [\n \"relative\",\n // Nothing below may be keyed on `data-slot`. See the docblock: `--size` was moved here first,\n // in `05f3a0a`, and the paint followed it once the same rename was measured against the colour.\n controlHeight,\n // The only one of the three locals a variant may leave unset — `outline` is the sole variant\n // that assigns `--btn-bd`, while all six assign the fill and the ink. A default for those two\n // would be a line that is overwritten every single render.\n \"[--btn-bd:transparent]\",\n // Derived, never assigned by a variant. `--relief: 0` collapses the edge and the lift to\n // nothing, which is what the library looks like today; `1` gives it relief. Same classes.\n //\n // daisyUI darkens a fill with `color-mix(in oklab, var(--btn-bg), #000 5%)`. Mixing toward\n // `--foreground` instead is a divergence taken on a reason: `black` is only \"darker\" in a light\n // theme, and on a dark one the hover of a pale button should move toward white. One formula\n // reads as \"push this fill away from the page and toward the ink\" in both, and it follows a\n // tenant's document instead of a constant — which is also why `--relief` can be a single number.\n // Their half-pixel inset gloss needs a colour that is toward the light side in both modes and\n // neither `--foreground` nor `--background` is that, so it waits for a reason to exist.\n \"[--btn-edge:color-mix(in_oklab,var(--btn-bd),var(--foreground)_calc(var(--relief)*8%))]\",\n \"[--btn-lift:color-mix(in_oklab,var(--btn-bg)_calc(var(--relief)*30%),transparent)]\",\n \"bg-(--btn-bg) text-(--btn-fg)\",\n // The grain, and the whole of the conditional that switches it off: at `--noise: 0` the layer\n // is sized to zero and never painted, at `1` it tiles. No variant — which is the property that\n // lets it be a value a tenant sets rather than a look somebody has to write. It defaults to `0`\n // here rather than in every theme, because a theme that wants no texture is saying nothing.\n \"bg-(image:--fx-noise) bg-size-[calc(var(--noise,0)*100%)]\",\n // `rounded-[var(--radius-field)]` and not `rounded-field`, which is the same radius and the\n // spelling every other recipe here uses: `tailwind-merge` knows nothing about a theme key it\n // was never configured with, so `rounded-field` and a caller's `rounded-full` both survive the\n // merge and the winner is whichever Tailwind happened to emit last. The `pill` variant is that\n // caller. An arbitrary value is in a group the merge does know.\n \"border-[length:var(--stroke)] border-(--btn-edge) rounded-[var(--radius-field)]\",\n // As `shadow-*` rather than a raw `box-shadow`, so it composes with `focus-visible:ring-[3px]`\n // through Tailwind's shadow chain instead of being replaced by it. At `--relief: 0` the lift is\n // transparent and nothing is drawn either way, which is why that was invisible before.\n \"shadow-[0_3px_2px_-2px_var(--btn-lift),0_4px_3px_-2px_var(--btn-lift)]\",\n // One hover and one active for every variant, solid and transparent alike — and the transparent\n // case is the tell that the formula is right. Mixing `transparent` with the foreground at 10%\n // IS the foreground at 10% alpha, which is exactly the wash a ghost button wants.\n //\n // The CSS rule guarded these with `:not(:disabled, [aria-disabled=\"true\"], [data-disabled])`.\n // All three spellings already carry `pointer-events-none` on this same base and an element with\n // `pointer-events: none` can match neither `:hover` nor `:active`, so the guard was\n // belt-and-braces. Dropping it is not tidiness: with the plain modifier, `tailwind-merge` can\n // see a variant's own `hover:bg-*` as the same utility and let it win — which is how `link`\n // opts out in one class, instead of losing to a longer selector on specificity.\n \"hover:bg-[color-mix(in_oklab,var(--btn-bg),var(--foreground)_10%)]\",\n \"active:bg-[color-mix(in_oklab,var(--btn-bg),var(--foreground)_16%)]\",\n \"inline-flex shrink-0 items-center justify-center gap-2\",\n \"whitespace-nowrap font-medium text-sm\",\n \"border-solid\",\n \"transition-all\",\n \"outline-none focus-visible:ring-[3px] focus-visible:ring-ring\",\n \"disabled:pointer-events-none disabled:opacity-64\",\n \"data-disabled:pointer-events-none data-disabled:opacity-64\",\n \"aria-disabled:pointer-events-none aria-disabled:opacity-64\",\n \"data-[state=loading]:pointer-events-none\",\n \"aria-invalid:border-destructive aria-invalid:ring-destructive/24\",\n \"[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n \"motion-reduce:transition-none!\",\n ],\n variants: {\n variant: {\n default: [\n \"[--btn-bg:var(--primary)]\",\n \"[--btn-fg:var(--primary-foreground)]\",\n \"focus-visible:border-background\",\n ],\n outline: [\n \"[--btn-bg:transparent]\",\n \"[--btn-fg:var(--foreground)]\",\n \"[--btn-bd:var(--input,var(--border))]\",\n \"focus-visible:border-primary\",\n ],\n destructive: [\n \"[--btn-bg:var(--destructive)]\",\n // Was `text-white` at 3.81 on red-500. The fill moved to `-600` and the ink became a token,\n // because no choice of ink rescued red-500: white 3.81, near-black 4.15, AA needs 4.5.\n \"[--btn-fg:var(--destructive-content)]\",\n \"focus-visible:border-background focus-visible:ring-destructive-foreground/32\",\n ],\n secondary: [\n \"[--btn-bg:var(--secondary)]\",\n \"[--btn-fg:var(--secondary-foreground,var(--foreground))]\",\n \"focus-visible:border-primary\",\n ],\n ghost: [\n \"[--btn-bg:transparent]\",\n \"[--btn-fg:var(--foreground)]\",\n \"focus-visible:border-primary\",\n ],\n // The one variant that opts OUT of the shared hover, because a link's hover is an underline\n // and not a wash. Same modifier and same utility group as the base's wash, so\n // `tailwind-variants` merges the two and the variant wins — which is what makes opting out\n // one class rather than an exception somewhere else.\n link: [\n \"[--btn-bg:transparent]\",\n \"[--btn-fg:var(--primary)]\",\n \"underline-offset-4\",\n \"hover:bg-transparent hover:underline active:bg-transparent\",\n \"focus-visible:border-primary\",\n ],\n },\n /**\n * Padding, gaps and icon sizes. A size variant only **moves `--size`** — the height that reads\n * it is on the `base` — so a tenant can ask for compact controls, through `--size-field`,\n * without asking for tighter text.\n *\n * The floor is still measured rather than chosen. `xs` and `icon-xs` were both `1.5rem`, and\n * every size is a `rem` against a root the density axis sets — 16px default, 14px compact, 18px\n * comfortable — so they measured **21px in compact**, under the 24×24 WCAG 2.5.8 states in CSS\n * pixels. `sm` is the smallest size that clears the bar in all three densities. No call site was\n * failing: the spacing exception saves a clustered control, and every measured `xs` was in a\n * cluster. The variant went because its NAME promised a size it could not deliver at one\n * density, and nothing was published to break.\n */\n size: {\n sm: [controlSizes.sm, \"px-2.5\", \"gap-1.5\", \"[&_svg:not([class*='size-'])]:size-3.5\"],\n md: [controlSizes.md, \"px-3\", \"py-2\"],\n lg: [controlSizes.lg, \"px-3.5\"],\n xl: [\"[--size:calc(var(--size-field)*10)]\", \"text-base\", \"px-4\"],\n // Square, and the width is stated rather than left to `aspect-ratio`: a caller who writes\n // `w-fit` on top of an aspect ratio gets the icon's own width and a control twice as tall.\n \"icon-sm\": [controlSizes.sm, \"w-(--size)\", \"px-0\"],\n \"icon-md\": [controlSizes.md, \"w-(--size)\", \"px-0\"],\n \"icon-lg\": [controlSizes.lg, \"w-(--size)\", \"px-0\"],\n \"icon-xl\": [\n \"[--size:calc(var(--size-field)*10)]\",\n \"w-(--size)\",\n \"px-0\",\n \"[&_svg:not([class*='size-'])]:size-5\",\n ],\n },\n clickEffect: {\n true: \"active:not-aria-[haspopup]:scale-[0.98]\",\n },\n pill: {\n true: [\n \"rounded-full\",\n \"has-[>svg]:data-[size=sm]:pe-3.5\",\n \"has-[>svg]:data-[size=md]:pe-4\",\n \"has-[>svg]:data-[size=lg]:pe-4.5\",\n \"has-[>svg]:data-[size=xl]:pe-5\",\n ],\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"md\",\n clickEffect: true,\n pill: false,\n },\n});\n\nexport interface ButtonProps\n extends React.ComponentProps<typeof ark.button>,\n VariantProps<typeof buttonVariants> {\n /**\n * Apply a click effect to the button\n *\n * @default true\n */\n clickEffect?: boolean;\n /**\n * Show a loading indicator\n *\n * @default false\n */\n isLoading?: boolean;\n}\n\nexport const Button = (props: ButtonProps) => {\n const {\n variant = \"default\",\n size = \"md\",\n clickEffect = true,\n pill = false,\n isLoading = false,\n className,\n children,\n slot,\n ...rest\n } = props;\n\n return (\n <ark.button\n className={cn(\n buttonVariants({ variant, size, clickEffect, pill }),\n className\n )}\n data-size={size}\n data-state={isLoading ? \"loading\" : \"idle\"}\n data-variant={variant}\n type=\"button\"\n {...rest}\n data-slot={slot ?? \"button\"}\n aria-busy={isLoading}\n aria-disabled={isLoading}\n >\n {isLoading ? (\n <>\n <span aria-hidden className=\"invisible\">\n {children}\n </span>\n\n <span className=\"sr-only\">{children}</span>\n\n <span className=\"absolute inset-0 flex items-center justify-center\">\n <Spinner aria-hidden />\n </span>\n </>\n ) : (\n children\n )}\n </ark.button>\n );\n};\n"],"names":["buttonVariants","tv","controlHeight","controlSizes","Button","props","variant","size","clickEffect","pill","isLoading","className","children","slot","rest","jsx","ark","cn","jsxs","Fragment","Spinner"],"mappings":"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"}
|
package/dist/simples/command.js
CHANGED
|
@@ -155,7 +155,7 @@ const q = y, J = (o) => {
|
|
|
155
155
|
"flex items-center justify-between gap-2",
|
|
156
156
|
"-m-2 mt-2 px-4 py-3",
|
|
157
157
|
"text-muted-foreground text-xs",
|
|
158
|
-
"rounded-b-[calc(var(--radius-2xl
|
|
158
|
+
"rounded-b-[calc(var(--radius-2xl)-1px)] border-t",
|
|
159
159
|
t
|
|
160
160
|
),
|
|
161
161
|
...r,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.js","sources":["../../src/simples/command.tsx"],"sourcesContent":["import { Portal } from \"@ark-ui/react\";\nimport { Combobox as ArkCombobox } from \"@ark-ui/react/combobox\";\nimport { Dialog as ArkDialog } from \"@ark-ui/react/dialog\";\nimport { SearchIcon } from \"lucide-react\";\nimport type React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n Combobox,\n ComboboxControl,\n ComboboxEmpty,\n ComboboxGroup,\n type ComboboxItem,\n ComboboxList,\n comboboxItemVariants,\n} from \"./combobox\";\nimport {\n Dialog,\n type DialogContent,\n DialogHeader,\n DialogOverlay,\n DialogPositioner,\n dialogContentVariants,\n} from \"./dialog\";\nimport type { InputProps } from \"./input\";\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"./input-group\";\nimport { MenuShortcut } from \"./menu\";\nimport { Separator } from \"./separator\";\n\nexport const CommandDialog = Dialog;\n\n// `CommandDialog` *is* `Dialog`, so its trigger is `DialogTrigger` — a renamed alias only made\n// the two look like different machines.\ninterface CommandDialogContentProps\n extends React.ComponentProps<typeof DialogContent> {\n /**\n * The description of the dialog\n *\n * @default \"Search for a command to run...\"\n */\n description?: string;\n /**\n * The title of the dialog\n *\n * @default \"Command Palette\"\n */\n title?: string;\n}\n\nexport const CommandDialogContent = (props: CommandDialogContentProps) => {\n const {\n size = \"lg\",\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n className,\n children,\n slot,\n ...rest\n } = props;\n\n return (\n <Portal>\n <DialogOverlay />\n\n <DialogPositioner>\n <ArkDialog.Content\n className={cn(\n \"max-sm:row-start-1\",\n dialogContentVariants({ size }),\n \"border-0 p-0\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"command-dialog-content\"}\n >\n <DialogHeader\n className=\"sr-only\"\n description={description}\n title={title}\n />\n\n {children}\n </ArkDialog.Content>\n </DialogPositioner>\n </Portal>\n );\n};\n\nexport const Command: ArkCombobox.RootComponent = (props) => {\n const { lazyMount = true, unmountOnExit = true, className, ...rest } = props;\n\n return (\n <Combobox\n className={cn(\n \"isolate\",\n \"flex min-h-0 flex-1 flex-col\",\n \"p-2\",\n \"bg-popover\",\n \"text-popover-foreground\",\n \"rounded-2xl border\",\n className\n )}\n closeOnSelect={false}\n disableLayer\n inputBehavior=\"autohighlight\"\n lazyMount={lazyMount}\n loopFocus={false}\n open\n selectionBehavior=\"clear\"\n unmountOnExit={unmountOnExit}\n {...rest}\n />\n );\n};\n\ninterface CommandInputProps\n extends Omit<React.ComponentProps<typeof ArkCombobox.Input>, \"size\"> {\n /**\n * The size of the input\n *\n * @default \"md\"\n */\n size?: InputProps[\"size\"];\n}\n\nexport const CommandContent = (\n props: React.ComponentProps<typeof ArkCombobox.Content>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ArkCombobox.Content\n className={cn(\n \"flex flex-1 flex-col\",\n \"max-h-(--available-height) min-h-0\",\n \"-me-2\",\n \"outline-none\",\n \"scrollbar-thin scrollbar-track-transparent scrollbar-thumb-foreground/20 overflow-auto overscroll-contain\",\n \"[:not(.has-[+[data-slot=command-footer]])]:rounded-b-2xl [:not(.has-[+[data-slot=command-footer]])]:border-b\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"command-content\"}\n />\n );\n};\n\nexport const CommandInput = (props: CommandInputProps) => {\n const { size = \"md\", className, ...rest } = props;\n\n return (\n <ComboboxControl className=\"mb-2\">\n <InputGroup\n className={cn(\"rounded-xl bg-field\", className)}\n size={size}\n {...rest}\n >\n <InputGroupAddon>\n <SearchIcon aria-hidden className=\"opacity-64\" />\n </InputGroupAddon>\n <ArkCombobox.Input asChild>\n <InputGroupInput autoFocus slot=\"command-input\" />\n </ArkCombobox.Input>\n </InputGroup>\n </ComboboxControl>\n );\n};\n\ninterface CommandListProps extends React.ComponentProps<typeof ComboboxList> {}\n\nexport const CommandList = (props: CommandListProps) => {\n const { className, slot, ...rest } = props;\n\n return (\n <div className=\"max-h-72 min-h-0 flex-1\">\n <ComboboxList\n className={cn(\"flex-1 pe-2.5\", className)}\n {...rest}\n slot={slot ?? \"command-list\"}\n />\n </div>\n );\n};\n\nexport const CommandEmpty = (\n props: React.ComponentProps<typeof ComboboxEmpty>\n) => {\n const { className, children, slot, ...rest } = props;\n\n return (\n <ComboboxEmpty\n className={cn(\"py-6 text-center text-sm\", className)}\n {...rest}\n slot={slot ?? \"command-empty\"}\n >\n {children || \"No results found.\"}\n </ComboboxEmpty>\n );\n};\n\n// A group's label comes from `heading`, which `ComboboxGroup` renders itself — so the renamed\n// `CommandGroupLabel` was redundant twice over and is gone.\nexport const CommandGroup = (\n { slot, ...rest }: React.ComponentProps<typeof ComboboxGroup>\n) => <ComboboxGroup {...rest} slot={slot ?? \"command-group\"} />;\n\nexport const CommandItem = (\n props: React.ComponentProps<typeof ComboboxItem>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ArkCombobox.Item\n className={cn(comboboxItemVariants({ showIndicator: false }), className)}\n persistFocus\n {...rest}\n data-slot={slot ?? \"command-item\"}\n />\n );\n};\n\nexport const CommandSeparator = (props: React.ComponentProps<\"div\">) => {\n const { className, slot, ...rest } = props;\n\n return (\n <Separator\n className={cn(\"my-2\", className)}\n {...rest}\n slot={slot ?? \"command-separator\"}\n />\n );\n};\n\nexport const CommandShortcut = (\n { slot, ...rest }: React.ComponentProps<typeof MenuShortcut>\n) => <MenuShortcut {...rest} slot={slot ?? \"command-shortcut\"} />;\n\nexport const CommandFooter = (props: React.ComponentProps<\"div\">) => {\n const { className, slot, ...rest } = props;\n\n return (\n <div\n className={cn(\n \"z-10\",\n \"flex items-center justify-between gap-2\",\n \"-m-2 mt-2 px-4 py-3\",\n \"text-muted-foreground text-xs\",\n \"rounded-b-[calc(var(--radius-2xl,1rem)-1px)] border-t\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"command-footer\"}\n />\n );\n};\n"],"names":["CommandDialog","Dialog","CommandDialogContent","props","size","title","description","className","children","slot","rest","Portal","jsx","DialogOverlay","DialogPositioner","jsxs","ArkDialog","cn","dialogContentVariants","DialogHeader","Command","lazyMount","unmountOnExit","Combobox","CommandContent","ArkCombobox","CommandInput","ComboboxControl","InputGroup","InputGroupAddon","SearchIcon","InputGroupInput","CommandList","ComboboxList","CommandEmpty","ComboboxEmpty","CommandGroup","ComboboxGroup","CommandItem","comboboxItemVariants","CommandSeparator","Separator","CommandShortcut","MenuShortcut","CommandFooter"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"command.js","sources":["../../src/simples/command.tsx"],"sourcesContent":["import { Portal } from \"@ark-ui/react\";\nimport { Combobox as ArkCombobox } from \"@ark-ui/react/combobox\";\nimport { Dialog as ArkDialog } from \"@ark-ui/react/dialog\";\nimport { SearchIcon } from \"lucide-react\";\nimport type React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n Combobox,\n ComboboxControl,\n ComboboxEmpty,\n ComboboxGroup,\n type ComboboxItem,\n ComboboxList,\n comboboxItemVariants,\n} from \"./combobox\";\nimport {\n Dialog,\n type DialogContent,\n DialogHeader,\n DialogOverlay,\n DialogPositioner,\n dialogContentVariants,\n} from \"./dialog\";\nimport type { InputProps } from \"./input\";\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupInput,\n} from \"./input-group\";\nimport { MenuShortcut } from \"./menu\";\nimport { Separator } from \"./separator\";\n\nexport const CommandDialog = Dialog;\n\n// `CommandDialog` *is* `Dialog`, so its trigger is `DialogTrigger` — a renamed alias only made\n// the two look like different machines.\ninterface CommandDialogContentProps\n extends React.ComponentProps<typeof DialogContent> {\n /**\n * The description of the dialog\n *\n * @default \"Search for a command to run...\"\n */\n description?: string;\n /**\n * The title of the dialog\n *\n * @default \"Command Palette\"\n */\n title?: string;\n}\n\nexport const CommandDialogContent = (props: CommandDialogContentProps) => {\n const {\n size = \"lg\",\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n className,\n children,\n slot,\n ...rest\n } = props;\n\n return (\n <Portal>\n <DialogOverlay />\n\n <DialogPositioner>\n <ArkDialog.Content\n className={cn(\n \"max-sm:row-start-1\",\n dialogContentVariants({ size }),\n \"border-0 p-0\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"command-dialog-content\"}\n >\n <DialogHeader\n className=\"sr-only\"\n description={description}\n title={title}\n />\n\n {children}\n </ArkDialog.Content>\n </DialogPositioner>\n </Portal>\n );\n};\n\nexport const Command: ArkCombobox.RootComponent = (props) => {\n const { lazyMount = true, unmountOnExit = true, className, ...rest } = props;\n\n return (\n <Combobox\n className={cn(\n \"isolate\",\n \"flex min-h-0 flex-1 flex-col\",\n \"p-2\",\n \"bg-popover\",\n \"text-popover-foreground\",\n \"rounded-2xl border\",\n className\n )}\n closeOnSelect={false}\n disableLayer\n inputBehavior=\"autohighlight\"\n lazyMount={lazyMount}\n loopFocus={false}\n open\n selectionBehavior=\"clear\"\n unmountOnExit={unmountOnExit}\n {...rest}\n />\n );\n};\n\ninterface CommandInputProps\n extends Omit<React.ComponentProps<typeof ArkCombobox.Input>, \"size\"> {\n /**\n * The size of the input\n *\n * @default \"md\"\n */\n size?: InputProps[\"size\"];\n}\n\nexport const CommandContent = (\n props: React.ComponentProps<typeof ArkCombobox.Content>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ArkCombobox.Content\n className={cn(\n \"flex flex-1 flex-col\",\n \"max-h-(--available-height) min-h-0\",\n \"-me-2\",\n \"outline-none\",\n \"scrollbar-thin scrollbar-track-transparent scrollbar-thumb-foreground/20 overflow-auto overscroll-contain\",\n \"[:not(.has-[+[data-slot=command-footer]])]:rounded-b-2xl [:not(.has-[+[data-slot=command-footer]])]:border-b\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"command-content\"}\n />\n );\n};\n\nexport const CommandInput = (props: CommandInputProps) => {\n const { size = \"md\", className, ...rest } = props;\n\n return (\n <ComboboxControl className=\"mb-2\">\n <InputGroup\n className={cn(\"rounded-xl bg-field\", className)}\n size={size}\n {...rest}\n >\n <InputGroupAddon>\n <SearchIcon aria-hidden className=\"opacity-64\" />\n </InputGroupAddon>\n <ArkCombobox.Input asChild>\n <InputGroupInput autoFocus slot=\"command-input\" />\n </ArkCombobox.Input>\n </InputGroup>\n </ComboboxControl>\n );\n};\n\ninterface CommandListProps extends React.ComponentProps<typeof ComboboxList> {}\n\nexport const CommandList = (props: CommandListProps) => {\n const { className, slot, ...rest } = props;\n\n return (\n <div className=\"max-h-72 min-h-0 flex-1\">\n <ComboboxList\n className={cn(\"flex-1 pe-2.5\", className)}\n {...rest}\n slot={slot ?? \"command-list\"}\n />\n </div>\n );\n};\n\nexport const CommandEmpty = (\n props: React.ComponentProps<typeof ComboboxEmpty>\n) => {\n const { className, children, slot, ...rest } = props;\n\n return (\n <ComboboxEmpty\n className={cn(\"py-6 text-center text-sm\", className)}\n {...rest}\n slot={slot ?? \"command-empty\"}\n >\n {children || \"No results found.\"}\n </ComboboxEmpty>\n );\n};\n\n// A group's label comes from `heading`, which `ComboboxGroup` renders itself — so the renamed\n// `CommandGroupLabel` was redundant twice over and is gone.\nexport const CommandGroup = (\n { slot, ...rest }: React.ComponentProps<typeof ComboboxGroup>\n) => <ComboboxGroup {...rest} slot={slot ?? \"command-group\"} />;\n\nexport const CommandItem = (\n props: React.ComponentProps<typeof ComboboxItem>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ArkCombobox.Item\n className={cn(comboboxItemVariants({ showIndicator: false }), className)}\n persistFocus\n {...rest}\n data-slot={slot ?? \"command-item\"}\n />\n );\n};\n\nexport const CommandSeparator = (props: React.ComponentProps<\"div\">) => {\n const { className, slot, ...rest } = props;\n\n return (\n <Separator\n className={cn(\"my-2\", className)}\n {...rest}\n slot={slot ?? \"command-separator\"}\n />\n );\n};\n\nexport const CommandShortcut = (\n { slot, ...rest }: React.ComponentProps<typeof MenuShortcut>\n) => <MenuShortcut {...rest} slot={slot ?? \"command-shortcut\"} />;\n\nexport const CommandFooter = (props: React.ComponentProps<\"div\">) => {\n const { className, slot, ...rest } = props;\n\n return (\n <div\n className={cn(\n \"z-10\",\n \"flex items-center justify-between gap-2\",\n \"-m-2 mt-2 px-4 py-3\",\n \"text-muted-foreground text-xs\",\n \"rounded-b-[calc(var(--radius-2xl)-1px)] border-t\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"command-footer\"}\n />\n );\n};\n"],"names":["CommandDialog","Dialog","CommandDialogContent","props","size","title","description","className","children","slot","rest","Portal","jsx","DialogOverlay","DialogPositioner","jsxs","ArkDialog","cn","dialogContentVariants","DialogHeader","Command","lazyMount","unmountOnExit","Combobox","CommandContent","ArkCombobox","CommandInput","ComboboxControl","InputGroup","InputGroupAddon","SearchIcon","InputGroupInput","CommandList","ComboboxList","CommandEmpty","ComboboxEmpty","CommandGroup","ComboboxGroup","CommandItem","comboboxItemVariants","CommandSeparator","Separator","CommandShortcut","MenuShortcut","CommandFooter"],"mappings":"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"}
|
package/dist/simples/dialog.js
CHANGED
|
@@ -101,7 +101,7 @@ const H = (t) => {
|
|
|
101
101
|
"max-sm:max-h-[calc(100svh-3rem)]",
|
|
102
102
|
"max-sm:max-w-none",
|
|
103
103
|
"max-sm:rounded-none max-sm:rounded-t-2xl max-sm:border-x-0 max-sm:border-t max-sm:border-b-0",
|
|
104
|
-
"max-sm:opacity-[calc(1-min(var(--nested-
|
|
104
|
+
"max-sm:opacity-[calc(1-min(var(--nested-layer-count),1))]",
|
|
105
105
|
"max-sm:data-[state=closed]:slide-out-to-bottom-5 max-sm:data-[state=open]:slide-in-from-bottom-5",
|
|
106
106
|
"max-sm:data-[state=closed]:zoom-out-100 max-sm:data-[state=open]:zoom-in-100"
|
|
107
107
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialog.js","sources":["../../src/simples/dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { Dialog as ArkDialog, useDialogContext } from \"@ark-ui/react/dialog\";\nimport { ark } from \"@ark-ui/react/factory\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport { XIcon } from \"lucide-react\";\nimport React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\nimport { Button } from \"./button\";\nimport { ScrollArea } from \"./scroll-area\";\n\nexport const useDialog = useDialogContext;\n\ninterface DialogContextProps {\n /**\n * Used internally to show or hide overlay\n *\n * @default true\n */\n modal?: boolean;\n}\n\nconst DialogContext = React.createContext<DialogContextProps | null>(null);\nDialogContext.displayName = \"DialogContext\";\n\nexport const Dialog = (props: React.ComponentProps<typeof ArkDialog.Root>) => {\n const {\n modal = true,\n lazyMount = true,\n unmountOnExit = true,\n ...rest\n } = props;\n\n return (\n <DialogContext.Provider value={{ modal }}>\n <ArkDialog.Root\n lazyMount={lazyMount}\n modal={modal}\n unmountOnExit={unmountOnExit}\n {...rest}\n />\n </DialogContext.Provider>\n );\n};\n\nexport const DialogTrigger = (\n props: React.ComponentProps<typeof ArkDialog.Trigger>\n) => <ArkDialog.Trigger {...props} />;\n\nexport const dialogOverlayVariants = tv({\n base: [\n \"fixed inset-0 z-50\",\n \"bg-black/32 backdrop-blur-xs\",\n \"duration-200\",\n \"peer peer-data-[slot=dialog-overlay]:hidden\",\n \"data-[state=open]:fade-in-0 data-[state=open]:animate-in\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:animate-out\",\n \"motion-reduce:animate-none!\",\n ],\n});\n\nexport const DialogOverlay = (\n props: React.ComponentProps<typeof ArkDialog.Backdrop>\n) => {\n const { className, slot, ...rest } = props;\n\n const { modal } = _useDialog();\n\n if (!modal) {\n return null;\n }\n\n return (\n <ArkDialog.Backdrop\n className={cn(dialogOverlayVariants(), className)}\n {...rest}\n data-slot={slot ?? \"dialog-overlay\"}\n />\n );\n};\n\nexport const DialogPositioner = (\n props: React.ComponentProps<typeof ArkDialog.Positioner>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ArkDialog.Positioner\n className={cn(\n \"fixed inset-0 z-50\",\n \"h-svh w-screen\",\n \"grid grid-rows-[1fr_auto_3fr] justify-items-center\",\n \"p-4\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-positioner\"}\n />\n );\n};\n\nexport const dialogContentVariants = tv({\n base: [\n \"[--space:--spacing(6)]\",\n \"z-[calc(50+var(--layer-index,0))]\",\n \"relative\",\n \"row-start-2\",\n \"max-h-[calc(100svh-2rem)] min-h-0 w-full min-w-0\",\n \"flex flex-col overflow-hidden\",\n \"bg-popover\",\n \"text-popover-foreground\",\n \"rounded-2xl border shadow-lg/5\",\n \"outline-none\",\n \"translate-y-[calc(-1.25rem*var(--nested-layer-count))]\",\n \"transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform\",\n \"data-[nested=dialog]:data-[state=closed]:slide-in-from-bottom-10 data-[nested=dialog]:data-[state=open]:slide-in-from-bottom-10 data-[has-nested=dialog]:origin-top\",\n \"scale-[calc(1-0.1*var(--nested-layer-count))] opacity-[calc(1-0.1*var(--nested-layer-count))]\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-[98%] data-[state=closed]:animate-out\",\n \"data-[state=open]:fade-in-0 data-[state=open]:zoom-in-[98%] data-[state=open]:animate-in\",\n \"motion-reduce:animate-none! motion-reduce:transition-none!\",\n ],\n variants: {\n size: {\n sm: [\"max-w-md\"],\n md: [\"max-w-lg\"],\n lg: [\"max-w-xl\"],\n xl: [\"max-w-2xl\"],\n \"2xl\": [\"max-w-3xl\"],\n \"3xl\": [\"max-w-4xl\"],\n \"4xl\": [\"max-w-5xl\"],\n \"5xl\": [\"max-w-6xl\"],\n \"6xl\": [\"max-w-7xl\"],\n fullscreen: [\"size-full\"],\n },\n bottomStickOnMobile: {\n true: [\n \"max-sm:max-h-[calc(100svh-3rem)]\",\n \"max-sm:max-w-none\",\n \"max-sm:rounded-none max-sm:rounded-t-2xl max-sm:border-x-0 max-sm:border-t max-sm:border-b-0\",\n \"max-sm:opacity-[calc(1-min(var(--nested-dialogs),1))]\",\n \"max-sm:data-[state=closed]:slide-out-to-bottom-5 max-sm:data-[state=open]:slide-in-from-bottom-5\",\n \"max-sm:data-[state=closed]:zoom-out-100 max-sm:data-[state=open]:zoom-in-100\",\n ],\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n});\n\ninterface DialogContentProps\n extends React.ComponentProps<typeof ArkDialog.Content>,\n VariantProps<typeof dialogContentVariants> {\n /**\n * Stick the dialog to the bottom of the screen on mobile\n *\n * @default true\n */\n bottomStickOnMobile?: boolean;\n /**\n * Show close button at the top right corner\n *\n * @default true\n */\n showCloseButton?: boolean;\n}\n\nexport const DialogContent = (props: DialogContentProps) => {\n const {\n showCloseButton = true,\n bottomStickOnMobile = true,\n size = \"md\",\n className,\n children,\n slot,\n ...rest\n } = props;\n\n return (\n <Portal>\n <DialogOverlay />\n\n <DialogPositioner\n className={cn(\n bottomStickOnMobile &&\n \"max-sm:grid-rows-[1fr_auto] max-sm:p-0 max-sm:pt-12\"\n )}\n >\n <ArkDialog.Content\n className={cn(\n dialogContentVariants({ size, bottomStickOnMobile }),\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-content\"}\n >\n {children}\n\n {!!showCloseButton && (\n <DialogClose asChild>\n <Button\n aria-label=\"Close\"\n // Aligned to the content padding: the button sits at 10px so the 16px icon\n // (6px inset inside the 28px icon-sm button) lands its corner on the 16px\n // `--space` grid — mirroring the header title on the opposite side.\n className=\"absolute inset-e-2.5 top-2.5 opacity-64 hover:opacity-100\"\n size=\"icon-sm\"\n variant=\"ghost\"\n >\n <XIcon />\n </Button>\n </DialogClose>\n )}\n </ArkDialog.Content>\n </DialogPositioner>\n </Portal>\n );\n};\n\ninterface DialogBodyProps extends React.ComponentProps<typeof ark.div> {\n /**\n * Add a fade effect to the scroll area\n *\n * @default false\n */\n scrollFade?: boolean;\n}\n\nexport const DialogBody = (props: DialogBodyProps) => {\n const { scrollFade = false, className, slot, ...rest } = props;\n\n return (\n <ScrollArea className=\"min-h-0 flex-1\" scrollFade={scrollFade}>\n <ark.div\n className={cn(\n \"p-(--space)\",\n \"in-[[data-slot=dialog-content]:has([data-slot=dialog-header])]:pt-0\",\n \"in-[[data-slot=dialog-content]:has([data-slot=dialog-footer]:not(.border-t))]:pb-1\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-body\"}\n />\n </ScrollArea>\n );\n};\n\ninterface DialogHeaderProps extends React.ComponentProps<typeof ark.div> {\n /**\n * The description of the dialog\n */\n description?: string;\n /**\n * The title of the dialog\n */\n title?: string;\n}\n\nexport const DialogHeader = (props: DialogHeaderProps) => {\n const { className, title, description, children, slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(\n \"shrink-0\",\n \"p-(--space)\",\n \"flex flex-col gap-2\",\n \"in-[[data-slot=dialog-content]:has([data-slot=dialog-body])]:pb-3\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-header\"}\n >\n {!!title && <DialogTitle>{title}</DialogTitle>}\n\n {!!description && <DialogDescription>{description}</DialogDescription>}\n\n {!title && typeof children === \"string\" ? (\n <DialogTitle>{children}</DialogTitle>\n ) : (\n children\n )}\n </ark.div>\n );\n};\n\nexport const DialogTitle = (\n props: React.ComponentProps<typeof ArkDialog.Title>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ArkDialog.Title\n className={cn(\n \"font-heading font-semibold text-lg leading-none\",\n // Reserve inline-end room so the absolutely-positioned close X never overlaps the title.\n \"in-[[data-slot=dialog-content]:has([data-slot=dialog-close-trigger])]:pe-8\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-title\"}\n />\n );\n};\n\nexport const DialogDescription = (\n props: React.ComponentProps<typeof ArkDialog.Description>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ArkDialog.Description\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...rest}\n data-slot={slot ?? \"dialog-description\"}\n />\n );\n};\n\nexport const DialogClose = ({\n slot,\n ...rest\n}: React.ComponentProps<typeof ArkDialog.CloseTrigger>) => (\n <ArkDialog.CloseTrigger\n {...rest}\n data-slot={slot ?? \"dialog-close-trigger\"}\n />\n);\n\nexport const DialogFooter = (props: React.ComponentProps<typeof ark.div>) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(\n \"shrink-0\",\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n \"sm:rounded-b-[calc(var(--radius-2xl)-1px)]\",\n \"px-(--space) py-4\",\n \"border-t\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-footer\"}\n />\n );\n};\n\nconst _useDialog = () => {\n const context = React.useContext(DialogContext);\n\n if (!context) {\n throw new Error(\"useDialog must be used within a DialogProvider\");\n }\n\n return context;\n};\n"],"names":["DialogContext"],"mappings":";;;;;;;;;;;AAYO;AAYPA;AAEO;AACL;AAAM;AACI;AACI;AACI;AACb;AAGL;AAEI;AAAW;AAAV;AACC;AACA;AACA;AACI;AAAA;AAIZ;AAMwC;AAChC;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AAEJ;AAKE;AAIA;AAKE;AAAW;AAAV;AACiD;AAC5C;AACe;AAAA;AAGzB;AAKE;AAEA;AACE;AAAW;AAAV;AACY;AACT;AACA;AACA;AACA;AACA;AAAA;AAEE;AACe;AAAA;AAGzB;AAEwC;AAChC;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACF;AACW;AACA;AACA;AACC;AACG;AACA;AACA;AACA;AACA;AACK;AAAA;AAEL;AACb;AACJ;AACA;AACA;AACA;AACA;AACA;AAAA;AACF;AACF;AAEe;AACT;AAEV;AAoBE;AAAM;AACc;AACI;AACf;AACP;AACA;AACA;AACG;AAGL;AAEI;AAAe;AAEf;AAAC;AAAA;AACY;AAEP;AAAA;AAGJ;AAAW;AAAV;AACY;AAC0C;AACnD;AAAA;AAEE;AACe;AAElB;AAAA;AAIG;AAAC;AAAA;AACY;AAID;AACL;AACG;AAED;AAAA;AAEX;AAAA;AAAA;AAAA;AAEJ;AAAA;AAIR;AAYE;AAEA;AAEI;AAAK;AAAJ;AACY;AACT;AACA;AACA;AACA;AAAA;AAEE;AACe;AAAA;AAI3B;AAcE;AAEA;AACE;AAAK;AAAJ;AACY;AACT;AACA;AACA;AACA;AACA;AAAA;AAEE;AACe;AAElB;AAA+B;AAEkB;AAKhD;AAAA;AAAA;AAIR;AAKE;AAEA;AACE;AAAW;AAAV;AACY;AACT;AAAA;AAEA;AACA;AAAA;AAEE;AACe;AAAA;AAGzB;AAKE;AAEA;AACE;AAAW;AAAV;AACyD;AACpD;AACe;AAAA;AAGzB;AAE4B;AAC1B;AAEF;AACE;AAAW;AAAV;AACK;AACe;AACrB;AAIA;AAEA;AACE;AAAK;AAAJ;AACY;AACT;AACA;AACA;AACA;AACA;AACA;AAAA;AAEE;AACe;AAAA;AAGzB;AAGE;AAEA;AACE;AAGF;AACF;;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"dialog.js","sources":["../../src/simples/dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { Dialog as ArkDialog, useDialogContext } from \"@ark-ui/react/dialog\";\nimport { ark } from \"@ark-ui/react/factory\";\nimport { Portal } from \"@ark-ui/react/portal\";\nimport { XIcon } from \"lucide-react\";\nimport React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\nimport { Button } from \"./button\";\nimport { ScrollArea } from \"./scroll-area\";\n\nexport const useDialog = useDialogContext;\n\ninterface DialogContextProps {\n /**\n * Used internally to show or hide overlay\n *\n * @default true\n */\n modal?: boolean;\n}\n\nconst DialogContext = React.createContext<DialogContextProps | null>(null);\nDialogContext.displayName = \"DialogContext\";\n\nexport const Dialog = (props: React.ComponentProps<typeof ArkDialog.Root>) => {\n const {\n modal = true,\n lazyMount = true,\n unmountOnExit = true,\n ...rest\n } = props;\n\n return (\n <DialogContext.Provider value={{ modal }}>\n <ArkDialog.Root\n lazyMount={lazyMount}\n modal={modal}\n unmountOnExit={unmountOnExit}\n {...rest}\n />\n </DialogContext.Provider>\n );\n};\n\nexport const DialogTrigger = (\n props: React.ComponentProps<typeof ArkDialog.Trigger>\n) => <ArkDialog.Trigger {...props} />;\n\nexport const dialogOverlayVariants = tv({\n base: [\n \"fixed inset-0 z-50\",\n \"bg-black/32 backdrop-blur-xs\",\n \"duration-200\",\n \"peer peer-data-[slot=dialog-overlay]:hidden\",\n \"data-[state=open]:fade-in-0 data-[state=open]:animate-in\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:animate-out\",\n \"motion-reduce:animate-none!\",\n ],\n});\n\nexport const DialogOverlay = (\n props: React.ComponentProps<typeof ArkDialog.Backdrop>\n) => {\n const { className, slot, ...rest } = props;\n\n const { modal } = _useDialog();\n\n if (!modal) {\n return null;\n }\n\n return (\n <ArkDialog.Backdrop\n className={cn(dialogOverlayVariants(), className)}\n {...rest}\n data-slot={slot ?? \"dialog-overlay\"}\n />\n );\n};\n\nexport const DialogPositioner = (\n props: React.ComponentProps<typeof ArkDialog.Positioner>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ArkDialog.Positioner\n className={cn(\n \"fixed inset-0 z-50\",\n \"h-svh w-screen\",\n \"grid grid-rows-[1fr_auto_3fr] justify-items-center\",\n \"p-4\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-positioner\"}\n />\n );\n};\n\nexport const dialogContentVariants = tv({\n base: [\n \"[--space:--spacing(6)]\",\n \"z-[calc(50+var(--layer-index,0))]\",\n \"relative\",\n \"row-start-2\",\n \"max-h-[calc(100svh-2rem)] min-h-0 w-full min-w-0\",\n \"flex flex-col overflow-hidden\",\n \"bg-popover\",\n \"text-popover-foreground\",\n \"rounded-2xl border shadow-lg/5\",\n \"outline-none\",\n \"translate-y-[calc(-1.25rem*var(--nested-layer-count))]\",\n \"transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform\",\n \"data-[nested=dialog]:data-[state=closed]:slide-in-from-bottom-10 data-[nested=dialog]:data-[state=open]:slide-in-from-bottom-10 data-[has-nested=dialog]:origin-top\",\n \"scale-[calc(1-0.1*var(--nested-layer-count))] opacity-[calc(1-0.1*var(--nested-layer-count))]\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-[98%] data-[state=closed]:animate-out\",\n \"data-[state=open]:fade-in-0 data-[state=open]:zoom-in-[98%] data-[state=open]:animate-in\",\n \"motion-reduce:animate-none! motion-reduce:transition-none!\",\n ],\n variants: {\n size: {\n sm: [\"max-w-md\"],\n md: [\"max-w-lg\"],\n lg: [\"max-w-xl\"],\n xl: [\"max-w-2xl\"],\n \"2xl\": [\"max-w-3xl\"],\n \"3xl\": [\"max-w-4xl\"],\n \"4xl\": [\"max-w-5xl\"],\n \"5xl\": [\"max-w-6xl\"],\n \"6xl\": [\"max-w-7xl\"],\n fullscreen: [\"size-full\"],\n },\n bottomStickOnMobile: {\n true: [\n \"max-sm:max-h-[calc(100svh-3rem)]\",\n \"max-sm:max-w-none\",\n \"max-sm:rounded-none max-sm:rounded-t-2xl max-sm:border-x-0 max-sm:border-t max-sm:border-b-0\",\n \"max-sm:opacity-[calc(1-min(var(--nested-layer-count),1))]\",\n \"max-sm:data-[state=closed]:slide-out-to-bottom-5 max-sm:data-[state=open]:slide-in-from-bottom-5\",\n \"max-sm:data-[state=closed]:zoom-out-100 max-sm:data-[state=open]:zoom-in-100\",\n ],\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n});\n\ninterface DialogContentProps\n extends React.ComponentProps<typeof ArkDialog.Content>,\n VariantProps<typeof dialogContentVariants> {\n /**\n * Stick the dialog to the bottom of the screen on mobile\n *\n * @default true\n */\n bottomStickOnMobile?: boolean;\n /**\n * Show close button at the top right corner\n *\n * @default true\n */\n showCloseButton?: boolean;\n}\n\nexport const DialogContent = (props: DialogContentProps) => {\n const {\n showCloseButton = true,\n bottomStickOnMobile = true,\n size = \"md\",\n className,\n children,\n slot,\n ...rest\n } = props;\n\n return (\n <Portal>\n <DialogOverlay />\n\n <DialogPositioner\n className={cn(\n bottomStickOnMobile &&\n \"max-sm:grid-rows-[1fr_auto] max-sm:p-0 max-sm:pt-12\"\n )}\n >\n <ArkDialog.Content\n className={cn(\n dialogContentVariants({ size, bottomStickOnMobile }),\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-content\"}\n >\n {children}\n\n {!!showCloseButton && (\n <DialogClose asChild>\n <Button\n aria-label=\"Close\"\n // Aligned to the content padding: the button sits at 10px so the 16px icon\n // (6px inset inside the 28px icon-sm button) lands its corner on the 16px\n // `--space` grid — mirroring the header title on the opposite side.\n className=\"absolute inset-e-2.5 top-2.5 opacity-64 hover:opacity-100\"\n size=\"icon-sm\"\n variant=\"ghost\"\n >\n <XIcon />\n </Button>\n </DialogClose>\n )}\n </ArkDialog.Content>\n </DialogPositioner>\n </Portal>\n );\n};\n\ninterface DialogBodyProps extends React.ComponentProps<typeof ark.div> {\n /**\n * Add a fade effect to the scroll area\n *\n * @default false\n */\n scrollFade?: boolean;\n}\n\nexport const DialogBody = (props: DialogBodyProps) => {\n const { scrollFade = false, className, slot, ...rest } = props;\n\n return (\n <ScrollArea className=\"min-h-0 flex-1\" scrollFade={scrollFade}>\n <ark.div\n className={cn(\n \"p-(--space)\",\n \"in-[[data-slot=dialog-content]:has([data-slot=dialog-header])]:pt-0\",\n \"in-[[data-slot=dialog-content]:has([data-slot=dialog-footer]:not(.border-t))]:pb-1\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-body\"}\n />\n </ScrollArea>\n );\n};\n\ninterface DialogHeaderProps extends React.ComponentProps<typeof ark.div> {\n /**\n * The description of the dialog\n */\n description?: string;\n /**\n * The title of the dialog\n */\n title?: string;\n}\n\nexport const DialogHeader = (props: DialogHeaderProps) => {\n const { className, title, description, children, slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(\n \"shrink-0\",\n \"p-(--space)\",\n \"flex flex-col gap-2\",\n \"in-[[data-slot=dialog-content]:has([data-slot=dialog-body])]:pb-3\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-header\"}\n >\n {!!title && <DialogTitle>{title}</DialogTitle>}\n\n {!!description && <DialogDescription>{description}</DialogDescription>}\n\n {!title && typeof children === \"string\" ? (\n <DialogTitle>{children}</DialogTitle>\n ) : (\n children\n )}\n </ark.div>\n );\n};\n\nexport const DialogTitle = (\n props: React.ComponentProps<typeof ArkDialog.Title>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ArkDialog.Title\n className={cn(\n \"font-heading font-semibold text-lg leading-none\",\n // Reserve inline-end room so the absolutely-positioned close X never overlaps the title.\n \"in-[[data-slot=dialog-content]:has([data-slot=dialog-close-trigger])]:pe-8\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-title\"}\n />\n );\n};\n\nexport const DialogDescription = (\n props: React.ComponentProps<typeof ArkDialog.Description>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ArkDialog.Description\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...rest}\n data-slot={slot ?? \"dialog-description\"}\n />\n );\n};\n\nexport const DialogClose = ({\n slot,\n ...rest\n}: React.ComponentProps<typeof ArkDialog.CloseTrigger>) => (\n <ArkDialog.CloseTrigger\n {...rest}\n data-slot={slot ?? \"dialog-close-trigger\"}\n />\n);\n\nexport const DialogFooter = (props: React.ComponentProps<typeof ark.div>) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(\n \"shrink-0\",\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n \"sm:rounded-b-[calc(var(--radius-2xl)-1px)]\",\n \"px-(--space) py-4\",\n \"border-t\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"dialog-footer\"}\n />\n );\n};\n\nconst _useDialog = () => {\n const context = React.useContext(DialogContext);\n\n if (!context) {\n throw new Error(\"useDialog must be used within a DialogProvider\");\n }\n\n return context;\n};\n"],"names":["DialogContext"],"mappings":";;;;;;;;;;;AAYO;AAYPA;AAEO;AACL;AAAM;AACI;AACI;AACI;AACb;AAGL;AAEI;AAAW;AAAV;AACC;AACA;AACA;AACI;AAAA;AAIZ;AAMwC;AAChC;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AAEJ;AAKE;AAIA;AAKE;AAAW;AAAV;AACiD;AAC5C;AACe;AAAA;AAGzB;AAKE;AAEA;AACE;AAAW;AAAV;AACY;AACT;AACA;AACA;AACA;AACA;AAAA;AAEE;AACe;AAAA;AAGzB;AAEwC;AAChC;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACF;AACW;AACA;AACA;AACC;AACG;AACA;AACA;AACA;AACA;AACK;AAAA;AAEL;AACb;AACJ;AACA;AACA;AACA;AACA;AACA;AAAA;AACF;AACF;AAEe;AACT;AAEV;AAoBE;AAAM;AACc;AACI;AACf;AACP;AACA;AACA;AACG;AAGL;AAEI;AAAe;AAEf;AAAC;AAAA;AACY;AAEP;AAAA;AAGJ;AAAW;AAAV;AACY;AAC0C;AACnD;AAAA;AAEE;AACe;AAElB;AAAA;AAIG;AAAC;AAAA;AACY;AAID;AACL;AACG;AAED;AAAA;AAEX;AAAA;AAAA;AAAA;AAEJ;AAAA;AAIR;AAYE;AAEA;AAEI;AAAK;AAAJ;AACY;AACT;AACA;AACA;AACA;AAAA;AAEE;AACe;AAAA;AAI3B;AAcE;AAEA;AACE;AAAK;AAAJ;AACY;AACT;AACA;AACA;AACA;AACA;AAAA;AAEE;AACe;AAElB;AAA+B;AAEkB;AAKhD;AAAA;AAAA;AAIR;AAKE;AAEA;AACE;AAAW;AAAV;AACY;AACT;AAAA;AAEA;AACA;AAAA;AAEE;AACe;AAAA;AAGzB;AAKE;AAEA;AACE;AAAW;AAAV;AACyD;AACpD;AACe;AAAA;AAGzB;AAE4B;AAC1B;AAEF;AACE;AAAW;AAAV;AACK;AACe;AACrB;AAIA;AAEA;AACE;AAAK;AAAJ;AACY;AACT;AACA;AACA;AACA;AACA;AACA;AAAA;AAEE;AACe;AAAA;AAGzB;AAGE;AAEA;AACE;AAGF;AACF;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsx as r, jsxs as
|
|
2
|
-
import { Portal as
|
|
1
|
+
import { jsx as r, jsxs as c } from "react/jsx-runtime";
|
|
2
|
+
import { Portal as l } from "@ark-ui/react";
|
|
3
3
|
import { useHoverCardContext as m, HoverCard as e } from "@ark-ui/react/hover-card";
|
|
4
4
|
import { cn as p } from "../lib/cn.js";
|
|
5
5
|
const C = m, b = (o) => {
|
|
@@ -27,7 +27,7 @@ const C = m, b = (o) => {
|
|
|
27
27
|
...t
|
|
28
28
|
}) => /* @__PURE__ */ r(e.Trigger, { ...t, "data-slot": o ?? "hover-card-trigger" }), H = (o) => {
|
|
29
29
|
const { className: t, children: a, slot: n, ...s } = o;
|
|
30
|
-
return /* @__PURE__ */ r(
|
|
30
|
+
return /* @__PURE__ */ r(l, { children: /* @__PURE__ */ r(e.Positioner, { "data-slot": "hover-card-positioner", children: /* @__PURE__ */ c(
|
|
31
31
|
e.Content,
|
|
32
32
|
{
|
|
33
33
|
className: p(
|
|
@@ -63,7 +63,7 @@ const C = m, b = (o) => {
|
|
|
63
63
|
e.Arrow,
|
|
64
64
|
{
|
|
65
65
|
style: {
|
|
66
|
-
"--arrow-background": "var(--popover)",
|
|
66
|
+
"--arrow-background": "var(--popover, var(--card))",
|
|
67
67
|
"--arrow-size": "calc(1.5 * var(--spacing))",
|
|
68
68
|
...t
|
|
69
69
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hover-card.js","sources":["../../src/simples/hover-card.tsx"],"sourcesContent":["import { Portal } from \"@ark-ui/react\";\nimport {\n HoverCard as ArkHoverCard,\n useHoverCardContext,\n} from \"@ark-ui/react/hover-card\";\nimport type React from \"react\";\nimport { cn } from \"../lib/cn\";\n\nexport const useHoverCard = useHoverCardContext;\n\ninterface HoverCardProps\n extends React.ComponentProps<typeof ArkHoverCard.Root> {}\n\nexport const HoverCard = (props: HoverCardProps) => {\n const {\n lazyMount = true,\n unmountOnExit = true,\n closeDelay = 100,\n openDelay = 10,\n positioning = { placement: \"top\" },\n ...rest\n } = props;\n\n return (\n <ArkHoverCard.Root\n closeDelay={closeDelay}\n lazyMount={lazyMount}\n openDelay={openDelay}\n positioning={positioning}\n unmountOnExit={unmountOnExit}\n {...rest}\n />\n );\n};\n\nexport const HoverCardTrigger = ({\n slot,\n ...rest\n}: React.ComponentProps<typeof ArkHoverCard.Trigger>) => (\n <ArkHoverCard.Trigger {...rest} data-slot={slot ?? \"hover-card-trigger\"} />\n);\n\nexport const HoverCardContent = (\n props: React.ComponentProps<typeof ArkHoverCard.Content>\n) => {\n const { className, children, slot, ...rest } = props;\n\n return (\n <Portal>\n <ArkHoverCard.Positioner data-slot=\"hover-card-positioner\">\n <ArkHoverCard.Content\n className={cn(\n \"z-50\",\n \"w-64\",\n \"p-4\",\n \"bg-popover\",\n \"text-popover-foreground\",\n \"origin-(--transform-origin)\",\n \"rounded-box border shadow-lg/5\",\n \"outline-hidden\",\n \"data-[state=closed]:zoom-out-[98%] data-[state=open]:zoom-in-[98%]\",\n \"data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0\",\n \"data-[state=closed]:animate-out data-[state=open]:animate-in\",\n \"data-[placement=bottom]:slide-in-from-top-2\",\n \"data-[placement=left]:slide-in-from-end-2\",\n \"data-[placement=right]:slide-in-from-start-2\",\n \"data-[placement=top]:slide-in-from-bottom-2\",\n \"motion-reduce:animate-none!\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"hover-card-content\"}\n >\n {children}\n\n <HoverCardArrow />\n </ArkHoverCard.Content>\n </ArkHoverCard.Positioner>\n </Portal>\n );\n};\n\nexport const HoverCardArrow = (\n props: React.ComponentProps<typeof ArkHoverCard.Arrow>\n) => {\n const { style, slot, ...rest } = props;\n\n return (\n <ArkHoverCard.Arrow\n style={\n {\n \"--arrow-background\": \"var(--popover)\",\n \"--arrow-size\": \"calc(1.5 * var(--spacing))\",\n ...style,\n } as React.CSSProperties\n }\n {...rest}\n data-slot={slot ?? \"hover-card-arrow\"}\n >\n <ArkHoverCard.ArrowTip className=\"border-s border-t\" />\n </ArkHoverCard.Arrow>\n );\n};\n"],"names":["useHoverCard","useHoverCardContext","HoverCard","props","lazyMount","unmountOnExit","closeDelay","openDelay","positioning","rest","jsx","ArkHoverCard","HoverCardTrigger","slot","HoverCardContent","className","children","Portal","jsxs","cn","HoverCardArrow","style"],"mappings":";;;;AAQO,MAAMA,IAAeC,GAKfC,IAAY,CAACC,MAA0B;AAClD,QAAM;AAAA,IACJ,WAAAC,IAAY;AAAA,IACZ,eAAAC,IAAgB;AAAA,IAChB,YAAAC,IAAa;AAAA,IACb,WAAAC,IAAY;AAAA,IACZ,aAAAC,IAAc,EAAE,WAAW,MAAA;AAAA,IAC3B,GAAGC;AAAA,EAAA,IACDN;AAEJ,SACE,gBAAAO;AAAA,IAACC,EAAa;AAAA,IAAb;AAAA,MACC,YAAAL;AAAA,MACA,WAAAF;AAAA,MACA,WAAAG;AAAA,MACA,aAAAC;AAAA,MACA,eAAAH;AAAA,MACC,GAAGI;AAAA,IAAA;AAAA,EAAA;AAGV,GAEaG,IAAmB,CAAC;AAAA,EAC/B,MAAAC;AAAA,EACA,GAAGJ;AACL,MACE,gBAAAC,EAACC,EAAa,SAAb,EAAsB,GAAGF,GAAM,aAAWI,KAAQ,qBAAA,CAAsB,GAG9DC,IAAmB,CAC9BX,MACG;AACH,QAAM,EAAE,WAAAY,GAAW,UAAAC,GAAU,MAAAH,GAAM,GAAGJ,MAASN;AAE/C,2BACGc,GAAA,EACC,UAAA,gBAAAP,EAACC,EAAa,YAAb,EAAwB,aAAU,yBACjC,UAAA,gBAAAO;AAAA,IAACP,EAAa;AAAA,IAAb;AAAA,MACC,WAAWQ;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAJ;AAAA,MAAA;AAAA,MAED,GAAGN;AAAA,MACJ,aAAWI,KAAQ;AAAA,MAElB,UAAA;AAAA,QAAAG;AAAA,0BAEAI,GAAA,CAAA,CAAe;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEpB,EAAA,CACF;AAEJ,GAEaA,IAAiB,CAC5BjB,MACG;AACH,QAAM,EAAE,OAAAkB,GAAO,MAAAR,GAAM,GAAGJ,MAASN;AAEjC,SACE,gBAAAO;AAAA,IAACC,EAAa;AAAA,IAAb;AAAA,MACC,OACE;AAAA,QACE,sBAAsB;AAAA,QACtB,gBAAgB;AAAA,QAChB,GAAGU;AAAA,MAAA;AAAA,MAGN,GAAGZ;AAAA,MACJ,aAAWI,KAAQ;AAAA,MAEnB,UAAA,gBAAAH,EAACC,EAAa,UAAb,EAAsB,WAAU,oBAAA,CAAoB;AAAA,IAAA;AAAA,EAAA;AAG3D;"}
|
|
1
|
+
{"version":3,"file":"hover-card.js","sources":["../../src/simples/hover-card.tsx"],"sourcesContent":["import { Portal } from \"@ark-ui/react\";\nimport {\n HoverCard as ArkHoverCard,\n useHoverCardContext,\n} from \"@ark-ui/react/hover-card\";\nimport type React from \"react\";\nimport { cn } from \"../lib/cn\";\n\nexport const useHoverCard = useHoverCardContext;\n\ninterface HoverCardProps\n extends React.ComponentProps<typeof ArkHoverCard.Root> {}\n\nexport const HoverCard = (props: HoverCardProps) => {\n const {\n lazyMount = true,\n unmountOnExit = true,\n closeDelay = 100,\n openDelay = 10,\n positioning = { placement: \"top\" },\n ...rest\n } = props;\n\n return (\n <ArkHoverCard.Root\n closeDelay={closeDelay}\n lazyMount={lazyMount}\n openDelay={openDelay}\n positioning={positioning}\n unmountOnExit={unmountOnExit}\n {...rest}\n />\n );\n};\n\nexport const HoverCardTrigger = ({\n slot,\n ...rest\n}: React.ComponentProps<typeof ArkHoverCard.Trigger>) => (\n <ArkHoverCard.Trigger {...rest} data-slot={slot ?? \"hover-card-trigger\"} />\n);\n\nexport const HoverCardContent = (\n props: React.ComponentProps<typeof ArkHoverCard.Content>\n) => {\n const { className, children, slot, ...rest } = props;\n\n return (\n <Portal>\n <ArkHoverCard.Positioner data-slot=\"hover-card-positioner\">\n <ArkHoverCard.Content\n className={cn(\n \"z-50\",\n \"w-64\",\n \"p-4\",\n \"bg-popover\",\n \"text-popover-foreground\",\n \"origin-(--transform-origin)\",\n \"rounded-box border shadow-lg/5\",\n \"outline-hidden\",\n \"data-[state=closed]:zoom-out-[98%] data-[state=open]:zoom-in-[98%]\",\n \"data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0\",\n \"data-[state=closed]:animate-out data-[state=open]:animate-in\",\n \"data-[placement=bottom]:slide-in-from-top-2\",\n \"data-[placement=left]:slide-in-from-end-2\",\n \"data-[placement=right]:slide-in-from-start-2\",\n \"data-[placement=top]:slide-in-from-bottom-2\",\n \"motion-reduce:animate-none!\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"hover-card-content\"}\n >\n {children}\n\n <HoverCardArrow />\n </ArkHoverCard.Content>\n </ArkHoverCard.Positioner>\n </Portal>\n );\n};\n\nexport const HoverCardArrow = (\n props: React.ComponentProps<typeof ArkHoverCard.Arrow>\n) => {\n const { style, slot, ...rest } = props;\n\n return (\n <ArkHoverCard.Arrow\n style={\n {\n \"--arrow-background\": \"var(--popover, var(--card))\",\n \"--arrow-size\": \"calc(1.5 * var(--spacing))\",\n ...style,\n } as React.CSSProperties\n }\n {...rest}\n data-slot={slot ?? \"hover-card-arrow\"}\n >\n <ArkHoverCard.ArrowTip className=\"border-s border-t\" />\n </ArkHoverCard.Arrow>\n );\n};\n"],"names":["useHoverCard","useHoverCardContext","HoverCard","props","lazyMount","unmountOnExit","closeDelay","openDelay","positioning","rest","jsx","ArkHoverCard","HoverCardTrigger","slot","HoverCardContent","className","children","Portal","jsxs","cn","HoverCardArrow","style"],"mappings":";;;;AAQO,MAAMA,IAAeC,GAKfC,IAAY,CAACC,MAA0B;AAClD,QAAM;AAAA,IACJ,WAAAC,IAAY;AAAA,IACZ,eAAAC,IAAgB;AAAA,IAChB,YAAAC,IAAa;AAAA,IACb,WAAAC,IAAY;AAAA,IACZ,aAAAC,IAAc,EAAE,WAAW,MAAA;AAAA,IAC3B,GAAGC;AAAA,EAAA,IACDN;AAEJ,SACE,gBAAAO;AAAA,IAACC,EAAa;AAAA,IAAb;AAAA,MACC,YAAAL;AAAA,MACA,WAAAF;AAAA,MACA,WAAAG;AAAA,MACA,aAAAC;AAAA,MACA,eAAAH;AAAA,MACC,GAAGI;AAAA,IAAA;AAAA,EAAA;AAGV,GAEaG,IAAmB,CAAC;AAAA,EAC/B,MAAAC;AAAA,EACA,GAAGJ;AACL,MACE,gBAAAC,EAACC,EAAa,SAAb,EAAsB,GAAGF,GAAM,aAAWI,KAAQ,qBAAA,CAAsB,GAG9DC,IAAmB,CAC9BX,MACG;AACH,QAAM,EAAE,WAAAY,GAAW,UAAAC,GAAU,MAAAH,GAAM,GAAGJ,MAASN;AAE/C,2BACGc,GAAA,EACC,UAAA,gBAAAP,EAACC,EAAa,YAAb,EAAwB,aAAU,yBACjC,UAAA,gBAAAO;AAAA,IAACP,EAAa;AAAA,IAAb;AAAA,MACC,WAAWQ;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAJ;AAAA,MAAA;AAAA,MAED,GAAGN;AAAA,MACJ,aAAWI,KAAQ;AAAA,MAElB,UAAA;AAAA,QAAAG;AAAA,0BAEAI,GAAA,CAAA,CAAe;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAEpB,EAAA,CACF;AAEJ,GAEaA,IAAiB,CAC5BjB,MACG;AACH,QAAM,EAAE,OAAAkB,GAAO,MAAAR,GAAM,GAAGJ,MAASN;AAEjC,SACE,gBAAAO;AAAA,IAACC,EAAa;AAAA,IAAb;AAAA,MACC,OACE;AAAA,QACE,sBAAsB;AAAA,QACtB,gBAAgB;AAAA,QAChB,GAAGU;AAAA,MAAA;AAAA,MAGN,GAAGZ;AAAA,MACJ,aAAWI,KAAQ;AAAA,MAEnB,UAAA,gBAAAH,EAACC,EAAa,UAAb,EAAsB,WAAU,oBAAA,CAAoB;AAAA,IAAA;AAAA,EAAA;AAG3D;"}
|
|
@@ -62,7 +62,7 @@ const h = p({
|
|
|
62
62
|
"select-none font-medium text-muted-foreground text-sm",
|
|
63
63
|
"cursor-text",
|
|
64
64
|
"group-data-[disabled=true]/input-group:opacity-64",
|
|
65
|
-
"[&>kbd]:rounded-[calc(var(--radius)-5px)]",
|
|
65
|
+
"[&>kbd]:rounded-[calc(var(--radius-lg)-5px)]",
|
|
66
66
|
"[&_svg:not([class*='size-'])]:size-4"
|
|
67
67
|
],
|
|
68
68
|
variants: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-group.js","sources":["../../src/simples/input-group.tsx"],"sourcesContent":["\"use client\";\n\nimport { ark } from \"@ark-ui/react/factory\";\nimport type React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\nimport { controlMinHeight, controlSizes } from \"../lib/control-size\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Textarea } from \"./textarea\";\n\nconst inpuGroupVariants = tv({\n base: [\n \"group/input-group\",\n \"relative\",\n \"w-full min-w-0\",\n \"flex items-center\",\n \"bg-background bg-field\",\n \"rounded-lg border border-input shadow-xs/5\",\n \"transition-[color,box-shadow]\",\n // **One height, the shared one — see `lib/control-size.ts`.** A group is `min-h-(--size)`\n // rather than `h-(--size)` because it also holds a `Textarea` and the two block addons, and\n // those grow it; what it may never do is come out TALLER than an `Input` beside it because of\n // what it holds. It did, by 14px: the `<input>` inside carried its own `h-8` and the group added\n // `p-1.5` around it, so a group at `md` measured 46px against an input's 32 — measured\n // 2026-09-30 on `/docs/forms/controls`, along with every control built on a group (combobox,\n // date picker, password input, language picker).\n //\n // So the `<input>` inside does not carry a height of its own: it stretches to the group's\n // content box (`InputGroupInput`), and the controls beside it are 24px (`InputGroupButton`),\n // which leaves a 32px group 4px of inset around them, and there is no padding to add to it: at\n // `sm` and compact density the group is 24.5px, and a 24px control plus the border already\n // asks 26. That one case is the exception the pressable floor buys (see `InputGroupButton`).\n controlMinHeight,\n \"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3\",\n \"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3\",\n \"outline-none focus-within:border-primary focus-within:ring-[3px] focus-within:ring-ring\",\n \"has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-[3px] has-[[data-slot][aria-invalid=true]]:ring-destructive/24\",\n \"dark:has-[[data-slot][aria-invalid=true]]:border-destructive-foreground dark:has-[[data-slot][aria-invalid=true]]:ring-destructive-foreground/40\",\n \"motion-reduce:transition-none!\",\n ],\n variants: {\n size: controlSizes,\n },\n defaultVariants: {\n size: \"md\",\n },\n});\n\nexport interface InputGroupProps\n extends React.ComponentProps<typeof ark.div>,\n VariantProps<typeof inpuGroupVariants> {}\n\nexport const InputGroup = (props: InputGroupProps) => {\n const { size = \"md\", className, slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(inpuGroupVariants({ size }), className)}\n data-size={size}\n role=\"group\"\n {...rest}\n data-slot={slot ?? \"input-group\"}\n />\n );\n};\n\nconst inputGroupAddonVariants = tv({\n base: [\n \"h-auto\",\n \"flex items-center justify-center gap-2\",\n \"select-none font-medium text-muted-foreground text-sm\",\n \"cursor-text\",\n \"group-data-[disabled=true]/input-group:opacity-64\",\n \"[&>kbd]:rounded-[calc(var(--radius)-5px)]\",\n \"[&_svg:not([class*='size-'])]:size-4\",\n ],\n variants: {\n align: {\n // **A smaller padding, not a negative margin**, and this is a measured divergence from the\n // reference rather than a taste one. Shark tucks the button in with `pe-3` plus\n // `me-[-0.45rem]`; a negative margin on the last flex item lets its border box run past the\n // container's content edge, so measured live on `docs/ai/fields` the addon sat **6.2px\n // outside the group's inline border and 6px outside its block border** — in a box with\n // `overflow: visible`, which is why it also showed up as 6px of scroll width on the parent.\n // The inner gap is what was wanted and it is unchanged: 12px of padding minus 7.2px of\n // margin is the 6px this sets directly.\n // **A button needs no padding beside it — the group's own `p-1.5` is the inset**, and this\n // is what puts the ✨ the same distance from the border here as inside a `TagsInputControl`.\n // Text and a `kbd` still take theirs, because neither carries a box of its own.\n \"inline-start\": [\"order-first ps-3\", \"has-[>button]:ps-0.75\", \"has-[>kbd]:ps-2\"],\n \"inline-end\": [\"order-last pe-3\", \"has-[>button]:pe-0.75\", \"has-[>kbd]:pe-2\"],\n // The block padding lives on the two block aligns and nowhere else. It was `py-1.5` in the\n // base, which is right for a band across the field and wrong for a control tucked into its\n // end: measured on `docs/ai/fields`, an `inline-end` addon was **44px tall inside a 32px\n // group** — 6px of transparent padding past the border on each side, in a box with\n // `overflow: visible`. The mark inside it is `size-8` and looked fine; what was wrong was the\n // group's own box.\n \"block-start\": [\n \"order-first w-full justify-start px-3 pt-3 pb-1.5\",\n \"group-has-[>input]/input-group:pt-2.5\",\n \"[.border-b]:pb-3\",\n ],\n \"block-end\": [\n \"order-last w-full justify-start px-3 pt-1.5 pb-3\",\n \"group-has-[>input]/input-group:pb-2.5\",\n \"[.border-t]:pt-3\",\n ],\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n});\n\ninterface InputGroupAddonProps\n extends React.ComponentProps<typeof ark.div>,\n VariantProps<typeof inputGroupAddonVariants> {}\n\nexport const InputGroupAddon = (props: InputGroupAddonProps) => {\n const { className, align = \"inline-start\", slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(inputGroupAddonVariants({ align }), className)}\n data-align={align}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest(\"button\")) {\n return;\n }\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus();\n }}\n role=\"group\"\n {...rest}\n data-slot={slot ?? \"input-group-addon\"}\n />\n );\n};\n\nconst inputGroupButtonVariants = tv({\n base: [\n \"relative\",\n \"flex items-center gap-2\",\n \"text-sm\",\n \"shadow-none\",\n \"pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11\",\n ],\n variants: {\n size: {\n /**\n * The floor, and the default, because there is nothing legal below it.\n *\n * `xs` and `icon-xs` were `1.5rem`, which is 24px at the default root and **21px at compact** —\n * every size here is a `rem` against a root the density axis sets. That is under the 24×24\n * WCAG 2.5.8 states in CSS pixels, and it was this component's DEFAULT, so an input group\n * that said nothing got the failing size.\n *\n * The `pointer-coarse` hit area below does not save it. 44px is the touch answer and 2.5.8\n * asks about pointers generally: with a mouse the target was 21px and the `::after` is not in\n * the hit path. This is the one thing `Button` does not carry, and it is why the two were\n * decided separately rather than in one sweep.\n */\n // 24 CSS pixels, not `h-6`: a `rem` is 21px at compact, under the bar above, and this is the\n // one size in a recipe that must not scale. Inside a group the bar and the group's own 28px\n // at `sm` (24.5px at compact) are the same number, which is why 24 fits at every size.\n sm: [\"h-[24px]\", \"gap-1.5\", \"px-2.5\", \"rounded-md\", \"has-[>svg]:px-2.5\"],\n \"icon-sm\": [\"size-[24px]\", \"p-0\", \"has-[>svg]:p-0\"],\n },\n },\n defaultVariants: {\n size: \"sm\",\n },\n});\n\ninterface InputGroupButtonProps\n extends Omit<React.ComponentProps<typeof Button>, \"size\">,\n VariantProps<typeof inputGroupButtonVariants> {}\n\nexport const InputGroupButton = (props: InputGroupButtonProps) => {\n const {\n className,\n type = \"button\",\n variant = \"ghost\",\n size = \"sm\",\n slot,\n ...rest\n } = props;\n\n return (\n <Button\n className={cn(inputGroupButtonVariants({ size }), className)}\n data-size={size}\n type={type}\n variant={variant}\n {...rest}\n slot={slot ?? \"input-group-button\"}\n />\n );\n};\n\nexport const InputGroupText = (\n props: React.ComponentProps<typeof ark.span>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ark.span\n className={cn(\n \"flex items-center gap-2\",\n \"text-muted-foreground text-sm\",\n \"[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"input-group-text\"}\n />\n );\n};\n\nexport const InputGroupInput = (props: React.ComponentProps<typeof Input>) => {\n const { className, slot, ...rest } = props;\n\n return (\n <Input\n className={cn(\n // `h-auto self-stretch`: the group's height, not the input's own. An `Input` is\n // `h-(--size)` and its size is its own, so inside a group of another size it would be a\n // different height from the box around it.\n \"h-auto flex-1 self-stretch\",\n \"bg-transparent\",\n \"rounded-none border-0 shadow-none\",\n \"focus-visible:ring-0\",\n \"disabled:bg-transparent aria-invalid:ring-0 data-invalid:ring-0\",\n className\n )}\n {...rest}\n slot={slot ?? \"input-group-control\"}\n />\n );\n};\n\nexport const InputGroupTextarea = (\n props: React.ComponentProps<typeof Textarea>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <Textarea\n className={cn(\n \"flex-1\",\n \"py-3\",\n \"bg-transparent\",\n \"resize-none rounded-none border-0 shadow-none\",\n \"focus-visible:ring-0\",\n \"disabled:bg-transparent aria-invalid:ring-0 data-invalid:ring-0\",\n className\n )}\n {...rest}\n slot={slot ?? \"input-group-control\"}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAWA;AAA6B;AACrB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACF;AAAA;AAES;AACT;AAEV;AAOE;AAEA;AACE;AAAK;AAAJ;AACqD;AACzC;AACN;AACD;AACe;AAAA;AAGzB;AAEmC;AAC3B;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAY0E;AACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAO7D;AACb;AACA;AACA;AAAA;AAEW;AACX;AACA;AACA;AAAA;AACF;AACF;AAEe;AACR;AAEX;AAOE;AAEA;AACE;AAAK;AAAJ;AAC4D;AAC/C;;AAEV;AAGuD;AACzD;AACK;AACD;AACe;AAAA;AAGzB;AAEoC;AAC5B;AACJ;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBmE;AACrB;AAAA;AACpD;AAEe;AACT;AAEV;AAOE;AAAM;AACJ;AACO;AACG;AACH;AACP;AACG;AAGL;AACE;AAAC;AAAA;AAC4D;AAChD;AACX;AACA;AACI;AACU;AAAA;AAGpB;AAKE;AAEA;AACE;AAAK;AAAJ;AACY;AACT;AACA;AACA;AACA;AAAA;AAEE;AACe;AAAA;AAGzB;AAGE;AAEA;AACE;AAAC;AAAA;AACY;AAAA;AAAA;AAAA;AAIT;AACA;AACA;AACA;AACA;AACQ;AAAA;AAEN;AACU;AAAA;AAGpB;AAKE;AAEA;AACE;AAAC;AAAA;AACY;AACT;AACA;AACA;AACA;AACA;AACA;AACQ;AAAA;AAEN;AACU;AAAA;AAGpB;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"input-group.js","sources":["../../src/simples/input-group.tsx"],"sourcesContent":["\"use client\";\n\nimport { ark } from \"@ark-ui/react/factory\";\nimport type React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\nimport { controlMinHeight, controlSizes } from \"../lib/control-size\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Textarea } from \"./textarea\";\n\nconst inpuGroupVariants = tv({\n base: [\n \"group/input-group\",\n \"relative\",\n \"w-full min-w-0\",\n \"flex items-center\",\n \"bg-background bg-field\",\n \"rounded-lg border border-input shadow-xs/5\",\n \"transition-[color,box-shadow]\",\n // **One height, the shared one — see `lib/control-size.ts`.** A group is `min-h-(--size)`\n // rather than `h-(--size)` because it also holds a `Textarea` and the two block addons, and\n // those grow it; what it may never do is come out TALLER than an `Input` beside it because of\n // what it holds. It did, by 14px: the `<input>` inside carried its own `h-8` and the group added\n // `p-1.5` around it, so a group at `md` measured 46px against an input's 32 — measured\n // 2026-09-30 on `/docs/forms/controls`, along with every control built on a group (combobox,\n // date picker, password input, language picker).\n //\n // So the `<input>` inside does not carry a height of its own: it stretches to the group's\n // content box (`InputGroupInput`), and the controls beside it are 24px (`InputGroupButton`),\n // which leaves a 32px group 4px of inset around them, and there is no padding to add to it: at\n // `sm` and compact density the group is 24.5px, and a 24px control plus the border already\n // asks 26. That one case is the exception the pressable floor buys (see `InputGroupButton`).\n controlMinHeight,\n \"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3\",\n \"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3\",\n \"outline-none focus-within:border-primary focus-within:ring-[3px] focus-within:ring-ring\",\n \"has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-[3px] has-[[data-slot][aria-invalid=true]]:ring-destructive/24\",\n \"dark:has-[[data-slot][aria-invalid=true]]:border-destructive-foreground dark:has-[[data-slot][aria-invalid=true]]:ring-destructive-foreground/40\",\n \"motion-reduce:transition-none!\",\n ],\n variants: {\n size: controlSizes,\n },\n defaultVariants: {\n size: \"md\",\n },\n});\n\nexport interface InputGroupProps\n extends React.ComponentProps<typeof ark.div>,\n VariantProps<typeof inpuGroupVariants> {}\n\nexport const InputGroup = (props: InputGroupProps) => {\n const { size = \"md\", className, slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(inpuGroupVariants({ size }), className)}\n data-size={size}\n role=\"group\"\n {...rest}\n data-slot={slot ?? \"input-group\"}\n />\n );\n};\n\nconst inputGroupAddonVariants = tv({\n base: [\n \"h-auto\",\n \"flex items-center justify-center gap-2\",\n \"select-none font-medium text-muted-foreground text-sm\",\n \"cursor-text\",\n \"group-data-[disabled=true]/input-group:opacity-64\",\n \"[&>kbd]:rounded-[calc(var(--radius-lg)-5px)]\",\n \"[&_svg:not([class*='size-'])]:size-4\",\n ],\n variants: {\n align: {\n // **A smaller padding, not a negative margin**, and this is a measured divergence from the\n // reference rather than a taste one. Shark tucks the button in with `pe-3` plus\n // `me-[-0.45rem]`; a negative margin on the last flex item lets its border box run past the\n // container's content edge, so measured live on `docs/ai/fields` the addon sat **6.2px\n // outside the group's inline border and 6px outside its block border** — in a box with\n // `overflow: visible`, which is why it also showed up as 6px of scroll width on the parent.\n // The inner gap is what was wanted and it is unchanged: 12px of padding minus 7.2px of\n // margin is the 6px this sets directly.\n // **A button needs no padding beside it — the group's own `p-1.5` is the inset**, and this\n // is what puts the ✨ the same distance from the border here as inside a `TagsInputControl`.\n // Text and a `kbd` still take theirs, because neither carries a box of its own.\n \"inline-start\": [\"order-first ps-3\", \"has-[>button]:ps-0.75\", \"has-[>kbd]:ps-2\"],\n \"inline-end\": [\"order-last pe-3\", \"has-[>button]:pe-0.75\", \"has-[>kbd]:pe-2\"],\n // The block padding lives on the two block aligns and nowhere else. It was `py-1.5` in the\n // base, which is right for a band across the field and wrong for a control tucked into its\n // end: measured on `docs/ai/fields`, an `inline-end` addon was **44px tall inside a 32px\n // group** — 6px of transparent padding past the border on each side, in a box with\n // `overflow: visible`. The mark inside it is `size-8` and looked fine; what was wrong was the\n // group's own box.\n \"block-start\": [\n \"order-first w-full justify-start px-3 pt-3 pb-1.5\",\n \"group-has-[>input]/input-group:pt-2.5\",\n \"[.border-b]:pb-3\",\n ],\n \"block-end\": [\n \"order-last w-full justify-start px-3 pt-1.5 pb-3\",\n \"group-has-[>input]/input-group:pb-2.5\",\n \"[.border-t]:pt-3\",\n ],\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n});\n\ninterface InputGroupAddonProps\n extends React.ComponentProps<typeof ark.div>,\n VariantProps<typeof inputGroupAddonVariants> {}\n\nexport const InputGroupAddon = (props: InputGroupAddonProps) => {\n const { className, align = \"inline-start\", slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(inputGroupAddonVariants({ align }), className)}\n data-align={align}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest(\"button\")) {\n return;\n }\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus();\n }}\n role=\"group\"\n {...rest}\n data-slot={slot ?? \"input-group-addon\"}\n />\n );\n};\n\nconst inputGroupButtonVariants = tv({\n base: [\n \"relative\",\n \"flex items-center gap-2\",\n \"text-sm\",\n \"shadow-none\",\n \"pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11\",\n ],\n variants: {\n size: {\n /**\n * The floor, and the default, because there is nothing legal below it.\n *\n * `xs` and `icon-xs` were `1.5rem`, which is 24px at the default root and **21px at compact** —\n * every size here is a `rem` against a root the density axis sets. That is under the 24×24\n * WCAG 2.5.8 states in CSS pixels, and it was this component's DEFAULT, so an input group\n * that said nothing got the failing size.\n *\n * The `pointer-coarse` hit area below does not save it. 44px is the touch answer and 2.5.8\n * asks about pointers generally: with a mouse the target was 21px and the `::after` is not in\n * the hit path. This is the one thing `Button` does not carry, and it is why the two were\n * decided separately rather than in one sweep.\n */\n // 24 CSS pixels, not `h-6`: a `rem` is 21px at compact, under the bar above, and this is the\n // one size in a recipe that must not scale. Inside a group the bar and the group's own 28px\n // at `sm` (24.5px at compact) are the same number, which is why 24 fits at every size.\n sm: [\"h-[24px]\", \"gap-1.5\", \"px-2.5\", \"rounded-md\", \"has-[>svg]:px-2.5\"],\n \"icon-sm\": [\"size-[24px]\", \"p-0\", \"has-[>svg]:p-0\"],\n },\n },\n defaultVariants: {\n size: \"sm\",\n },\n});\n\ninterface InputGroupButtonProps\n extends Omit<React.ComponentProps<typeof Button>, \"size\">,\n VariantProps<typeof inputGroupButtonVariants> {}\n\nexport const InputGroupButton = (props: InputGroupButtonProps) => {\n const {\n className,\n type = \"button\",\n variant = \"ghost\",\n size = \"sm\",\n slot,\n ...rest\n } = props;\n\n return (\n <Button\n className={cn(inputGroupButtonVariants({ size }), className)}\n data-size={size}\n type={type}\n variant={variant}\n {...rest}\n slot={slot ?? \"input-group-button\"}\n />\n );\n};\n\nexport const InputGroupText = (\n props: React.ComponentProps<typeof ark.span>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ark.span\n className={cn(\n \"flex items-center gap-2\",\n \"text-muted-foreground text-sm\",\n \"[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"input-group-text\"}\n />\n );\n};\n\nexport const InputGroupInput = (props: React.ComponentProps<typeof Input>) => {\n const { className, slot, ...rest } = props;\n\n return (\n <Input\n className={cn(\n // `h-auto self-stretch`: the group's height, not the input's own. An `Input` is\n // `h-(--size)` and its size is its own, so inside a group of another size it would be a\n // different height from the box around it.\n \"h-auto flex-1 self-stretch\",\n \"bg-transparent\",\n \"rounded-none border-0 shadow-none\",\n \"focus-visible:ring-0\",\n \"disabled:bg-transparent aria-invalid:ring-0 data-invalid:ring-0\",\n className\n )}\n {...rest}\n slot={slot ?? \"input-group-control\"}\n />\n );\n};\n\nexport const InputGroupTextarea = (\n props: React.ComponentProps<typeof Textarea>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <Textarea\n className={cn(\n \"flex-1\",\n \"py-3\",\n \"bg-transparent\",\n \"resize-none rounded-none border-0 shadow-none\",\n \"focus-visible:ring-0\",\n \"disabled:bg-transparent aria-invalid:ring-0 data-invalid:ring-0\",\n className\n )}\n {...rest}\n slot={slot ?? \"input-group-control\"}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAWA;AAA6B;AACrB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACF;AAAA;AAES;AACT;AAEV;AAOE;AAEA;AACE;AAAK;AAAJ;AACqD;AACzC;AACN;AACD;AACe;AAAA;AAGzB;AAEmC;AAC3B;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAY0E;AACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAO7D;AACb;AACA;AACA;AAAA;AAEW;AACX;AACA;AACA;AAAA;AACF;AACF;AAEe;AACR;AAEX;AAOE;AAEA;AACE;AAAK;AAAJ;AAC4D;AAC/C;;AAEV;AAGuD;AACzD;AACK;AACD;AACe;AAAA;AAGzB;AAEoC;AAC5B;AACJ;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBmE;AACrB;AAAA;AACpD;AAEe;AACT;AAEV;AAOE;AAAM;AACJ;AACO;AACG;AACH;AACP;AACG;AAGL;AACE;AAAC;AAAA;AAC4D;AAChD;AACX;AACA;AACI;AACU;AAAA;AAGpB;AAKE;AAEA;AACE;AAAK;AAAJ;AACY;AACT;AACA;AACA;AACA;AAAA;AAEE;AACe;AAAA;AAGzB;AAGE;AAEA;AACE;AAAC;AAAA;AACY;AAAA;AAAA;AAAA;AAIT;AACA;AACA;AACA;AACA;AACQ;AAAA;AAEN;AACU;AAAA;AAGpB;AAKE;AAEA;AACE;AAAC;AAAA;AACY;AACT;AACA;AACA;AACA;AACA;AACA;AACQ;AAAA;AAEN;AACU;AAAA;AAGpB;;;;;;;;;"}
|
package/dist/simples/menu.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as a, jsxs as c } from "react/jsx-runtime";
|
|
2
2
|
import { Portal as l } from "@ark-ui/react";
|
|
3
|
-
import { ark as
|
|
3
|
+
import { ark as v } from "@ark-ui/react/factory";
|
|
4
4
|
import { Menu as o } from "@ark-ui/react/menu";
|
|
5
5
|
import { useMenuContext as B } from "@ark-ui/react/menu";
|
|
6
|
-
import { CheckIcon as d, ChevronRight as
|
|
6
|
+
import { CheckIcon as d, ChevronRight as f } from "lucide-react";
|
|
7
7
|
import { tv as m } from "tailwind-variants";
|
|
8
8
|
import { cn as s } from "../lib/cn.js";
|
|
9
9
|
const x = (t) => {
|
|
@@ -234,14 +234,14 @@ const x = (t) => {
|
|
|
234
234
|
"data-slot": r ?? "menu-sub-trigger",
|
|
235
235
|
children: [
|
|
236
236
|
n,
|
|
237
|
-
/* @__PURE__ */ a(b, { children: /* @__PURE__ */ a(
|
|
237
|
+
/* @__PURE__ */ a(b, { children: /* @__PURE__ */ a(f, {}) })
|
|
238
238
|
]
|
|
239
239
|
}
|
|
240
240
|
);
|
|
241
241
|
}, b = (t) => {
|
|
242
242
|
const { className: e, slot: n, ...r } = t;
|
|
243
243
|
return /* @__PURE__ */ a(
|
|
244
|
-
|
|
244
|
+
v.span,
|
|
245
245
|
{
|
|
246
246
|
className: s(
|
|
247
247
|
"ms-auto rtl:me-auto",
|
|
@@ -259,7 +259,7 @@ const x = (t) => {
|
|
|
259
259
|
o.Arrow,
|
|
260
260
|
{
|
|
261
261
|
style: {
|
|
262
|
-
"--arrow-background": "var(--popover)",
|
|
262
|
+
"--arrow-background": "var(--popover, var(--card))",
|
|
263
263
|
"--arrow-size": "calc(1.5 * var(--spacing))",
|
|
264
264
|
...e
|
|
265
265
|
},
|