moverlay 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/layout/form.d.ts +31 -0
- package/dist/layout/form.js +7 -0
- package/dist/layout/normal.d.ts +12 -0
- package/dist/layout/normal.js +16 -0
- package/dist/layout/root.d.ts +1 -0
- package/dist/layout/root.js +14 -0
- package/dist/state/manager.d.ts +5 -0
- package/dist/state/manager.js +30 -0
- package/dist/state/root.js +2 -2
- package/dist/templates/login.d.ts +20 -0
- package/dist/templates/login.js +18 -0
- package/dist/templates/register.d.ts +20 -0
- package/dist/templates/register.js +18 -0
- package/package.json +39 -3
- package/dist/assets/forms/register.json +0 -17
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import { type Props as BaseProps } from "./normal";
|
|
3
|
+
import { type Option, type FormSection, SetState } from "@bouko/form";
|
|
4
|
+
import { JsonMap } from "@bouko/ts";
|
|
5
|
+
import { ZodTypeAny } from "zod";
|
|
6
|
+
type Field<T, K = string> = {
|
|
7
|
+
id: string;
|
|
8
|
+
label?: string;
|
|
9
|
+
style?: string;
|
|
10
|
+
value?: K;
|
|
11
|
+
update: SetState<T>;
|
|
12
|
+
required?: boolean;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
note?: ReactNode;
|
|
15
|
+
};
|
|
16
|
+
type FormBuilderField<T> = (Omit<Field<T>, "value" | "update"> & {
|
|
17
|
+
element: string;
|
|
18
|
+
rows?: number;
|
|
19
|
+
placeholder?: string;
|
|
20
|
+
options?: Option[];
|
|
21
|
+
})[][];
|
|
22
|
+
type Props<T> = BaseProps & FormSection<T> & {
|
|
23
|
+
fields: FormBuilderField<T>;
|
|
24
|
+
validator: ZodTypeAny;
|
|
25
|
+
styles?: {
|
|
26
|
+
submit?: string;
|
|
27
|
+
};
|
|
28
|
+
submit: (data: T, clear?: (() => void) | undefined) => Promise<void>;
|
|
29
|
+
};
|
|
30
|
+
export declare function FormModal<T extends JsonMap>({ fields, data, validator, update, submit, styles, clear, ...props }: Props<T>): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export default FormModal;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import Modal from "./normal";
|
|
3
|
+
import { FormBuilder } from "@bouko/form";
|
|
4
|
+
export function FormModal({ fields, data, validator, update, submit, styles, clear, ...props }) {
|
|
5
|
+
return (_jsx(Modal, { ...props, children: _jsx(FormBuilder, { styles: styles, fields: fields, validator: validator.safeParse, submit: submit }) }));
|
|
6
|
+
}
|
|
7
|
+
export default FormModal;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type Props = {
|
|
3
|
+
style?: string;
|
|
4
|
+
title: string;
|
|
5
|
+
subtitle?: ReactNode;
|
|
6
|
+
redirect?: {
|
|
7
|
+
label: string;
|
|
8
|
+
to: string;
|
|
9
|
+
};
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
};
|
|
12
|
+
export default function ModalLayout({ style, title, subtitle, redirect, children }: Props): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "@bouko/style";
|
|
3
|
+
import useModal from "../state/context";
|
|
4
|
+
import X from "../assets/icons/x.svg";
|
|
5
|
+
export default function ModalLayout({ style, title, subtitle, redirect, children }) {
|
|
6
|
+
const { openModal, closeModal } = useModal();
|
|
7
|
+
return (_jsxs("div", { className: cn(styles.container, style), role: "dialog", "aria-modal": "true", children: [_jsxs("div", { className: styles.header, children: [_jsxs("div", { className: styles.heading, children: [_jsx("span", { className: styles.title, children: title }), _jsxs("span", { className: styles.subtitle, children: [subtitle, redirect && (_jsx("button", { className: "p-0 bg-transparent border-none outline-none text-sm text-accent duration-200 hover:text-accent-light cursor-pointer font-semibold", onClick: () => openModal(redirect.to), children: redirect.label }))] })] }), _jsx(X, { className: styles.close, onClick: closeModal })] }), children] }));
|
|
8
|
+
}
|
|
9
|
+
const styles = {
|
|
10
|
+
container: "relative flex flex-col gap-4 w-lg p-7 pt-6 select-none overflow-hidden",
|
|
11
|
+
header: "relative flex flex-col gap-px mb-1 w-full",
|
|
12
|
+
heading: "flex flex-col gap-px",
|
|
13
|
+
title: "leading-none text-xl font-semibold",
|
|
14
|
+
subtitle: "flex items-center gap-2 text-sm text-slate-400",
|
|
15
|
+
close: "absolute -right-2 -top-1 text-error hover:text-error text-lg duration-200 cursor-pointer"
|
|
16
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function RootModal(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import useModal from "../state/context";
|
|
4
|
+
import { AnimatePresence, motion } from "framer-motion";
|
|
5
|
+
export default function RootModal() {
|
|
6
|
+
const { isOpen, templateId, templates } = useModal();
|
|
7
|
+
return (_jsx(AnimatePresence, { mode: "wait", children: isOpen && templateId && (_jsxs(motion.div, { className: styles.container, initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, layout: true, children: [_jsx("div", { className: styles.backdrop }), _jsx("div", { className: styles.content, children: _jsx("div", { className: styles.subcontainer, children: templates[templateId] }) })] }, templateId)) }));
|
|
8
|
+
}
|
|
9
|
+
const styles = {
|
|
10
|
+
container: "fixed inset-0 flex justify-center items-center z-[99]",
|
|
11
|
+
backdrop: "absolute inset-0 bg-background-dark/60",
|
|
12
|
+
content: "absolute top-0 left-0 w-[100dvw] h-[100dvh] flex justify-center items-center 2xl:scale-125 select-none",
|
|
13
|
+
subcontainer: "relative flex max-w-[80%] max-h-[85%] bg-background border border-border rounded-lg shadow-soft overflow-hidden"
|
|
14
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Context } from "./context";
|
|
5
|
+
import { parseData } from "@bouko/react";
|
|
6
|
+
export default function ModalManager({ config, children }) {
|
|
7
|
+
const [isOpen, setOpen] = useState(false);
|
|
8
|
+
const [templateId, setTemplate] = useState();
|
|
9
|
+
const [params, setParams] = useState({});
|
|
10
|
+
const openModal = async (template, params) => {
|
|
11
|
+
setTemplate(template);
|
|
12
|
+
setParams(params ?? {});
|
|
13
|
+
setOpen(true);
|
|
14
|
+
};
|
|
15
|
+
const getParams = () => parseData(params ?? {});
|
|
16
|
+
const closeModal = () => {
|
|
17
|
+
setOpen(false);
|
|
18
|
+
setTemplate(undefined);
|
|
19
|
+
setParams({});
|
|
20
|
+
};
|
|
21
|
+
return (_jsx(Context.Provider, { value: {
|
|
22
|
+
templates: config,
|
|
23
|
+
templateId,
|
|
24
|
+
isOpen,
|
|
25
|
+
params,
|
|
26
|
+
getParams,
|
|
27
|
+
openModal,
|
|
28
|
+
closeModal
|
|
29
|
+
}, children: children }));
|
|
30
|
+
}
|
package/dist/state/root.js
CHANGED
|
@@ -10,8 +10,8 @@ import { AnimatePresence, Animation } from "@bouko/react";
|
|
|
10
10
|
* the new modal with a backdrop.
|
|
11
11
|
**/
|
|
12
12
|
export default function RootModal() {
|
|
13
|
-
const { activeId, modal } = useModal();
|
|
14
|
-
return (_jsx(AnimatePresence, { mode: "wait", children: modal && (_jsx(Animation, { style: styles.backdrop, children: _jsx("div", { className: styles.content, children: modal }) }, activeId)) }));
|
|
13
|
+
const { activeId, modal, closeModal } = useModal();
|
|
14
|
+
return (_jsx(AnimatePresence, { mode: "wait", children: modal && (_jsx(Animation, { style: styles.backdrop, onClick: closeModal, children: _jsx("div", { className: styles.content, onClick: e => e.stopPropagation(), children: modal }) }, activeId)) }));
|
|
15
15
|
}
|
|
16
16
|
const styles = {
|
|
17
17
|
backdrop: "fixed inset-0 flex justify-center items-center bg-background-light/60 dark:bg-background-dark/60 z-[99]",
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Login Modal component
|
|
3
|
+
*
|
|
4
|
+
* Displays a modal for user login with handling for
|
|
5
|
+
* input validation and submission logic for existing users.
|
|
6
|
+
* Uses `nupabase` which is a Supabase wrapper.
|
|
7
|
+
*
|
|
8
|
+
* Form Fields:
|
|
9
|
+
* `email` - User's email address
|
|
10
|
+
* `password` - User's desired password
|
|
11
|
+
**/
|
|
12
|
+
export declare function LoginModal(): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export default LoginModal;
|
|
14
|
+
/**
|
|
15
|
+
* Problems:
|
|
16
|
+
*
|
|
17
|
+
* - Perfect `FormModal`.
|
|
18
|
+
* - Perfect `login`.
|
|
19
|
+
* - Perfect `LoginSchema`.
|
|
20
|
+
**/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FormModal } from "../layouts/form";
|
|
3
|
+
import { login, LoginSchema } from "nupabase";
|
|
4
|
+
/**
|
|
5
|
+
* Login Modal component
|
|
6
|
+
*
|
|
7
|
+
* Displays a modal for user login with handling for
|
|
8
|
+
* input validation and submission logic for existing users.
|
|
9
|
+
* Uses `nupabase` which is a Supabase wrapper.
|
|
10
|
+
*
|
|
11
|
+
* Form Fields:
|
|
12
|
+
* `email` - User's email address
|
|
13
|
+
* `password` - User's desired password
|
|
14
|
+
**/
|
|
15
|
+
export function LoginModal() {
|
|
16
|
+
return (_jsx(FormModal, { formId: "login", title: "Login to your Account", subtitle: "We'll send a verification to your email.", validator: LoginSchema.safeParse, submit: login }));
|
|
17
|
+
}
|
|
18
|
+
export default LoginModal;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register Modal component
|
|
3
|
+
*
|
|
4
|
+
* Displays a modal for user registration with handling
|
|
5
|
+
* for input validation and submission logic for new users.
|
|
6
|
+
* Uses `nupabase` which is a Supabase wrapper.
|
|
7
|
+
*
|
|
8
|
+
* Form Fields:
|
|
9
|
+
* `email` - User's email address
|
|
10
|
+
* `password` - User's desired password
|
|
11
|
+
**/
|
|
12
|
+
export declare function RegisterModal(): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export default RegisterModal;
|
|
14
|
+
/**
|
|
15
|
+
* Problems:
|
|
16
|
+
*
|
|
17
|
+
* - Perfect `FormModal`.
|
|
18
|
+
* - Perfect `register`.
|
|
19
|
+
* - Perfect `RegisterSchema`.
|
|
20
|
+
**/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { FormModal } from "../layouts/form";
|
|
3
|
+
import { register, RegisterSchema } from "nupabase";
|
|
4
|
+
/**
|
|
5
|
+
* Register Modal component
|
|
6
|
+
*
|
|
7
|
+
* Displays a modal for user registration with handling
|
|
8
|
+
* for input validation and submission logic for new users.
|
|
9
|
+
* Uses `nupabase` which is a Supabase wrapper.
|
|
10
|
+
*
|
|
11
|
+
* Form Fields:
|
|
12
|
+
* `email` - User's email address
|
|
13
|
+
* `password` - User's desired password
|
|
14
|
+
**/
|
|
15
|
+
export function RegisterModal() {
|
|
16
|
+
return (_jsx(FormModal, { formId: "register", title: "Create an Account", subtitle: "We'll send a verification to your email.", validator: RegisterSchema.safeParse, submit: register }));
|
|
17
|
+
}
|
|
18
|
+
export default RegisterModal;
|
package/package.json
CHANGED
|
@@ -1,46 +1,82 @@
|
|
|
1
1
|
{
|
|
2
2
|
|
|
3
3
|
"name": "moverlay",
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
"version": "0.0.7",
|
|
6
|
+
|
|
5
7
|
"main": "./dist/index.js",
|
|
8
|
+
|
|
6
9
|
"types": "./dist/index.d.ts",
|
|
10
|
+
|
|
7
11
|
"license": "MIT",
|
|
12
|
+
|
|
8
13
|
"files": [
|
|
14
|
+
|
|
9
15
|
"dist"
|
|
16
|
+
|
|
10
17
|
],
|
|
18
|
+
|
|
11
19
|
"publishConfig": {
|
|
20
|
+
|
|
12
21
|
"access": "public"
|
|
22
|
+
|
|
13
23
|
},
|
|
24
|
+
|
|
14
25
|
"author": "",
|
|
26
|
+
|
|
15
27
|
"description": "",
|
|
28
|
+
|
|
16
29
|
"peerDependencies": {
|
|
30
|
+
|
|
17
31
|
"react": ">=18.3.1"
|
|
32
|
+
|
|
18
33
|
},
|
|
34
|
+
|
|
19
35
|
"engines": {},
|
|
20
36
|
|
|
21
37
|
"scripts": {
|
|
38
|
+
|
|
22
39
|
"build": "tsc"
|
|
40
|
+
|
|
23
41
|
},
|
|
24
42
|
|
|
25
43
|
"dependencies": {
|
|
26
|
-
|
|
44
|
+
|
|
45
|
+
"@bouko/react": "^2.7.2",
|
|
46
|
+
|
|
27
47
|
"@bouko/style": "^0.1.6",
|
|
48
|
+
|
|
28
49
|
"@bouko/ts": "^0.2.0",
|
|
50
|
+
|
|
29
51
|
"clsx": "^2.1.1",
|
|
52
|
+
|
|
30
53
|
"formeact": "^0.0.3",
|
|
54
|
+
|
|
31
55
|
"framer-motion": "^12.16.0",
|
|
56
|
+
|
|
32
57
|
"superstruct": "^2.0.2",
|
|
58
|
+
|
|
33
59
|
"tailwind-merge": "^3.3.0",
|
|
60
|
+
|
|
34
61
|
"tailwind-variants": "^1.0.0",
|
|
62
|
+
|
|
35
63
|
"zod": "^4.0.17"
|
|
64
|
+
|
|
36
65
|
},
|
|
37
66
|
|
|
38
67
|
"devDependencies": {
|
|
68
|
+
|
|
39
69
|
"@types/react": "^19.1.10",
|
|
70
|
+
|
|
40
71
|
"dependency-cruiser": "^17.0.1",
|
|
72
|
+
|
|
41
73
|
"nupabase": "^0.2.0",
|
|
74
|
+
|
|
42
75
|
"react": "^19.1.1",
|
|
76
|
+
|
|
43
77
|
"typescript": "^5.9.2"
|
|
78
|
+
|
|
44
79
|
}
|
|
45
80
|
|
|
46
|
-
}
|
|
81
|
+
}
|
|
82
|
+
|