@neuronix-tech/ui 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/dist/cli/index.js +4 -0
  2. package/dist/components/button/button.d.ts +18 -0
  3. package/dist/components/button/button.js +40 -0
  4. package/dist/components/button/button.js.map +1 -0
  5. package/dist/components/button/button.types.d.ts +36 -0
  6. package/dist/components/button/button.types.js +1 -0
  7. package/dist/components/button/button.types.js.map +1 -0
  8. package/dist/components/button/button.variants.d.ts +27 -0
  9. package/dist/components/button/button.variants.js +45 -0
  10. package/dist/components/button/button.variants.js.map +1 -0
  11. package/dist/components/button/index.d.ts +8 -0
  12. package/dist/components/button/index.js +5 -0
  13. package/dist/components/button/index.js.map +1 -0
  14. package/dist/components/form-currency-input/form-currency-input.d.ts +12 -0
  15. package/dist/components/form-currency-input/form-currency-input.js +62 -0
  16. package/dist/components/form-currency-input/form-currency-input.js.map +1 -0
  17. package/dist/components/form-currency-input/form-currency-input.types.d.ts +32 -0
  18. package/dist/components/form-currency-input/form-currency-input.types.js +1 -0
  19. package/dist/components/form-currency-input/form-currency-input.types.js.map +1 -0
  20. package/dist/components/form-currency-input/index.d.ts +4 -0
  21. package/dist/components/form-currency-input/index.js +5 -0
  22. package/dist/components/form-currency-input/index.js.map +1 -0
  23. package/dist/components/form-number-input/form-number-input.d.ts +13 -0
  24. package/dist/components/form-number-input/form-number-input.js +75 -0
  25. package/dist/components/form-number-input/form-number-input.js.map +1 -0
  26. package/dist/components/form-number-input/form-number-input.types.d.ts +34 -0
  27. package/dist/components/form-number-input/form-number-input.types.js +1 -0
  28. package/dist/components/form-number-input/form-number-input.types.js.map +1 -0
  29. package/dist/components/form-number-input/index.d.ts +4 -0
  30. package/dist/components/form-number-input/index.js +5 -0
  31. package/dist/components/form-number-input/index.js.map +1 -0
  32. package/dist/components/form-percentage-input/form-percentage-input.d.ts +12 -0
  33. package/dist/components/form-percentage-input/form-percentage-input.js +65 -0
  34. package/dist/components/form-percentage-input/form-percentage-input.js.map +1 -0
  35. package/dist/components/form-percentage-input/form-percentage-input.types.d.ts +33 -0
  36. package/dist/components/form-percentage-input/form-percentage-input.types.js +1 -0
  37. package/dist/components/form-percentage-input/form-percentage-input.types.js.map +1 -0
  38. package/dist/components/form-percentage-input/index.d.ts +4 -0
  39. package/dist/components/form-percentage-input/index.js +5 -0
  40. package/dist/components/form-percentage-input/index.js.map +1 -0
  41. package/dist/components/form-text-input/form-text-input.d.ts +19 -0
  42. package/dist/components/form-text-input/form-text-input.js +64 -0
  43. package/dist/components/form-text-input/form-text-input.js.map +1 -0
  44. package/dist/components/form-text-input/form-text-input.types.d.ts +45 -0
  45. package/dist/components/form-text-input/form-text-input.types.js +1 -0
  46. package/dist/components/form-text-input/form-text-input.types.js.map +1 -0
  47. package/dist/components/form-text-input/index.d.ts +4 -0
  48. package/dist/components/form-text-input/index.js +5 -0
  49. package/dist/components/form-text-input/index.js.map +1 -0
  50. package/dist/components/icon-button/icon-button.d.ts +20 -0
  51. package/dist/components/icon-button/icon-button.js +32 -0
  52. package/dist/components/icon-button/icon-button.js.map +1 -0
  53. package/dist/components/icon-button/icon-button.types.d.ts +24 -0
  54. package/dist/components/icon-button/icon-button.types.js +1 -0
  55. package/dist/components/icon-button/icon-button.types.js.map +1 -0
  56. package/dist/components/icon-button/index.d.ts +8 -0
  57. package/dist/components/icon-button/index.js +5 -0
  58. package/dist/components/icon-button/index.js.map +1 -0
  59. package/dist/components/spinner/index.d.ts +2 -0
  60. package/dist/components/spinner/index.js +5 -0
  61. package/dist/components/spinner/index.js.map +1 -0
  62. package/dist/components/spinner/spinner.d.ts +15 -0
  63. package/dist/components/spinner/spinner.js +9 -0
  64. package/dist/components/spinner/spinner.js.map +1 -0
  65. package/dist/hooks/use-number-mask.d.ts +24 -0
  66. package/dist/hooks/use-number-mask.js +59 -0
  67. package/dist/hooks/use-number-mask.js.map +1 -0
  68. package/dist/index.d.ts +21 -0
  69. package/dist/index.js +28 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/lib/cn.d.ts +10 -0
  72. package/dist/lib/cn.js +8 -0
  73. package/dist/lib/cn.js.map +1 -0
  74. package/dist/lib/format/number.d.ts +6 -0
  75. package/dist/lib/format/number.js +26 -0
  76. package/dist/lib/format/number.js.map +1 -0
  77. package/dist/lib/format/percent.d.ts +15 -0
  78. package/dist/lib/format/percent.js +7 -0
  79. package/dist/lib/format/percent.js.map +1 -0
  80. package/dist/lib/sealed.d.ts +14 -0
  81. package/dist/lib/sealed.js +1 -0
  82. package/dist/lib/sealed.js.map +1 -0
  83. package/dist/primitives/field.d.ts +17 -0
  84. package/dist/primitives/field.js +74 -0
  85. package/dist/primitives/field.js.map +1 -0
  86. package/dist/primitives/form-field.d.ts +27 -0
  87. package/dist/primitives/form-field.js +27 -0
  88. package/dist/primitives/form-field.js.map +1 -0
  89. package/dist/primitives/input-group.d.ts +19 -0
  90. package/dist/primitives/input-group.js +87 -0
  91. package/dist/primitives/input-group.js.map +1 -0
  92. package/dist/primitives/input.d.ts +11 -0
  93. package/dist/primitives/input.js +22 -0
  94. package/dist/primitives/input.js.map +1 -0
  95. package/dist/primitives/label.d.ts +6 -0
  96. package/dist/primitives/label.js +19 -0
  97. package/dist/primitives/label.js.map +1 -0
  98. package/dist/primitives/spinner.d.ts +10 -0
  99. package/dist/primitives/spinner.js +19 -0
  100. package/dist/primitives/spinner.js.map +1 -0
  101. package/dist/primitives/tooltip.d.ts +17 -0
  102. package/dist/primitives/tooltip.js +51 -0
  103. package/dist/primitives/tooltip.js.map +1 -0
  104. package/dist/styles.css +2 -0
  105. package/package.json +70 -3
  106. package/README.md +0 -3
