@cystackapp/ui 1.4.1 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/badge/Badge.js +3 -3
- package/dist/components/badge/variants/BadgeTag.js +1 -1
- package/dist/components/button/Button.d.ts +21 -0
- package/dist/components/button/Button.js +49 -0
- package/dist/components/button/ButtonLoader.d.ts +7 -0
- package/dist/components/button/ButtonLoader.js +44 -0
- package/dist/components/button/ButtonTestStory.d.ts +5 -0
- package/dist/components/button/button-variants.d.ts +13 -0
- package/dist/components/button/button-variants.js +58 -0
- package/dist/components/card/Card.d.ts +91 -0
- package/dist/components/card/Card.js +56 -0
- package/dist/components/card/Card.stories-ct.d.ts +1 -0
- package/dist/components/card/CardBody.d.ts +9 -0
- package/dist/components/card/CardBody.js +16 -0
- package/dist/components/card/CardHeader.d.ts +15 -0
- package/dist/components/card/CardHeader.js +79 -0
- package/dist/components/card/types.d.ts +1 -0
- package/dist/components/checkbox/Checkbox.d.ts +6 -0
- package/dist/components/checkbox/Checkbox.js +72 -0
- package/dist/components/checkbox/CheckboxTestStory.d.ts +7 -0
- package/dist/components/collapsible/Collapsible.d.ts +21 -0
- package/dist/components/collapsible/Collapsible.js +50 -0
- package/dist/components/input/Input.d.ts +11 -0
- package/dist/components/input/Input.js +39 -0
- package/dist/components/modal/Modal.d.ts +9 -0
- package/dist/components/modal/Modal.js +68 -0
- package/dist/components/modal/helpers/HeaderIcon.d.ts +8 -0
- package/dist/components/modal/helpers/HeaderIcon.js +32 -0
- package/dist/components/modal/helpers/Title.d.ts +6 -0
- package/dist/components/modal/helpers/Title.js +9 -0
- package/dist/components/modal/helpers/circles-sm.svg.js +5 -0
- package/dist/components/modal/modal-context.d.ts +2 -0
- package/dist/components/modal/modal-context.js +9 -0
- package/dist/components/modal/use-click-outside-modal.d.ts +2 -0
- package/dist/components/modal/use-click-outside-modal.js +15 -0
- package/dist/components/toast/ToastSlice.d.ts +11 -0
- package/dist/components/toast/ToastSlice.js +103 -0
- package/dist/components/toast/icons.d.ts +8 -0
- package/dist/components/toast/icons.js +19 -0
- package/dist/components/toast/index.d.ts +4 -0
- package/dist/components/toast/index.js +35 -0
- package/dist/components/toast/types.d.ts +14 -0
- package/dist/components/toast/use-toast-list.d.ts +4 -0
- package/dist/components/toast/use-toast-list.js +27 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +55 -34
- package/dist/test-utils/expect-visibility.d.ts +45 -0
- package/dist/utils/observable.d.ts +7 -0
- package/dist/utils/observable.js +22 -0
- package/package.json +3 -2
- package/theme.css +3 -0
|
@@ -4,7 +4,7 @@ import { XClose as k } from "@untitled-ui/icons-react";
|
|
|
4
4
|
import { cn as u } from "../../utils/cn.js";
|
|
5
5
|
import { Tooltip as B } from "../tooltip/Tooltip.js";
|
|
6
6
|
import { useResizeObserver as R } from "../../hooks/element-shift/use-resize-observer.js";
|
|
7
|
-
import {
|
|
7
|
+
import { BADGE_DOT_CLASSES as T, BADGE_ICON_SIZE_CLASSES as h, BADGE_MODERN_TEXT_CLASSES as w, BADGE_COLOR_CLASSES as G, BADGE_SIZE_CLASSES as O, BADGE_TYPE_CLASSES as v } from "./badge-utils.js";
|
|
8
8
|
const X = ({
|
|
9
9
|
children: t,
|
|
10
10
|
color: o = "gray",
|
|
@@ -41,7 +41,7 @@ const X = ({
|
|
|
41
41
|
{
|
|
42
42
|
className: u(
|
|
43
43
|
"size-1.5 rounded-full shrink-0",
|
|
44
|
-
|
|
44
|
+
T[o]
|
|
45
45
|
)
|
|
46
46
|
}
|
|
47
47
|
) : null,
|
|
@@ -55,7 +55,7 @@ const X = ({
|
|
|
55
55
|
"aria-label": typeof t == "string" ? `Remove ${t}` : "Remove",
|
|
56
56
|
onClick: m,
|
|
57
57
|
className: "shrink-0 cursor-pointer rounded-full p-0 hover:opacity-70 transition-opacity",
|
|
58
|
-
children: /* @__PURE__ */ e(k, { className:
|
|
58
|
+
children: /* @__PURE__ */ e(k, { className: h[a] })
|
|
59
59
|
}
|
|
60
60
|
) : null
|
|
61
61
|
]
|
|
@@ -2,7 +2,7 @@ import { jsx as o } from "react/jsx-runtime";
|
|
|
2
2
|
import { Tag01 as g } from "@untitled-ui/icons-react";
|
|
3
3
|
import { cn as i } from "../../../utils/cn.js";
|
|
4
4
|
import { Badge as c } from "../Badge.js";
|
|
5
|
-
import {
|
|
5
|
+
import { BADGE_ICON_SIZE_CLASSES as l, BADGE_COLORS as n } from "../badge-utils.js";
|
|
6
6
|
function u(t) {
|
|
7
7
|
const r = Array.from(t).reduce(
|
|
8
8
|
(e, a) => e + a.charCodeAt(0),
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ButtonHTMLAttributes } from 'react';
|
|
2
|
+
import { ButtonColor, ButtonLoadingStyle, ButtonSize, ButtonVariant } from './button-variants';
|
|
3
|
+
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
4
|
+
variant?: ButtonVariant;
|
|
5
|
+
color?: ButtonColor;
|
|
6
|
+
size?: ButtonSize;
|
|
7
|
+
/** Show a loading spinner and disable the button. */
|
|
8
|
+
pending?: boolean;
|
|
9
|
+
/** How the spinner is positioned relative to the button label. */
|
|
10
|
+
loadingStyle?: ButtonLoadingStyle;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* @example With icon — size-4 for sm/md, size-5 for lg
|
|
14
|
+
* ```tsx
|
|
15
|
+
* <Button size="md">
|
|
16
|
+
* <Plus className="size-4" />
|
|
17
|
+
* New item
|
|
18
|
+
* </Button>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare const Button: import('react').ForwardRefExoticComponent<ButtonProps & import('react').RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx as t, jsxs as a, Fragment as d } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as f } from "react";
|
|
3
|
+
import { cn as u } from "../../utils/cn.js";
|
|
4
|
+
import { VARIANT_DISABLED_CLASSES as c, VARIANT_COLOR_CLASSES as _, PADDING_CLASSES as p, TEXT_SIZE_CLASSES as E, COLOR_FOCUS_CLASSES as L, VARIANT_BASE_CLASSES as C } from "./button-variants.js";
|
|
5
|
+
import { ButtonLoader as N } from "./ButtonLoader.js";
|
|
6
|
+
const b = f(
|
|
7
|
+
({
|
|
8
|
+
variant: o = "primary",
|
|
9
|
+
color: e = "blue-dark",
|
|
10
|
+
size: r = "md",
|
|
11
|
+
loadingStyle: s = "inline",
|
|
12
|
+
pending: S,
|
|
13
|
+
disabled: n,
|
|
14
|
+
className: m,
|
|
15
|
+
children: i,
|
|
16
|
+
...l
|
|
17
|
+
}, A) => /* @__PURE__ */ t(
|
|
18
|
+
"button",
|
|
19
|
+
{
|
|
20
|
+
ref: A,
|
|
21
|
+
disabled: S || n,
|
|
22
|
+
className: u(
|
|
23
|
+
"relative inline-flex items-center justify-center gap-1.5 rounded-lg font-semibold transition-colors focus:outline-offset-2 cursor-pointer disabled:cursor-not-allowed",
|
|
24
|
+
C[o],
|
|
25
|
+
L[e],
|
|
26
|
+
E[r],
|
|
27
|
+
o !== "tertiary" ? p[r] : void 0,
|
|
28
|
+
_[`${o}-${e}`],
|
|
29
|
+
c[o],
|
|
30
|
+
m
|
|
31
|
+
),
|
|
32
|
+
...l,
|
|
33
|
+
children: S ? /* @__PURE__ */ a(d, { children: [
|
|
34
|
+
/* @__PURE__ */ t(N, { size: r, loadingStyle: s }),
|
|
35
|
+
/* @__PURE__ */ t(
|
|
36
|
+
"span",
|
|
37
|
+
{
|
|
38
|
+
className: s === "overlay" ? "invisible" : "contents",
|
|
39
|
+
children: i
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
] }) : i
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
);
|
|
46
|
+
b.displayName = "Button";
|
|
47
|
+
export {
|
|
48
|
+
b as Button
|
|
49
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ButtonLoadingStyle, ButtonSize } from './button-variants';
|
|
2
|
+
interface Props {
|
|
3
|
+
size: ButtonSize;
|
|
4
|
+
loadingStyle: ButtonLoadingStyle;
|
|
5
|
+
}
|
|
6
|
+
export declare function ButtonLoader({ size, loadingStyle }: Props): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
2
|
+
import { cn as r } from "../../utils/cn.js";
|
|
3
|
+
import { LOADER_SIZE_CLASSES as i } from "./button-variants.js";
|
|
4
|
+
function a({ size: C, loadingStyle: e }) {
|
|
5
|
+
return /* @__PURE__ */ t(
|
|
6
|
+
"div",
|
|
7
|
+
{
|
|
8
|
+
className: r("flex items-center justify-center", {
|
|
9
|
+
"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2": e === "overlay",
|
|
10
|
+
"mr-1": e === "inline"
|
|
11
|
+
}),
|
|
12
|
+
children: /* @__PURE__ */ n(
|
|
13
|
+
"svg",
|
|
14
|
+
{
|
|
15
|
+
"aria-hidden": "true",
|
|
16
|
+
role: "status",
|
|
17
|
+
className: r("inline animate-spin", i[C]),
|
|
18
|
+
viewBox: "0 0 100 101",
|
|
19
|
+
fill: "none",
|
|
20
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
21
|
+
children: [
|
|
22
|
+
/* @__PURE__ */ t(
|
|
23
|
+
"path",
|
|
24
|
+
{
|
|
25
|
+
d: "M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 50.5908 9.08144 50.5908Z",
|
|
26
|
+
fill: "#E5E7EB"
|
|
27
|
+
}
|
|
28
|
+
),
|
|
29
|
+
/* @__PURE__ */ t(
|
|
30
|
+
"path",
|
|
31
|
+
{
|
|
32
|
+
d: "M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z",
|
|
33
|
+
fill: "currentColor"
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
a as ButtonLoader
|
|
44
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function ButtonDefault(): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function ButtonWithClickCounter(): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare function ButtonPendingInline(): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export declare function ButtonPendingOverlay(): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function ButtonDisabled(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type ButtonVariant = "primary" | "secondary" | "tertiary";
|
|
2
|
+
export type ButtonColor = "blue-dark" | "error" | "gray";
|
|
3
|
+
export type ButtonSize = "sm" | "md" | "lg";
|
|
4
|
+
export type ButtonLoadingStyle = "inline" | "overlay";
|
|
5
|
+
type VariantColorKey = `${ButtonVariant}-${ButtonColor}`;
|
|
6
|
+
export declare const VARIANT_BASE_CLASSES: Record<ButtonVariant, string>;
|
|
7
|
+
export declare const COLOR_FOCUS_CLASSES: Record<ButtonColor, string>;
|
|
8
|
+
export declare const VARIANT_COLOR_CLASSES: Record<VariantColorKey, string>;
|
|
9
|
+
export declare const VARIANT_DISABLED_CLASSES: Record<ButtonVariant, string>;
|
|
10
|
+
export declare const TEXT_SIZE_CLASSES: Record<ButtonSize, string>;
|
|
11
|
+
export declare const PADDING_CLASSES: Record<ButtonSize, string>;
|
|
12
|
+
export declare const LOADER_SIZE_CLASSES: Record<ButtonSize, string>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const r = {
|
|
2
|
+
// Solid background, white text — transparent border keeps size consistent with secondary.
|
|
3
|
+
primary: "text-white border border-transparent shadow-xs-skeuomorphic",
|
|
4
|
+
// White background, colored border.
|
|
5
|
+
secondary: "bg-white border shadow-xs-skeuomorphic",
|
|
6
|
+
// Transparent background — rounded-sm overrides the shared base (rounded-lg).
|
|
7
|
+
// No padding; smaller radius is appropriate for a padless button.
|
|
8
|
+
tertiary: "bg-transparent border border-transparent rounded-sm"
|
|
9
|
+
}, e = {
|
|
10
|
+
"blue-dark": "focus:outline-blue-dark-v2-400",
|
|
11
|
+
error: "focus:outline-error-v2-400",
|
|
12
|
+
gray: "focus:outline-gray-v2-400"
|
|
13
|
+
}, a = {
|
|
14
|
+
// --------------------------------------------------
|
|
15
|
+
// Primary — solid background, white text
|
|
16
|
+
// --------------------------------------------------
|
|
17
|
+
"primary-blue-dark": "bg-blue-dark-v2-600 hover:bg-blue-dark-v2-700",
|
|
18
|
+
"primary-error": "bg-error-v2-600 hover:bg-error-v2-700",
|
|
19
|
+
"primary-gray": "bg-gray-v2-600 hover:bg-gray-v2-700",
|
|
20
|
+
// --------------------------------------------------
|
|
21
|
+
// Secondary — white background, colored border + text
|
|
22
|
+
// --------------------------------------------------
|
|
23
|
+
"secondary-blue-dark": "text-blue-dark-v2-700 hover:bg-blue-dark-v2-50 hover:text-blue-dark-v2-800 border-blue-dark-v2-300",
|
|
24
|
+
"secondary-error": "text-error-v2-700 hover:bg-error-v2-50 hover:text-error-v2-800 border-error-v2-300",
|
|
25
|
+
"secondary-gray": "text-gray-v2-600 hover:bg-gray-v2-50 hover:text-gray-v2-700 border-gray-v2-300",
|
|
26
|
+
// --------------------------------------------------
|
|
27
|
+
// Tertiary — transparent background, colored text only
|
|
28
|
+
// Hover uses -25 (lighter) to match the InlineButton style this variant replaces.
|
|
29
|
+
// --------------------------------------------------
|
|
30
|
+
"tertiary-blue-dark": "text-blue-dark-v2-700 hover:bg-blue-dark-v2-50 hover:text-blue-dark-v2-800",
|
|
31
|
+
"tertiary-error": "text-error-v2-700 hover:bg-error-v2-50 hover:text-error-v2-800",
|
|
32
|
+
"tertiary-gray": "text-gray-v2-600 hover:bg-gray-v2-50 hover:text-gray-v2-700"
|
|
33
|
+
}, t = {
|
|
34
|
+
primary: "disabled:text-gray-v2-400 disabled:bg-gray-v2-100 disabled:hover:bg-gray-v2-100 disabled:border disabled:border-transparent",
|
|
35
|
+
secondary: "disabled:hover:bg-white disabled:text-gray-v2-400 disabled:hover:text-gray-v2-400 disabled:border-gray-v2-200",
|
|
36
|
+
tertiary: "disabled:bg-transparent disabled:hover:bg-transparent disabled:text-gray-v2-400 disabled:hover:text-gray-v2-400"
|
|
37
|
+
}, o = {
|
|
38
|
+
sm: "text-sm",
|
|
39
|
+
md: "text-sm",
|
|
40
|
+
lg: "text-md"
|
|
41
|
+
}, d = {
|
|
42
|
+
sm: "py-2 px-3",
|
|
43
|
+
md: "py-2.5 px-3.5",
|
|
44
|
+
lg: "py-2.5 px-4"
|
|
45
|
+
}, v = {
|
|
46
|
+
sm: "size-4",
|
|
47
|
+
md: "size-4",
|
|
48
|
+
lg: "size-5"
|
|
49
|
+
};
|
|
50
|
+
export {
|
|
51
|
+
e as COLOR_FOCUS_CLASSES,
|
|
52
|
+
v as LOADER_SIZE_CLASSES,
|
|
53
|
+
d as PADDING_CLASSES,
|
|
54
|
+
o as TEXT_SIZE_CLASSES,
|
|
55
|
+
r as VARIANT_BASE_CLASSES,
|
|
56
|
+
a as VARIANT_COLOR_CLASSES,
|
|
57
|
+
t as VARIANT_DISABLED_CLASSES
|
|
58
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { ReactNode, SVGProps } from 'react';
|
|
2
|
+
import { CardSize } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Two modes:
|
|
5
|
+
* 1. **Standard** — provide `title` (+ optional `Icon`, `hint`, `actions`) for the built-in header.
|
|
6
|
+
* 2. **Custom header** — provide `header` to fully override the header area; `title`/`Icon`/`hint`/`actions` are ignored.
|
|
7
|
+
*/
|
|
8
|
+
interface CardProps {
|
|
9
|
+
title?: ReactNode;
|
|
10
|
+
Icon?: (props: SVGProps<SVGSVGElement>) => ReactNode;
|
|
11
|
+
hint?: ReactNode;
|
|
12
|
+
actions?: ReactNode;
|
|
13
|
+
header?: ReactNode;
|
|
14
|
+
size?: CardSize;
|
|
15
|
+
collapsible?: boolean;
|
|
16
|
+
/** When provided, collapse state is controlled externally. */
|
|
17
|
+
collapsed?: boolean;
|
|
18
|
+
/** Fires in both controlled and uncontrolled modes. */
|
|
19
|
+
onCollapsedChange?: (collapsed: boolean) => void;
|
|
20
|
+
/** Uncontrolled initial state. Default: `false`. */
|
|
21
|
+
defaultCollapsed?: boolean;
|
|
22
|
+
children?: ReactNode;
|
|
23
|
+
noPadding?: boolean;
|
|
24
|
+
/** Skips the white body wrapper. When `true`, `noPadding` and `bodyClassName` are ignored. */
|
|
25
|
+
noBodyWrapper?: boolean;
|
|
26
|
+
className?: string;
|
|
27
|
+
/** Classname for the inner div of the Card. Ignored when `noBodyWrapper` is `true`. */
|
|
28
|
+
bodyClassName?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Unified card layout component. Replaces SectionCardV2, SectionCardCollapsible,
|
|
32
|
+
* SectionCardWithTable, and SectionCardBaseV2.
|
|
33
|
+
*
|
|
34
|
+
* @example Standard card
|
|
35
|
+
* ```tsx
|
|
36
|
+
* <Card title="Overview" Icon={BarChart} size="md">
|
|
37
|
+
* <p>Card content here</p>
|
|
38
|
+
* </Card>
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @example Collapsible card
|
|
42
|
+
* ```tsx
|
|
43
|
+
* <Card title="Details" collapsible defaultCollapsed>
|
|
44
|
+
* <p>Hidden by default, click header to expand</p>
|
|
45
|
+
* </Card>
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @example Controlled collapse
|
|
49
|
+
* ```tsx
|
|
50
|
+
* <Card title="Section" collapsible collapsed={isOpen} onCollapsedChange={setIsOpen}>
|
|
51
|
+
* <p>Controlled externally</p>
|
|
52
|
+
* </Card>
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @example Table (no body padding)
|
|
56
|
+
* ```tsx
|
|
57
|
+
* <Card title="Devices" Icon={Monitor} noPadding>
|
|
58
|
+
* <TableV2 ... />
|
|
59
|
+
* </Card>
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @example Collapsible table
|
|
63
|
+
* ```tsx
|
|
64
|
+
* <Card title="Logs" collapsible noPadding>
|
|
65
|
+
* <TableV2 ... />
|
|
66
|
+
* </Card>
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @example Small card
|
|
70
|
+
* ```tsx
|
|
71
|
+
* <Card title="Stats" size="sm">
|
|
72
|
+
* <span>42</span>
|
|
73
|
+
* </Card>
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @example Large card with actions
|
|
77
|
+
* ```tsx
|
|
78
|
+
* <Card title="Vulnerabilities" size="lg" actions={<button>Export</button>}>
|
|
79
|
+
* <Content />
|
|
80
|
+
* </Card>
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @example Custom header (escape hatch for DangerZone, Payment Summary, etc.)
|
|
84
|
+
* ```tsx
|
|
85
|
+
* <Card header={<div className="px-4 py-3">Custom</div>} className="bg-error-v2-100" noBodyWrapper>
|
|
86
|
+
* <div className="p-4">Fully custom body</div>
|
|
87
|
+
* </Card>
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare const Card: ({ title, Icon, hint, actions, header, size, collapsible, collapsed: controlledCollapsed, onCollapsedChange, defaultCollapsed, children, noPadding, noBodyWrapper, className, bodyClassName, }: CardProps) => import("react/jsx-runtime").JSX.Element;
|
|
91
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsxs as B, jsx as t } from "react/jsx-runtime";
|
|
2
|
+
import { useState as I } from "react";
|
|
3
|
+
import { cn as S } from "../../utils/cn.js";
|
|
4
|
+
import { Collapsible as T } from "../collapsible/Collapsible.js";
|
|
5
|
+
import { CardHeader as k } from "./CardHeader.js";
|
|
6
|
+
import { CardBody as q } from "./CardBody.js";
|
|
7
|
+
const J = ({
|
|
8
|
+
title: n,
|
|
9
|
+
Icon: l,
|
|
10
|
+
hint: c,
|
|
11
|
+
actions: f,
|
|
12
|
+
header: x,
|
|
13
|
+
size: p = "md",
|
|
14
|
+
collapsible: e = !1,
|
|
15
|
+
collapsed: o,
|
|
16
|
+
onCollapsedChange: r,
|
|
17
|
+
defaultCollapsed: v = !1,
|
|
18
|
+
children: a,
|
|
19
|
+
noPadding: y = !1,
|
|
20
|
+
noBodyWrapper: b = !1,
|
|
21
|
+
className: g,
|
|
22
|
+
bodyClassName: u
|
|
23
|
+
}) => {
|
|
24
|
+
const d = o !== void 0, [j, H] = I(v), s = d ? o : j, N = () => {
|
|
25
|
+
const m = !s;
|
|
26
|
+
d || H(m), r == null || r(m);
|
|
27
|
+
}, w = e || o !== void 0, A = x ?? /* @__PURE__ */ t(
|
|
28
|
+
k,
|
|
29
|
+
{
|
|
30
|
+
title: n,
|
|
31
|
+
Icon: l,
|
|
32
|
+
hint: c,
|
|
33
|
+
actions: f,
|
|
34
|
+
size: p,
|
|
35
|
+
collapsible: e,
|
|
36
|
+
isCollapsed: s,
|
|
37
|
+
onToggle: N
|
|
38
|
+
}
|
|
39
|
+
), i = b ? a : /* @__PURE__ */ t(q, { noPadding: y, className: u, children: a });
|
|
40
|
+
return /* @__PURE__ */ B(
|
|
41
|
+
"div",
|
|
42
|
+
{
|
|
43
|
+
className: S(
|
|
44
|
+
"flex flex-col bg-gray-v2-100 rounded-xl text-gray-v2-900 shadow-xs scrollbar-none",
|
|
45
|
+
g
|
|
46
|
+
),
|
|
47
|
+
children: [
|
|
48
|
+
A,
|
|
49
|
+
w ? /* @__PURE__ */ t(T, { expanded: !s, children: i }) : i
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
export {
|
|
55
|
+
J as Card
|
|
56
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CardCollapseCallback: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
interface Props {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
noPadding?: boolean;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
/** White body wrapper with conditional padding. */
|
|
8
|
+
export declare const CardBody: ({ children, noPadding, className }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as d } from "react/jsx-runtime";
|
|
2
|
+
import { cn as x } from "../../utils/cn.js";
|
|
3
|
+
const a = ({ children: o, noPadding: e, className: r }) => /* @__PURE__ */ d(
|
|
4
|
+
"div",
|
|
5
|
+
{
|
|
6
|
+
className: x(
|
|
7
|
+
"flex flex-col gap-5 flex-1 bg-white text-gray-v2-600 border shadow-xs rounded-xl overflow-hidden",
|
|
8
|
+
{ "p-4": !e },
|
|
9
|
+
r
|
|
10
|
+
),
|
|
11
|
+
children: o
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
export {
|
|
15
|
+
a as CardBody
|
|
16
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReactNode, SVGProps } from 'react';
|
|
2
|
+
import { CardSize } from './types';
|
|
3
|
+
interface Props {
|
|
4
|
+
title: ReactNode;
|
|
5
|
+
Icon?: (props: SVGProps<SVGSVGElement>) => ReactNode;
|
|
6
|
+
hint?: ReactNode;
|
|
7
|
+
actions?: ReactNode;
|
|
8
|
+
size?: CardSize;
|
|
9
|
+
collapsible?: boolean;
|
|
10
|
+
isCollapsed?: boolean;
|
|
11
|
+
onToggle?: () => void;
|
|
12
|
+
}
|
|
13
|
+
/** Standard header layout: icon + title + hint on left, actions on right. */
|
|
14
|
+
export declare const CardHeader: ({ title, Icon, hint, actions, size, collapsible, isCollapsed, onToggle, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { jsxs as s, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { cn as m } from "../../utils/cn.js";
|
|
3
|
+
import { ChevronDown as v } from "@untitled-ui/icons-react";
|
|
4
|
+
const h = {
|
|
5
|
+
sm: "text-sm",
|
|
6
|
+
md: "text-md",
|
|
7
|
+
lg: "text-lg"
|
|
8
|
+
}, p = {
|
|
9
|
+
sm: "py-1.5",
|
|
10
|
+
md: "py-2",
|
|
11
|
+
lg: "py-3"
|
|
12
|
+
}, f = ({
|
|
13
|
+
children: d,
|
|
14
|
+
size: n
|
|
15
|
+
}) => /* @__PURE__ */ e("span", { className: m(h[n], "font-semibold"), children: d }), N = ({
|
|
16
|
+
title: d,
|
|
17
|
+
Icon: n,
|
|
18
|
+
hint: c,
|
|
19
|
+
actions: o,
|
|
20
|
+
size: i = "md",
|
|
21
|
+
collapsible: t,
|
|
22
|
+
isCollapsed: x,
|
|
23
|
+
onToggle: r
|
|
24
|
+
}) => {
|
|
25
|
+
const l = (a) => {
|
|
26
|
+
(a.key === "Enter" || a.key === " ") && (a.preventDefault(), r == null || r());
|
|
27
|
+
};
|
|
28
|
+
return /* @__PURE__ */ s(
|
|
29
|
+
"div",
|
|
30
|
+
{
|
|
31
|
+
className: m(
|
|
32
|
+
"px-4 flex items-center justify-between",
|
|
33
|
+
p[i],
|
|
34
|
+
{
|
|
35
|
+
"cursor-pointer select-none": t
|
|
36
|
+
}
|
|
37
|
+
),
|
|
38
|
+
onClick: t ? r : void 0,
|
|
39
|
+
onKeyDown: t ? l : void 0,
|
|
40
|
+
role: t ? "button" : void 0,
|
|
41
|
+
tabIndex: t ? 0 : void 0,
|
|
42
|
+
"aria-expanded": t ? !x : void 0,
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ s("div", { className: "flex flex-col gap-0.5", children: [
|
|
45
|
+
n ? /* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
|
|
46
|
+
/* @__PURE__ */ e(n, { className: "h-5 w-5 min-w-5 text-gray-v2" }),
|
|
47
|
+
/* @__PURE__ */ e(f, { size: i, children: d })
|
|
48
|
+
] }) : /* @__PURE__ */ e(f, { size: i, children: d }),
|
|
49
|
+
c ? /* @__PURE__ */ e("span", { className: m("text-md text-gray-v2-600", { "pl-7": !!n }), children: c }) : null
|
|
50
|
+
] }),
|
|
51
|
+
o || t ? (
|
|
52
|
+
// stopPropagation so clicking actions doesn't toggle collapse
|
|
53
|
+
/* @__PURE__ */ s(
|
|
54
|
+
"div",
|
|
55
|
+
{
|
|
56
|
+
className: "flex items-center gap-2",
|
|
57
|
+
onClick: (a) => a.stopPropagation(),
|
|
58
|
+
children: [
|
|
59
|
+
o,
|
|
60
|
+
t ? /* @__PURE__ */ e("button", { onClick: r, tabIndex: -1, children: /* @__PURE__ */ e(
|
|
61
|
+
v,
|
|
62
|
+
{
|
|
63
|
+
className: m(
|
|
64
|
+
"h-5 w-5 min-w-5 text-gray-v2-400 motion-safe:transition-transform",
|
|
65
|
+
{ "rotate-180": x }
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
) }) : null
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
) : null
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
export {
|
|
78
|
+
N as CardHeader
|
|
79
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type CardSize = "sm" | "md" | "lg";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { InputHTMLAttributes } from 'react';
|
|
2
|
+
interface Props extends InputHTMLAttributes<HTMLInputElement> {
|
|
3
|
+
indeterminate?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare const Checkbox: import('react').ForwardRefExoticComponent<Props & import('react').RefAttributes<HTMLInputElement>>;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsxs as l, jsx as s } from "react/jsx-runtime";
|
|
2
|
+
import { Check as d, Minus as b } from "@untitled-ui/icons-react";
|
|
3
|
+
import { forwardRef as u } from "react";
|
|
4
|
+
import { cn as t } from "../../utils/cn.js";
|
|
5
|
+
const c = u(
|
|
6
|
+
({ checked: a, indeterminate: o, className: r, ...e }, n) => {
|
|
7
|
+
const i = !!o && !a;
|
|
8
|
+
return /* @__PURE__ */ l(
|
|
9
|
+
"label",
|
|
10
|
+
{
|
|
11
|
+
className: t(
|
|
12
|
+
"relative size-5 shrink-0 block rounded-md bg-white transition-all ease-out border overflow-hidden",
|
|
13
|
+
a || i ? e.disabled ? "border-gray-v2-300" : "border-brand-v2-600" : "border-gray-v2-300",
|
|
14
|
+
{ "bg-gray-v2-50": e.disabled },
|
|
15
|
+
r
|
|
16
|
+
),
|
|
17
|
+
children: [
|
|
18
|
+
/* @__PURE__ */ s(
|
|
19
|
+
"input",
|
|
20
|
+
{
|
|
21
|
+
ref: n,
|
|
22
|
+
...e,
|
|
23
|
+
checked: a,
|
|
24
|
+
className: t(
|
|
25
|
+
"absolute top-0 left-0 z-10 size-full rounded-md appearance-none",
|
|
26
|
+
"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-v2-400",
|
|
27
|
+
e.disabled ? "cursor-not-allowed" : "cursor-pointer"
|
|
28
|
+
),
|
|
29
|
+
type: "checkbox"
|
|
30
|
+
}
|
|
31
|
+
),
|
|
32
|
+
/* @__PURE__ */ l(
|
|
33
|
+
"span",
|
|
34
|
+
{
|
|
35
|
+
className: t(
|
|
36
|
+
"relative size-full transition-all ease-out rounded-0.5 flex justify-center items-center",
|
|
37
|
+
{ "bg-brand-v2-600": !e.disabled },
|
|
38
|
+
{ "scale-[40%] opacity-0 rotate-12": !(a || i) }
|
|
39
|
+
),
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ s(
|
|
42
|
+
d,
|
|
43
|
+
{
|
|
44
|
+
className: t(
|
|
45
|
+
"absolute size-[70%] transition-all ease-out",
|
|
46
|
+
e.disabled ? "text-gray-v2-300" : "text-white",
|
|
47
|
+
{ "scale-0": !a }
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
),
|
|
51
|
+
/* @__PURE__ */ s(
|
|
52
|
+
b,
|
|
53
|
+
{
|
|
54
|
+
className: t(
|
|
55
|
+
"absolute size-[70%] transition-all ease-out",
|
|
56
|
+
e.disabled ? "text-gray-v2-300" : "text-white",
|
|
57
|
+
{ "scale-0": !i }
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
c.displayName = "Checkbox";
|
|
70
|
+
export {
|
|
71
|
+
c as Checkbox
|
|
72
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function CheckboxUnchecked(): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function CheckboxChecked(): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare function CheckboxIndeterminate(): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
export declare function CheckboxCheckedAndIndeterminate(): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function CheckboxDisabled(): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function CheckboxDisabledChecked(): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function CheckboxWithClickCounter(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
interface Props {
|
|
3
|
+
expanded: boolean;
|
|
4
|
+
duration?: number;
|
|
5
|
+
className?: string;
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Pure animated collapse container. No trigger, no label — just an outer
|
|
10
|
+
* grid whose row template animates between `0fr` and `1fr`, with a delayed
|
|
11
|
+
* `visibility` transition so collapsed content is unreachable by pointer,
|
|
12
|
+
* focus, and assistive tech once the fade finishes.
|
|
13
|
+
*
|
|
14
|
+
* Consumers own the toggle UI (e.g. `Accordion` wraps its own `role=button`
|
|
15
|
+
* label around this; `Card` keeps its collapse button in `CardHeader`).
|
|
16
|
+
*
|
|
17
|
+
* @param expanded - Whether the content is shown.
|
|
18
|
+
* @param duration - Transition duration in milliseconds (default: 300).
|
|
19
|
+
*/
|
|
20
|
+
export declare const Collapsible: ({ expanded, duration, className, children, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export {};
|