@hexdspace/react 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -3
- package/dist/css/base-theme.css +0 -5
- package/dist/css/entry.css +1 -0
- package/dist/css/primitive.css +16 -10
- package/dist/css/semantic.css +30 -17
- package/dist/index.d.ts +49 -13
- package/dist/index.js +361 -90
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hexdspace/react
|
|
2
2
|
|
|
3
|
-
React basic features, UI components plus a Tailwind v4-compatible theme CSS.
|
|
3
|
+
React basic features, UI components, plus a Tailwind v4-compatible theme CSS.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -17,9 +17,21 @@ pnpm add react react-dom react-router-dom radix-ui lucide-react react-toastify @
|
|
|
17
17
|
Tailwind requirements (for the theme + utilities):
|
|
18
18
|
|
|
19
19
|
```sh
|
|
20
|
-
pnpm add -D tailwindcss
|
|
20
|
+
pnpm add -D tailwindcss tailwind-scrollbar
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
if you're on Vite:
|
|
24
|
+
```sh
|
|
25
|
+
pnpm add -D @tailwindcss/vite
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
if using postcss instead:
|
|
29
|
+
```shell
|
|
30
|
+
pnpm add @tailwindcss/postcss
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
and configure your postcss pipeline to include tailwind.
|
|
34
|
+
|
|
23
35
|
## Usage
|
|
24
36
|
|
|
25
37
|
Import the theme into your Tailwind entry stylesheet and specify tailwind config:
|
|
@@ -27,7 +39,7 @@ Import the theme into your Tailwind entry stylesheet and specify tailwind config
|
|
|
27
39
|
```css
|
|
28
40
|
/* src/index.css */
|
|
29
41
|
@import "@hexdspace/react/css";
|
|
30
|
-
@config "../tailwind.config.ts"; /* adjust path
|
|
42
|
+
@config "../tailwind.config.ts"; /* adjust path */
|
|
31
43
|
|
|
32
44
|
/* Your app styles */
|
|
33
45
|
```
|
package/dist/css/base-theme.css
CHANGED
|
@@ -95,11 +95,6 @@
|
|
|
95
95
|
--color-warning: var(--warning);
|
|
96
96
|
--color-danger: var(--danger);
|
|
97
97
|
|
|
98
|
-
--color-info-soft: var(--info-soft);
|
|
99
|
-
--color-success-soft: var(--success-soft);
|
|
100
|
-
--color-warning-soft: var(--warning-soft);
|
|
101
|
-
--color-danger-soft: var(--danger-soft);
|
|
102
|
-
|
|
103
98
|
--color-on-info: var(--on-info);
|
|
104
99
|
--color-on-success: var(--on-success);
|
|
105
100
|
--color-on-warning: var(--on-warning);
|
package/dist/css/entry.css
CHANGED
package/dist/css/primitive.css
CHANGED
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
--shape-radius-50: 1.5rem; /* 24px */
|
|
20
20
|
--shape-radius-pill: 999px;
|
|
21
21
|
|
|
22
|
+
/* Motion */
|
|
23
|
+
--motion-fast: 0.1s;
|
|
24
|
+
--motion-med: 0.16s;
|
|
25
|
+
--motion-slow: 0.24s;
|
|
26
|
+
|
|
22
27
|
/* Neutral ramp */
|
|
23
28
|
--ink-10: oklch(0.92 0.043 258);
|
|
24
29
|
--ink-20: oklch(0.84 0.043 258);
|
|
@@ -32,16 +37,17 @@
|
|
|
32
37
|
--ink-100: oklch(0.16 0.025 258);
|
|
33
38
|
|
|
34
39
|
/* Accent */
|
|
35
|
-
|
|
36
|
-
--accent-
|
|
37
|
-
--accent-
|
|
38
|
-
--accent-
|
|
39
|
-
--accent-
|
|
40
|
-
--accent-
|
|
41
|
-
--accent-
|
|
42
|
-
--accent-
|
|
43
|
-
--accent-
|
|
44
|
-
--accent-
|
|
40
|
+
/* Accent (cool mint green) */
|
|
41
|
+
--accent-10: oklch(0.93 0.028 160);
|
|
42
|
+
--accent-20: oklch(0.87 0.052 160);
|
|
43
|
+
--accent-30: oklch(0.84 0.068 160);
|
|
44
|
+
--accent-40: oklch(0.80 0.085 160);
|
|
45
|
+
--accent-50: oklch(0.74 0.105 160);
|
|
46
|
+
--accent-60: oklch(0.66 0.125 160);
|
|
47
|
+
--accent-70: oklch(0.58 0.135 160);
|
|
48
|
+
--accent-80: oklch(0.48 0.125 160);
|
|
49
|
+
--accent-90: oklch(0.42 0.105 160);
|
|
50
|
+
--accent-100: oklch(0.36 0.105 160);
|
|
45
51
|
|
|
46
52
|
/* Brand ramp */
|
|
47
53
|
--brand-10: oklch(0.97 0.020 250);
|
package/dist/css/semantic.css
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
:root {
|
|
5
5
|
/* Surfaces */
|
|
6
6
|
--bg: var(--ink-10);
|
|
7
|
-
--surface-1: color-mix(in oklab, var(--ink-10), black
|
|
7
|
+
--surface-1: color-mix(in oklab, var(--ink-10), black 10%);
|
|
8
8
|
--surface-2: color-mix(in oklab, var(--ink-10), black 6%);
|
|
9
9
|
--surface-3: color-mix(in oklab, var(--ink-10), black 4%);
|
|
10
10
|
|
|
@@ -19,14 +19,16 @@
|
|
|
19
19
|
--divider: color-mix(in oklab, var(--border), transparent 55%);
|
|
20
20
|
|
|
21
21
|
/* Brand + accent roles */
|
|
22
|
-
--brand: var(--brand-
|
|
23
|
-
--brand-strong: var(--brand-
|
|
22
|
+
--brand: var(--brand-60);
|
|
23
|
+
--brand-strong: var(--brand-80);
|
|
24
|
+
--brand-contrast: var(--brand-90);
|
|
24
25
|
|
|
25
|
-
--accent: var(--accent-
|
|
26
|
-
--accent-strong: var(--accent-
|
|
26
|
+
--accent: var(--accent-50);
|
|
27
|
+
--accent-strong: var(--accent-70);
|
|
28
|
+
--accent-contrast: var(--accent-80);
|
|
27
29
|
|
|
28
30
|
/* UI roles */
|
|
29
|
-
--link: var(--accent);
|
|
31
|
+
--link: var(--accent-contrast);
|
|
30
32
|
--link-hover: color-mix(in oklab, var(--link), white 14%);
|
|
31
33
|
--focus: var(--brand);
|
|
32
34
|
--focus-ring: 0 0 0 3px color-mix(in oklab, var(--focus), transparent 60%);
|
|
@@ -37,10 +39,10 @@
|
|
|
37
39
|
--warning: var(--warning-60);
|
|
38
40
|
--danger: var(--danger-60);
|
|
39
41
|
|
|
40
|
-
--info-
|
|
41
|
-
--success-
|
|
42
|
-
--warning-
|
|
43
|
-
--danger-
|
|
42
|
+
--info-contrast: var(--info-90);
|
|
43
|
+
--success-contrast: var(--success-80);
|
|
44
|
+
--warning-contrast: var(--warning-90);
|
|
45
|
+
--danger-contrast: var(--danger-80);
|
|
44
46
|
|
|
45
47
|
/* On-colors */
|
|
46
48
|
--on-info: oklch(0.16 0 0);
|
|
@@ -49,8 +51,8 @@
|
|
|
49
51
|
--on-danger: oklch(0.16 0 0);
|
|
50
52
|
|
|
51
53
|
/* Interaction tokens */
|
|
52
|
-
--surface-hover: color-mix(in oklab, var(--surface-1), black
|
|
53
|
-
--surface-active: color-mix(in oklab, var(--surface-1), black
|
|
54
|
+
--surface-hover: color-mix(in oklab, var(--surface-1), black 2%);
|
|
55
|
+
--surface-active: color-mix(in oklab, var(--surface-1), black 4%);
|
|
54
56
|
|
|
55
57
|
/* Overlay */
|
|
56
58
|
--overlay: oklch(0.16 0 0 / 0.40);
|
|
@@ -88,13 +90,15 @@
|
|
|
88
90
|
--border: var(--ink-40);
|
|
89
91
|
--divider: color-mix(in oklab, var(--border), transparent 40%);
|
|
90
92
|
|
|
91
|
-
--brand: var(--brand-
|
|
92
|
-
--brand-strong: var(--brand-
|
|
93
|
+
--brand: var(--brand-80);
|
|
94
|
+
--brand-strong: var(--brand-100);
|
|
95
|
+
--brand-contrast: var(--brand-50);
|
|
93
96
|
|
|
94
|
-
--accent: var(--accent-
|
|
95
|
-
--accent-strong: var(--accent-
|
|
97
|
+
--accent: var(--accent-80);
|
|
98
|
+
--accent-strong: var(--accent-100);
|
|
99
|
+
--accent-contrast: var(--accent-50);
|
|
96
100
|
|
|
97
|
-
--link: var(--accent);
|
|
101
|
+
--link: var(--accent-contrast);
|
|
98
102
|
--link-hover: color-mix(in oklab, var(--link), white 18%);
|
|
99
103
|
--focus: var(--brand);
|
|
100
104
|
--focus-ring: 0 0 0 3px color-mix(in oklab, var(--focus), transparent 60%);
|
|
@@ -104,6 +108,11 @@
|
|
|
104
108
|
--warning: var(--warning-60);
|
|
105
109
|
--danger: var(--danger-60);
|
|
106
110
|
|
|
111
|
+
--info-contrast: var(--info-50);
|
|
112
|
+
--success-contrast: var(--success-50);
|
|
113
|
+
--warning-contrast: var(--warning-50);
|
|
114
|
+
--danger-contrast: var(--danger-50);
|
|
115
|
+
|
|
107
116
|
--surface-hover: color-mix(in oklab, var(--surface-1), white 6%);
|
|
108
117
|
--surface-active: color-mix(in oklab, var(--surface-1), white 8%);
|
|
109
118
|
|
|
@@ -118,3 +127,7 @@
|
|
|
118
127
|
--disabled-bg: color-mix(in oklab, var(--surface-2), transparent 35%);
|
|
119
128
|
--disabled-border: color-mix(in oklab, var(--border), transparent 55%);
|
|
120
129
|
}
|
|
130
|
+
|
|
131
|
+
@media (prefers-reduced-motion: reduce) {
|
|
132
|
+
transition-duration: 1ms; animation-duration: 1ms;
|
|
133
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -352,17 +352,6 @@ type AuthControllerProviderProps = {
|
|
|
352
352
|
};
|
|
353
353
|
declare function AuthControllerProvider({ children, controller }: AuthControllerProviderProps): react_jsx_runtime.JSX.Element;
|
|
354
354
|
|
|
355
|
-
interface InputProps {
|
|
356
|
-
id: string;
|
|
357
|
-
label: string;
|
|
358
|
-
type: string;
|
|
359
|
-
value: string;
|
|
360
|
-
onChange: (e: React__default.ChangeEvent<HTMLInputElement>) => void;
|
|
361
|
-
placeholder: string;
|
|
362
|
-
className?: string;
|
|
363
|
-
}
|
|
364
|
-
declare const AuthFormInputField: React__default.FC<InputProps>;
|
|
365
|
-
|
|
366
355
|
type RequireAuthProps = {
|
|
367
356
|
guarded?: ReactNode;
|
|
368
357
|
loadingPlaceholder?: ReactNode;
|
|
@@ -400,7 +389,7 @@ declare class MockAuthHttpClient extends MockHttpClient {
|
|
|
400
389
|
}
|
|
401
390
|
|
|
402
391
|
declare const buttonVariants: (props?: ({
|
|
403
|
-
variant?: "success" | "warning" | "info" | "link" | "primary" | "secondary" | "outline" | "ghost" | "danger" | null | undefined;
|
|
392
|
+
variant?: "success" | "warning" | "info" | "link" | "primary" | "accent" | "secondary" | "outline" | "ghost" | "danger" | null | undefined;
|
|
404
393
|
size?: "icon" | "sm" | "md" | "lg" | null | undefined;
|
|
405
394
|
chrome?: "push" | "flat" | "inset" | "soft" | "glass" | "glow" | "hairline" | null | undefined;
|
|
406
395
|
fullWidth?: boolean | null | undefined;
|
|
@@ -411,7 +400,54 @@ interface ButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
411
400
|
loading?: boolean;
|
|
412
401
|
leftIcon?: React.ReactNode;
|
|
413
402
|
rightIcon?: React.ReactNode;
|
|
403
|
+
reserveLeftIcon?: boolean;
|
|
404
|
+
reserveRightIcon?: boolean;
|
|
414
405
|
}
|
|
415
406
|
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
416
407
|
|
|
417
|
-
|
|
408
|
+
type ControlLikeProps = {
|
|
409
|
+
id?: string;
|
|
410
|
+
disabled?: boolean;
|
|
411
|
+
required?: boolean;
|
|
412
|
+
invalid?: boolean;
|
|
413
|
+
"aria-describedby"?: string;
|
|
414
|
+
};
|
|
415
|
+
interface FieldProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
416
|
+
label?: React.ReactNode;
|
|
417
|
+
hint?: React.ReactNode;
|
|
418
|
+
error?: React.ReactNode;
|
|
419
|
+
required?: boolean;
|
|
420
|
+
disabled?: boolean;
|
|
421
|
+
id?: string;
|
|
422
|
+
children: React.ReactElement<ControlLikeProps>;
|
|
423
|
+
}
|
|
424
|
+
declare function Field({ label, hint, error, required, disabled, id, children, className, ...props }: FieldProps): react_jsx_runtime.JSX.Element;
|
|
425
|
+
|
|
426
|
+
declare const controlShellVariants: (props?: ({
|
|
427
|
+
variant?: "outline" | "ghost" | "surface" | null | undefined;
|
|
428
|
+
size?: "sm" | "md" | "lg" | null | undefined;
|
|
429
|
+
fullWidth?: boolean | null | undefined;
|
|
430
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
431
|
+
interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">, VariantProps<typeof controlShellVariants> {
|
|
432
|
+
invalid?: boolean;
|
|
433
|
+
leftSlot?: React.ReactNode;
|
|
434
|
+
rightSlot?: React.ReactNode;
|
|
435
|
+
reserveLeftSlot?: boolean;
|
|
436
|
+
reserveRightSlot?: boolean;
|
|
437
|
+
inputClassName?: string;
|
|
438
|
+
}
|
|
439
|
+
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
|
|
440
|
+
|
|
441
|
+
declare const textareaShellVariants: (props?: ({
|
|
442
|
+
variant?: "outline" | "ghost" | "surface" | null | undefined;
|
|
443
|
+
size?: "sm" | "md" | "lg" | null | undefined;
|
|
444
|
+
fullWidth?: boolean | null | undefined;
|
|
445
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
446
|
+
interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement>, VariantProps<typeof textareaShellVariants> {
|
|
447
|
+
invalid?: boolean;
|
|
448
|
+
textareaClassName?: string;
|
|
449
|
+
autoResize?: boolean;
|
|
450
|
+
}
|
|
451
|
+
declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
452
|
+
|
|
453
|
+
export { AuthController, AuthControllerCtx, type AuthControllerDeps, AuthControllerProvider, AuthDispatchCtx, AuthProvider, type AuthState, AuthStateCtx, Button, type ButtonProps, type CacheInstruction, type CustomInstruction, DEFAULT_NOTIFICATION_CHANNEL, type ErrorResponse, Field, type FieldProps, type GenericResponse, type HttpClient, HttpError, type HttpMethod, type HttpResponse, Input, type InputProps, type Instruction, type InstructionContext, MockAuthHttpClient, MockHttpClient, type MutationFn, type Notification, type NotificationAction, NotificationHost, type NotificationInstruction, type NotificationVariant, NotifierController, type OnSuccessFn, type OptimisticSnapshot, type OptimisticUpdateFn, RedirectIfAuthed, type RedirectIfAuthedProps, type RequestConfig, RequireAuth, type RequireAuthProps, type ResolvedToastTheme, type ResponsiveMutation, Textarea, type TextareaProps, type ToastActionTheme, type ToastTheme, type ToastTransition, type ToastifyCSSVars, type UIFail, type UIOk, type UIResult, type User, authController, controllerFactory, createAuthController, httpClient as fetchHttpClient, notifierController, resolveToastTheme, ui, useAuth, useAuthActions, useAuthController, useAuthDispatch, useAuthedUser, useResponsiveMutation };
|
package/dist/index.js
CHANGED
|
@@ -897,42 +897,9 @@ function useAuthedUser() {
|
|
|
897
897
|
return auth.user;
|
|
898
898
|
}
|
|
899
899
|
|
|
900
|
-
// src/feature/auth/interface/web/react/AuthFormInputField.tsx
|
|
901
|
-
import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
902
|
-
var inputLabelStyles = {
|
|
903
|
-
display: "block",
|
|
904
|
-
fontSize: "small",
|
|
905
|
-
fontWeight: "bolder",
|
|
906
|
-
marginBottom: "4px"
|
|
907
|
-
};
|
|
908
|
-
var inputFieldStyles = {
|
|
909
|
-
display: "block",
|
|
910
|
-
width: "100%",
|
|
911
|
-
padding: "0.5rem 0.75rem"
|
|
912
|
-
};
|
|
913
|
-
var AuthFormInputField = ({ id, label, type, value, onChange, placeholder, className }) => {
|
|
914
|
-
return /* @__PURE__ */ jsxs2("div", { children: [
|
|
915
|
-
/* @__PURE__ */ jsx5("label", { htmlFor: id, style: inputLabelStyles, children: label }),
|
|
916
|
-
/* @__PURE__ */ jsx5(
|
|
917
|
-
"input",
|
|
918
|
-
{
|
|
919
|
-
id,
|
|
920
|
-
name: id,
|
|
921
|
-
type,
|
|
922
|
-
required: true,
|
|
923
|
-
value,
|
|
924
|
-
onChange,
|
|
925
|
-
className,
|
|
926
|
-
placeholder,
|
|
927
|
-
style: inputFieldStyles
|
|
928
|
-
}
|
|
929
|
-
)
|
|
930
|
-
] });
|
|
931
|
-
};
|
|
932
|
-
|
|
933
900
|
// src/feature/auth/interface/web/react/auth-route-guards.tsx
|
|
934
901
|
import { Navigate, Outlet, useLocation } from "react-router-dom";
|
|
935
|
-
import { Fragment, jsx as
|
|
902
|
+
import { Fragment, jsx as jsx5 } from "react/jsx-runtime";
|
|
936
903
|
function RequireAuth({
|
|
937
904
|
guarded,
|
|
938
905
|
loadingPlaceholder,
|
|
@@ -943,18 +910,18 @@ function RequireAuth({
|
|
|
943
910
|
const auth = useAuth();
|
|
944
911
|
const location = useLocation();
|
|
945
912
|
if (auth.status === "loading") {
|
|
946
|
-
return /* @__PURE__ */
|
|
913
|
+
return /* @__PURE__ */ jsx5(Fragment, { children: loadingPlaceholder ?? null });
|
|
947
914
|
}
|
|
948
915
|
if (auth.status === "error") {
|
|
949
|
-
return /* @__PURE__ */
|
|
916
|
+
return /* @__PURE__ */ jsx5(Fragment, { children: errorPlaceholder ?? null });
|
|
950
917
|
}
|
|
951
918
|
if (auth.status === "unauthenticated") {
|
|
952
919
|
if (unauthenticatedRedirectTo) {
|
|
953
|
-
return /* @__PURE__ */
|
|
920
|
+
return /* @__PURE__ */ jsx5(Navigate, { to: unauthenticatedRedirectTo, replace: true, state: { from: location } });
|
|
954
921
|
}
|
|
955
|
-
return /* @__PURE__ */
|
|
922
|
+
return /* @__PURE__ */ jsx5(Fragment, { children: unauthenticatedPlaceholder ?? null });
|
|
956
923
|
}
|
|
957
|
-
return guarded ? /* @__PURE__ */
|
|
924
|
+
return guarded ? /* @__PURE__ */ jsx5(Fragment, { children: guarded }) : /* @__PURE__ */ jsx5(Outlet, {});
|
|
958
925
|
}
|
|
959
926
|
function RedirectIfAuthed({
|
|
960
927
|
redirectTo,
|
|
@@ -965,18 +932,18 @@ function RedirectIfAuthed({
|
|
|
965
932
|
}) {
|
|
966
933
|
const auth = useAuth();
|
|
967
934
|
if (auth.status === "loading") {
|
|
968
|
-
return /* @__PURE__ */
|
|
935
|
+
return /* @__PURE__ */ jsx5(Fragment, { children: loadingPlaceholder ?? null });
|
|
969
936
|
}
|
|
970
937
|
if (auth.status === "error") {
|
|
971
|
-
return /* @__PURE__ */
|
|
938
|
+
return /* @__PURE__ */ jsx5(Fragment, { children: errorPlaceholder ?? loadingPlaceholder ?? null });
|
|
972
939
|
}
|
|
973
940
|
if (auth.status === "authenticated") {
|
|
974
941
|
if (redirectTo) {
|
|
975
|
-
return /* @__PURE__ */
|
|
942
|
+
return /* @__PURE__ */ jsx5(Navigate, { to: redirectTo, replace: true });
|
|
976
943
|
}
|
|
977
|
-
return /* @__PURE__ */
|
|
944
|
+
return /* @__PURE__ */ jsx5(Fragment, { children: authenticatedPlaceholder ?? null });
|
|
978
945
|
}
|
|
979
|
-
return nonAuthedPlaceholder ? /* @__PURE__ */
|
|
946
|
+
return nonAuthedPlaceholder ? /* @__PURE__ */ jsx5(Fragment, { children: nonAuthedPlaceholder }) : /* @__PURE__ */ jsx5(Outlet, {});
|
|
980
947
|
}
|
|
981
948
|
|
|
982
949
|
// src/feature/auth/infra/mock-auth-http-client.ts
|
|
@@ -1064,22 +1031,22 @@ function cn(...inputs) {
|
|
|
1064
1031
|
}
|
|
1065
1032
|
|
|
1066
1033
|
// src/ui/components/Button.tsx
|
|
1067
|
-
import {
|
|
1034
|
+
import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1068
1035
|
var buttonBase = cn(
|
|
1069
1036
|
"relative isolate inline-flex items-center justify-center gap-2 leading-none text-sm font-medium select-none cursor-pointer",
|
|
1070
1037
|
"rounded-[var(--radius-btn)]",
|
|
1071
|
-
"shadow-[var(--
|
|
1072
|
-
"
|
|
1038
|
+
"transition-[background-color,color,box-shadow,transform] duration-[var(--motion-med)] ease",
|
|
1039
|
+
"focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]",
|
|
1073
1040
|
"[--state-hover:color-mix(in_oklab,currentColor,transparent_92%)]",
|
|
1074
1041
|
"[--state-active:color-mix(in_oklab,currentColor,transparent_86%)]",
|
|
1075
|
-
"after:content-[''] after:absolute after:inset-0 after:rounded-[inherit] after:bg-[color:var(--state-hover)] after:opacity-0 after:pointer-events-none after:transition-opacity after:duration-
|
|
1076
|
-
"hover:after:opacity-100 active:after:bg-[color:var(--state-active)] active:after:opacity-100"
|
|
1077
|
-
"disabled:opacity-50 disabled:pointer-events-none disabled:cursor-not-allowed"
|
|
1042
|
+
"after:content-[''] after:absolute after:inset-0 after:rounded-[inherit] after:bg-[color:var(--state-hover)] after:opacity-0 after:pointer-events-none after:transition-opacity after:duration-[var(--motion-fast)] after:ease",
|
|
1043
|
+
"hover:after:opacity-100 active:after:bg-[color:var(--state-active)] active:after:opacity-100"
|
|
1078
1044
|
);
|
|
1045
|
+
var flatChrome = cn();
|
|
1079
1046
|
var pushChrome = cn(
|
|
1080
|
-
"border-b-[
|
|
1047
|
+
"border-b-[3px]",
|
|
1081
1048
|
"transition-all",
|
|
1082
|
-
"duration-
|
|
1049
|
+
"duration-[var(--motion-fast)]",
|
|
1083
1050
|
"ease-out",
|
|
1084
1051
|
"shadow-[0_2px_4px_rgba(0,0,0,0.28),0_8px_16px_rgba(0,0,0,0.14)]",
|
|
1085
1052
|
"hover:shadow-[0_3px_6px_rgba(0,0,0,0.30),0_12px_22px_rgba(0,0,0,0.18)]",
|
|
@@ -1087,9 +1054,10 @@ var pushChrome = cn(
|
|
|
1087
1054
|
"active:translate-y-[1px]"
|
|
1088
1055
|
);
|
|
1089
1056
|
var softChrome = cn(
|
|
1057
|
+
"font-thin",
|
|
1090
1058
|
"border",
|
|
1091
|
-
"border-[color:color-mix(in_oklab,var(--border),
|
|
1092
|
-
"shadow-[
|
|
1059
|
+
"border-[color:color-mix(in_oklab,var(--border),transparent_80%)]",
|
|
1060
|
+
"shadow-[0_0_2px_1px_rgba(255,255,255,0.35)_inset,0_2px_4px_rgba(0,0,0,0.14)]"
|
|
1093
1061
|
);
|
|
1094
1062
|
var insetChrome = cn(
|
|
1095
1063
|
"border",
|
|
@@ -1097,7 +1065,7 @@ var insetChrome = cn(
|
|
|
1097
1065
|
"shadow-[inset_0_2px_6px_rgba(0,0,0,0.18)]"
|
|
1098
1066
|
);
|
|
1099
1067
|
var glassChrome = cn(
|
|
1100
|
-
"backdrop-blur-[
|
|
1068
|
+
"backdrop-blur-[2px]",
|
|
1101
1069
|
"border",
|
|
1102
1070
|
"shadow-[0_8px_18px_rgba(0,0,0,0.12)]"
|
|
1103
1071
|
);
|
|
@@ -1116,7 +1084,8 @@ var hairlineChrome = cn(
|
|
|
1116
1084
|
var buttonVariants = cva(buttonBase, {
|
|
1117
1085
|
variants: {
|
|
1118
1086
|
variant: {
|
|
1119
|
-
primary: "bg-[color:var(--brand)]
|
|
1087
|
+
primary: "bg-[color:var(--brand)]",
|
|
1088
|
+
accent: "bg-[color:var(--accent)]",
|
|
1120
1089
|
secondary: "border border-[color:var(--border)] bg-[color:var(--surface-2)]",
|
|
1121
1090
|
outline: "bg-transparent border border-[color:var(--border)] shadow-none",
|
|
1122
1091
|
ghost: "bg-transparent shadow-none",
|
|
@@ -1133,7 +1102,7 @@ var buttonVariants = cva(buttonBase, {
|
|
|
1133
1102
|
icon: "h-10 w-10 p-0"
|
|
1134
1103
|
},
|
|
1135
1104
|
chrome: {
|
|
1136
|
-
flat:
|
|
1105
|
+
flat: flatChrome,
|
|
1137
1106
|
push: pushChrome,
|
|
1138
1107
|
soft: softChrome,
|
|
1139
1108
|
inset: insetChrome,
|
|
@@ -1148,25 +1117,28 @@ var buttonVariants = cva(buttonBase, {
|
|
|
1148
1117
|
{ variant: "link", className: "border-0" },
|
|
1149
1118
|
{ chrome: "soft", className: "text-[color:var(--text-1)]" },
|
|
1150
1119
|
{ chrome: "glass", className: "text-[color:var(--text-1)]" },
|
|
1151
|
-
{ chrome: "push", variant: "primary", className: "border-b-[color:var(--brand-
|
|
1152
|
-
{ chrome: "push", variant: "
|
|
1153
|
-
{ chrome: "push", variant: "
|
|
1120
|
+
{ chrome: "push", variant: "primary", className: "border-b-[color:var(--brand-strong)]" },
|
|
1121
|
+
{ chrome: "push", variant: "accent", className: "border-b-[color:var(--accent-strong)]" },
|
|
1122
|
+
{ chrome: "push", variant: "secondary", className: "border-b-[color:color-mix(in_oklab,var(--border),transparent 50%)]" },
|
|
1123
|
+
{ chrome: "push", variant: "outline", className: "border-b-[color:color-mix(in_oklab,var(--border),transparent 50%)]" },
|
|
1154
1124
|
{ chrome: "push", variant: "ghost", className: "border-b-transparent shadow-none" },
|
|
1155
1125
|
{ chrome: "push", variant: "success", className: "border-b-[color:var(--success-80)]" },
|
|
1156
1126
|
{ chrome: "push", variant: "info", className: "border-b-[color:var(--info-80)]" },
|
|
1157
1127
|
{ chrome: "push", variant: "warning", className: "border-b-[color:var(--warning-80)]" },
|
|
1158
1128
|
{ chrome: "push", variant: "danger", className: "border-b-[color:var(--danger-80)]" },
|
|
1159
1129
|
{ chrome: "push", variant: "link", className: "border-b-0 shadow-none" },
|
|
1160
|
-
{ chrome: "soft", variant: "primary", className: cn("bg-[color:color-mix(in_oklab,var(--brand),transparent_70%)]", "border-[color:color-mix(in_oklab,var(--brand),
|
|
1161
|
-
{ chrome: "soft", variant: "
|
|
1162
|
-
{ chrome: "soft", variant: "
|
|
1163
|
-
{ chrome: "soft", variant: "
|
|
1164
|
-
{ chrome: "soft", variant: "
|
|
1165
|
-
{ chrome: "soft", variant: "
|
|
1166
|
-
{ chrome: "soft", variant: "
|
|
1167
|
-
{ chrome: "soft", variant: "
|
|
1168
|
-
{ chrome: "soft", variant: "
|
|
1130
|
+
{ chrome: "soft", variant: "primary", className: cn("bg-[color:color-mix(in_oklab,var(--brand),transparent_70%)]", "border-[color:color-mix(in_oklab,var(--brand),transparent_85%)]", "shadow-[0_0_2px_1px_rgba(255,255,255,0.2)_inset,0_2px_4px_color-mix(in_oklab,var(--brand),transparent_70%)]") },
|
|
1131
|
+
{ chrome: "soft", variant: "accent", className: cn("bg-[color:color-mix(in_oklab,var(--accent),transparent_70%)]", "border-[color:color-mix(in_oklab,var(--accent),transparent_85%)]", "shadow-[0_0_2px_1px_rgba(255,255,255,0.2)_inset,0_2px_4px_color-mix(in_oklab,var(--accent),transparent_70%)]") },
|
|
1132
|
+
{ chrome: "soft", variant: "secondary", className: cn("bg-[color:color-mix(in_oklab,var(--surface-2),transparent_25%)]", "border-[color:color-mix(in_oklab,var(--border),transparent_45%)]", "shadow-[0_0_2px_1px_rgba(255,255,255,0.1)_inset,0_2px_4px_color-mix(in_oklab,var(--border),transparent_70%)]") },
|
|
1133
|
+
{ chrome: "soft", variant: "outline", className: cn("border-[color:color-mix(in_oklab,var(--border),transparent_45%)]", "shadow-[0_0_2px_1px_rgba(255,255,255,0.1)_inset,0_2px_4px_color-mix(in_oklab,var(--border),transparent_70%)]") },
|
|
1134
|
+
{ chrome: "soft", variant: "ghost", className: "shadow-[0_2px_4px_color-mix(in_oklab,var(--border),transparent_75%)]" },
|
|
1135
|
+
{ chrome: "soft", variant: "success", className: cn("bg-[color:color-mix(in_oklab,var(--success),transparent_70%)]", "border-[color:color-mix(in_oklab,var(--success),transparent_75%)]", "shadow-[0_0_2px_1px_rgba(255,255,255,0.2)_inset,0_2px_4px_color-mix(in_oklab,var(--success),transparent_70%)]") },
|
|
1136
|
+
{ chrome: "soft", variant: "info", className: cn("bg-[color:color-mix(in_oklab,var(--info),transparent_70%)]", "border-[color:color-mix(in_oklab,var(--info),transparent_75%)]", "shadow-[0_0_2px_1px_rgba(255,255,255,0.2)_inset,0_2px_4px_color-mix(in_oklab,var(--info),transparent_70%)]") },
|
|
1137
|
+
{ chrome: "soft", variant: "warning", className: cn("bg-[color:color-mix(in_oklab,var(--warning),transparent_70%)]", "border-[color:color-mix(in_oklab,var(--warning),transparent_75%)]", "shadow-[0_0_2px_1px_rgba(255,255,255,0.2)_inset,0_2px_4px_color-mix(in_oklab,var(--warning),transparent_70%)]") },
|
|
1138
|
+
{ chrome: "soft", variant: "danger", className: cn("bg-[color:color-mix(in_oklab,var(--danger),transparent_70%)]", "border-[color:color-mix(in_oklab,var(--danger),transparent_75%)]", "shadow-[0_0_2px_1px_rgba(255,255,255,0.2)_inset,0_2px_4px_color-mix(in_oklab,var(--danger),transparent_70%)]") },
|
|
1139
|
+
{ chrome: "soft", variant: "link", className: cn("text-[color:var(--link)]", "shadow-[0_2px_4px_color-mix(in_oklab,var(--link),transparent_75%)]") },
|
|
1169
1140
|
{ chrome: "glass", variant: "primary", className: cn("bg-[color:color-mix(in_oklab,var(--brand),transparent_65%)]", "border-[color:var(--brand)]") },
|
|
1141
|
+
{ chrome: "glass", variant: "accent", className: cn("bg-[color:color-mix(in_oklab,var(--accent),transparent_65%)]", "border-[color:var(--accent)]") },
|
|
1170
1142
|
{ chrome: "glass", variant: "secondary", className: cn("bg-[color:color-mix(in_oklab,var(--surface-2),transparent_35%)]", "border-[color:color-mix(in_oklab,var(--border),transparent_70%)]") },
|
|
1171
1143
|
{ chrome: "glass", variant: "outline", className: "" },
|
|
1172
1144
|
{ chrome: "glass", variant: "ghost", className: "" },
|
|
@@ -1176,6 +1148,7 @@ var buttonVariants = cva(buttonBase, {
|
|
|
1176
1148
|
{ chrome: "glass", variant: "danger", className: cn("bg-[color:color-mix(in_oklab,var(--danger),transparent_65%)]", "border-[color:var(--danger)]") },
|
|
1177
1149
|
{ chrome: "glass", variant: "link", className: "text-[color:var(--link)]" },
|
|
1178
1150
|
{ chrome: "glow", variant: "primary", className: cn("border-[color:var(--brand)]", "shadow-[0_0_0_1px_color-mix(in_oklab,var(--brand),transparent_20%),0_10px_26px_color-mix(in_oklab,var(--brand),transparent_55%)]", "hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--brand),transparent_10%),0_14px_34px_color-mix(in_oklab,var(--brand),transparent_40%)]", "dark:shadow-[0_0_0_1px_color-mix(in_oklab,var(--brand),transparent_30%),0_8px_22px_color-mix(in_oklab,var(--brand),transparent_70%)]", "dark:hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--brand),transparent_15%),0_12px_30px_color-mix(in_oklab,var(--brand),transparent_55%)]") },
|
|
1151
|
+
{ chrome: "glow", variant: "accent", className: cn("border-[color:var(--accent)]", "shadow-[0_0_0_1px_color-mix(in_oklab,var(--accent),transparent_20%),0_10px_26px_color-mix(in_oklab,var(--accent),transparent_55%)]", "hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--accent),transparent_10%),0_14px_34px_color-mix(in_oklab,var(--accent),transparent_40%)]", "dark:shadow-[0_0_0_1px_color-mix(in_oklab,var(--accent),transparent_30%),0_8px_22px_color-mix(in_oklab,var(--accent),transparent_70%)]", "dark:hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--accent),transparent_15%),0_12px_30px_color-mix(in_oklab,var(--accent),transparent_55%)]") },
|
|
1179
1152
|
{ chrome: "glow", variant: "secondary", className: cn("border-[color:color-mix(in_oklab,var(--border),transparent_20%)]", "shadow-[0_0_0_1px_color-mix(in_oklab,var(--border),transparent_20%),0_10px_26px_color-mix(in_oklab,var(--border),transparent_60%)]", "hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--border),transparent_15%),0_14px_34px_color-mix(in_oklab,var(--border),transparent_45%)]", "dark:shadow-[0_0_0_1px_color-mix(in_oklab,var(--border),transparent_30%),0_8px_22px_color-mix(in_oklab,var(--border),transparent_75%)]", "dark:hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--border),transparent_20%),0_12px_30px_color-mix(in_oklab,var(--border),transparent_60%)]") },
|
|
1180
1153
|
{ chrome: "glow", variant: "outline", className: cn("border-[color:color-mix(in_oklab,var(--border),transparent_20%)]", "shadow-[0_0_0_1px_color-mix(in_oklab,var(--border),transparent_20%),0_10px_26px_color-mix(in_oklab,var(--border),transparent_60%)]", "hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--border),transparent_15%),0_14px_34px_color-mix(in_oklab,var(--border),transparent_45%)]", "dark:shadow-[0_0_0_1px_color-mix(in_oklab,var(--border),transparent_30%),0_8px_22px_color-mix(in_oklab,var(--border),transparent_75%)]", "dark:hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--border),transparent_20%),0_12px_30px_color-mix(in_oklab,var(--border),transparent_60%)]") },
|
|
1181
1154
|
{ chrome: "glow", variant: "ghost", className: "shadow-none border-transparent" },
|
|
@@ -1184,18 +1157,21 @@ var buttonVariants = cva(buttonBase, {
|
|
|
1184
1157
|
{ chrome: "glow", variant: "warning", className: cn("border-[color:var(--warning)]", "shadow-[0_0_0_1px_color-mix(in_oklab,var(--warning),transparent_20%),0_10px_26px_color-mix(in_oklab,var(--warning),transparent_55%)]", "hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--warning),transparent_10%),0_14px_34px_color-mix(in_oklab,var(--warning),transparent_40%)]", "dark:shadow-[0_0_0_1px_color-mix(in_oklab,var(--warning),transparent_30%),0_8px_22px_color-mix(in_oklab,var(--warning),transparent_70%)]", "dark:hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--warning),transparent_15%),0_12px_30px_color-mix(in_oklab,var(--warning),transparent_55%)]") },
|
|
1185
1158
|
{ chrome: "glow", variant: "danger", className: cn("border-[color:var(--danger)]", "shadow-[0_0_0_1px_color-mix(in_oklab,var(--danger),transparent_20%),0_10px_26px_color-mix(in_oklab,var(--danger),transparent_55%)]", "hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--danger),transparent_10%),0_14px_34px_color-mix(in_oklab,var(--danger),transparent_40%)]", "dark:shadow-[0_0_0_1px_color-mix(in_oklab,var(--danger),transparent_30%),0_8px_22px_color-mix(in_oklab,var(--danger),transparent_70%)]", "dark:hover:shadow-[0_0_0_1px_color-mix(in_oklab,var(--danger),transparent_15%),0_12px_30px_color-mix(in_oklab,var(--danger),transparent_55%)]") },
|
|
1186
1159
|
{ chrome: "glow", variant: "link", className: "text-[color:var(--link)] shadow-none border-transparent" },
|
|
1187
|
-
{ chrome: "hairline", variant: "primary", className: "border-[color:color-mix(in_oklab,var(--brand),transparent_20%)] text-[color:var(--brand)]" },
|
|
1160
|
+
{ chrome: "hairline", variant: "primary", className: "border-[color:color-mix(in_oklab,var(--brand-contrast),transparent_20%)] text-[color:var(--brand-contrast)]" },
|
|
1161
|
+
{ chrome: "hairline", variant: "accent", className: "border-[color:color-mix(in_oklab,var(--accent-contrast),transparent_20%)] text-[color:var(--accent-contrast)]" },
|
|
1188
1162
|
{ chrome: "hairline", variant: "secondary", className: "border-[color:color-mix(in_oklab,var(--border),transparent_20%)] text-[color:var(--text-1)]" },
|
|
1189
1163
|
{ chrome: "hairline", variant: "outline", className: "border-[color:color-mix(in_oklab,var(--border),transparent_20%)] text-[color:var(--text-1)]" },
|
|
1190
1164
|
{ chrome: "hairline", variant: "ghost", className: "border-transparent text-[color:var(--text-1)]" },
|
|
1191
|
-
{ chrome: "hairline", variant: "success", className: "border-[color:color-mix(in_oklab,var(--success),transparent_20%)] text-[color:var(--success)]" },
|
|
1192
|
-
{ chrome: "hairline", variant: "info", className: "border-[color:color-mix(in_oklab,var(--info),transparent_20%)] text-[color:var(--info)]" },
|
|
1193
|
-
{ chrome: "hairline", variant: "warning", className: "border-[color:color-mix(in_oklab,var(--warning),transparent_20%)] text-[color:var(--warning)]" },
|
|
1194
|
-
{ chrome: "hairline", variant: "danger", className: "border-[color:color-mix(in_oklab,var(--danger),transparent_20%)] text-[color:var(--danger)]" },
|
|
1165
|
+
{ chrome: "hairline", variant: "success", className: "border-[color:color-mix(in_oklab,var(--success),transparent_20%)] text-[color:var(--success-contrast)]" },
|
|
1166
|
+
{ chrome: "hairline", variant: "info", className: "border-[color:color-mix(in_oklab,var(--info),transparent_20%)] text-[color:var(--info-contrast)]" },
|
|
1167
|
+
{ chrome: "hairline", variant: "warning", className: "border-[color:color-mix(in_oklab,var(--warning),transparent_20%)] text-[color:var(--warning-contrast)]" },
|
|
1168
|
+
{ chrome: "hairline", variant: "danger", className: "border-[color:color-mix(in_oklab,var(--danger),transparent_20%)] text-[color:var(--danger-contrast)]" },
|
|
1195
1169
|
{ chrome: "hairline", variant: "link", className: "text-[color:var(--link)] border-transparent" }
|
|
1196
1170
|
],
|
|
1197
1171
|
defaultVariants: { variant: "primary", size: "md", chrome: "flat", fullWidth: false }
|
|
1198
1172
|
});
|
|
1173
|
+
var iconSlotBase = cn("inline-flex items-center justify-center", "shrink-0");
|
|
1174
|
+
var iconSlotReserve = "min-w-4 min-h-4";
|
|
1199
1175
|
var Button = React3.forwardRef(
|
|
1200
1176
|
({
|
|
1201
1177
|
asChild = false,
|
|
@@ -1208,6 +1184,8 @@ var Button = React3.forwardRef(
|
|
|
1208
1184
|
disabled,
|
|
1209
1185
|
leftIcon,
|
|
1210
1186
|
rightIcon,
|
|
1187
|
+
reserveLeftIcon,
|
|
1188
|
+
reserveRightIcon,
|
|
1211
1189
|
children,
|
|
1212
1190
|
onClick,
|
|
1213
1191
|
type,
|
|
@@ -1219,19 +1197,19 @@ var Button = React3.forwardRef(
|
|
|
1219
1197
|
isDisabled && "opacity-50 pointer-events-none cursor-not-allowed",
|
|
1220
1198
|
className
|
|
1221
1199
|
);
|
|
1222
|
-
const
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1200
|
+
const showLeftSlot = Boolean(loading || leftIcon || reserveLeftIcon);
|
|
1201
|
+
const showRightSlot = Boolean(rightIcon || reserveRightIcon);
|
|
1202
|
+
const spinner = /* @__PURE__ */ jsx6(
|
|
1203
|
+
"span",
|
|
1204
|
+
{
|
|
1205
|
+
"aria-hidden": "true",
|
|
1206
|
+
className: "inline-block h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent"
|
|
1207
|
+
}
|
|
1208
|
+
);
|
|
1209
|
+
const leftSlot = showLeftSlot ? /* @__PURE__ */ jsx6("span", { className: cn(iconSlotBase, reserveLeftIcon && iconSlotReserve), children: loading ? spinner : leftIcon }) : null;
|
|
1210
|
+
const rightSlot = showRightSlot ? /* @__PURE__ */ jsx6("span", { className: cn(iconSlotBase, reserveRightIcon && iconSlotReserve), children: rightIcon }) : null;
|
|
1233
1211
|
if (asChild) {
|
|
1234
|
-
return /* @__PURE__ */
|
|
1212
|
+
return /* @__PURE__ */ jsxs2(
|
|
1235
1213
|
Slot.Root,
|
|
1236
1214
|
{
|
|
1237
1215
|
ref,
|
|
@@ -1249,11 +1227,15 @@ var Button = React3.forwardRef(
|
|
|
1249
1227
|
onClick?.(e);
|
|
1250
1228
|
},
|
|
1251
1229
|
...props,
|
|
1252
|
-
children:
|
|
1230
|
+
children: [
|
|
1231
|
+
leftSlot,
|
|
1232
|
+
/* @__PURE__ */ jsx6(Slot.Slottable, { children }),
|
|
1233
|
+
rightSlot
|
|
1234
|
+
]
|
|
1253
1235
|
}
|
|
1254
1236
|
);
|
|
1255
1237
|
}
|
|
1256
|
-
return /* @__PURE__ */
|
|
1238
|
+
return /* @__PURE__ */ jsxs2(
|
|
1257
1239
|
"button",
|
|
1258
1240
|
{
|
|
1259
1241
|
ref,
|
|
@@ -1264,29 +1246,318 @@ var Button = React3.forwardRef(
|
|
|
1264
1246
|
"data-loading": loading ? "" : void 0,
|
|
1265
1247
|
onClick,
|
|
1266
1248
|
...props,
|
|
1267
|
-
children:
|
|
1249
|
+
children: [
|
|
1250
|
+
leftSlot,
|
|
1251
|
+
children,
|
|
1252
|
+
rightSlot
|
|
1253
|
+
]
|
|
1268
1254
|
}
|
|
1269
1255
|
);
|
|
1270
1256
|
}
|
|
1271
1257
|
);
|
|
1272
1258
|
Button.displayName = "Button";
|
|
1259
|
+
|
|
1260
|
+
// src/ui/components/Field.tsx
|
|
1261
|
+
import * as React5 from "react";
|
|
1262
|
+
|
|
1263
|
+
// src/ui/components/Label.tsx
|
|
1264
|
+
import * as React4 from "react";
|
|
1265
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1266
|
+
var Label = React4.forwardRef(
|
|
1267
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx7(
|
|
1268
|
+
"label",
|
|
1269
|
+
{
|
|
1270
|
+
ref,
|
|
1271
|
+
className: cn(
|
|
1272
|
+
"inline-flex items-center gap-2 text-sm font-medium text-[color:var(--text-1)]",
|
|
1273
|
+
className
|
|
1274
|
+
),
|
|
1275
|
+
...props
|
|
1276
|
+
}
|
|
1277
|
+
)
|
|
1278
|
+
);
|
|
1279
|
+
Label.displayName = "Label";
|
|
1280
|
+
|
|
1281
|
+
// src/ui/components/Field.tsx
|
|
1282
|
+
import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1283
|
+
function Field({ label, hint, error, required, disabled, id, children, className, ...props }) {
|
|
1284
|
+
const reactId = React5.useId();
|
|
1285
|
+
const controlId = id ?? `field-${reactId}`;
|
|
1286
|
+
const hintId = hint ? `${controlId}-hint` : void 0;
|
|
1287
|
+
const errorId = error ? `${controlId}-error` : void 0;
|
|
1288
|
+
const childInvalid = Boolean(children.props.invalid);
|
|
1289
|
+
const invalid = Boolean(error) || childInvalid;
|
|
1290
|
+
const describedByParts = [
|
|
1291
|
+
children.props["aria-describedby"],
|
|
1292
|
+
hintId,
|
|
1293
|
+
errorId
|
|
1294
|
+
].filter(Boolean);
|
|
1295
|
+
const ariaDescribedBy = describedByParts.length ? describedByParts.join(" ") : void 0;
|
|
1296
|
+
const control = React5.cloneElement(children, {
|
|
1297
|
+
id: controlId,
|
|
1298
|
+
disabled: disabled ?? children.props.disabled,
|
|
1299
|
+
required: required ?? children.props.required,
|
|
1300
|
+
invalid,
|
|
1301
|
+
"aria-describedby": ariaDescribedBy
|
|
1302
|
+
});
|
|
1303
|
+
return /* @__PURE__ */ jsxs3("div", { className: cn("grid gap-1.5", className), ...props, children: [
|
|
1304
|
+
label ? /* @__PURE__ */ jsx8("div", { className: "flex items-center justify-between gap-3", children: /* @__PURE__ */ jsxs3(Label, { htmlFor: controlId, children: [
|
|
1305
|
+
label,
|
|
1306
|
+
required ? /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", className: "text-(--muted)", children: " * " }) : null
|
|
1307
|
+
] }) }) : null,
|
|
1308
|
+
control,
|
|
1309
|
+
error ? /* @__PURE__ */ jsx8(
|
|
1310
|
+
"p",
|
|
1311
|
+
{
|
|
1312
|
+
id: errorId,
|
|
1313
|
+
className: "text-xs leading-5 text-(--danger-contrast)",
|
|
1314
|
+
role: "alert",
|
|
1315
|
+
children: error
|
|
1316
|
+
}
|
|
1317
|
+
) : hint ? /* @__PURE__ */ jsx8("p", { id: hintId, className: "text-xs leading-5 text-(--muted)", children: hint }) : null
|
|
1318
|
+
] });
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
// src/ui/components/Input.tsx
|
|
1322
|
+
import * as React6 from "react";
|
|
1323
|
+
import { cva as cva2 } from "class-variance-authority";
|
|
1324
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1325
|
+
var controlShellBase = cn(
|
|
1326
|
+
"relative inline-flex items-center gap-2",
|
|
1327
|
+
"rounded-[var(--radius-input)]",
|
|
1328
|
+
"border border-[color:color-mix(in_oklab,var(--border),transparent_55%)]",
|
|
1329
|
+
"text-[color:var(--text-1)]",
|
|
1330
|
+
"transition-[background-color,border-color,box-shadow] duration-[var(--motion-med)] ease",
|
|
1331
|
+
"[--control-focus:var(--focus)]",
|
|
1332
|
+
"focus-within:shadow-[0_0_0_3px_color-mix(in_oklab,var(--control-focus),transparent_60%)]",
|
|
1333
|
+
"focus-within:border-[color:var(--control-focus)]",
|
|
1334
|
+
"data-[invalid]:[--control-focus:var(--danger)]",
|
|
1335
|
+
"data-[invalid]:border-[color:color-mix(in_oklab,var(--danger),transparent_20%)]",
|
|
1336
|
+
"data-[disabled]:bg-[color:var(--disabled-bg)]",
|
|
1337
|
+
"data-[disabled]:text-[color:var(--disabled-fg)]",
|
|
1338
|
+
"data-[disabled]:border-[color:var(--disabled-border)]",
|
|
1339
|
+
"data-[disabled]:cursor-not-allowed"
|
|
1340
|
+
);
|
|
1341
|
+
var controlShellVariants = cva2(controlShellBase, {
|
|
1342
|
+
variants: {
|
|
1343
|
+
variant: {
|
|
1344
|
+
surface: cn(
|
|
1345
|
+
"bg-[color:var(--surface-2)]",
|
|
1346
|
+
"hover:bg-[color:var(--surface-hover)]"
|
|
1347
|
+
),
|
|
1348
|
+
outline: cn(
|
|
1349
|
+
"bg-transparent",
|
|
1350
|
+
"hover:bg-[color:color-mix(in_oklab,var(--surface-2),transparent_40%)]",
|
|
1351
|
+
"border-[color:color-mix(in_oklab,var(--border),transparent_35%)]"
|
|
1352
|
+
),
|
|
1353
|
+
ghost: cn(
|
|
1354
|
+
"bg-transparent",
|
|
1355
|
+
"border-[color:transparent]",
|
|
1356
|
+
"hover:bg-[color:color-mix(in_oklab,var(--surface-2),transparent_55%)]",
|
|
1357
|
+
"focus-within:border-[color:color-mix(in_oklab,var(--border),transparent_35%)]"
|
|
1358
|
+
)
|
|
1359
|
+
},
|
|
1360
|
+
size: {
|
|
1361
|
+
sm: "h-8 px-3 text-sm [--input-slot-size:2rem]",
|
|
1362
|
+
md: "h-10 px-3.5 text-sm [--input-slot-size:2.5rem]",
|
|
1363
|
+
lg: "h-11 px-4 text-base [--input-slot-size:2.75rem]"
|
|
1364
|
+
},
|
|
1365
|
+
fullWidth: { true: "w-full", false: "w-auto" }
|
|
1366
|
+
},
|
|
1367
|
+
defaultVariants: { variant: "surface", size: "md", fullWidth: false }
|
|
1368
|
+
});
|
|
1369
|
+
var inputBase = cn(
|
|
1370
|
+
"min-w-0 flex-1 bg-transparent",
|
|
1371
|
+
"outline-none border-0 ring-0",
|
|
1372
|
+
"placeholder:text-[color:color-mix(in_oklab,var(--muted),transparent_20%)]",
|
|
1373
|
+
"disabled:cursor-not-allowed",
|
|
1374
|
+
"read-only:cursor-default"
|
|
1375
|
+
);
|
|
1376
|
+
var slotBase = cn(
|
|
1377
|
+
"inline-flex items-center justify-center",
|
|
1378
|
+
"text-[color:var(--muted)]",
|
|
1379
|
+
"data-[disabled]:text-[color:var(--disabled-fg)]"
|
|
1380
|
+
);
|
|
1381
|
+
var slotReserve = "min-w-[var(--input-slot-size)]";
|
|
1382
|
+
var Input = React6.forwardRef(
|
|
1383
|
+
({
|
|
1384
|
+
variant,
|
|
1385
|
+
size,
|
|
1386
|
+
fullWidth,
|
|
1387
|
+
invalid,
|
|
1388
|
+
leftSlot,
|
|
1389
|
+
rightSlot,
|
|
1390
|
+
reserveLeftSlot,
|
|
1391
|
+
reserveRightSlot,
|
|
1392
|
+
className,
|
|
1393
|
+
inputClassName,
|
|
1394
|
+
disabled,
|
|
1395
|
+
...props
|
|
1396
|
+
}, ref) => {
|
|
1397
|
+
const isDisabled = Boolean(disabled);
|
|
1398
|
+
const showLeftSlot = Boolean(leftSlot || reserveLeftSlot);
|
|
1399
|
+
const showRightSlot = Boolean(rightSlot || reserveRightSlot);
|
|
1400
|
+
return /* @__PURE__ */ jsxs4(
|
|
1401
|
+
"div",
|
|
1402
|
+
{
|
|
1403
|
+
className: cn(controlShellVariants({ variant, size, fullWidth }), className),
|
|
1404
|
+
"data-invalid": invalid ? "" : void 0,
|
|
1405
|
+
"data-disabled": isDisabled ? "" : void 0,
|
|
1406
|
+
children: [
|
|
1407
|
+
showLeftSlot ? /* @__PURE__ */ jsx9(
|
|
1408
|
+
"span",
|
|
1409
|
+
{
|
|
1410
|
+
className: cn(slotBase, reserveLeftSlot && slotReserve),
|
|
1411
|
+
"data-disabled": isDisabled ? "" : void 0,
|
|
1412
|
+
children: leftSlot
|
|
1413
|
+
}
|
|
1414
|
+
) : null,
|
|
1415
|
+
/* @__PURE__ */ jsx9(
|
|
1416
|
+
"input",
|
|
1417
|
+
{
|
|
1418
|
+
ref,
|
|
1419
|
+
disabled: isDisabled,
|
|
1420
|
+
"aria-invalid": invalid || void 0,
|
|
1421
|
+
className: cn(inputBase, inputClassName),
|
|
1422
|
+
...props
|
|
1423
|
+
}
|
|
1424
|
+
),
|
|
1425
|
+
showRightSlot ? /* @__PURE__ */ jsx9(
|
|
1426
|
+
"span",
|
|
1427
|
+
{
|
|
1428
|
+
className: cn(slotBase, reserveRightSlot && slotReserve),
|
|
1429
|
+
"data-disabled": isDisabled ? "" : void 0,
|
|
1430
|
+
children: rightSlot
|
|
1431
|
+
}
|
|
1432
|
+
) : null
|
|
1433
|
+
]
|
|
1434
|
+
}
|
|
1435
|
+
);
|
|
1436
|
+
}
|
|
1437
|
+
);
|
|
1438
|
+
Input.displayName = "Input";
|
|
1439
|
+
|
|
1440
|
+
// src/ui/components/Textarea.tsx
|
|
1441
|
+
import * as React7 from "react";
|
|
1442
|
+
import { cva as cva3 } from "class-variance-authority";
|
|
1443
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1444
|
+
var controlShellBase2 = cn(
|
|
1445
|
+
"relative inline-flex w-full",
|
|
1446
|
+
"rounded-[var(--radius-input)]",
|
|
1447
|
+
"border border-[color:color-mix(in_oklab,var(--border),transparent_55%)]",
|
|
1448
|
+
"text-[color:var(--text-1)]",
|
|
1449
|
+
"transition-[background-color,border-color,box-shadow] duration-[var(--motion-med)] ease",
|
|
1450
|
+
"[--control-focus:var(--focus)]",
|
|
1451
|
+
"focus-within:shadow-[0_0_0_3px_color-mix(in_oklab,var(--control-focus),transparent_60%)]",
|
|
1452
|
+
"focus-within:border-[color:var(--control-focus)]",
|
|
1453
|
+
"data-[invalid]:[--control-focus:var(--danger)]",
|
|
1454
|
+
"data-[invalid]:border-[color:color-mix(in_oklab,var(--danger),transparent_20%)]",
|
|
1455
|
+
"data-[disabled]:bg-[color:var(--disabled-bg)]",
|
|
1456
|
+
"data-[disabled]:text-[color:var(--disabled-fg)]",
|
|
1457
|
+
"data-[disabled]:border-[color:var(--disabled-border)]",
|
|
1458
|
+
"data-[disabled]:cursor-not-allowed"
|
|
1459
|
+
);
|
|
1460
|
+
var textareaShellVariants = cva3(controlShellBase2, {
|
|
1461
|
+
variants: {
|
|
1462
|
+
variant: {
|
|
1463
|
+
surface: cn(
|
|
1464
|
+
"bg-[color:var(--surface-2)]",
|
|
1465
|
+
"hover:bg-[color:var(--surface-hover)]"
|
|
1466
|
+
),
|
|
1467
|
+
outline: cn(
|
|
1468
|
+
"bg-transparent",
|
|
1469
|
+
"hover:bg-[color:color-mix(in_oklab,var(--surface-2),transparent_40%)]",
|
|
1470
|
+
"border-[color:color-mix(in_oklab,var(--border),transparent_35%)]"
|
|
1471
|
+
),
|
|
1472
|
+
ghost: cn(
|
|
1473
|
+
"bg-transparent",
|
|
1474
|
+
"border-[color:transparent]",
|
|
1475
|
+
"hover:bg-[color:color-mix(in_oklab,var(--surface-2),transparent_55%)]",
|
|
1476
|
+
"focus-within:border-[color:color-mix(in_oklab,var(--border),transparent_35%)]"
|
|
1477
|
+
)
|
|
1478
|
+
},
|
|
1479
|
+
size: {
|
|
1480
|
+
sm: "p-3 text-sm",
|
|
1481
|
+
md: "p-3.5 text-sm",
|
|
1482
|
+
lg: "p-4 text-base"
|
|
1483
|
+
},
|
|
1484
|
+
fullWidth: { true: "w-full", false: "w-auto" }
|
|
1485
|
+
},
|
|
1486
|
+
defaultVariants: { variant: "surface", size: "md", fullWidth: true }
|
|
1487
|
+
});
|
|
1488
|
+
var textareaBase = cn(
|
|
1489
|
+
"min-w-0 w-full bg-transparent",
|
|
1490
|
+
"outline-none border-0 ring-0",
|
|
1491
|
+
"resize-y",
|
|
1492
|
+
"placeholder:text-[color:color-mix(in_oklab,var(--muted),transparent_20%)]",
|
|
1493
|
+
"disabled:cursor-not-allowed",
|
|
1494
|
+
"read-only:cursor-default"
|
|
1495
|
+
);
|
|
1496
|
+
var Textarea = React7.forwardRef(
|
|
1497
|
+
({
|
|
1498
|
+
variant,
|
|
1499
|
+
size,
|
|
1500
|
+
fullWidth,
|
|
1501
|
+
invalid,
|
|
1502
|
+
className,
|
|
1503
|
+
textareaClassName,
|
|
1504
|
+
disabled,
|
|
1505
|
+
autoResize,
|
|
1506
|
+
onInput,
|
|
1507
|
+
rows = 4,
|
|
1508
|
+
...props
|
|
1509
|
+
}, ref) => {
|
|
1510
|
+
const isDisabled = Boolean(disabled);
|
|
1511
|
+
const handleInput = (e) => {
|
|
1512
|
+
if (autoResize) {
|
|
1513
|
+
const el = e.currentTarget;
|
|
1514
|
+
el.style.height = "auto";
|
|
1515
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
1516
|
+
}
|
|
1517
|
+
onInput?.(e);
|
|
1518
|
+
};
|
|
1519
|
+
return /* @__PURE__ */ jsx10(
|
|
1520
|
+
"div",
|
|
1521
|
+
{
|
|
1522
|
+
className: cn(textareaShellVariants({ variant, size, fullWidth }), className),
|
|
1523
|
+
"data-invalid": invalid ? "" : void 0,
|
|
1524
|
+
"data-disabled": isDisabled ? "" : void 0,
|
|
1525
|
+
children: /* @__PURE__ */ jsx10(
|
|
1526
|
+
"textarea",
|
|
1527
|
+
{
|
|
1528
|
+
ref,
|
|
1529
|
+
disabled: isDisabled,
|
|
1530
|
+
"aria-invalid": invalid || void 0,
|
|
1531
|
+
className: cn(textareaBase, textareaClassName),
|
|
1532
|
+
rows,
|
|
1533
|
+
onInput: handleInput,
|
|
1534
|
+
...props
|
|
1535
|
+
}
|
|
1536
|
+
)
|
|
1537
|
+
}
|
|
1538
|
+
);
|
|
1539
|
+
}
|
|
1540
|
+
);
|
|
1541
|
+
Textarea.displayName = "Textarea";
|
|
1273
1542
|
export {
|
|
1274
1543
|
AuthController,
|
|
1275
1544
|
AuthControllerCtx,
|
|
1276
1545
|
AuthControllerProvider,
|
|
1277
1546
|
AuthDispatchCtx,
|
|
1278
|
-
AuthFormInputField,
|
|
1279
1547
|
AuthProvider,
|
|
1280
1548
|
AuthStateCtx,
|
|
1281
1549
|
Button,
|
|
1282
1550
|
DEFAULT_NOTIFICATION_CHANNEL,
|
|
1551
|
+
Field,
|
|
1283
1552
|
HttpError,
|
|
1553
|
+
Input,
|
|
1284
1554
|
MockAuthHttpClient,
|
|
1285
1555
|
MockHttpClient,
|
|
1286
1556
|
NotificationHost,
|
|
1287
1557
|
NotifierController,
|
|
1288
1558
|
RedirectIfAuthed,
|
|
1289
1559
|
RequireAuth,
|
|
1560
|
+
Textarea,
|
|
1290
1561
|
authController,
|
|
1291
1562
|
controllerFactory,
|
|
1292
1563
|
createAuthController,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hexdspace/react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -52,8 +52,7 @@
|
|
|
52
52
|
"@tailwindcss/vite": "^4.1.18",
|
|
53
53
|
"@tanstack/react-query": "^5.90.11",
|
|
54
54
|
"@types/react": "^19.2.7",
|
|
55
|
-
"@vitest/browser": "^
|
|
56
|
-
"@vitest/coverage-v8": "^3.2.4",
|
|
55
|
+
"@vitest/browser-playwright": "^4.0.16",
|
|
57
56
|
"autoprefixer": "^10.4.22",
|
|
58
57
|
"lucide-react": "^0.555.0",
|
|
59
58
|
"playwright": "^1.57.0",
|