@@ -0,0 +1,7 @@
1
+ const percentToFraction = (points) => points === null ? null : points / 100;
2
+ const fractionToPercent = (fraction) => fraction === null ? null : fraction * 100;
3
+ export {
4
+ fractionToPercent,
5
+ percentToFraction
6
+ };
7
+ //# sourceMappingURL=percent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/format/percent.ts"],"sourcesContent":["/**\n * Percentage boundary converters.\n *\n * FormPercentageInput stores PERCENT POINTS in form state (user types 15 →\n * state holds 15) — the UI convention (what you see is what's stored). When a\n * backend or formula expects a FRACTION (0.15), convert explicitly at the\n * boundary with these — one greppable call instead of scattered `/100`s.\n *\n * api.discountRate = percentToFraction(values.discount) // 15 → 0.15\n * defaultValues: { discount: fractionToPercent(api.rate) } // 0.15 → 15\n */\nexport const percentToFraction = (points: number | null): number | null =>\n points === null ? null : points / 100\n\nexport const fractionToPercent = (fraction: number | null): number | null =>\n fraction === null ? null : fraction * 100\n"],"mappings":"AAWO,MAAM,oBAAoB,CAAC,WAChC,WAAW,OAAO,OAAO,SAAS;AAE7B,MAAM,oBAAoB,CAAC,aAChC,aAAa,OAAO,OAAO,WAAW;","names":[]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The sealing type: strips styling escape hatches from a props contract.
3
+ *
4
+ * Neuronix UI components are Legos — devs pick variants and sizes from a fixed
5
+ * menu and make no other UI decisions. `className`/`style` are removed at the
6
+ * type level, and components never spread unknown props onto styled nodes, so
7
+ * JS-level smuggling is inert too. Layout placement belongs to the layout
8
+ * components (Box/Stack/Grid/GridItem), never to per-component overrides.
9
+ *
10
+ * `data-*` attributes still pass through for testing and analytics.
11
+ */
12
+ type Sealed<T> = Omit<T, "className" | "style">;
13
+
14
+ export type { Sealed };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=sealed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,17 @@
1
+ import * as react from 'react';
2
+ import { LabelPrimitive } from './label.js';
3
+
4
+ /**
5
+ * Internal field skeleton (ported subset of nx-automations ui/field.tsx —
6
+ * vertical orientation only; more variants come with future components).
7
+ * Every form input renders: Field → FieldLabel → control → FieldError.
8
+ */
9
+ declare function Field({ className, ...props }: React.ComponentProps<"div">): react.JSX.Element;
10
+ declare function FieldLabel({ className, ...props }: React.ComponentProps<typeof LabelPrimitive>): react.JSX.Element;
11
+ declare function FieldError({ className, children, errors, ...props }: React.ComponentProps<"div"> & {
12
+ errors?: Array<{
13
+ message?: string;
14
+ } | undefined>;
15
+ }): react.JSX.Element | null;
16
+
17
+ export { Field, FieldError, FieldLabel };
@@ -0,0 +1,74 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useMemo } from "react";
4
+ import { cn } from "../lib/cn.js";
5
+ import { LabelPrimitive } from "./label.js";
6
+ function Field({ className, ...props }) {
7
+ return /* @__PURE__ */ jsx(
8
+ "div",
9
+ {
10
+ role: "group",
11
+ "data-slot": "field",
12
+ "data-orientation": "vertical",
13
+ className: cn(
14
+ "nxui:group/field nxui:flex nxui:w-full nxui:gap-2 nxui:flex-col nxui:*:w-full nxui:[&>.sr-only]:w-auto nxui:data-[invalid=true]:text-destructive",
15
+ className
16
+ ),
17
+ ...props
18
+ }
19
+ );
20
+ }
21
+ function FieldLabel({ className, ...props }) {
22
+ return /* @__PURE__ */ jsx(
23
+ LabelPrimitive,
24
+ {
25
+ "data-slot": "field-label",
26
+ className: cn(
27
+ "nxui:group/field-label nxui:peer/field-label nxui:flex nxui:w-fit nxui:gap-2 nxui:leading-snug nxui:group-data-[disabled=true]/field:opacity-50",
28
+ className
29
+ ),
30
+ ...props
31
+ }
32
+ );
33
+ }
34
+ function FieldError({
35
+ className,
36
+ children,
37
+ errors,
38
+ ...props
39
+ }) {
40
+ const content = useMemo(() => {
41
+ if (children) {
42
+ return children;
43
+ }
44
+ if (!errors?.length) {
45
+ return null;
46
+ }
47
+ const uniqueErrors = [...new Map(errors.map((error) => [error?.message, error])).values()];
48
+ if (uniqueErrors?.length == 1) {
49
+ return uniqueErrors[0]?.message;
50
+ }
51
+ return /* @__PURE__ */ jsx("ul", { className: "nxui:ml-4 nxui:flex nxui:list-disc nxui:flex-col nxui:gap-1", children: uniqueErrors.map(
52
+ (error, index) => error?.message && /* @__PURE__ */ jsx("li", { children: error.message }, index)
53
+ ) });
54
+ }, [children, errors]);
55
+ if (!content) {
56
+ return null;
57
+ }
58
+ return /* @__PURE__ */ jsx(
59
+ "div",
60
+ {
61
+ role: "alert",
62
+ "data-slot": "field-error",
63
+ className: cn("nxui:text-body/relaxed nxui:font-normal nxui:text-destructive", className),
64
+ ...props,
65
+ children: content
66
+ }
67
+ );
68
+ }
69
+ export {
70
+ Field,
71
+ FieldError,
72
+ FieldLabel
73
+ };
74
+ //# sourceMappingURL=field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives/field.tsx"],"sourcesContent":["\"use client\"\n\nimport { useMemo } from \"react\"\n\nimport { cn } from \"../lib/cn.js\"\nimport { LabelPrimitive } from \"./label.js\"\n\n/**\n * Internal field skeleton (ported subset of nx-automations ui/field.tsx —\n * vertical orientation only; more variants come with future components).\n * Every form input renders: Field → FieldLabel → control → FieldError.\n */\n\nfunction Field({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n role=\"group\"\n data-slot=\"field\"\n data-orientation=\"vertical\"\n className={cn(\n \"nxui:group/field nxui:flex nxui:w-full nxui:gap-2 nxui:flex-col nxui:*:w-full nxui:[&>.sr-only]:w-auto nxui:data-[invalid=true]:text-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLabel({ className, ...props }: React.ComponentProps<typeof LabelPrimitive>) {\n return (\n <LabelPrimitive\n data-slot=\"field-label\"\n className={cn(\n \"nxui:group/field-label nxui:peer/field-label nxui:flex nxui:w-fit nxui:gap-2 nxui:leading-snug nxui:group-data-[disabled=true]/field:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n ...props\n}: React.ComponentProps<\"div\"> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const content = useMemo(() => {\n if (children) {\n return children\n }\n if (!errors?.length) {\n return null\n }\n const uniqueErrors = [...new Map(errors.map((error) => [error?.message, error])).values()]\n if (uniqueErrors?.length == 1) {\n return uniqueErrors[0]?.message\n }\n return (\n <ul className=\"nxui:ml-4 nxui:flex nxui:list-disc nxui:flex-col nxui:gap-1\">\n {uniqueErrors.map(\n (error, index) => error?.message && <li key={index}>{error.message}</li>\n )}\n </ul>\n )\n }, [children, errors])\n\n if (!content) {\n return null\n }\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n className={cn(\"nxui:text-body/relaxed nxui:font-normal nxui:text-destructive\", className)}\n {...props}\n >\n {content}\n </div>\n )\n}\n\nexport { Field, FieldLabel, FieldError }\n"],"mappings":";AAeI;AAbJ,SAAS,eAAe;AAExB,SAAS,UAAU;AACnB,SAAS,sBAAsB;AAQ/B,SAAS,MAAM,EAAE,WAAW,GAAG,MAAM,GAAgC;AACnE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAU;AAAA,MACV,oBAAiB;AAAA,MACjB,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,MAAM,GAAgD;AACxF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAEG;AACD,QAAM,UAAU,QAAQ,MAAM;AAC5B,QAAI,UAAU;AACZ,aAAO;AAAA,IACT;AACA,QAAI,CAAC,QAAQ,QAAQ;AACnB,aAAO;AAAA,IACT;AACA,UAAM,eAAe,CAAC,GAAG,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,SAAS,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC;AACzF,QAAI,cAAc,UAAU,GAAG;AAC7B,aAAO,aAAa,CAAC,GAAG;AAAA,IAC1B;AACA,WACE,oBAAC,QAAG,WAAU,+DACX,uBAAa;AAAA,MACZ,CAAC,OAAO,UAAU,OAAO,WAAW,oBAAC,QAAgB,gBAAM,WAAd,KAAsB;AAAA,IACrE,GACF;AAAA,EAEJ,GAAG,CAAC,UAAU,MAAM,CAAC;AAErB,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAU;AAAA,MACV,WAAW,GAAG,iEAAiE,SAAS;AAAA,MACvF,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;","names":[]}
@@ -0,0 +1,27 @@
1
+ import * as react from 'react';
2
+
3
+ /**
4
+ * Shared pieces of the Form* input skeleton, so every input in the family has
5
+ * an identical label (asterisk, hint) and loading treatment without each
6
+ * component re-implementing them.
7
+ */
8
+ interface FormFieldLabelProps {
9
+ htmlFor: string;
10
+ label: string;
11
+ optional: boolean;
12
+ labelHint?: string;
13
+ }
14
+ /**
15
+ * The uniform Form* label: required-by-default asterisk and the optional
16
+ * dotted-underline hint tooltip. A single inline wrapper keeps the label's
17
+ * flex gap from ever separating the asterisk from the text.
18
+ */
19
+ declare function FormFieldLabel({ htmlFor, label, optional, labelHint }: FormFieldLabelProps): react.JSX.Element;
20
+ /**
21
+ * Spinner overlay for a control whose value is being seeded asynchronously.
22
+ * Render inside the control's `nxui:relative` wrapper; pair with disabling the
23
+ * control itself.
24
+ */
25
+ declare function ControlLoadingOverlay(): react.JSX.Element;
26
+
27
+ export { ControlLoadingOverlay, FormFieldLabel };
@@ -0,0 +1,27 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { FieldLabel } from "./field.js";
3
+ import { SpinnerPrimitive } from "./spinner.js";
4
+ import { TooltipContent, TooltipRoot, TooltipTrigger } from "./tooltip.js";
5
+ function FormFieldLabel({ htmlFor, label, optional, labelHint }) {
6
+ return /* @__PURE__ */ jsx(FieldLabel, { htmlFor, children: /* @__PURE__ */ jsxs("span", { children: [
7
+ labelHint ? /* @__PURE__ */ jsxs(TooltipRoot, { children: [
8
+ /* @__PURE__ */ jsx(
9
+ TooltipTrigger,
10
+ {
11
+ render: /* @__PURE__ */ jsx("span", { className: "nxui:underline nxui:decoration-dotted nxui:underline-offset-4" }),
12
+ children: label
13
+ }
14
+ ),
15
+ /* @__PURE__ */ jsx(TooltipContent, { side: "bottom", className: "nxui:max-w-xs nxui:text-left", children: labelHint })
16
+ ] }) : label,
17
+ !optional && " *"
18
+ ] }) });
19
+ }
20
+ function ControlLoadingOverlay() {
21
+ return /* @__PURE__ */ jsx("div", { className: "nxui:absolute nxui:inset-0 nxui:m-0.5 nxui:flex nxui:items-center nxui:justify-center nxui:bg-background", children: /* @__PURE__ */ jsx(SpinnerPrimitive, {}) });
22
+ }
23
+ export {
24
+ ControlLoadingOverlay,
25
+ FormFieldLabel
26
+ };
27
+ //# sourceMappingURL=form-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives/form-field.tsx"],"sourcesContent":["import { FieldLabel } from \"./field.js\"\nimport { SpinnerPrimitive } from \"./spinner.js\"\nimport { TooltipContent, TooltipRoot, TooltipTrigger } from \"./tooltip.js\"\n\n/**\n * Shared pieces of the Form* input skeleton, so every input in the family has\n * an identical label (asterisk, hint) and loading treatment without each\n * component re-implementing them.\n */\n\ninterface FormFieldLabelProps {\n htmlFor: string\n label: string\n optional: boolean\n labelHint?: string\n}\n\n/**\n * The uniform Form* label: required-by-default asterisk and the optional\n * dotted-underline hint tooltip. A single inline wrapper keeps the label's\n * flex gap from ever separating the asterisk from the text.\n */\nfunction FormFieldLabel({ htmlFor, label, optional, labelHint }: FormFieldLabelProps) {\n return (\n <FieldLabel htmlFor={htmlFor}>\n <span>\n {labelHint ? (\n <TooltipRoot>\n <TooltipTrigger\n render={\n <span className=\"nxui:underline nxui:decoration-dotted nxui:underline-offset-4\" />\n }\n >\n {label}\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"nxui:max-w-xs nxui:text-left\">\n {labelHint}\n </TooltipContent>\n </TooltipRoot>\n ) : (\n label\n )}\n {!optional && \" *\"}\n </span>\n </FieldLabel>\n )\n}\n\n/**\n * Spinner overlay for a control whose value is being seeded asynchronously.\n * Render inside the control's `nxui:relative` wrapper; pair with disabling the\n * control itself.\n */\nfunction ControlLoadingOverlay() {\n return (\n <div className=\"nxui:absolute nxui:inset-0 nxui:m-0.5 nxui:flex nxui:items-center nxui:justify-center nxui:bg-background\">\n <SpinnerPrimitive />\n </div>\n )\n}\n\nexport { FormFieldLabel, ControlLoadingOverlay }\n"],"mappings":"AA2BU,SAGM,KAHN;AA3BV,SAAS,kBAAkB;AAC3B,SAAS,wBAAwB;AACjC,SAAS,gBAAgB,aAAa,sBAAsB;AAoB5D,SAAS,eAAe,EAAE,SAAS,OAAO,UAAU,UAAU,GAAwB;AACpF,SACE,oBAAC,cAAW,SACV,+BAAC,UACE;AAAA,gBACC,qBAAC,eACC;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,QACE,oBAAC,UAAK,WAAU,iEAAgE;AAAA,UAGjF;AAAA;AAAA,MACH;AAAA,MACA,oBAAC,kBAAe,MAAK,UAAS,WAAU,gCACrC,qBACH;AAAA,OACF,IAEA;AAAA,IAED,CAAC,YAAY;AAAA,KAChB,GACF;AAEJ;AAOA,SAAS,wBAAwB;AAC/B,SACE,oBAAC,SAAI,WAAU,4GACb,8BAAC,oBAAiB,GACpB;AAEJ;","names":[]}
@@ -0,0 +1,19 @@
1
+ import * as class_variance_authority_types from 'class-variance-authority/types';
2
+ import * as react from 'react';
3
+ import { VariantProps } from 'class-variance-authority';
4
+
5
+ /**
6
+ * Internal input-group primitives (ported subset of nx-automations
7
+ * ui/input-group.tsx — the pieces the form inputs need: group shell, inline
8
+ * addons, text adornment, and the borderless inner input; kbd/button/textarea
9
+ * variants come with the components that need them).
10
+ */
11
+ declare function InputGroup({ className, ...props }: React.ComponentProps<"div">): react.JSX.Element;
12
+ declare const inputGroupAddonVariants: (props?: ({
13
+ align?: "inline-end" | "inline-start" | null | undefined;
14
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
15
+ declare function InputGroupAddon({ className, align, ...props }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>): react.JSX.Element;
16
+ declare function InputGroupText({ className, ...props }: React.ComponentProps<"span">): react.JSX.Element;
17
+ declare function InputGroupInput({ className, ...props }: React.ComponentProps<"input">): react.JSX.Element;
18
+
19
+ export { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText };
@@ -0,0 +1,87 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { cva } from "class-variance-authority";
4
+ import { cn } from "../lib/cn.js";
5
+ import { InputPrimitive } from "./input.js";
6
+ function InputGroup({ className, ...props }) {
7
+ return /* @__PURE__ */ jsx(
8
+ "div",
9
+ {
10
+ "data-slot": "input-group",
11
+ role: "group",
12
+ className: cn(
13
+ "nxui:group/input-group nxui:relative nxui:flex nxui:h-control-md nxui:w-full nxui:min-w-0 nxui:items-center nxui:rounded-md nxui:border nxui:border-input nxui:bg-input/20 nxui:transition-colors nxui:outline-none nxui:has-[[data-slot=input-group-control]:focus-visible]:border-ring nxui:has-[[data-slot=input-group-control]:focus-visible]:ring-2 nxui:has-[[data-slot=input-group-control]:focus-visible]:ring-ring/30 nxui:has-[[data-slot][aria-invalid=true]]:border-destructive nxui:has-[[data-slot][aria-invalid=true]]:ring-2 nxui:has-[[data-slot][aria-invalid=true]]:ring-destructive/20 nxui:dark:bg-input/30 nxui:dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 nxui:has-[>[data-align=inline-end]]:[&>input]:pr-1.5 nxui:has-[>[data-align=inline-start]]:[&>input]:pl-1.5",
14
+ className
15
+ ),
16
+ ...props
17
+ }
18
+ );
19
+ }
20
+ const inputGroupAddonVariants = cva(
21
+ "nxui:flex nxui:h-auto nxui:cursor-text nxui:items-center nxui:justify-center nxui:gap-1 nxui:py-2 nxui:text-body/relaxed nxui:font-medium nxui:text-muted-foreground nxui:select-none nxui:group-data-[disabled=true]/input-group:opacity-50 nxui:[&>svg:not([class*=size-])]:size-3.5",
22
+ {
23
+ variants: {
24
+ align: {
25
+ "inline-start": "nxui:order-first nxui:pl-2",
26
+ "inline-end": "nxui:order-last nxui:pr-2"
27
+ }
28
+ },
29
+ defaultVariants: {
30
+ align: "inline-start"
31
+ }
32
+ }
33
+ );
34
+ function InputGroupAddon({
35
+ className,
36
+ align = "inline-start",
37
+ ...props
38
+ }) {
39
+ return /* @__PURE__ */ jsx(
40
+ "div",
41
+ {
42
+ role: "group",
43
+ "data-slot": "input-group-addon",
44
+ "data-align": align,
45
+ className: cn(inputGroupAddonVariants({ align }), className),
46
+ onClick: (e) => {
47
+ if (e.target.closest("button")) {
48
+ return;
49
+ }
50
+ e.currentTarget.parentElement?.querySelector("input")?.focus();
51
+ },
52
+ ...props
53
+ }
54
+ );
55
+ }
56
+ function InputGroupText({ className, ...props }) {
57
+ return /* @__PURE__ */ jsx(
58
+ "span",
59
+ {
60
+ className: cn(
61
+ "nxui:flex nxui:items-center nxui:gap-2 nxui:text-body/relaxed nxui:text-muted-foreground nxui:[&_svg]:pointer-events-none nxui:[&_svg:not([class*=size-])]:size-4",
62
+ className
63
+ ),
64
+ ...props
65
+ }
66
+ );
67
+ }
68
+ function InputGroupInput({ className, ...props }) {
69
+ return /* @__PURE__ */ jsx(
70
+ InputPrimitive,
71
+ {
72
+ "data-slot": "input-group-control",
73
+ className: cn(
74
+ "nxui:flex-1 nxui:rounded-none nxui:border-0 nxui:bg-transparent nxui:shadow-none nxui:ring-0 nxui:focus-visible:ring-0 nxui:aria-invalid:ring-0 nxui:dark:bg-transparent",
75
+ className
76
+ ),
77
+ ...props
78
+ }
79
+ );
80
+ }
81
+ export {
82
+ InputGroup,
83
+ InputGroupAddon,
84
+ InputGroupInput,
85
+ InputGroupText
86
+ };
87
+ //# sourceMappingURL=input-group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives/input-group.tsx"],"sourcesContent":["\"use client\"\n\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../lib/cn.js\"\nimport { InputPrimitive } from \"./input.js\"\n\n/**\n * Internal input-group primitives (ported subset of nx-automations\n * ui/input-group.tsx — the pieces the form inputs need: group shell, inline\n * addons, text adornment, and the borderless inner input; kbd/button/textarea\n * variants come with the components that need them).\n */\n\nfunction InputGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"input-group\"\n role=\"group\"\n className={cn(\n \"nxui:group/input-group nxui:relative nxui:flex nxui:h-control-md nxui:w-full nxui:min-w-0 nxui:items-center nxui:rounded-md nxui:border nxui:border-input nxui:bg-input/20 nxui:transition-colors nxui:outline-none nxui:has-[[data-slot=input-group-control]:focus-visible]:border-ring nxui:has-[[data-slot=input-group-control]:focus-visible]:ring-2 nxui:has-[[data-slot=input-group-control]:focus-visible]:ring-ring/30 nxui:has-[[data-slot][aria-invalid=true]]:border-destructive nxui:has-[[data-slot][aria-invalid=true]]:ring-2 nxui:has-[[data-slot][aria-invalid=true]]:ring-destructive/20 nxui:dark:bg-input/30 nxui:dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 nxui:has-[>[data-align=inline-end]]:[&>input]:pr-1.5 nxui:has-[>[data-align=inline-start]]:[&>input]:pl-1.5\",\n className\n )}\n {...props}\n />\n )\n}\n\nconst inputGroupAddonVariants = cva(\n \"nxui:flex nxui:h-auto nxui:cursor-text nxui:items-center nxui:justify-center nxui:gap-1 nxui:py-2 nxui:text-body/relaxed nxui:font-medium nxui:text-muted-foreground nxui:select-none nxui:group-data-[disabled=true]/input-group:opacity-50 nxui:[&>svg:not([class*=size-])]:size-3.5\",\n {\n variants: {\n align: {\n \"inline-start\": \"nxui:order-first nxui:pl-2\",\n \"inline-end\": \"nxui:order-last nxui:pr-2\",\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n }\n)\n\nfunction InputGroupAddon({\n className,\n align = \"inline-start\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof inputGroupAddonVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"input-group-addon\"\n data-align={align}\n className={cn(inputGroupAddonVariants({ align }), className)}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest(\"button\")) {\n return\n }\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus()\n }}\n {...props}\n />\n )\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n className={cn(\n \"nxui:flex nxui:items-center nxui:gap-2 nxui:text-body/relaxed nxui:text-muted-foreground nxui:[&_svg]:pointer-events-none nxui:[&_svg:not([class*=size-])]:size-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction InputGroupInput({ className, ...props }: React.ComponentProps<\"input\">) {\n return (\n <InputPrimitive\n data-slot=\"input-group-control\"\n className={cn(\n \"nxui:flex-1 nxui:rounded-none nxui:border-0 nxui:bg-transparent nxui:shadow-none nxui:ring-0 nxui:focus-visible:ring-0 nxui:aria-invalid:ring-0 nxui:dark:bg-transparent\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { InputGroup, InputGroupAddon, InputGroupText, InputGroupInput }\n"],"mappings":";AAgBI;AAdJ,SAAS,WAA8B;AAEvC,SAAS,UAAU;AACnB,SAAS,sBAAsB;AAS/B,SAAS,WAAW,EAAE,WAAW,GAAG,MAAM,GAAgC;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,MAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,OAAO;AAAA,QACL,gBAAgB;AAAA,QAChB,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA,QAAQ;AAAA,EACR,GAAG;AACL,GAA+E;AAC7E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAY;AAAA,MACZ,WAAW,GAAG,wBAAwB,EAAE,MAAM,CAAC,GAAG,SAAS;AAAA,MAC3D,SAAS,CAAC,MAAM;AACd,YAAK,EAAE,OAAuB,QAAQ,QAAQ,GAAG;AAC/C;AAAA,QACF;AACA,UAAE,cAAc,eAAe,cAAc,OAAO,GAAG,MAAM;AAAA,MAC/D;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAiC;AAC7E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,MAAM,GAAkC;AAC/E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
@@ -0,0 +1,11 @@
1
+ import * as react from 'react';
2
+
3
+ /**
4
+ * Internal input primitive (ported from nx-automations ui/input.tsx).
5
+ * Density-tokenized: h-7 → h-control-md, text sizes → body tokens. The larger
6
+ * mobile text size (text-body-lg below md) mirrors the source's text-sm and
7
+ * keeps mobile browsers from zooming on focus.
8
+ */
9
+ declare function InputPrimitive({ className, type, ...props }: React.ComponentProps<"input">): react.JSX.Element;
10
+
11
+ export { InputPrimitive };
@@ -0,0 +1,22 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { Input as InputPrimitiveBase } from "@base-ui/react/input";
4
+ import { cn } from "../lib/cn.js";
5
+ function InputPrimitive({ className, type, ...props }) {
6
+ return /* @__PURE__ */ jsx(
7
+ InputPrimitiveBase,
8
+ {
9
+ type,
10
+ "data-slot": "input",
11
+ className: cn(
12
+ "nxui:h-control-md nxui:w-full nxui:min-w-0 nxui:rounded-md nxui:border nxui:border-input nxui:bg-input/20 nxui:px-2 nxui:py-0.5 nxui:text-body-lg nxui:transition-colors nxui:outline-none nxui:file:inline-flex nxui:file:h-control-sm nxui:file:border-0 nxui:file:bg-transparent nxui:file:text-body/relaxed nxui:file:font-medium nxui:file:text-foreground nxui:placeholder:text-muted-foreground nxui:focus-visible:border-ring nxui:focus-visible:ring-2 nxui:focus-visible:ring-ring/30 nxui:disabled:pointer-events-none nxui:disabled:cursor-not-allowed nxui:disabled:opacity-50 nxui:aria-invalid:border-destructive nxui:aria-invalid:ring-2 nxui:aria-invalid:ring-destructive/20 nxui:md:text-body/relaxed nxui:dark:bg-input/30 nxui:dark:aria-invalid:border-destructive/50 nxui:dark:aria-invalid:ring-destructive/40",
13
+ className
14
+ ),
15
+ ...props
16
+ }
17
+ );
18
+ }
19
+ export {
20
+ InputPrimitive
21
+ };
22
+ //# sourceMappingURL=input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives/input.tsx"],"sourcesContent":["\"use client\"\n\nimport { Input as InputPrimitiveBase } from \"@base-ui/react/input\"\n\nimport { cn } from \"../lib/cn.js\"\n\n/**\n * Internal input primitive (ported from nx-automations ui/input.tsx).\n * Density-tokenized: h-7 → h-control-md, text sizes → body tokens. The larger\n * mobile text size (text-body-lg below md) mirrors the source's text-sm and\n * keeps mobile browsers from zooming on focus.\n */\nfunction InputPrimitive({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <InputPrimitiveBase\n type={type}\n data-slot=\"input\"\n className={cn(\n \"nxui:h-control-md nxui:w-full nxui:min-w-0 nxui:rounded-md nxui:border nxui:border-input nxui:bg-input/20 nxui:px-2 nxui:py-0.5 nxui:text-body-lg nxui:transition-colors nxui:outline-none nxui:file:inline-flex nxui:file:h-control-sm nxui:file:border-0 nxui:file:bg-transparent nxui:file:text-body/relaxed nxui:file:font-medium nxui:file:text-foreground nxui:placeholder:text-muted-foreground nxui:focus-visible:border-ring nxui:focus-visible:ring-2 nxui:focus-visible:ring-ring/30 nxui:disabled:pointer-events-none nxui:disabled:cursor-not-allowed nxui:disabled:opacity-50 nxui:aria-invalid:border-destructive nxui:aria-invalid:ring-2 nxui:aria-invalid:ring-destructive/20 nxui:md:text-body/relaxed nxui:dark:bg-input/30 nxui:dark:aria-invalid:border-destructive/50 nxui:dark:aria-invalid:ring-destructive/40\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { InputPrimitive }\n"],"mappings":";AAcI;AAZJ,SAAS,SAAS,0BAA0B;AAE5C,SAAS,UAAU;AAQnB,SAAS,eAAe,EAAE,WAAW,MAAM,GAAG,MAAM,GAAkC;AACpF,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
@@ -0,0 +1,6 @@
1
+ import * as react from 'react';
2
+
3
+ /** Internal label primitive (ported from nx-automations ui/label.tsx). */
4
+ declare function LabelPrimitive({ className, ...props }: React.ComponentProps<"label">): react.JSX.Element;
5
+
6
+ export { LabelPrimitive };
@@ -0,0 +1,19 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { cn } from "../lib/cn.js";
3
+ function LabelPrimitive({ className, ...props }) {
4
+ return /* @__PURE__ */ jsx(
5
+ "label",
6
+ {
7
+ "data-slot": "label",
8
+ className: cn(
9
+ "nxui:flex nxui:items-center nxui:gap-2 nxui:text-body/relaxed nxui:leading-none nxui:font-medium nxui:select-none nxui:group-data-[disabled=true]:pointer-events-none nxui:group-data-[disabled=true]:opacity-50 nxui:peer-disabled:cursor-not-allowed nxui:peer-disabled:opacity-50",
10
+ className
11
+ ),
12
+ ...props
13
+ }
14
+ );
15
+ }
16
+ export {
17
+ LabelPrimitive
18
+ };
19
+ //# sourceMappingURL=label.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives/label.tsx"],"sourcesContent":["import { cn } from \"../lib/cn.js\"\n\n/** Internal label primitive (ported from nx-automations ui/label.tsx). */\nfunction LabelPrimitive({ className, ...props }: React.ComponentProps<\"label\">) {\n return (\n <label\n data-slot=\"label\"\n className={cn(\n \"nxui:flex nxui:items-center nxui:gap-2 nxui:text-body/relaxed nxui:leading-none nxui:font-medium nxui:select-none nxui:group-data-[disabled=true]:pointer-events-none nxui:group-data-[disabled=true]:opacity-50 nxui:peer-disabled:cursor-not-allowed nxui:peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { LabelPrimitive }\n"],"mappings":"AAKI;AALJ,SAAS,UAAU;AAGnB,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAkC;AAC9E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
@@ -0,0 +1,10 @@
1
+ import * as react from 'react';
2
+
3
+ /**
4
+ * Internal spinner primitive — accepts className because internal callers (Button's
5
+ * loading overlay) need exact placement/size control. Never exported publicly; the
6
+ * sealed surface is components/spinner.
7
+ */
8
+ declare function SpinnerPrimitive({ className, ...props }: React.ComponentProps<"svg">): react.JSX.Element;
9
+
10
+ export { SpinnerPrimitive };
@@ -0,0 +1,19 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { IconLoader } from "@tabler/icons-react";
3
+ import { cn } from "../lib/cn.js";
4
+ function SpinnerPrimitive({ className, ...props }) {
5
+ return /* @__PURE__ */ jsx(
6
+ IconLoader,
7
+ {
8
+ "data-slot": "spinner",
9
+ role: "status",
10
+ "aria-label": "Loading",
11
+ className: cn("nxui:size-4 nxui:animate-spin", className),
12
+ ...props
13
+ }
14
+ );
15
+ }
16
+ export {
17
+ SpinnerPrimitive
18
+ };
19
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives/spinner.tsx"],"sourcesContent":["import { IconLoader } from \"@tabler/icons-react\"\n\nimport { cn } from \"../lib/cn.js\"\n\n/**\n * Internal spinner primitive — accepts className because internal callers (Button's\n * loading overlay) need exact placement/size control. Never exported publicly; the\n * sealed surface is components/spinner.\n */\nfunction SpinnerPrimitive({ className, ...props }: React.ComponentProps<\"svg\">) {\n return (\n <IconLoader\n data-slot=\"spinner\"\n role=\"status\"\n aria-label=\"Loading\"\n className={cn(\"nxui:size-4 nxui:animate-spin\", className)}\n {...props}\n />\n )\n}\n\nexport { SpinnerPrimitive }\n"],"mappings":"AAWI;AAXJ,SAAS,kBAAkB;AAE3B,SAAS,UAAU;AAOnB,SAAS,iBAAiB,EAAE,WAAW,GAAG,MAAM,GAAgC;AAC9E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,cAAW;AAAA,MACX,WAAW,GAAG,iCAAiC,SAAS;AAAA,MACvD,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
@@ -0,0 +1,17 @@
1
+ import * as react from 'react';
2
+ import { Tooltip } from '@base-ui/react/tooltip';
3
+
4
+ /**
5
+ * Internal tooltip primitives (ported from nx-automations ui/tooltip.tsx).
6
+ * NEVER exported publicly: in this library a tooltip is a PROP on the component
7
+ * that needs one (e.g. <Button tooltip="...">), not a wrapper devs compose.
8
+ *
9
+ * House rules baked in (instead of asked of every call site like in
10
+ * nx-automations): delay 0 via a local provider, and disableHoverablePopup so
11
+ * the popup never traps the pointer.
12
+ */
13
+ declare function TooltipRoot({ ...props }: Tooltip.Root.Props): react.JSX.Element;
14
+ declare function TooltipTrigger({ ...props }: Tooltip.Trigger.Props): react.JSX.Element;
15
+ declare function TooltipContent({ className, side, sideOffset, align, alignOffset, children, ...props }: Tooltip.Popup.Props & Pick<Tooltip.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">): react.JSX.Element;
16
+
17
+ export { TooltipContent, TooltipRoot, TooltipTrigger };
@@ -0,0 +1,51 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
4
+ import { cn } from "../lib/cn.js";
5
+ function TooltipRoot({ ...props }) {
6
+ return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delay: 0, children: /* @__PURE__ */ jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", disableHoverablePopup: true, ...props }) });
7
+ }
8
+ function TooltipTrigger({ ...props }) {
9
+ return /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
10
+ }
11
+ function TooltipContent({
12
+ className,
13
+ side = "top",
14
+ sideOffset = 4,
15
+ align = "center",
16
+ alignOffset = 0,
17
+ children,
18
+ ...props
19
+ }) {
20
+ return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
21
+ TooltipPrimitive.Positioner,
22
+ {
23
+ align,
24
+ alignOffset,
25
+ side,
26
+ sideOffset,
27
+ className: "nxui:isolate nxui:z-50",
28
+ children: /* @__PURE__ */ jsxs(
29
+ TooltipPrimitive.Popup,
30
+ {
31
+ "data-slot": "tooltip-content",
32
+ className: cn(
33
+ "nxui:z-50 nxui:inline-flex nxui:w-fit nxui:max-w-xs nxui:origin-(--transform-origin) nxui:items-center nxui:gap-1.5 nxui:rounded-md nxui:bg-foreground nxui:px-3 nxui:py-1.5 nxui:text-body nxui:text-background nxui:data-[side=bottom]:slide-in-from-top-2 nxui:data-[side=inline-end]:slide-in-from-left-2 nxui:data-[side=inline-start]:slide-in-from-right-2 nxui:data-[side=left]:slide-in-from-right-2 nxui:data-[side=right]:slide-in-from-left-2 nxui:data-[side=top]:slide-in-from-bottom-2 nxui:data-[state=delayed-open]:animate-in nxui:data-[state=delayed-open]:fade-in-0 nxui:data-[state=delayed-open]:zoom-in-95 nxui:data-open:animate-in nxui:data-open:fade-in-0 nxui:data-open:zoom-in-95 nxui:data-closed:animate-out nxui:data-closed:fade-out-0 nxui:data-closed:zoom-out-95",
34
+ className
35
+ ),
36
+ ...props,
37
+ children: [
38
+ children,
39
+ /* @__PURE__ */ jsx(TooltipPrimitive.Arrow, { className: "nxui:z-50 nxui:size-2.5 nxui:translate-y-[calc(-50%-2px)] nxui:rotate-45 nxui:rounded-[2px] nxui:bg-foreground nxui:fill-foreground nxui:data-[side=bottom]:top-1 nxui:data-[side=inline-end]:top-1/2! nxui:data-[side=inline-end]:-left-1 nxui:data-[side=inline-end]:-translate-y-1/2 nxui:data-[side=inline-start]:top-1/2! nxui:data-[side=inline-start]:-right-1 nxui:data-[side=inline-start]:-translate-y-1/2 nxui:data-[side=left]:top-1/2! nxui:data-[side=left]:-right-1 nxui:data-[side=left]:-translate-y-1/2 nxui:data-[side=right]:top-1/2! nxui:data-[side=right]:-left-1 nxui:data-[side=right]:-translate-y-1/2 nxui:data-[side=top]:-bottom-2.5" })
40
+ ]
41
+ }
42
+ )
43
+ }
44
+ ) });
45
+ }
46
+ export {
47
+ TooltipContent,
48
+ TooltipRoot,
49
+ TooltipTrigger
50
+ };
51
+ //# sourceMappingURL=tooltip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/primitives/tooltip.tsx"],"sourcesContent":["\"use client\"\n\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\"\n\nimport { cn } from \"../lib/cn.js\"\n\n/**\n * Internal tooltip primitives (ported from nx-automations ui/tooltip.tsx).\n * NEVER exported publicly: in this library a tooltip is a PROP on the component\n * that needs one (e.g. <Button tooltip=\"...\">), not a wrapper devs compose.\n *\n * House rules baked in (instead of asked of every call site like in\n * nx-automations): delay 0 via a local provider, and disableHoverablePopup so\n * the popup never traps the pointer.\n */\n\nfunction TooltipRoot({ ...props }: TooltipPrimitive.Root.Props) {\n return (\n <TooltipPrimitive.Provider delay={0}>\n <TooltipPrimitive.Root data-slot=\"tooltip\" disableHoverablePopup {...props} />\n </TooltipPrimitive.Provider>\n )\n}\n\nfunction TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n className,\n side = \"top\",\n sideOffset = 4,\n align = \"center\",\n alignOffset = 0,\n children,\n ...props\n}: TooltipPrimitive.Popup.Props &\n Pick<TooltipPrimitive.Positioner.Props, \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\">) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n className=\"nxui:isolate nxui:z-50\"\n >\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n className={cn(\n \"nxui:z-50 nxui:inline-flex nxui:w-fit nxui:max-w-xs nxui:origin-(--transform-origin) nxui:items-center nxui:gap-1.5 nxui:rounded-md nxui:bg-foreground nxui:px-3 nxui:py-1.5 nxui:text-body nxui:text-background nxui:data-[side=bottom]:slide-in-from-top-2 nxui:data-[side=inline-end]:slide-in-from-left-2 nxui:data-[side=inline-start]:slide-in-from-right-2 nxui:data-[side=left]:slide-in-from-right-2 nxui:data-[side=right]:slide-in-from-left-2 nxui:data-[side=top]:slide-in-from-bottom-2 nxui:data-[state=delayed-open]:animate-in nxui:data-[state=delayed-open]:fade-in-0 nxui:data-[state=delayed-open]:zoom-in-95 nxui:data-open:animate-in nxui:data-open:fade-in-0 nxui:data-open:zoom-in-95 nxui:data-closed:animate-out nxui:data-closed:fade-out-0 nxui:data-closed:zoom-out-95\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"nxui:z-50 nxui:size-2.5 nxui:translate-y-[calc(-50%-2px)] nxui:rotate-45 nxui:rounded-[2px] nxui:bg-foreground nxui:fill-foreground nxui:data-[side=bottom]:top-1 nxui:data-[side=inline-end]:top-1/2! nxui:data-[side=inline-end]:-left-1 nxui:data-[side=inline-end]:-translate-y-1/2 nxui:data-[side=inline-start]:top-1/2! nxui:data-[side=inline-start]:-right-1 nxui:data-[side=inline-start]:-translate-y-1/2 nxui:data-[side=left]:top-1/2! nxui:data-[side=left]:-right-1 nxui:data-[side=left]:-translate-y-1/2 nxui:data-[side=right]:top-1/2! nxui:data-[side=right]:-left-1 nxui:data-[side=right]:-translate-y-1/2 nxui:data-[side=top]:-bottom-2.5\" />\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { TooltipRoot, TooltipTrigger, TooltipContent }\n"],"mappings":";AAmBM,cA4BE,YA5BF;AAjBN,SAAS,WAAW,wBAAwB;AAE5C,SAAS,UAAU;AAYnB,SAAS,YAAY,EAAE,GAAG,MAAM,GAAgC;AAC9D,SACE,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,GAChC,8BAAC,iBAAiB,MAAjB,EAAsB,aAAU,WAAU,uBAAqB,MAAE,GAAG,OAAO,GAC9E;AAEJ;AAEA,SAAS,eAAe,EAAE,GAAG,MAAM,GAAmC;AACpE,SAAO,oBAAC,iBAAiB,SAAjB,EAAyB,aAAU,mBAAmB,GAAG,OAAO;AAC1E;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,cAAc;AAAA,EACd;AAAA,EACA,GAAG;AACL,GAC4F;AAC1F,SACE,oBAAC,iBAAiB,QAAjB,EACC;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MAEV;AAAA,QAAC,iBAAiB;AAAA,QAAjB;AAAA,UACC,aAAU;AAAA,UACV,WAAW;AAAA,YACT;AAAA,YACA;AAAA,UACF;AAAA,UACC,GAAG;AAAA,UAEH;AAAA;AAAA,YACD,oBAAC,iBAAiB,OAAjB,EAAuB,WAAU,qoBAAooB;AAAA;AAAA;AAAA,MACxqB;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.1.11 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0}}}@layer nx-theme{:root,:host{--nxui-spacing:.25rem;--nxui-container-xs:20rem;--nxui-font-weight-normal:400;--nxui-font-weight-medium:500;--nxui-leading-snug:1.375;--nxui-leading-relaxed:1.625;--nxui-animate-spin:spin 1s linear infinite;--nxui-default-transition-duration:.15s;--nxui-default-transition-timing-function:cubic-bezier(.4,0,.2,1)}}@layer nx-base;@layer nx-utilities{.nxui\:pointer-events-none{pointer-events:none}.nxui\:invisible{visibility:hidden}.nxui\:absolute{position:absolute}.nxui\:relative{position:relative}.nxui\:inset-0{inset:calc(var(--nxui-spacing)*0)}.nxui\:top-1\/2{top:50%}.nxui\:right-2{right:calc(var(--nxui-spacing)*2)}.nxui\:isolate{isolation:isolate}.nxui\:z-50{z-index:50}.nxui\:order-first{order:-9999}.nxui\:order-last{order:9999}.nxui\:m-0\.5{margin:calc(var(--nxui-spacing)*.5)}.nxui\:m-auto{margin:auto}.nxui\:ml-4{margin-left:calc(var(--nxui-spacing)*4)}.nxui\:contents{display:contents}.nxui\:flex{display:flex}.nxui\:inline-flex{display:inline-flex}.nxui\:size-2\.5{width:calc(var(--nxui-spacing)*2.5);height:calc(var(--nxui-spacing)*2.5)}.nxui\:size-3{width:calc(var(--nxui-spacing)*3);height:calc(var(--nxui-spacing)*3)}.nxui\:size-3\.5{width:calc(var(--nxui-spacing)*3.5);height:calc(var(--nxui-spacing)*3.5)}.nxui\:size-4{width:calc(var(--nxui-spacing)*4);height:calc(var(--nxui-spacing)*4)}.nxui\:size-control-lg{width:var(--nx-control-lg);height:var(--nx-control-lg)}.nxui\:size-control-md{width:var(--nx-control-md);height:var(--nx-control-md)}.nxui\:size-control-sm{width:var(--nx-control-sm);height:var(--nx-control-sm)}.nxui\:size-control-xs{width:var(--nx-control-xs);height:var(--nx-control-xs)}.nxui\:h-auto{height:auto}.nxui\:h-control-lg{height:var(--nx-control-lg)}.nxui\:h-control-md{height:var(--nx-control-md)}.nxui\:h-control-sm{height:var(--nx-control-sm)}.nxui\:h-control-xs{height:var(--nx-control-xs)}.nxui\:w-fit{width:fit-content}.nxui\:w-full{width:100%}.nxui\:max-w-xs{max-width:var(--nxui-container-xs)}.nxui\:min-w-0{min-width:calc(var(--nxui-spacing)*0)}.nxui\:flex-1{flex:1}.nxui\:shrink-0{flex-shrink:0}.nxui\:origin-\(--transform-origin\){transform-origin:var(--transform-origin)}.nxui\:-translate-y-1\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.nxui\:translate-y-\[calc\(-50\%-2px\)\]{--tw-translate-y:calc(-50% - 2px);translate:var(--tw-translate-x)var(--tw-translate-y)}.nxui\:rotate-45{rotate:45deg}.nxui\:animate-spin{animation:var(--nxui-animate-spin)}.nxui\:cursor-text{cursor:text}.nxui\:list-disc{list-style-type:disc}.nxui\:flex-col{flex-direction:column}.nxui\:items-center{align-items:center}.nxui\:justify-center{justify-content:center}.nxui\:gap-1{gap:calc(var(--nxui-spacing)*1)}.nxui\:gap-1\.5{gap:calc(var(--nxui-spacing)*1.5)}.nxui\:gap-2{gap:calc(var(--nxui-spacing)*2)}.nxui\:rounded-\[2px\]{border-radius:2px}.nxui\:rounded-md{border-radius:calc(var(--nx-radius)*.8)}.nxui\:rounded-none{border-radius:0}.nxui\:rounded-sm{border-radius:calc(var(--nx-radius)*.6)}.nxui\:border{border-style:var(--tw-border-style);border-width:1px}.nxui\:border-0{border-style:var(--tw-border-style);border-width:0}.nxui\:border-border{border-color:var(--nx-border)}.nxui\:border-input{border-color:var(--nx-input)}.nxui\:border-transparent{border-color:#0000}.nxui\:bg-background{background-color:var(--nx-background)}.nxui\:bg-destructive\/10{background-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:bg-destructive\/10{background-color:color-mix(in oklab,var(--nx-destructive)10%,transparent)}}.nxui\:bg-foreground{background-color:var(--nx-foreground)}.nxui\:bg-input\/20{background-color:var(--nx-input)}@supports (color:color-mix(in lab, red, red)){.nxui\:bg-input\/20{background-color:color-mix(in oklab,var(--nx-input)20%,transparent)}}.nxui\:bg-primary{background-color:var(--nx-primary)}.nxui\:bg-secondary{background-color:var(--nx-secondary)}.nxui\:bg-transparent{background-color:#0000}.nxui\:bg-clip-padding{background-clip:padding-box}.nxui\:fill-foreground{fill:var(--nx-foreground)}.nxui\:px-2{padding-inline:calc(var(--nxui-spacing)*2)}.nxui\:px-2\.5{padding-inline:calc(var(--nxui-spacing)*2.5)}.nxui\:px-3{padding-inline:calc(var(--nxui-spacing)*3)}.nxui\:py-0\.5{padding-block:calc(var(--nxui-spacing)*.5)}.nxui\:py-1\.5{padding-block:calc(var(--nxui-spacing)*1.5)}.nxui\:py-2{padding-block:calc(var(--nxui-spacing)*2)}.nxui\:pr-2{padding-right:calc(var(--nxui-spacing)*2)}.nxui\:pr-8{padding-right:calc(var(--nxui-spacing)*8)}.nxui\:pr-12{padding-right:calc(var(--nxui-spacing)*12)}.nxui\:pl-2{padding-left:calc(var(--nxui-spacing)*2)}.nxui\:text-left{text-align:left}.nxui\:text-body\/relaxed{font-size:var(--nx-text-md);line-height:var(--nxui-leading-relaxed)}.nxui\:text-body{font-size:var(--nx-text-md)}.nxui\:text-body-lg{font-size:var(--nx-text-lg)}.nxui\:text-body-xs{font-size:var(--nx-text-xs)}.nxui\:leading-none{--tw-leading:1;line-height:1}.nxui\:leading-snug{--tw-leading:var(--nxui-leading-snug);line-height:var(--nxui-leading-snug)}.nxui\:font-medium{--tw-font-weight:var(--nxui-font-weight-medium);font-weight:var(--nxui-font-weight-medium)}.nxui\:font-normal{--tw-font-weight:var(--nxui-font-weight-normal);font-weight:var(--nxui-font-weight-normal)}.nxui\:whitespace-nowrap{white-space:nowrap}.nxui\:text-background{color:var(--nx-background)}.nxui\:text-destructive{color:var(--nx-destructive)}.nxui\:text-muted-foreground{color:var(--nx-muted-foreground)}.nxui\:text-primary{color:var(--nx-primary)}.nxui\:text-primary-foreground{color:var(--nx-primary-foreground)}.nxui\:text-secondary-foreground{color:var(--nx-secondary-foreground)}.nxui\:underline{text-decoration-line:underline}.nxui\:decoration-dotted{text-decoration-style:dotted}.nxui\:underline-offset-4{text-underline-offset:4px}.nxui\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.nxui\:ring-0{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.nxui\:transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--nxui-default-transition-timing-function));transition-duration:var(--tw-duration,var(--nxui-default-transition-duration))}.nxui\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--nxui-default-transition-timing-function));transition-duration:var(--tw-duration,var(--nxui-default-transition-duration))}.nxui\:outline-none{--tw-outline-style:none;outline-style:none}.nxui\:select-none{-webkit-user-select:none;user-select:none}:is(.nxui\:\*\:w-full>*){width:100%}.nxui\:group-data-\[disabled\=true\]\:pointer-events-none:is(:where(.nxui\:group)[data-disabled=true] *){pointer-events:none}.nxui\:group-data-\[disabled\=true\]\:opacity-50:is(:where(.nxui\:group)[data-disabled=true] *),.nxui\:group-data-\[disabled\=true\]\/field\:opacity-50:is(:where(.nxui\:group\/field)[data-disabled=true] *),.nxui\:group-data-\[disabled\=true\]\/input-group\:opacity-50:is(:where(.nxui\:group\/input-group)[data-disabled=true] *){opacity:.5}.nxui\:peer-disabled\:cursor-not-allowed:is(:where(.nxui\:peer):disabled~*){cursor:not-allowed}.nxui\:peer-disabled\:opacity-50:is(:where(.nxui\:peer):disabled~*){opacity:.5}.nxui\:file\:inline-flex::file-selector-button{display:inline-flex}.nxui\:file\:h-control-sm::file-selector-button{height:var(--nx-control-sm)}.nxui\:file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.nxui\:file\:bg-transparent::file-selector-button{background-color:#0000}.nxui\:file\:text-body\/relaxed::file-selector-button{font-size:var(--nx-text-md);line-height:var(--nxui-leading-relaxed)}.nxui\:file\:font-medium::file-selector-button{--tw-font-weight:var(--nxui-font-weight-medium);font-weight:var(--nxui-font-weight-medium)}.nxui\:file\:text-foreground::file-selector-button{color:var(--nx-foreground)}.nxui\:placeholder\:text-muted-foreground::placeholder{color:var(--nx-muted-foreground)}@media (hover:hover){.nxui\:hover\:bg-\[color-mix\(in_oklch\,var\(--nx-secondary\)\,var\(--nx-foreground\)_5\%\)\]:hover{background-color:var(--nx-secondary)}@supports (color:color-mix(in lab, red, red)){.nxui\:hover\:bg-\[color-mix\(in_oklch\,var\(--nx-secondary\)\,var\(--nx-foreground\)_5\%\)\]:hover{background-color:color-mix(in oklch,var(--nx-secondary),var(--nx-foreground)5%)}}.nxui\:hover\:bg-destructive\/20:hover{background-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:hover\:bg-destructive\/20:hover{background-color:color-mix(in oklab,var(--nx-destructive)20%,transparent)}}.nxui\:hover\:bg-input\/50:hover{background-color:var(--nx-input)}@supports (color:color-mix(in lab, red, red)){.nxui\:hover\:bg-input\/50:hover{background-color:color-mix(in oklab,var(--nx-input)50%,transparent)}}.nxui\:hover\:bg-muted:hover{background-color:var(--nx-muted)}.nxui\:hover\:bg-primary\/80:hover{background-color:var(--nx-primary)}@supports (color:color-mix(in lab, red, red)){.nxui\:hover\:bg-primary\/80:hover{background-color:color-mix(in oklab,var(--nx-primary)80%,transparent)}}.nxui\:hover\:text-foreground:hover{color:var(--nx-foreground)}.nxui\:hover\:underline:hover{text-decoration-line:underline}}.nxui\:focus-visible\:border-destructive\/40:focus-visible{border-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:focus-visible\:border-destructive\/40:focus-visible{border-color:color-mix(in oklab,var(--nx-destructive)40%,transparent)}}.nxui\:focus-visible\:border-ring:focus-visible{border-color:var(--nx-ring)}.nxui\:focus-visible\:ring-0:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.nxui\:focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.nxui\:focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:color-mix(in oklab,var(--nx-destructive)20%,transparent)}}.nxui\:focus-visible\:ring-ring\/30:focus-visible{--tw-ring-color:var(--nx-ring)}@supports (color:color-mix(in lab, red, red)){.nxui\:focus-visible\:ring-ring\/30:focus-visible{--tw-ring-color:color-mix(in oklab,var(--nx-ring)30%,transparent)}}.nxui\:active\:not-aria-\[haspopup\]\:translate-y-px:active:not([aria-haspopup]){--tw-translate-y:1px;translate:var(--tw-translate-x)var(--tw-translate-y)}.nxui\:disabled\:pointer-events-none:disabled{pointer-events:none}.nxui\:disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.nxui\:disabled\:opacity-50:disabled{opacity:.5}.nxui\:has-data-\[icon\=inline-end\]\:pr-1\.5:has([data-icon=inline-end]){padding-right:calc(var(--nxui-spacing)*1.5)}.nxui\:has-data-\[icon\=inline-end\]\:pr-2:has([data-icon=inline-end]){padding-right:calc(var(--nxui-spacing)*2)}.nxui\:has-data-\[icon\=inline-start\]\:pl-1\.5:has([data-icon=inline-start]){padding-left:calc(var(--nxui-spacing)*1.5)}.nxui\:has-data-\[icon\=inline-start\]\:pl-2:has([data-icon=inline-start]){padding-left:calc(var(--nxui-spacing)*2)}.nxui\:has-\[\[data-slot\=input-group-control\]\:focus-visible\]\:border-ring:has([data-slot=input-group-control]:focus-visible){border-color:var(--nx-ring)}.nxui\:has-\[\[data-slot\=input-group-control\]\:focus-visible\]\:ring-2:has([data-slot=input-group-control]:focus-visible){--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.nxui\:has-\[\[data-slot\=input-group-control\]\:focus-visible\]\:ring-ring\/30:has([data-slot=input-group-control]:focus-visible){--tw-ring-color:var(--nx-ring)}@supports (color:color-mix(in lab, red, red)){.nxui\:has-\[\[data-slot\=input-group-control\]\:focus-visible\]\:ring-ring\/30:has([data-slot=input-group-control]:focus-visible){--tw-ring-color:color-mix(in oklab,var(--nx-ring)30%,transparent)}}.nxui\:has-\[\[data-slot\]\[aria-invalid\=true\]\]\:border-destructive:has([data-slot][aria-invalid=true]){border-color:var(--nx-destructive)}.nxui\:has-\[\[data-slot\]\[aria-invalid\=true\]\]\:ring-2:has([data-slot][aria-invalid=true]){--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.nxui\:has-\[\[data-slot\]\[aria-invalid\=true\]\]\:ring-destructive\/20:has([data-slot][aria-invalid=true]){--tw-ring-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:has-\[\[data-slot\]\[aria-invalid\=true\]\]\:ring-destructive\/20:has([data-slot][aria-invalid=true]){--tw-ring-color:color-mix(in oklab,var(--nx-destructive)20%,transparent)}}.nxui\:aria-expanded\:bg-muted[aria-expanded=true]{background-color:var(--nx-muted)}.nxui\:aria-expanded\:bg-secondary[aria-expanded=true]{background-color:var(--nx-secondary)}.nxui\:aria-expanded\:text-foreground[aria-expanded=true]{color:var(--nx-foreground)}.nxui\:aria-expanded\:text-secondary-foreground[aria-expanded=true]{color:var(--nx-secondary-foreground)}.nxui\:aria-invalid\:border-destructive[aria-invalid=true]{border-color:var(--nx-destructive)}.nxui\:aria-invalid\:ring-0[aria-invalid=true]{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.nxui\:aria-invalid\:ring-2[aria-invalid=true]{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.nxui\:aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--nx-destructive)20%,transparent)}}.nxui\:data-closed\:animate-out[data-closed]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.nxui\:data-closed\:fade-out-0[data-closed]{--tw-exit-opacity:0}.nxui\:data-closed\:zoom-out-95[data-closed]{--tw-exit-scale:.95}.nxui\:data-open\:animate-in[data-open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.nxui\:data-open\:fade-in-0[data-open]{--tw-enter-opacity:0}.nxui\:data-open\:zoom-in-95[data-open]{--tw-enter-scale:.95}.nxui\:data-\[invalid\=true\]\:text-destructive[data-invalid=true]{color:var(--nx-destructive)}.nxui\:data-\[side\=bottom\]\:top-1[data-side=bottom]{top:calc(var(--nxui-spacing)*1)}.nxui\:data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:calc(2*var(--spacing)*-1)}.nxui\:data-\[side\=inline-end\]\:top-1\/2\![data-side=inline-end]{top:50%!important}.nxui\:data-\[side\=inline-end\]\:-left-1[data-side=inline-end]{left:calc(var(--nxui-spacing)*-1)}.nxui\:data-\[side\=inline-end\]\:-translate-y-1\/2[data-side=inline-end]{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.nxui\:data-\[side\=inline-end\]\:slide-in-from-left-2[data-side=inline-end]{--tw-enter-translate-x:calc(2*var(--spacing)*-1)}.nxui\:data-\[side\=inline-start\]\:top-1\/2\![data-side=inline-start]{top:50%!important}.nxui\:data-\[side\=inline-start\]\:-right-1[data-side=inline-start]{right:calc(var(--nxui-spacing)*-1)}.nxui\:data-\[side\=inline-start\]\:-translate-y-1\/2[data-side=inline-start]{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.nxui\:data-\[side\=inline-start\]\:slide-in-from-right-2[data-side=inline-start]{--tw-enter-translate-x:calc(2*var(--spacing))}.nxui\:data-\[side\=left\]\:top-1\/2\![data-side=left]{top:50%!important}.nxui\:data-\[side\=left\]\:-right-1[data-side=left]{right:calc(var(--nxui-spacing)*-1)}.nxui\:data-\[side\=left\]\:-translate-y-1\/2[data-side=left]{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.nxui\:data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:calc(2*var(--spacing))}.nxui\:data-\[side\=right\]\:top-1\/2\![data-side=right]{top:50%!important}.nxui\:data-\[side\=right\]\:-left-1[data-side=right]{left:calc(var(--nxui-spacing)*-1)}.nxui\:data-\[side\=right\]\:-translate-y-1\/2[data-side=right]{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.nxui\:data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:calc(2*var(--spacing)*-1)}.nxui\:data-\[side\=top\]\:-bottom-2\.5[data-side=top]{bottom:calc(var(--nxui-spacing)*-2.5)}.nxui\:data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:calc(2*var(--spacing))}.nxui\:data-\[state\=delayed-open\]\:animate-in[data-state=delayed-open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.nxui\:data-\[state\=delayed-open\]\:fade-in-0[data-state=delayed-open]{--tw-enter-opacity:0}.nxui\:data-\[state\=delayed-open\]\:zoom-in-95[data-state=delayed-open]{--tw-enter-scale:.95}@media (min-width:48rem){.nxui\:md\:text-body\/relaxed{font-size:var(--nx-text-md);line-height:var(--nxui-leading-relaxed)}}.nxui\:dark\:bg-destructive\/20:is(.dark *,[data-theme=dark] *){background-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:dark\:bg-destructive\/20:is(.dark *,[data-theme=dark] *){background-color:color-mix(in oklab,var(--nx-destructive)20%,transparent)}}.nxui\:dark\:bg-input\/30:is(.dark *,[data-theme=dark] *){background-color:var(--nx-input)}@supports (color:color-mix(in lab, red, red)){.nxui\:dark\:bg-input\/30:is(.dark *,[data-theme=dark] *){background-color:color-mix(in oklab,var(--nx-input)30%,transparent)}}.nxui\:dark\:bg-transparent:is(.dark *,[data-theme=dark] *){background-color:#0000}@media (hover:hover){.nxui\:dark\:hover\:bg-destructive\/30:is(.dark *,[data-theme=dark] *):hover{background-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:dark\:hover\:bg-destructive\/30:is(.dark *,[data-theme=dark] *):hover{background-color:color-mix(in oklab,var(--nx-destructive)30%,transparent)}}.nxui\:dark\:hover\:bg-muted\/50:is(.dark *,[data-theme=dark] *):hover{background-color:var(--nx-muted)}@supports (color:color-mix(in lab, red, red)){.nxui\:dark\:hover\:bg-muted\/50:is(.dark *,[data-theme=dark] *):hover{background-color:color-mix(in oklab,var(--nx-muted)50%,transparent)}}}.nxui\:dark\:focus-visible\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):focus-visible{--tw-ring-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:dark\:focus-visible\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):focus-visible{--tw-ring-color:color-mix(in oklab,var(--nx-destructive)40%,transparent)}}.nxui\:dark\:has-\[\[data-slot\]\[aria-invalid\=true\]\]\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):has([data-slot][aria-invalid=true]){--tw-ring-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:dark\:has-\[\[data-slot\]\[aria-invalid\=true\]\]\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):has([data-slot][aria-invalid=true]){--tw-ring-color:color-mix(in oklab,var(--nx-destructive)40%,transparent)}}.nxui\:dark\:aria-invalid\:border-destructive\/50:is(.dark *,[data-theme=dark] *)[aria-invalid=true]{border-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:dark\:aria-invalid\:border-destructive\/50:is(.dark *,[data-theme=dark] *)[aria-invalid=true]{border-color:color-mix(in oklab,var(--nx-destructive)50%,transparent)}}.nxui\:dark\:aria-invalid\:ring-destructive\/40:is(.dark *,[data-theme=dark] *)[aria-invalid=true]{--tw-ring-color:var(--nx-destructive)}@supports (color:color-mix(in lab, red, red)){.nxui\:dark\:aria-invalid\:ring-destructive\/40:is(.dark *,[data-theme=dark] *)[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--nx-destructive)40%,transparent)}}.nxui\:\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.nxui\:\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.nxui\:\[\&_svg\:not\(\[class\*\=size-\]\)\]\:size-2\.5 svg:not([class*=size-]){width:calc(var(--nxui-spacing)*2.5);height:calc(var(--nxui-spacing)*2.5)}.nxui\:\[\&_svg\:not\(\[class\*\=size-\]\)\]\:size-3 svg:not([class*=size-]){width:calc(var(--nxui-spacing)*3);height:calc(var(--nxui-spacing)*3)}.nxui\:\[\&_svg\:not\(\[class\*\=size-\]\)\]\:size-3\.5 svg:not([class*=size-]){width:calc(var(--nxui-spacing)*3.5);height:calc(var(--nxui-spacing)*3.5)}.nxui\:\[\&_svg\:not\(\[class\*\=size-\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--nxui-spacing)*4);height:calc(var(--nxui-spacing)*4)}.nxui\:\[\&\>\.sr-only\]\:w-auto>.sr-only{width:auto}.nxui\:has-\[\>\[data-align\=inline-end\]\]\:\[\&\>input\]\:pr-1\.5:has(>[data-align=inline-end])>input{padding-right:calc(var(--nxui-spacing)*1.5)}.nxui\:has-\[\>\[data-align\=inline-start\]\]\:\[\&\>input\]\:pl-1\.5:has(>[data-align=inline-start])>input{padding-left:calc(var(--nxui-spacing)*1.5)}.nxui\:\[\&\>svg\:not\(\[class\*\=size-\]\)\]\:size-3\.5>svg:not([class*=size-]){width:calc(var(--nxui-spacing)*3.5);height:calc(var(--nxui-spacing)*3.5)}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@keyframes spin{to{transform:rotate(360deg)}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}