@slugbase/ui 0.0.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/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-lint.log +4 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/dist/components/AppShell.d.ts +17 -0
- package/dist/components/AppShell.d.ts.map +1 -0
- package/dist/components/AppShell.js +11 -0
- package/dist/components/AppShell.js.map +1 -0
- package/dist/components/Badge.d.ts +13 -0
- package/dist/components/Badge.d.ts.map +1 -0
- package/dist/components/Badge.js +21 -0
- package/dist/components/Badge.js.map +1 -0
- package/dist/components/Button.d.ts +11 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Button.js +21 -0
- package/dist/components/Button.js.map +1 -0
- package/dist/components/Checkbox.d.ts +16 -0
- package/dist/components/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox.js +19 -0
- package/dist/components/Checkbox.js.map +1 -0
- package/dist/components/ColorPicker.d.ts +14 -0
- package/dist/components/ColorPicker.d.ts.map +1 -0
- package/dist/components/ColorPicker.js +29 -0
- package/dist/components/ColorPicker.js.map +1 -0
- package/dist/components/ConfirmDialog.d.ts +17 -0
- package/dist/components/ConfirmDialog.d.ts.map +1 -0
- package/dist/components/ConfirmDialog.js +8 -0
- package/dist/components/ConfirmDialog.js.map +1 -0
- package/dist/components/Dialog.d.ts +15 -0
- package/dist/components/Dialog.d.ts.map +1 -0
- package/dist/components/Dialog.js +12 -0
- package/dist/components/Dialog.js.map +1 -0
- package/dist/components/EmptyState.d.ts +12 -0
- package/dist/components/EmptyState.d.ts.map +1 -0
- package/dist/components/EmptyState.js +6 -0
- package/dist/components/EmptyState.js.map +1 -0
- package/dist/components/FieldError.d.ts +7 -0
- package/dist/components/FieldError.d.ts.map +1 -0
- package/dist/components/FieldError.js +5 -0
- package/dist/components/FieldError.js.map +1 -0
- package/dist/components/FolderGlyph.d.ts +8 -0
- package/dist/components/FolderGlyph.d.ts.map +1 -0
- package/dist/components/FolderGlyph.js +14 -0
- package/dist/components/FolderGlyph.js.map +1 -0
- package/dist/components/IconButton.d.ts +14 -0
- package/dist/components/IconButton.d.ts.map +1 -0
- package/dist/components/IconButton.js +15 -0
- package/dist/components/IconButton.js.map +1 -0
- package/dist/components/IconPicker.d.ts +16 -0
- package/dist/components/IconPicker.d.ts.map +1 -0
- package/dist/components/IconPicker.js +32 -0
- package/dist/components/IconPicker.js.map +1 -0
- package/dist/components/Input.d.ts +10 -0
- package/dist/components/Input.d.ts.map +1 -0
- package/dist/components/Input.js +33 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/Kbd.d.ts +11 -0
- package/dist/components/Kbd.d.ts.map +1 -0
- package/dist/components/Kbd.js +18 -0
- package/dist/components/Kbd.js.map +1 -0
- package/dist/components/Label.d.ts +6 -0
- package/dist/components/Label.d.ts.map +1 -0
- package/dist/components/Label.js +5 -0
- package/dist/components/Label.js.map +1 -0
- package/dist/components/Popover.d.ts +14 -0
- package/dist/components/Popover.d.ts.map +1 -0
- package/dist/components/Popover.js +9 -0
- package/dist/components/Popover.js.map +1 -0
- package/dist/components/Skeleton.d.ts +22 -0
- package/dist/components/Skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton.js +14 -0
- package/dist/components/Skeleton.js.map +1 -0
- package/dist/components/SlugBadge.d.ts +13 -0
- package/dist/components/SlugBadge.d.ts.map +1 -0
- package/dist/components/SlugBadge.js +17 -0
- package/dist/components/SlugBadge.js.map +1 -0
- package/dist/components/Tag.d.ts +11 -0
- package/dist/components/Tag.d.ts.map +1 -0
- package/dist/components/Tag.js +16 -0
- package/dist/components/Tag.js.map +1 -0
- package/dist/components/ThemeSwitcher.d.ts +11 -0
- package/dist/components/ThemeSwitcher.d.ts.map +1 -0
- package/dist/components/ThemeSwitcher.js +25 -0
- package/dist/components/ThemeSwitcher.js.map +1 -0
- package/dist/components/ToastProvider.d.ts +19 -0
- package/dist/components/ToastProvider.d.ts.map +1 -0
- package/dist/components/ToastProvider.js +62 -0
- package/dist/components/ToastProvider.js.map +1 -0
- package/dist/components/Tooltip.d.ts +13 -0
- package/dist/components/Tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip.js +9 -0
- package/dist/components/Tooltip.js.map +1 -0
- package/dist/components/auth-kit.d.ts +59 -0
- package/dist/components/auth-kit.d.ts.map +1 -0
- package/dist/components/auth-kit.js +101 -0
- package/dist/components/auth-kit.js.map +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -0
- package/dist/icons/folder-icon-names.d.ts +4 -0
- package/dist/icons/folder-icon-names.d.ts.map +1 -0
- package/dist/icons/folder-icon-names.js +164 -0
- package/dist/icons/folder-icon-names.js.map +1 -0
- package/dist/icons/lucide-icon.d.ts +8 -0
- package/dist/icons/lucide-icon.d.ts.map +1 -0
- package/dist/icons/lucide-icon.js +38 -0
- package/dist/icons/lucide-icon.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/tailwind/token-theme.d.ts +167 -0
- package/dist/tailwind/token-theme.d.ts.map +1 -0
- package/dist/tailwind/token-theme.js +109 -0
- package/dist/tailwind/token-theme.js.map +1 -0
- package/dist/theme/resolve-theme.d.ts +6 -0
- package/dist/theme/resolve-theme.d.ts.map +1 -0
- package/dist/theme/resolve-theme.js +24 -0
- package/dist/theme/resolve-theme.js.map +1 -0
- package/dist/theme/theme-context.d.ts +15 -0
- package/dist/theme/theme-context.d.ts.map +1 -0
- package/dist/theme/theme-context.js +51 -0
- package/dist/theme/theme-context.js.map +1 -0
- package/dist/theme/theme-types.d.ts +5 -0
- package/dist/theme/theme-types.d.ts.map +1 -0
- package/dist/theme/theme-types.js +3 -0
- package/dist/theme/theme-types.js.map +1 -0
- package/package.json +55 -0
- package/postcss.config.js +6 -0
- package/src/components/AppShell.spec.tsx +28 -0
- package/src/components/AppShell.tsx +49 -0
- package/src/components/Badge.tsx +41 -0
- package/src/components/Button.tsx +56 -0
- package/src/components/Checkbox.tsx +70 -0
- package/src/components/ColorPicker.spec.tsx +53 -0
- package/src/components/ColorPicker.tsx +87 -0
- package/src/components/ConfirmDialog.spec.tsx +44 -0
- package/src/components/ConfirmDialog.tsx +67 -0
- package/src/components/Dialog.tsx +63 -0
- package/src/components/EmptyState.spec.tsx +22 -0
- package/src/components/EmptyState.tsx +54 -0
- package/src/components/FieldError.tsx +19 -0
- package/src/components/FolderGlyph.tsx +38 -0
- package/src/components/IconButton.tsx +42 -0
- package/src/components/IconPicker.spec.tsx +54 -0
- package/src/components/IconPicker.tsx +132 -0
- package/src/components/Input.tsx +76 -0
- package/src/components/Kbd.tsx +30 -0
- package/src/components/Label.tsx +17 -0
- package/src/components/Popover.tsx +35 -0
- package/src/components/Skeleton.spec.tsx +18 -0
- package/src/components/Skeleton.tsx +94 -0
- package/src/components/SlugBadge.tsx +35 -0
- package/src/components/Tag.tsx +31 -0
- package/src/components/ThemeSwitcher.tsx +60 -0
- package/src/components/ToastProvider.spec.tsx +60 -0
- package/src/components/ToastProvider.tsx +167 -0
- package/src/components/Tooltip.tsx +33 -0
- package/src/components/__snapshots__/AppShell.spec.tsx.snap +41 -0
- package/src/components/auth-kit.spec.tsx +24 -0
- package/src/components/auth-kit.tsx +475 -0
- package/src/constants.ts +1 -0
- package/src/icons/folder-icon-names.ts +165 -0
- package/src/icons/lucide-icon.spec.ts +32 -0
- package/src/icons/lucide-icon.tsx +47 -0
- package/src/index.ts +100 -0
- package/src/styles/app.css +5 -0
- package/src/styles/colors-and-type.css +140 -0
- package/src/styles/ibm-plex-fonts.css +8 -0
- package/src/tailwind/token-theme.spec.ts +13 -0
- package/src/tailwind/token-theme.ts +114 -0
- package/src/theme/resolve-theme.spec.ts +17 -0
- package/src/theme/resolve-theme.ts +30 -0
- package/src/theme/theme-context.tsx +99 -0
- package/src/theme/theme-types.ts +7 -0
- package/tailwind.config.ts +11 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +11 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type KbdProps = {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Keyboard hint badge - 11px mono, canvas bg, 3D bottom border.
|
|
8
|
+
* Matches prototype `.kbd` from app.css.
|
|
9
|
+
*/
|
|
10
|
+
export declare function Kbd({ children, className }: KbdProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=Kbd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Kbd.d.ts","sourceRoot":"","sources":["../../src/components/Kbd.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAc,EAAE,EAAE,QAAQ,2CAkBzD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Keyboard hint badge - 11px mono, canvas bg, 3D bottom border.
|
|
4
|
+
* Matches prototype `.kbd` from app.css.
|
|
5
|
+
*/
|
|
6
|
+
export function Kbd({ children, className = "" }) {
|
|
7
|
+
return (_jsx("kbd", { className: [
|
|
8
|
+
"inline-flex min-h-[18px] min-w-[18px] items-center justify-center gap-[2px] rounded-sm",
|
|
9
|
+
"border border-[color:var(--border)] bg-canvas",
|
|
10
|
+
"font-mono font-medium leading-none text-fg-muted",
|
|
11
|
+
className,
|
|
12
|
+
].join(" "), style: {
|
|
13
|
+
fontSize: "11px",
|
|
14
|
+
padding: "3px 5px",
|
|
15
|
+
borderBottomWidth: "2px",
|
|
16
|
+
}, children: children }));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=Kbd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Kbd.js","sourceRoot":"","sources":["../../src/components/Kbd.tsx"],"names":[],"mappings":";AAOA;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAS,GAAG,EAAE,EAAY;IACxD,OAAO,CACL,cACE,SAAS,EAAE;YACT,wFAAwF;YACxF,+CAA+C;YAC/C,kDAAkD;YAClD,SAAS;SACV,CAAC,IAAI,CAAC,GAAG,CAAC,EACX,KAAK,EAAE;YACL,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,SAAS;YAClB,iBAAiB,EAAE,KAAK;SACzB,YAEA,QAAQ,GACL,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LabelHTMLAttributes, ReactNode } from "react";
|
|
2
|
+
export type LabelProps = LabelHTMLAttributes<HTMLLabelElement> & {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
};
|
|
5
|
+
export declare function Label({ className, children, ...props }: LabelProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
//# sourceMappingURL=Label.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Label.d.ts","sourceRoot":"","sources":["../../src/components/Label.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5D,MAAM,MAAM,UAAU,GAAG,mBAAmB,CAAC,gBAAgB,CAAC,GAAG;IAC/D,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,wBAAgB,KAAK,CAAC,EAAE,SAAc,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,2CAUvE"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export function Label({ className = "", children, ...props }) {
|
|
3
|
+
return (_jsx("label", { className: `font-medium text-fg-muted ${className}`, style: { fontSize: "var(--text-small)", lineHeight: "var(--lh-small)" }, ...props, children: children }));
|
|
4
|
+
}
|
|
5
|
+
//# sourceMappingURL=Label.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Label.js","sourceRoot":"","sources":["../../src/components/Label.tsx"],"names":[],"mappings":";AAMA,MAAM,UAAU,KAAK,CAAC,EAAE,SAAS,GAAG,EAAE,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAc;IACtE,OAAO,CACL,gBACE,SAAS,EAAE,6BAA6B,SAAS,EAAE,EACnD,KAAK,EAAE,EAAE,QAAQ,EAAE,mBAAmB,EAAE,UAAU,EAAE,iBAAiB,EAAE,KACnE,KAAK,YAER,QAAQ,GACH,CACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
export declare const Popover: import("react").FC<PopoverPrimitive.PopoverProps>;
|
|
4
|
+
export declare const PopoverTrigger: import("react").ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
5
|
+
export declare const PopoverClose: import("react").ForwardRefExoticComponent<PopoverPrimitive.PopoverCloseProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
6
|
+
export type PopoverContentProps = {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
testId?: string;
|
|
10
|
+
align?: "start" | "center" | "end";
|
|
11
|
+
sideOffset?: number;
|
|
12
|
+
};
|
|
13
|
+
export declare function PopoverContent({ children, className, testId, align, sideOffset, }: PopoverContentProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=Popover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../../src/components/Popover.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,eAAO,MAAM,OAAO,mDAAwB,CAAC;AAC7C,eAAO,MAAM,cAAc,oIAA2B,CAAC;AACvD,eAAO,MAAM,YAAY,kIAAyB,CAAC;AAEnD,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,SAAc,EACd,MAAM,EACN,KAAe,EACf,UAAc,GACf,EAAE,mBAAmB,2CAarB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
3
|
+
export const Popover = PopoverPrimitive.Root;
|
|
4
|
+
export const PopoverTrigger = PopoverPrimitive.Trigger;
|
|
5
|
+
export const PopoverClose = PopoverPrimitive.Close;
|
|
6
|
+
export function PopoverContent({ children, className = "", testId, align = "start", sideOffset = 4, }) {
|
|
7
|
+
return (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { "data-testid": testId, align: align, sideOffset: sideOffset, className: `z-[130] max-h-[min(360px,70vh)] w-[min(320px,92vw)] overflow-y-auto rounded-lg border border-[color:var(--border)] bg-[color:var(--overlay)] p-sp-4 shadow-lg focus:outline-none ${className}`, children: children }) }));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=Popover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Popover.js","sourceRoot":"","sources":["../../src/components/Popover.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAG5D,MAAM,CAAC,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC,OAAO,CAAC;AACvD,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC,KAAK,CAAC;AAUnD,MAAM,UAAU,cAAc,CAAC,EAC7B,QAAQ,EACR,SAAS,GAAG,EAAE,EACd,MAAM,EACN,KAAK,GAAG,OAAO,EACf,UAAU,GAAG,CAAC,GACM;IACpB,OAAO,CACL,KAAC,gBAAgB,CAAC,MAAM,cACtB,KAAC,gBAAgB,CAAC,OAAO,mBACV,MAAM,EACnB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,oLAAoL,SAAS,EAAE,YAEzM,QAAQ,GACgB,GACH,CAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
+
export type SkeletonProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
style?: CSSProperties;
|
|
5
|
+
testId?: string;
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
};
|
|
8
|
+
/** Shimmer placeholder block - prototype `.sk` pattern (spec §23). */
|
|
9
|
+
export declare function Skeleton({ className, style, testId, children, }: SkeletonProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export type SkeletonListProps = {
|
|
11
|
+
rows?: number;
|
|
12
|
+
testId?: string;
|
|
13
|
+
};
|
|
14
|
+
/** Horizontal list-row skeletons for table/list surfaces. */
|
|
15
|
+
export declare function SkeletonList({ rows, testId }: SkeletonListProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export type SkeletonCardGridProps = {
|
|
17
|
+
count?: number;
|
|
18
|
+
testId?: string;
|
|
19
|
+
};
|
|
20
|
+
/** Card grid skeleton matching bookmark grid loading state in the prototype. */
|
|
21
|
+
export declare function SkeletonCardGrid({ count, testId, }: SkeletonCardGridProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=Skeleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.d.ts","sourceRoot":"","sources":["../../src/components/Skeleton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtD,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,sEAAsE;AACtE,wBAAgB,QAAQ,CAAC,EACvB,SAAc,EACd,KAAK,EACL,MAAM,EACN,QAAQ,GACT,EAAE,aAAa,2CAWf;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,6DAA6D;AAC7D,wBAAgB,YAAY,CAAC,EAAE,IAAQ,EAAE,MAAwB,EAAE,EAAE,iBAAiB,2CAkBrF;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,EAC/B,KAAS,EACT,MAA6B,GAC9B,EAAE,qBAAqB,2CA8BvB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/** Shimmer placeholder block - prototype `.sk` pattern (spec §23). */
|
|
3
|
+
export function Skeleton({ className = "", style, testId, children, }) {
|
|
4
|
+
return (_jsx("div", { "aria-hidden": "true", className: `animate-shimmer rounded-sm bg-[linear-gradient(90deg,var(--raised)_0%,var(--raised-2)_50%,var(--raised)_100%)] bg-[length:200%_100%] motion-reduce:animate-none ${className}`, "data-testid": testId, style: style, children: children }));
|
|
5
|
+
}
|
|
6
|
+
/** Horizontal list-row skeletons for table/list surfaces. */
|
|
7
|
+
export function SkeletonList({ rows = 6, testId = "skeleton-list" }) {
|
|
8
|
+
return (_jsx("div", { className: "flex flex-col gap-sp-3", "data-testid": testId, "aria-busy": "true", "aria-live": "polite", children: Array.from({ length: rows }).map((_, index) => (_jsxs("div", { className: "flex items-center gap-sp-5 rounded-lg border border-[color:var(--border-subtle)] bg-raised px-sp-5 py-sp-5", children: [_jsx(Skeleton, { className: "h-8 w-8 shrink-0 rounded-md" }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-sp-3", children: [_jsx(Skeleton, { className: "h-3 w-[85%]" }), _jsx(Skeleton, { className: "h-2.5 w-[55%]" })] }), _jsx(Skeleton, { className: "ml-auto h-8 w-20 shrink-0" })] }, index))) }));
|
|
9
|
+
}
|
|
10
|
+
/** Card grid skeleton matching bookmark grid loading state in the prototype. */
|
|
11
|
+
export function SkeletonCardGrid({ count = 9, testId = "skeleton-card-grid", }) {
|
|
12
|
+
return (_jsx("div", { className: "grid gap-sp-4 sm:grid-cols-2 lg:grid-cols-3", "data-testid": testId, "aria-busy": "true", "aria-live": "polite", children: Array.from({ length: count }).map((_, index) => (_jsxs("div", { className: "flex flex-col gap-sp-5 rounded-lg border border-[color:var(--border-subtle)] bg-raised p-sp-5", children: [_jsxs("div", { className: "flex gap-sp-4", children: [_jsx(Skeleton, { className: "h-8 w-8 shrink-0 rounded-md" }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-sp-3", children: [_jsx(Skeleton, { className: "h-3 w-[85%]" }), _jsx(Skeleton, { className: "h-2.5 w-[55%]" })] })] }), _jsx(Skeleton, { className: "h-2.5 w-[70%]" }), _jsx(Skeleton, { className: "h-[22px] w-[120px] rounded-sm" }), _jsxs("div", { className: "mt-sp-2 flex gap-sp-3", children: [_jsx(Skeleton, { className: "h-2.5 w-[70px]" }), _jsx(Skeleton, { className: "ml-auto h-4 w-10 rounded-sm" })] })] }, index))) }));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=Skeleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.js","sourceRoot":"","sources":["../../src/components/Skeleton.tsx"],"names":[],"mappings":";AASA,sEAAsE;AACtE,MAAM,UAAU,QAAQ,CAAC,EACvB,SAAS,GAAG,EAAE,EACd,KAAK,EACL,MAAM,EACN,QAAQ,GACM;IACd,OAAO,CACL,6BACc,MAAM,EAClB,SAAS,EAAE,mKAAmK,SAAS,EAAE,iBAC5K,MAAM,EACnB,KAAK,EAAE,KAAK,YAEX,QAAQ,GACL,CACP,CAAC;AACJ,CAAC;AAOD,6DAA6D;AAC7D,MAAM,UAAU,YAAY,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,MAAM,GAAG,eAAe,EAAqB;IACpF,OAAO,CACL,cAAK,SAAS,EAAC,wBAAwB,iBAAc,MAAM,eAAY,MAAM,eAAW,QAAQ,YAC7F,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAC9C,eAEE,SAAS,EAAC,4GAA4G,aAEtH,KAAC,QAAQ,IAAC,SAAS,EAAC,6BAA6B,GAAG,EACpD,eAAK,SAAS,EAAC,uCAAuC,aACpD,KAAC,QAAQ,IAAC,SAAS,EAAC,aAAa,GAAG,EACpC,KAAC,QAAQ,IAAC,SAAS,EAAC,eAAe,GAAG,IAClC,EACN,KAAC,QAAQ,IAAC,SAAS,EAAC,2BAA2B,GAAG,KAR7C,KAAK,CASN,CACP,CAAC,GACE,CACP,CAAC;AACJ,CAAC;AAOD,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,EAC/B,KAAK,GAAG,CAAC,EACT,MAAM,GAAG,oBAAoB,GACP;IACtB,OAAO,CACL,cACE,SAAS,EAAC,6CAA6C,iBAC1C,MAAM,eACT,MAAM,eACN,QAAQ,YAEjB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAC/C,eAEE,SAAS,EAAC,+FAA+F,aAEzG,eAAK,SAAS,EAAC,eAAe,aAC5B,KAAC,QAAQ,IAAC,SAAS,EAAC,6BAA6B,GAAG,EACpD,eAAK,SAAS,EAAC,uCAAuC,aACpD,KAAC,QAAQ,IAAC,SAAS,EAAC,aAAa,GAAG,EACpC,KAAC,QAAQ,IAAC,SAAS,EAAC,eAAe,GAAG,IAClC,IACF,EACN,KAAC,QAAQ,IAAC,SAAS,EAAC,eAAe,GAAG,EACtC,KAAC,QAAQ,IAAC,SAAS,EAAC,+BAA+B,GAAG,EACtD,eAAK,SAAS,EAAC,uBAAuB,aACpC,KAAC,QAAQ,IAAC,SAAS,EAAC,gBAAgB,GAAG,EACvC,KAAC,QAAQ,IAAC,SAAS,EAAC,6BAA6B,GAAG,IAChD,KAfD,KAAK,CAgBN,CACP,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type SlugBadgeProps = {
|
|
3
|
+
slug: string;
|
|
4
|
+
icon?: ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Inline slug address pill - accent-subtle bg, mono small font.
|
|
9
|
+
* Matches prototype `.slug-line` pattern from app.css.
|
|
10
|
+
* Used on bookmark cards and table rows.
|
|
11
|
+
*/
|
|
12
|
+
export declare function SlugBadge({ slug, icon, className }: SlugBadgeProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=SlugBadge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SlugBadge.d.ts","sourceRoot":"","sources":["../../src/components/SlugBadge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAc,EAAE,EAAE,cAAc,2CAqBvE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Inline slug address pill - accent-subtle bg, mono small font.
|
|
4
|
+
* Matches prototype `.slug-line` pattern from app.css.
|
|
5
|
+
* Used on bookmark cards and table rows.
|
|
6
|
+
*/
|
|
7
|
+
export function SlugBadge({ slug, icon, className = "" }) {
|
|
8
|
+
return (_jsxs("span", { className: `inline-flex max-w-full items-center gap-[6px] rounded-sm border border-[color:var(--accent-border)] bg-accent-subtle text-accent-text ${className}`, style: {
|
|
9
|
+
height: "22px",
|
|
10
|
+
padding: "0 7px 0 6px",
|
|
11
|
+
fontFamily: "var(--font-mono)",
|
|
12
|
+
fontSize: "var(--text-small)",
|
|
13
|
+
fontWeight: "var(--weight-medium)",
|
|
14
|
+
lineHeight: "1",
|
|
15
|
+
}, children: [icon ? (_jsx("span", { "aria-hidden": "true", className: "shrink-0 opacity-80", children: icon })) : null, _jsx("span", { className: "overflow-hidden text-ellipsis whitespace-nowrap", children: slug })] }));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=SlugBadge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SlugBadge.js","sourceRoot":"","sources":["../../src/components/SlugBadge.tsx"],"names":[],"mappings":";AAQA;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,GAAG,EAAE,EAAkB;IACtE,OAAO,CACL,gBACE,SAAS,EAAE,yIAAyI,SAAS,EAAE,EAC/J,KAAK,EAAE;YACL,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,aAAa;YACtB,UAAU,EAAE,kBAAkB;YAC9B,QAAQ,EAAE,mBAAmB;YAC7B,UAAU,EAAE,sBAAsB;YAClC,UAAU,EAAE,GAAG;SAChB,aAEA,IAAI,CAAC,CAAC,CAAC,CACN,8BAAkB,MAAM,EAAC,SAAS,EAAC,qBAAqB,YACrD,IAAI,GACA,CACR,CAAC,CAAC,CAAC,IAAI,EACR,eAAM,SAAS,EAAC,iDAAiD,YAAE,IAAI,GAAQ,IAC1E,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type TagProps = {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Tag pill - `#` prefix at 45% opacity, mono micro font.
|
|
8
|
+
* Matches prototype `.tag` pattern from app.css.
|
|
9
|
+
*/
|
|
10
|
+
export declare function Tag({ children, className }: TagProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=Tag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tag.d.ts","sourceRoot":"","sources":["../../src/components/Tag.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAc,EAAE,EAAE,QAAQ,2CAmBzD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Tag pill - `#` prefix at 45% opacity, mono micro font.
|
|
4
|
+
* Matches prototype `.tag` pattern from app.css.
|
|
5
|
+
*/
|
|
6
|
+
export function Tag({ children, className = "" }) {
|
|
7
|
+
return (_jsxs("span", { className: `inline-flex items-center gap-1 whitespace-nowrap rounded-sm border border-[color:var(--border-subtle)] bg-raised-2 text-fg-muted ${className}`, style: {
|
|
8
|
+
height: "19px",
|
|
9
|
+
padding: "0 7px",
|
|
10
|
+
fontFamily: "var(--font-mono)",
|
|
11
|
+
fontSize: "var(--text-micro)",
|
|
12
|
+
fontWeight: "var(--weight-medium)",
|
|
13
|
+
lineHeight: "1",
|
|
14
|
+
}, children: [_jsx("span", { "aria-hidden": "true", style: { opacity: 0.45 }, children: "#" }), children] }));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=Tag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tag.js","sourceRoot":"","sources":["../../src/components/Tag.tsx"],"names":[],"mappings":";AAOA;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAS,GAAG,EAAE,EAAY;IACxD,OAAO,CACL,gBACE,SAAS,EAAE,oIAAoI,SAAS,EAAE,EAC1J,KAAK,EAAE;YACL,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,OAAO;YAChB,UAAU,EAAE,kBAAkB;YAC9B,QAAQ,EAAE,mBAAmB;YAC7B,UAAU,EAAE,sBAAsB;YAClC,UAAU,EAAE,GAAG;SAChB,aAED,8BAAkB,MAAM,EAAC,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,kBAE1C,EACN,QAAQ,IACJ,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type ThemeSwitcherLabels = {
|
|
2
|
+
group: string;
|
|
3
|
+
light: string;
|
|
4
|
+
dark: string;
|
|
5
|
+
auto: string;
|
|
6
|
+
};
|
|
7
|
+
export type ThemeSwitcherProps = {
|
|
8
|
+
labels: ThemeSwitcherLabels;
|
|
9
|
+
};
|
|
10
|
+
export declare function ThemeSwitcher({ labels }: ThemeSwitcherProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=ThemeSwitcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThemeSwitcher.d.ts","sourceRoot":"","sources":["../../src/components/ThemeSwitcher.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAIF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,EAAE,kBAAkB,2CA2C3D"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useTheme } from "../theme/theme-context.js";
|
|
3
|
+
const OPTIONS = ["light", "dark", "auto"];
|
|
4
|
+
export function ThemeSwitcher({ labels }) {
|
|
5
|
+
const { preference, setPreference } = useTheme();
|
|
6
|
+
const labelFor = (value) => {
|
|
7
|
+
switch (value) {
|
|
8
|
+
case "light":
|
|
9
|
+
return labels.light;
|
|
10
|
+
case "dark":
|
|
11
|
+
return labels.dark;
|
|
12
|
+
case "auto":
|
|
13
|
+
return labels.auto;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
return (_jsx("div", { className: "inline-flex rounded-md border border-[color:var(--border)] bg-raised p-sp-2", role: "group", "aria-label": labels.group, "data-testid": "theme-switcher", children: OPTIONS.map((value) => {
|
|
17
|
+
const active = preference === value;
|
|
18
|
+
return (_jsx("button", { type: "button", "aria-pressed": active, className: active
|
|
19
|
+
? "rounded-sm bg-accent px-sp-5 py-sp-3 text-small font-medium text-accent-fg transition-micro"
|
|
20
|
+
: "rounded-sm px-sp-5 py-sp-3 text-small text-fg-muted transition-micro hover:bg-raised-2 hover:text-fg", onClick: () => {
|
|
21
|
+
setPreference(value);
|
|
22
|
+
}, children: labelFor(value) }, value));
|
|
23
|
+
}) }));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=ThemeSwitcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThemeSwitcher.js","sourceRoot":"","sources":["../../src/components/ThemeSwitcher.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AASrD,MAAM,OAAO,GAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAM7D,MAAM,UAAU,aAAa,CAAC,EAAE,MAAM,EAAsB;IAC1D,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,QAAQ,EAAE,CAAC;IAEjD,MAAM,QAAQ,GAAG,CAAC,KAAsB,EAAU,EAAE;QAClD,QAAQ,KAAK,EAAE,CAAC;YACd,KAAK,OAAO;gBACV,OAAO,MAAM,CAAC,KAAK,CAAC;YACtB,KAAK,MAAM;gBACT,OAAO,MAAM,CAAC,IAAI,CAAC;YACrB,KAAK,MAAM;gBACT,OAAO,MAAM,CAAC,IAAI,CAAC;QACvB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,cACE,SAAS,EAAC,6EAA6E,EACvF,IAAI,EAAC,OAAO,gBACA,MAAM,CAAC,KAAK,iBACZ,gBAAgB,YAE3B,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACrB,MAAM,MAAM,GAAG,UAAU,KAAK,KAAK,CAAC;YACpC,OAAO,CACL,iBAEE,IAAI,EAAC,QAAQ,kBACC,MAAM,EACpB,SAAS,EACP,MAAM;oBACJ,CAAC,CAAC,6FAA6F;oBAC/F,CAAC,CAAC,sGAAsG,EAE5G,OAAO,EAAE,GAAG,EAAE;oBACZ,aAAa,CAAC,KAAK,CAAC,CAAC;gBACvB,CAAC,YAEA,QAAQ,CAAC,KAAK,CAAC,IAZX,KAAK,CAaH,CACV,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export type ToastKind = "success" | "info" | "warning" | "danger";
|
|
3
|
+
export type ToastInput = {
|
|
4
|
+
title: ReactNode;
|
|
5
|
+
description?: ReactNode;
|
|
6
|
+
kind?: ToastKind;
|
|
7
|
+
durationMs?: number;
|
|
8
|
+
};
|
|
9
|
+
export type ToastContextValue = {
|
|
10
|
+
toast: (input: ToastInput) => string;
|
|
11
|
+
dismiss: (id: string) => void;
|
|
12
|
+
};
|
|
13
|
+
export type ToastProviderProps = {
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
dismissLabel: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function ToastProvider({ children, dismissLabel }: ToastProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export declare function useToast(): ToastContextValue;
|
|
19
|
+
//# sourceMappingURL=ToastProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToastProvider.d.ts","sourceRoot":"","sources":["../../src/components/ToastProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAElE,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAMF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,MAAM,CAAC;IACrC,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B,CAAC;AAaF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,SAAS,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AA2FF,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,kBAAkB,2CAwB3E;AAED,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
|
|
3
|
+
const ToastContext = createContext(null);
|
|
4
|
+
const DEFAULT_DURATION_MS = 3200;
|
|
5
|
+
const kindClasses = {
|
|
6
|
+
success: "bg-[color:var(--success-subtle)] text-success-text",
|
|
7
|
+
info: "bg-[color:var(--accent-subtle)] text-accent-text",
|
|
8
|
+
warning: "bg-[color:var(--warning-subtle)] text-warning-text",
|
|
9
|
+
danger: "bg-[color:var(--danger-subtle)] text-danger-text",
|
|
10
|
+
};
|
|
11
|
+
function ToastViewport({ items, onDismiss, dismissLabel, }) {
|
|
12
|
+
const timersRef = useRef(new Map());
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const timers = timersRef.current;
|
|
15
|
+
for (const item of items) {
|
|
16
|
+
if (timers.has(item.id))
|
|
17
|
+
continue;
|
|
18
|
+
const duration = item.durationMs ?? DEFAULT_DURATION_MS;
|
|
19
|
+
timers.set(item.id, setTimeout(() => {
|
|
20
|
+
onDismiss(item.id);
|
|
21
|
+
timers.delete(item.id);
|
|
22
|
+
}, duration));
|
|
23
|
+
}
|
|
24
|
+
return () => {
|
|
25
|
+
for (const timer of timers.values()) {
|
|
26
|
+
clearTimeout(timer);
|
|
27
|
+
}
|
|
28
|
+
timers.clear();
|
|
29
|
+
};
|
|
30
|
+
}, [items, onDismiss]);
|
|
31
|
+
if (items.length === 0)
|
|
32
|
+
return null;
|
|
33
|
+
return (_jsx("div", { className: "pointer-events-none fixed bottom-sp-7 right-sp-7 z-[120] flex max-w-[min(100vw-2rem,360px)] flex-col gap-sp-4", "aria-live": "polite", "aria-relevant": "additions", "data-testid": "toast-viewport", children: items.map((item) => {
|
|
34
|
+
const kind = item.kind ?? "success";
|
|
35
|
+
return (_jsxs("div", { className: "pointer-events-auto flex animate-toast-in items-start gap-sp-4 rounded-lg border border-[color:var(--border-strong)] bg-overlay p-sp-5 shadow-overlay motion-reduce:animate-none", "data-testid": `toast-${item.id}`, role: "status", children: [_jsx("span", { "aria-hidden": "true", className: `grid h-[26px] w-[26px] shrink-0 place-items-center rounded-md ${kindClasses[kind]}`, children: _jsx("span", { className: "h-2 w-2 rounded-full bg-current" }) }), _jsxs("div", { className: "min-w-0 flex-1 text-left", children: [_jsx("p", { className: "m-0 text-fg", style: { fontSize: "var(--text-body)", lineHeight: "var(--lh-body)" }, children: item.title }), item.description ? (_jsx("p", { className: "mt-sp-1 m-0 text-fg-subtle", style: { fontSize: "var(--text-small)", lineHeight: "var(--lh-small)" }, children: item.description })) : null] }), _jsx("button", { type: "button", className: "shrink-0 rounded-sm px-sp-2 py-sp-1 text-fg-subtle transition-colors hover:bg-raised hover:text-fg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent", onClick: () => {
|
|
36
|
+
onDismiss(item.id);
|
|
37
|
+
}, "aria-label": dismissLabel, children: "\u00D7" })] }, item.id));
|
|
38
|
+
}) }));
|
|
39
|
+
}
|
|
40
|
+
export function ToastProvider({ children, dismissLabel }) {
|
|
41
|
+
const [items, setItems] = useState([]);
|
|
42
|
+
const dismiss = useCallback((id) => {
|
|
43
|
+
setItems((current) => current.filter((item) => item.id !== id));
|
|
44
|
+
}, []);
|
|
45
|
+
const toast = useCallback((input) => {
|
|
46
|
+
const id = typeof crypto !== "undefined" && "randomUUID" in crypto
|
|
47
|
+
? crypto.randomUUID()
|
|
48
|
+
: `${String(Date.now())}-${Math.random().toString(16).slice(2)}`;
|
|
49
|
+
setItems((current) => [...current, { ...input, id }]);
|
|
50
|
+
return id;
|
|
51
|
+
}, []);
|
|
52
|
+
const value = useMemo(() => ({ toast, dismiss }), [toast, dismiss]);
|
|
53
|
+
return (_jsxs(ToastContext.Provider, { value: value, children: [children, _jsx(ToastViewport, { items: items, onDismiss: dismiss, dismissLabel: dismissLabel })] }));
|
|
54
|
+
}
|
|
55
|
+
export function useToast() {
|
|
56
|
+
const context = useContext(ToastContext);
|
|
57
|
+
if (!context) {
|
|
58
|
+
throw new Error("useToast must be used within ToastProvider");
|
|
59
|
+
}
|
|
60
|
+
return context;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=ToastProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToastProvider.js","sourceRoot":"","sources":["../../src/components/ToastProvider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
export declare const TooltipProvider: import("react").FC<TooltipPrimitive.TooltipProviderProps>;
|
|
4
|
+
export declare const Tooltip: import("react").FC<TooltipPrimitive.TooltipProps>;
|
|
5
|
+
export declare const TooltipTrigger: import("react").ForwardRefExoticComponent<TooltipPrimitive.TooltipTriggerProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
6
|
+
export type TooltipContentProps = {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
testId?: string;
|
|
10
|
+
sideOffset?: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function TooltipContent({ children, className, testId, sideOffset, }: TooltipContentProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=Tooltip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../src/components/Tooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,eAAO,MAAM,eAAe,2DAA4B,CAAC;AACzD,eAAO,MAAM,OAAO,mDAAwB,CAAC;AAC7C,eAAO,MAAM,cAAc,oIAA2B,CAAC;AAEvD,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,SAAc,EACd,MAAM,EACN,UAAc,GACf,EAAE,mBAAmB,2CAarB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
3
|
+
export const TooltipProvider = TooltipPrimitive.Provider;
|
|
4
|
+
export const Tooltip = TooltipPrimitive.Root;
|
|
5
|
+
export const TooltipTrigger = TooltipPrimitive.Trigger;
|
|
6
|
+
export function TooltipContent({ children, className = "", testId, sideOffset = 4, }) {
|
|
7
|
+
return (_jsx(TooltipPrimitive.Portal, { children: _jsxs(TooltipPrimitive.Content, { "data-testid": testId, sideOffset: sideOffset, className: `z-[130] max-w-[280px] rounded-md border border-[color:var(--border-subtle)] bg-overlay px-sp-4 py-sp-3 text-small text-fg shadow-overlay ${className}`, children: [children, _jsx(TooltipPrimitive.Arrow, { className: "fill-[color:var(--overlay)]" })] }) }));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=Tooltip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../src/components/Tooltip.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAG5D,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC,QAAQ,CAAC;AACzD,MAAM,CAAC,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC,OAAO,CAAC;AASvD,MAAM,UAAU,cAAc,CAAC,EAC7B,QAAQ,EACR,SAAS,GAAG,EAAE,EACd,MAAM,EACN,UAAU,GAAG,CAAC,GACM;IACpB,OAAO,CACL,KAAC,gBAAgB,CAAC,MAAM,cACtB,MAAC,gBAAgB,CAAC,OAAO,mBACV,MAAM,EACnB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,4IAA4I,SAAS,EAAE,aAEjK,QAAQ,EACT,KAAC,gBAAgB,CAAC,KAAK,IAAC,SAAS,EAAC,6BAA6B,GAAG,IACzC,GACH,CAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type AuthShellBrandLabels = {
|
|
3
|
+
headline: string;
|
|
4
|
+
subline: string;
|
|
5
|
+
footer: string;
|
|
6
|
+
};
|
|
7
|
+
export type AuthShellProps = {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
brand: AuthShellBrandLabels;
|
|
10
|
+
/** Setup wizard omits slug rows in the brand rail (spec §8.3) */
|
|
11
|
+
showSlugRows?: boolean;
|
|
12
|
+
/** Brand icon URL (web serves `/slugbase_icon.svg`) */
|
|
13
|
+
iconSrc?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Shared two-pane auth layout (prototype AuthKit.jsx / auth.css).
|
|
17
|
+
* Left pane: brand rail (gradient wash, hero, optional slug rows).
|
|
18
|
+
* Right pane: form card at min(404px, 100%).
|
|
19
|
+
* Grid: minmax(440px, 0.9fr) 1fr; brand hidden below 920px.
|
|
20
|
+
*/
|
|
21
|
+
export declare function AuthShell({ children, brand, showSlugRows, iconSrc, }: AuthShellProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export declare function AuthInput({ leadingIcon, trailingSlot, className, style, ...inputProps }: React.InputHTMLAttributes<HTMLInputElement> & {
|
|
23
|
+
leadingIcon?: ReactNode;
|
|
24
|
+
trailingSlot?: ReactNode;
|
|
25
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export interface OidcProviderItem {
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
}
|
|
30
|
+
export type SsoSectionProps = {
|
|
31
|
+
providers: OidcProviderItem[];
|
|
32
|
+
mode: "login" | "register";
|
|
33
|
+
t: (key: string, params?: Record<string, string>) => string;
|
|
34
|
+
/** Base URL for OIDC authorize links (e.g. API origin) */
|
|
35
|
+
apiBaseUrl?: string;
|
|
36
|
+
};
|
|
37
|
+
export declare function SsoSection({ providers, mode, t, apiBaseUrl }: SsoSectionProps): import("react/jsx-runtime").JSX.Element | null;
|
|
38
|
+
export declare function MailFieldIcon(): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
export declare function LockFieldIcon(): import("react/jsx-runtime").JSX.Element;
|
|
40
|
+
export declare function UserFieldIcon(): import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
export declare function KeyFieldIcon(): import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
export declare function AuthButton({ children, isSubmitting, disabled, className, style, }: {
|
|
43
|
+
children: React.ReactNode;
|
|
44
|
+
isSubmitting?: boolean;
|
|
45
|
+
disabled?: boolean;
|
|
46
|
+
className?: string;
|
|
47
|
+
style?: React.CSSProperties;
|
|
48
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
export declare function AuthHeading({ title, subtitle, }: {
|
|
50
|
+
title: string;
|
|
51
|
+
subtitle?: string;
|
|
52
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
53
|
+
export declare function ErrorBanner({ message }: {
|
|
54
|
+
message: string;
|
|
55
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
56
|
+
export declare function SuccessBanner({ message }: {
|
|
57
|
+
message: string;
|
|
58
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
59
|
+
//# sourceMappingURL=auth-kit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-kit.d.ts","sourceRoot":"","sources":["../../src/components/auth-kit.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,oBAAoB,CAAC;IAC5B,iEAAiE;IACjE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,KAAK,EACL,YAAmB,EACnB,OAA8B,GAC/B,EAAE,cAAc,2CA6GhB;AAqDD,wBAAgB,SAAS,CAAC,EACxB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,KAAK,EACL,GAAG,UAAU,EACd,EAAE,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,GAAG;IAC/C,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE,SAAS,CAAC;CAC1B,2CAiCA;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;IAC3B,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC;IAC5D,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,UAAe,EAAE,EAAE,eAAe,kDAoClF;AAsBD,wBAAgB,aAAa,4CAiB5B;AAED,wBAAgB,aAAa,4CAiB5B;AAED,wBAAgB,aAAa,4CAiB5B;AAED,wBAAgB,YAAY,4CAkB3B;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B,2CAWA;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,2CAyBA;AAED,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,2CAe3D;AAED,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,2CAe7D"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Shared two-pane auth layout (prototype AuthKit.jsx / auth.css).
|
|
4
|
+
* Left pane: brand rail (gradient wash, hero, optional slug rows).
|
|
5
|
+
* Right pane: form card at min(404px, 100%).
|
|
6
|
+
* Grid: minmax(440px, 0.9fr) 1fr; brand hidden below 920px.
|
|
7
|
+
*/
|
|
8
|
+
export function AuthShell({ children, brand, showSlugRows = true, iconSrc = "/slugbase_icon.svg", }) {
|
|
9
|
+
return (_jsxs("div", { className: "min-h-screen bg-canvas font-sans grid grid-cols-1 min-[920px]:grid-cols-[minmax(440px,0.9fr)_1fr]", "data-testid": "auth-shell", children: [_jsxs("aside", { className: "relative overflow-hidden hidden min-[920px]:flex flex-col justify-between border-r border-[color:var(--border-subtle)] bg-base", style: { padding: "var(--sp-11) var(--sp-11) var(--sp-10)", gap: "var(--sp-8)" }, "aria-hidden": "true", "data-testid": "auth-shell-brand-rail", children: [_jsx("div", { className: "absolute pointer-events-none", style: {
|
|
10
|
+
top: "-180px",
|
|
11
|
+
left: "-140px",
|
|
12
|
+
width: "460px",
|
|
13
|
+
height: "460px",
|
|
14
|
+
background: "radial-gradient(circle, var(--accent-subtle) 0%, transparent 68%)",
|
|
15
|
+
} }), _jsxs("div", { className: "relative flex items-center", style: { gap: "var(--sp-4)" }, children: [_jsx("img", { src: iconSrc, alt: "", width: 30, height: 30, className: "shrink-0" }), _jsx("span", { className: "text-fg", style: {
|
|
16
|
+
fontWeight: "var(--weight-semi)",
|
|
17
|
+
fontSize: "var(--text-h2)",
|
|
18
|
+
lineHeight: "var(--lh-h2)",
|
|
19
|
+
letterSpacing: "var(--track-tight)",
|
|
20
|
+
}, children: "SlugBase" })] }), _jsxs("div", { className: "relative flex flex-col flex-1 justify-center", style: { gap: "var(--sp-8)" }, children: [_jsxs("div", { style: { maxWidth: "30ch" }, children: [_jsx("h1", { className: "text-fg", style: {
|
|
21
|
+
margin: 0,
|
|
22
|
+
marginBottom: "var(--sp-5)",
|
|
23
|
+
fontWeight: "var(--weight-semi)",
|
|
24
|
+
fontSize: "var(--text-display)",
|
|
25
|
+
lineHeight: "var(--lh-display)",
|
|
26
|
+
letterSpacing: "var(--track-tight)",
|
|
27
|
+
}, children: brand.headline }), _jsx("p", { className: "text-fg-muted", style: { margin: 0, fontSize: "var(--text-body-lg)", lineHeight: "var(--lh-body-lg)" }, children: brand.subline })] }), showSlugRows && (_jsxs("div", { className: "relative flex flex-col", style: { gap: "var(--sp-3)" }, children: [_jsx(BrandSlugRow, { src: "cloud.slugbase.app/react19", dst: "react.dev/blog", opacity: 1 }), _jsx(BrandSlugRow, { src: "cloud.slugbase.app/ddia", dst: "dataintensive.net", opacity: 0.55 }), _jsx(BrandSlugRow, { src: "cloud.slugbase.app/rustperf", dst: "nnethercote.github.io", opacity: 0.28 })] }))] }), _jsx("p", { className: "relative text-fg-subtle", style: { fontSize: "var(--text-small)", lineHeight: "var(--lh-small)" }, children: brand.footer })] }), _jsx("div", { className: "grid place-items-center", style: { padding: "var(--sp-9) var(--sp-8)" }, "data-testid": "auth-shell-form-pane", children: _jsxs("div", { style: { width: "min(404px, 100%)" }, children: [_jsxs("div", { className: "flex min-[920px]:hidden items-center", style: { gap: "var(--sp-4)", marginBottom: "var(--sp-8)" }, children: [_jsx("img", { src: iconSrc, alt: "", width: 26, height: 26, className: "shrink-0" }), _jsx("span", { className: "text-fg", style: { fontWeight: "var(--weight-semi)", fontSize: "var(--text-h3)" }, children: "SlugBase" })] }), children] }) })] }));
|
|
28
|
+
}
|
|
29
|
+
function BrandSlugRow({ src, dst, opacity, }) {
|
|
30
|
+
return (_jsxs("div", { className: "flex items-center border border-[color:var(--border-subtle)] bg-raised", style: {
|
|
31
|
+
opacity,
|
|
32
|
+
padding: "var(--sp-4) var(--sp-5)",
|
|
33
|
+
borderRadius: "var(--r-lg)",
|
|
34
|
+
gap: "var(--sp-4)",
|
|
35
|
+
fontFamily: "var(--font-mono)",
|
|
36
|
+
fontWeight: "var(--weight-medium)",
|
|
37
|
+
fontSize: "var(--text-mono)",
|
|
38
|
+
lineHeight: 1,
|
|
39
|
+
}, children: [_jsx("span", { className: "text-accent-text shrink-0", children: src }), _jsx("span", { className: "text-fg-faint shrink-0", children: _jsx(ArrowRightIcon, {}) }), _jsx("span", { className: "text-fg-subtle overflow-hidden text-ellipsis whitespace-nowrap", children: dst })] }));
|
|
40
|
+
}
|
|
41
|
+
function ArrowRightIcon() {
|
|
42
|
+
return (_jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M5 12h14" }), _jsx("path", { d: "m12 5 7 7-7 7" })] }));
|
|
43
|
+
}
|
|
44
|
+
export function AuthInput({ leadingIcon, trailingSlot, className, style, ...inputProps }) {
|
|
45
|
+
const paddingLeft = leadingIcon ? "calc(var(--sp-4) + 16px + var(--sp-3))" : "var(--sp-5)";
|
|
46
|
+
const paddingRight = trailingSlot ? "2.5rem" : "var(--sp-5)";
|
|
47
|
+
return (_jsxs("div", { className: "relative", children: [leadingIcon && (_jsx("span", { className: "absolute inset-y-0 left-0 flex items-center text-fg-subtle pointer-events-none", style: { paddingLeft: "var(--sp-4)" }, children: leadingIcon })), _jsx("input", { ...inputProps, className: `w-full rounded-md border border-[color:var(--border)] bg-raised text-fg placeholder:text-fg-faint focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-2 focus:ring-offset-canvas disabled:cursor-not-allowed disabled:opacity-50 ${className ?? ""}`, style: {
|
|
48
|
+
height: "42px",
|
|
49
|
+
paddingLeft,
|
|
50
|
+
paddingRight,
|
|
51
|
+
fontSize: "var(--text-body-lg)",
|
|
52
|
+
lineHeight: "var(--lh-body-lg)",
|
|
53
|
+
...style,
|
|
54
|
+
} }), trailingSlot && (_jsx("div", { className: "absolute inset-y-0 right-0 flex items-center pr-sp-4", children: trailingSlot }))] }));
|
|
55
|
+
}
|
|
56
|
+
export function SsoSection({ providers, mode, t, apiBaseUrl = "" }) {
|
|
57
|
+
if (providers.length === 0)
|
|
58
|
+
return null;
|
|
59
|
+
const labelKey = mode === "login" ? "auth.sso.sign_in_with" : "auth.sso.sign_up_with";
|
|
60
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center", style: { gap: "var(--sp-5)", margin: "var(--sp-2) 0" }, children: [_jsx("span", { className: "flex-1 h-px bg-[color:var(--border-subtle)]", "aria-hidden": "true" }), _jsx("span", { className: "text-fg-subtle lowercase", style: { fontSize: "var(--text-small)" }, children: t("auth.sso.divider") }), _jsx("span", { className: "flex-1 h-px bg-[color:var(--border-subtle)]", "aria-hidden": "true" })] }), _jsx("div", { className: "flex flex-col", style: { gap: "var(--sp-4)" }, children: providers.map((p) => (_jsxs("a", { href: `${apiBaseUrl}/auth/oidc/${p.id}/authorize`, className: "flex items-center justify-center border border-[color:var(--border)] bg-raised text-fg font-medium transition-colors hover:bg-raised-2 hover:border-[color:var(--border-strong)]", style: {
|
|
61
|
+
height: "44px",
|
|
62
|
+
borderRadius: "var(--r-md)",
|
|
63
|
+
gap: "var(--sp-4)",
|
|
64
|
+
fontSize: "var(--text-body-lg)",
|
|
65
|
+
lineHeight: 1,
|
|
66
|
+
}, children: [_jsx(ExternalProviderIcon, {}), t(labelKey, { provider: p.name })] }, p.id))) })] }));
|
|
67
|
+
}
|
|
68
|
+
function ExternalProviderIcon() {
|
|
69
|
+
return (_jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" }), _jsx("path", { d: "M2 12h20" })] }));
|
|
70
|
+
}
|
|
71
|
+
export function MailFieldIcon() {
|
|
72
|
+
return (_jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("rect", { width: "20", height: "16", x: "2", y: "4", rx: "2" }), _jsx("path", { d: "m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" })] }));
|
|
73
|
+
}
|
|
74
|
+
export function LockFieldIcon() {
|
|
75
|
+
return (_jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("rect", { width: "18", height: "11", x: "3", y: "11", rx: "2", ry: "2" }), _jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] }));
|
|
76
|
+
}
|
|
77
|
+
export function UserFieldIcon() {
|
|
78
|
+
return (_jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("circle", { cx: "12", cy: "8", r: "5" }), _jsx("path", { d: "M20 21a8 8 0 0 0-16 0" })] }));
|
|
79
|
+
}
|
|
80
|
+
export function KeyFieldIcon() {
|
|
81
|
+
return (_jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("circle", { cx: "7.5", cy: "15.5", r: "5.5" }), _jsx("path", { d: "m21 2-9.6 9.6" }), _jsx("path", { d: "m15.5 7.5 3 3L22 7l-3-3" })] }));
|
|
82
|
+
}
|
|
83
|
+
export function AuthButton({ children, isSubmitting, disabled, className, style, }) {
|
|
84
|
+
return (_jsx("button", { type: "submit", disabled: isSubmitting || disabled, className: `w-full rounded-md bg-accent font-medium text-accent-fg transition-colors hover:bg-accent-hover active:bg-accent-active disabled:cursor-not-allowed disabled:opacity-50 ${className ?? ""}`, style: { height: "44px", fontSize: "var(--text-body-lg)", lineHeight: 1, ...style }, children: children }));
|
|
85
|
+
}
|
|
86
|
+
export function AuthHeading({ title, subtitle, }) {
|
|
87
|
+
return (_jsxs("div", { style: { marginBottom: "var(--sp-8)" }, children: [_jsx("h2", { className: "text-fg", style: {
|
|
88
|
+
margin: subtitle ? "0 0 var(--sp-4)" : 0,
|
|
89
|
+
fontWeight: "var(--weight-semi)",
|
|
90
|
+
fontSize: "var(--text-h1)",
|
|
91
|
+
lineHeight: "var(--lh-h1)",
|
|
92
|
+
letterSpacing: "var(--track-tight)",
|
|
93
|
+
}, children: title }), subtitle && (_jsx("p", { className: "text-fg-muted", style: { margin: 0, fontSize: "var(--text-body-lg)", lineHeight: "var(--lh-body-lg)" }, children: subtitle }))] }));
|
|
94
|
+
}
|
|
95
|
+
export function ErrorBanner({ message }) {
|
|
96
|
+
return (_jsx("div", { role: "alert", className: "flex items-start rounded-md border border-[color:var(--danger-subtle)] bg-[color:var(--danger-subtle)] px-sp-4 py-sp-3", style: { gap: "var(--sp-3)" }, children: _jsx("p", { className: "text-danger-text", style: { fontSize: "var(--text-small)", lineHeight: "var(--lh-small)" }, children: message }) }));
|
|
97
|
+
}
|
|
98
|
+
export function SuccessBanner({ message }) {
|
|
99
|
+
return (_jsx("div", { role: "status", className: "flex items-start rounded-md border border-[color:var(--success-subtle)] bg-[color:var(--success-subtle)] px-sp-4 py-sp-3", style: { gap: "var(--sp-3)" }, children: _jsx("p", { className: "text-success-text", style: { fontSize: "var(--text-small)", lineHeight: "var(--lh-small)" }, children: message }) }));
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=auth-kit.js.map
|