@lattice-php/lattice 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/action/components/action.js +16 -85
- package/dist/action/components/action.js.map +1 -1
- package/dist/action/use-action.d.ts +18 -0
- package/dist/action/use-action.js +90 -0
- package/dist/action/use-action.js.map +1 -0
- package/dist/core/components/control.d.ts +0 -1
- package/dist/core/components/control.js +0 -1
- package/dist/core/components/control.js.map +1 -1
- package/dist/core/components/fragment.js +4 -1
- package/dist/core/components/fragment.js.map +1 -1
- package/dist/core/components/icon.js +4 -1
- package/dist/core/components/icon.js.map +1 -1
- package/dist/core/components/link.js +24 -3
- package/dist/core/components/link.js.map +1 -1
- package/dist/core/components/text.js +4 -1
- package/dist/core/components/text.js.map +1 -1
- package/dist/core/renderer.d.ts +0 -2
- package/dist/core/renderer.js +0 -2
- package/dist/core/renderer.js.map +1 -1
- package/dist/effects/dispatch.d.ts +0 -1
- package/dist/effects/dispatch.js.map +1 -1
- package/dist/effects/registry.js +0 -1
- package/dist/effects/registry.js.map +1 -1
- package/dist/form/components/base/input-otp.d.ts +0 -1
- package/dist/form/components/base/input-otp.js +0 -1
- package/dist/form/components/base/input-otp.js.map +1 -1
- package/dist/form/components/field-props.d.ts +0 -1
- package/dist/form/components/field-props.js +0 -1
- package/dist/form/components/field-props.js.map +1 -1
- package/dist/form/components/fields/repeater-rows.d.ts +0 -2
- package/dist/form/components/fields/repeater-rows.js +0 -2
- package/dist/form/components/fields/repeater-rows.js.map +1 -1
- package/dist/form/components/fields/simple-field.d.ts +0 -1
- package/dist/form/components/fields/simple-field.js +0 -1
- package/dist/form/components/fields/simple-field.js.map +1 -1
- package/dist/form/components/fields/toggle.d.ts +2 -0
- package/dist/form/components/fields/toggle.js +65 -0
- package/dist/form/components/fields/toggle.js.map +1 -0
- package/dist/form/components/index.d.ts +1 -0
- package/dist/form/components/index.js +2 -1
- package/dist/form/components/use-controlled-field.d.ts +0 -1
- package/dist/form/components/use-controlled-field.js +0 -1
- package/dist/form/components/use-controlled-field.js.map +1 -1
- package/dist/form/index.js +2 -1
- package/dist/form/index.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/lattice.css +6 -0
- package/dist/layout/menu-item.js +21 -0
- package/dist/layout/menu-item.js.map +1 -1
- package/dist/lib/utils.js +11 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/table/components/cells/boolean-cell.d.ts +0 -1
- package/dist/table/components/cells/boolean-cell.js +0 -1
- package/dist/table/components/cells/boolean-cell.js.map +1 -1
- package/dist/table/components/cells/numeric.d.ts +0 -1
- package/dist/table/components/cells/numeric.js +0 -1
- package/dist/table/components/cells/numeric.js.map +1 -1
- package/dist/table/components/cells/stack-cell.d.ts +0 -1
- package/dist/table/components/cells/stack-cell.js +0 -1
- package/dist/table/components/cells/stack-cell.js.map +1 -1
- package/dist/table/registry.d.ts +0 -2
- package/dist/table/registry.js.map +1 -1
- package/dist/toast/callout.d.ts +0 -2
- package/dist/toast/callout.js +0 -2
- package/dist/toast/callout.js.map +1 -1
- package/dist/toast/toast.d.ts +0 -3
- package/dist/toast/toast.js +0 -3
- package/dist/toast/toast.js.map +1 -1
- package/dist/types/generated.d.ts +33 -2
- package/package.json +5 -2
|
@@ -1,101 +1,32 @@
|
|
|
1
|
-
import { withHeaders } from "../../core/headers.js";
|
|
2
1
|
import { IconRenderer } from "../../icons/icon-renderer.js";
|
|
3
2
|
import { prefixedTestId } from "../../core/test-id.js";
|
|
4
|
-
import { getActionEffects } from "../../effects/dispatch.js";
|
|
5
|
-
import { useEffectDispatcher } from "../../effects/use-effect-dispatcher.js";
|
|
6
3
|
import { Button } from "../../core/components/button.js";
|
|
7
4
|
import { Spinner } from "../../core/components/spinner.js";
|
|
8
|
-
import {
|
|
9
|
-
import { runAction } from "../run-action.js";
|
|
10
|
-
import { ActionForm, useLazyActionForm } from "./action-form.js";
|
|
5
|
+
import { useAction } from "../use-action.js";
|
|
11
6
|
import { actionMenuItemClassName, useActionMenu } from "./action-menu-context.js";
|
|
12
|
-
import {
|
|
13
|
-
import { useState } from "react";
|
|
14
|
-
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
15
8
|
//#region resources/js/action/components/action.tsx
|
|
16
9
|
var ActionComponent = ({ node }) => {
|
|
17
10
|
const endpoint = node.props.endpoint ?? "";
|
|
18
11
|
const icon = node.props.icon;
|
|
19
12
|
const label = node.props.label ?? "Run action";
|
|
20
|
-
const componentRef = node.props.ref ?? "";
|
|
21
|
-
const method = node.props.method ?? "post";
|
|
22
|
-
const http = useHttp({});
|
|
23
|
-
const dispatch = useEffectDispatcher();
|
|
24
|
-
const [isConfirming, setIsConfirming] = useState(false);
|
|
25
|
-
const [isFilling, setIsFilling] = useState(false);
|
|
26
13
|
const isMenuItem = useActionMenu();
|
|
27
|
-
const confirmation = node.props.confirmation;
|
|
28
14
|
const variant = node.props.variant ?? "default";
|
|
29
|
-
const
|
|
30
|
-
const lazyForm = node.props.lazyForm === true;
|
|
31
|
-
const hasForm = Boolean(inlineForm) || lazyForm;
|
|
32
|
-
const lazyNode = useLazyActionForm(endpoint, componentRef, isFilling && lazyForm);
|
|
33
|
-
const formNode = lazyForm ? lazyNode : inlineForm;
|
|
34
|
-
const submit = async () => {
|
|
35
|
-
if (!endpoint) return;
|
|
36
|
-
if (method === "get") {
|
|
37
|
-
router.visit(endpoint, { headers: withHeaders(componentRef) });
|
|
38
|
-
setIsConfirming(false);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
if (await runAction(() => http[method](endpoint, { headers: withHeaders(componentRef) }), dispatch)) setIsConfirming(false);
|
|
42
|
-
};
|
|
43
|
-
const requestSubmit = () => {
|
|
44
|
-
if (hasForm) {
|
|
45
|
-
setIsFilling(true);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
if (confirmation) {
|
|
49
|
-
setIsConfirming(true);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
submit();
|
|
53
|
-
};
|
|
54
|
-
const confirmationTitle = confirmation?.title ?? label;
|
|
55
|
-
const confirmationConfirmLabel = confirmation?.confirmLabel ?? label;
|
|
56
|
-
const confirmationCancelLabel = confirmation?.cancelLabel ?? "Cancel";
|
|
15
|
+
const { processing, requestSubmit, overlays } = useAction(node);
|
|
57
16
|
const testId = node.key ?? prefixedTestId("action", node.id);
|
|
58
|
-
return /* @__PURE__ */ jsxs(Fragment
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}),
|
|
72
|
-
isConfirming && confirmation && /* @__PURE__ */ jsx(ConfirmDialog, {
|
|
73
|
-
title: confirmationTitle,
|
|
74
|
-
description: confirmation.description ?? void 0,
|
|
75
|
-
confirmLabel: confirmationConfirmLabel,
|
|
76
|
-
cancelLabel: confirmationCancelLabel,
|
|
77
|
-
confirmVariant: variant,
|
|
78
|
-
processing: http.processing,
|
|
79
|
-
confirmDisabled: !endpoint,
|
|
80
|
-
onConfirm: () => void submit(),
|
|
81
|
-
onCancel: () => setIsConfirming(false)
|
|
82
|
-
}),
|
|
83
|
-
isFilling && hasForm && /* @__PURE__ */ jsx(ActionForm, {
|
|
84
|
-
cancelLabel: confirmationCancelLabel,
|
|
85
|
-
componentRef,
|
|
86
|
-
description: confirmation?.description ?? void 0,
|
|
87
|
-
endpoint,
|
|
88
|
-
formNode,
|
|
89
|
-
method,
|
|
90
|
-
onClose: () => setIsFilling(false),
|
|
91
|
-
onSuccess: (response) => {
|
|
92
|
-
dispatch(getActionEffects(response.effects));
|
|
93
|
-
setIsFilling(false);
|
|
94
|
-
},
|
|
95
|
-
submitLabel: confirmationConfirmLabel,
|
|
96
|
-
title: confirmationTitle
|
|
97
|
-
})
|
|
98
|
-
] });
|
|
17
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Button, {
|
|
18
|
+
className: isMenuItem ? actionMenuItemClassName : void 0,
|
|
19
|
+
"data-lattice-component": node.id,
|
|
20
|
+
"data-test": testId,
|
|
21
|
+
disabled: processing || !endpoint,
|
|
22
|
+
onClick: requestSubmit,
|
|
23
|
+
type: "button",
|
|
24
|
+
variant: isMenuItem ? "ghost" : variant,
|
|
25
|
+
children: [processing ? /* @__PURE__ */ jsx(Spinner, { className: isMenuItem ? "size-lt-icon-sm" : void 0 }) : icon && /* @__PURE__ */ jsx(IconRenderer, {
|
|
26
|
+
className: isMenuItem ? "size-lt-icon-sm" : "size-lt-icon-md",
|
|
27
|
+
icon
|
|
28
|
+
}), label]
|
|
29
|
+
}), overlays] });
|
|
99
30
|
};
|
|
100
31
|
//#endregion
|
|
101
32
|
export { ActionComponent as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action.js","names":[],"sources":["../../../resources/js/action/components/action.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"action.js","names":[],"sources":["../../../resources/js/action/components/action.tsx"],"sourcesContent":["import { Button } from \"@lattice-php/lattice/core/components/button\";\nimport { Spinner } from \"@lattice-php/lattice/core/components/spinner\";\nimport { prefixedTestId } from \"@lattice-php/lattice/core/test-id\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { IconRenderer } from \"@lattice-php/lattice/icons\";\nimport { useAction } from \"../use-action\";\nimport { actionMenuItemClassName, useActionMenu } from \"./action-menu-context\";\n\nconst ActionComponent: RendererComponent<\"action\"> = ({ node }) => {\n const endpoint = node.props.endpoint ?? \"\";\n const icon = node.props.icon;\n const label = node.props.label ?? \"Run action\";\n const isMenuItem = useActionMenu();\n const variant = node.props.variant ?? \"default\";\n const { processing, requestSubmit, overlays } = useAction(node);\n const testId = node.key ?? prefixedTestId(\"action\", node.id);\n\n return (\n <>\n <Button\n className={isMenuItem ? actionMenuItemClassName : undefined}\n data-lattice-component={node.id}\n data-test={testId}\n disabled={processing || !endpoint}\n onClick={requestSubmit}\n type=\"button\"\n variant={isMenuItem ? \"ghost\" : variant}\n >\n {processing ? (\n <Spinner className={isMenuItem ? \"size-lt-icon-sm\" : undefined} />\n ) : (\n icon && (\n <IconRenderer\n className={isMenuItem ? \"size-lt-icon-sm\" : \"size-lt-icon-md\"}\n icon={icon}\n />\n )\n )}\n {label}\n </Button>\n\n {overlays}\n </>\n );\n};\n\nexport default ActionComponent;\n"],"mappings":";;;;;;;;AAQA,IAAM,mBAAgD,EAAE,WAAW;CACjE,MAAM,WAAW,KAAK,MAAM,YAAY;CACxC,MAAM,OAAO,KAAK,MAAM;CACxB,MAAM,QAAQ,KAAK,MAAM,SAAS;CAClC,MAAM,aAAa,cAAc;CACjC,MAAM,UAAU,KAAK,MAAM,WAAW;CACtC,MAAM,EAAE,YAAY,eAAe,aAAa,UAAU,IAAI;CAC9D,MAAM,SAAS,KAAK,OAAO,eAAe,UAAU,KAAK,EAAE;CAE3D,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,qBAAC,QAAD;EACE,WAAW,aAAa,0BAA0B,KAAA;EAClD,0BAAwB,KAAK;EAC7B,aAAW;EACX,UAAU,cAAc,CAAC;EACzB,SAAS;EACT,MAAK;EACL,SAAS,aAAa,UAAU;YAPlC,CASG,aACC,oBAAC,SAAD,EAAS,WAAW,aAAa,oBAAoB,KAAA,EAAY,CAAA,IAEjE,QACE,oBAAC,cAAD;GACE,WAAW,aAAa,oBAAoB;GACtC;EACP,CAAA,GAGJ,KACK;KAEP,QACD,EAAA,CAAA;AAEN"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { Node } from '../core/types';
|
|
3
|
+
type UseAction = {
|
|
4
|
+
/** Whether the action request is in flight. */
|
|
5
|
+
processing: boolean;
|
|
6
|
+
/** Gate then run the action: open the form, confirm, or dispatch directly. */
|
|
7
|
+
requestSubmit: () => void;
|
|
8
|
+
/** The confirm dialog and action form rendered next to the trigger. */
|
|
9
|
+
overlays: ReactNode;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The shared action machinery behind the Action button, action menu items, and
|
|
13
|
+
* action links: it gates submission (form → modal, confirmation → confirm,
|
|
14
|
+
* otherwise dispatch) and renders the matching overlays. The host owns the
|
|
15
|
+
* trigger element so each surface keeps its own styling.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useAction(node: Node<"action">): UseAction;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { withHeaders } from "../core/headers.js";
|
|
2
|
+
import { getActionEffects } from "../effects/dispatch.js";
|
|
3
|
+
import { useEffectDispatcher } from "../effects/use-effect-dispatcher.js";
|
|
4
|
+
import { ConfirmDialog } from "../core/components/confirm-dialog.js";
|
|
5
|
+
import { runAction } from "./run-action.js";
|
|
6
|
+
import { ActionForm, useLazyActionForm } from "./components/action-form.js";
|
|
7
|
+
import { router, useHttp } from "@inertiajs/react";
|
|
8
|
+
import { useState } from "react";
|
|
9
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
//#region resources/js/action/use-action.tsx
|
|
11
|
+
/**
|
|
12
|
+
* The shared action machinery behind the Action button, action menu items, and
|
|
13
|
+
* action links: it gates submission (form → modal, confirmation → confirm,
|
|
14
|
+
* otherwise dispatch) and renders the matching overlays. The host owns the
|
|
15
|
+
* trigger element so each surface keeps its own styling.
|
|
16
|
+
*/
|
|
17
|
+
function useAction(node) {
|
|
18
|
+
const endpoint = node.props.endpoint ?? "";
|
|
19
|
+
const componentRef = node.props.ref ?? "";
|
|
20
|
+
const method = node.props.method ?? "post";
|
|
21
|
+
const label = node.props.label ?? "Run action";
|
|
22
|
+
const variant = node.props.variant ?? "default";
|
|
23
|
+
const confirmation = node.props.confirmation;
|
|
24
|
+
const inlineForm = node.props.form;
|
|
25
|
+
const lazyForm = node.props.lazyForm === true;
|
|
26
|
+
const hasForm = Boolean(inlineForm) || lazyForm;
|
|
27
|
+
const http = useHttp({});
|
|
28
|
+
const dispatch = useEffectDispatcher();
|
|
29
|
+
const [isConfirming, setIsConfirming] = useState(false);
|
|
30
|
+
const [isFilling, setIsFilling] = useState(false);
|
|
31
|
+
const lazyNode = useLazyActionForm(endpoint, componentRef, isFilling && lazyForm);
|
|
32
|
+
const formNode = lazyForm ? lazyNode : inlineForm;
|
|
33
|
+
const submit = async () => {
|
|
34
|
+
if (!endpoint) return;
|
|
35
|
+
if (method === "get") {
|
|
36
|
+
router.visit(endpoint, { headers: withHeaders(componentRef) });
|
|
37
|
+
setIsConfirming(false);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (await runAction(() => http[method](endpoint, { headers: withHeaders(componentRef) }), dispatch)) setIsConfirming(false);
|
|
41
|
+
};
|
|
42
|
+
const requestSubmit = () => {
|
|
43
|
+
if (hasForm) {
|
|
44
|
+
setIsFilling(true);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (confirmation) {
|
|
48
|
+
setIsConfirming(true);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
submit();
|
|
52
|
+
};
|
|
53
|
+
const confirmationTitle = confirmation?.title ?? label;
|
|
54
|
+
const confirmationConfirmLabel = confirmation?.confirmLabel ?? label;
|
|
55
|
+
const confirmationCancelLabel = confirmation?.cancelLabel ?? "Cancel";
|
|
56
|
+
const overlays = /* @__PURE__ */ jsxs(Fragment$1, { children: [isConfirming && confirmation && /* @__PURE__ */ jsx(ConfirmDialog, {
|
|
57
|
+
title: confirmationTitle,
|
|
58
|
+
description: confirmation.description ?? void 0,
|
|
59
|
+
confirmLabel: confirmationConfirmLabel,
|
|
60
|
+
cancelLabel: confirmationCancelLabel,
|
|
61
|
+
confirmVariant: variant,
|
|
62
|
+
processing: http.processing,
|
|
63
|
+
confirmDisabled: !endpoint,
|
|
64
|
+
onConfirm: () => void submit(),
|
|
65
|
+
onCancel: () => setIsConfirming(false)
|
|
66
|
+
}), isFilling && hasForm && /* @__PURE__ */ jsx(ActionForm, {
|
|
67
|
+
cancelLabel: confirmationCancelLabel,
|
|
68
|
+
componentRef,
|
|
69
|
+
description: confirmation?.description ?? void 0,
|
|
70
|
+
endpoint,
|
|
71
|
+
formNode,
|
|
72
|
+
method,
|
|
73
|
+
onClose: () => setIsFilling(false),
|
|
74
|
+
onSuccess: (response) => {
|
|
75
|
+
dispatch(getActionEffects(response.effects));
|
|
76
|
+
setIsFilling(false);
|
|
77
|
+
},
|
|
78
|
+
submitLabel: confirmationConfirmLabel,
|
|
79
|
+
title: confirmationTitle
|
|
80
|
+
})] });
|
|
81
|
+
return {
|
|
82
|
+
processing: http.processing,
|
|
83
|
+
requestSubmit,
|
|
84
|
+
overlays
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export { useAction };
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=use-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-action.js","names":[],"sources":["../../resources/js/action/use-action.tsx"],"sourcesContent":["import { router, useHttp } from \"@inertiajs/react\";\nimport type { Method } from \"@inertiajs/core\";\nimport { useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { ConfirmDialog } from \"@lattice-php/lattice/core/components/confirm-dialog\";\nimport { withHeaders } from \"@lattice-php/lattice/core/headers\";\nimport type { Node } from \"@lattice-php/lattice/core/types\";\nimport { getActionEffects } from \"@lattice-php/lattice/effects/dispatch\";\nimport type { ActionResponse } from \"@lattice-php/lattice/effects/dispatch\";\nimport { useEffectDispatcher } from \"@lattice-php/lattice/effects/use-effect-dispatcher\";\nimport { runAction } from \"./run-action\";\nimport { ActionForm, useLazyActionForm } from \"./components/action-form\";\n\ntype UseAction = {\n /** Whether the action request is in flight. */\n processing: boolean;\n /** Gate then run the action: open the form, confirm, or dispatch directly. */\n requestSubmit: () => void;\n /** The confirm dialog and action form rendered next to the trigger. */\n overlays: ReactNode;\n};\n\n/**\n * The shared action machinery behind the Action button, action menu items, and\n * action links: it gates submission (form → modal, confirmation → confirm,\n * otherwise dispatch) and renders the matching overlays. The host owns the\n * trigger element so each surface keeps its own styling.\n */\nexport function useAction(node: Node<\"action\">): UseAction {\n const endpoint = node.props.endpoint ?? \"\";\n const componentRef = node.props.ref ?? \"\";\n const method: Method = node.props.method ?? \"post\";\n const label = node.props.label ?? \"Run action\";\n const variant = node.props.variant ?? \"default\";\n const confirmation = node.props.confirmation;\n const inlineForm = node.props.form;\n const lazyForm = node.props.lazyForm === true;\n const hasForm = Boolean(inlineForm) || lazyForm;\n\n const http = useHttp<Record<string, never>, ActionResponse>({});\n const dispatch = useEffectDispatcher();\n const [isConfirming, setIsConfirming] = useState(false);\n const [isFilling, setIsFilling] = useState(false);\n const lazyNode = useLazyActionForm(endpoint, componentRef, isFilling && lazyForm);\n const formNode = lazyForm ? lazyNode : inlineForm;\n\n const submit = async (): Promise<void> => {\n if (!endpoint) {\n return;\n }\n\n if (method === \"get\") {\n router.visit(endpoint, { headers: withHeaders(componentRef) });\n setIsConfirming(false);\n\n return;\n }\n\n const ok = await runAction(\n () => http[method](endpoint, { headers: withHeaders(componentRef) }),\n dispatch,\n );\n\n if (ok) {\n setIsConfirming(false);\n }\n };\n\n const requestSubmit = (): void => {\n if (hasForm) {\n setIsFilling(true);\n\n return;\n }\n\n if (confirmation) {\n setIsConfirming(true);\n\n return;\n }\n\n void submit();\n };\n\n const confirmationTitle = confirmation?.title ?? label;\n const confirmationConfirmLabel = confirmation?.confirmLabel ?? label;\n const confirmationCancelLabel = confirmation?.cancelLabel ?? \"Cancel\";\n\n const overlays = (\n <>\n {isConfirming && confirmation && (\n <ConfirmDialog\n title={confirmationTitle}\n description={confirmation.description ?? undefined}\n confirmLabel={confirmationConfirmLabel}\n cancelLabel={confirmationCancelLabel}\n confirmVariant={variant}\n processing={http.processing}\n confirmDisabled={!endpoint}\n onConfirm={() => void submit()}\n onCancel={() => setIsConfirming(false)}\n />\n )}\n\n {isFilling && hasForm && (\n <ActionForm\n cancelLabel={confirmationCancelLabel}\n componentRef={componentRef}\n description={confirmation?.description ?? undefined}\n endpoint={endpoint}\n formNode={formNode}\n method={method}\n onClose={() => setIsFilling(false)}\n onSuccess={(response) => {\n dispatch(getActionEffects(response.effects));\n setIsFilling(false);\n }}\n submitLabel={confirmationConfirmLabel}\n title={confirmationTitle}\n />\n )}\n </>\n );\n\n return { processing: http.processing, requestSubmit, overlays };\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA4BA,SAAgB,UAAU,MAAiC;CACzD,MAAM,WAAW,KAAK,MAAM,YAAY;CACxC,MAAM,eAAe,KAAK,MAAM,OAAO;CACvC,MAAM,SAAiB,KAAK,MAAM,UAAU;CAC5C,MAAM,QAAQ,KAAK,MAAM,SAAS;CAClC,MAAM,UAAU,KAAK,MAAM,WAAW;CACtC,MAAM,eAAe,KAAK,MAAM;CAChC,MAAM,aAAa,KAAK,MAAM;CAC9B,MAAM,WAAW,KAAK,MAAM,aAAa;CACzC,MAAM,UAAU,QAAQ,UAAU,KAAK;CAEvC,MAAM,OAAO,QAA+C,CAAC,CAAC;CAC9D,MAAM,WAAW,oBAAoB;CACrC,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,WAAW,kBAAkB,UAAU,cAAc,aAAa,QAAQ;CAChF,MAAM,WAAW,WAAW,WAAW;CAEvC,MAAM,SAAS,YAA2B;EACxC,IAAI,CAAC,UACH;EAGF,IAAI,WAAW,OAAO;GACpB,OAAO,MAAM,UAAU,EAAE,SAAS,YAAY,YAAY,EAAE,CAAC;GAC7D,gBAAgB,KAAK;GAErB;EACF;EAOA,IAAI,MALa,gBACT,KAAK,QAAQ,UAAU,EAAE,SAAS,YAAY,YAAY,EAAE,CAAC,GACnE,QACF,GAGE,gBAAgB,KAAK;CAEzB;CAEA,MAAM,sBAA4B;EAChC,IAAI,SAAS;GACX,aAAa,IAAI;GAEjB;EACF;EAEA,IAAI,cAAc;GAChB,gBAAgB,IAAI;GAEpB;EACF;EAEA,OAAY;CACd;CAEA,MAAM,oBAAoB,cAAc,SAAS;CACjD,MAAM,2BAA2B,cAAc,gBAAgB;CAC/D,MAAM,0BAA0B,cAAc,eAAe;CAE7D,MAAM,WACJ,qBAAA,YAAA,EAAA,UAAA,CACG,gBAAgB,gBACf,oBAAC,eAAD;EACE,OAAO;EACP,aAAa,aAAa,eAAe,KAAA;EACzC,cAAc;EACd,aAAa;EACb,gBAAgB;EAChB,YAAY,KAAK;EACjB,iBAAiB,CAAC;EAClB,iBAAiB,KAAK,OAAO;EAC7B,gBAAgB,gBAAgB,KAAK;CACtC,CAAA,GAGF,aAAa,WACZ,oBAAC,YAAD;EACE,aAAa;EACC;EACd,aAAa,cAAc,eAAe,KAAA;EAChC;EACA;EACF;EACR,eAAe,aAAa,KAAK;EACjC,YAAY,aAAa;GACvB,SAAS,iBAAiB,SAAS,OAAO,CAAC;GAC3C,aAAa,KAAK;EACpB;EACA,aAAa;EACb,OAAO;CACR,CAAA,CAEH,EAAA,CAAA;CAGJ,OAAO;EAAE,YAAY,KAAK;EAAY;EAAe;CAAS;AAChE"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { VariantProps } from 'class-variance-authority';
|
|
2
|
-
/** The focus-visible ring shared by every interactive control surface. */
|
|
3
2
|
export declare const FOCUS_RING = "focus-visible:border-lt-ring focus-visible:ring-lt-ring/50 focus-visible:ring-[3px]";
|
|
4
3
|
/**
|
|
5
4
|
* The shared chrome for single-line form/table controls (text inputs, native
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { cva } from "class-variance-authority";
|
|
2
2
|
//#region resources/js/core/components/control.ts
|
|
3
|
-
/** The focus-visible ring shared by every interactive control surface. */
|
|
4
3
|
var FOCUS_RING = "focus-visible:border-lt-ring focus-visible:ring-lt-ring/50 focus-visible:ring-[3px]";
|
|
5
4
|
/**
|
|
6
5
|
* The shared chrome for single-line form/table controls (text inputs, native
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.js","names":[],"sources":["../../../resources/js/core/components/control.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\
|
|
1
|
+
{"version":3,"file":"control.js","names":[],"sources":["../../../resources/js/core/components/control.ts"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\n\nexport const FOCUS_RING =\n \"focus-visible:border-lt-ring focus-visible:ring-lt-ring/50 focus-visible:ring-[3px]\";\n\n/**\n * The shared chrome for single-line form/table controls (text inputs, native\n * selects, and the Select/filter trigger buttons). `density` is the only axis\n * that differs between forms (comfortable) and table filters (compact); the\n * border, focus ring, invalid, and disabled treatment are unified.\n */\nexport const controlSurface = cva(\n [\n \"w-full min-w-0 rounded-lt-sm border border-lt-input shadow-lt-xs outline-none transition-[color,box-shadow]\",\n \"placeholder:text-lt-muted-fg\",\n FOCUS_RING,\n \"aria-invalid:border-lt-danger aria-invalid:ring-lt-danger/20 dark:aria-invalid:ring-lt-danger/40\",\n \"disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-lt-disabled disabled:text-lt-disabled-fg\",\n ],\n {\n variants: {\n density: {\n comfortable: \"h-lt-control-md bg-transparent px-3 py-1 text-base\",\n compact: \"h-lt-control-md bg-lt-bg px-2 text-sm font-normal\",\n },\n },\n defaultVariants: { density: \"comfortable\" },\n },\n);\n\nexport type ControlSurfaceVariants = VariantProps<typeof controlSurface>;\n"],"mappings":";;AAEA,IAAa,aACX;;;;;;;AAQF,IAAa,iBAAiB,IAC5B;CACE;CACA;CACA;CACA;CACA;AACF,GACA;CACE,UAAU,EACR,SAAS;EACP,aAAa;EACb,SAAS;CACX,EACF;CACA,iBAAiB,EAAE,SAAS,cAAc;AAC5C,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fragment.js","names":[],"sources":["../../../resources/js/core/components/fragment.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { apiJson } from \"@lattice-php/lattice/core/api\";\nimport { Skeleton } from \"@lattice-php/lattice/core/components/skeleton\";\nimport { Renderer } from \"@lattice-php/lattice/core/renderer\";\nimport type { RendererComponent, Schema } from \"@lattice-php/lattice/core/types\";\nimport { toNodes } from \"@lattice-php/lattice/core/nodes\";\nimport { LATTICE_EVENT, type ReloadComponentEvent } from \"@lattice-php/lattice/events/event-names\";\n\ntype FragmentResponse = {\n schema?: Schema;\n};\n\nconst fragmentSizeHeights = {\n lg: 320,\n md: 64,\n sm: 40,\n xl: 384,\n xs: 32,\n} as const;\n\nconst FragmentComponent: RendererComponent<\"fragment\"> = ({ node }) => {\n const endpoint = node.props.endpoint ?? \"\";\n const isLazy = node.props.lazy === true;\n const componentRef = node.props.ref ?? \"\";\n const placeholderHeight = fragmentSizeHeights[node.props.size];\n const [components, setComponents] = useState(() => node.schema ?? []);\n const [hasLoaded, setHasLoaded] = useState(!isLazy);\n const [processing, setProcessing] = useState(isLazy && endpoint !== \"\");\n\n const load = useCallback(async (): Promise<void> => {\n if (!endpoint) {\n return;\n }\n\n setProcessing(true);\n\n try {\n const result = await apiJson<FragmentResponse>(endpoint, { ref: componentRef });\n\n setComponents(toNodes(result.schema));\n setHasLoaded(true);\n } finally {\n setProcessing(false);\n }\n }, [endpoint, componentRef]);\n\n useEffect(() => {\n if (!isLazy || hasLoaded) {\n return;\n }\n\n void load();\n }, [hasLoaded, isLazy, load]);\n\n useEffect(() => {\n function reload(event: Event): void {\n const detail = (event as ReloadComponentEvent).detail;\n\n if (detail?.component !== node.id) {\n return;\n }\n\n void load();\n }\n\n window.addEventListener(LATTICE_EVENT.reloadComponent, reload);\n\n return () => window.removeEventListener(LATTICE_EVENT.reloadComponent, reload);\n }, [load, node.id]);\n\n useEffect(() => {\n function reloadOnLocaleChange(): void {\n if (!hasLoaded) {\n return;\n }\n\n void load();\n }\n\n window.addEventListener(LATTICE_EVENT.localeChange, reloadOnLocaleChange);\n\n return () => window.removeEventListener(LATTICE_EVENT.localeChange, reloadOnLocaleChange);\n }, [hasLoaded, load]);\n\n return (\n <div\n data-lattice-fragment={node.id}\n style={processing && components.length === 0 ? { minHeight: placeholderHeight } : undefined}\n >\n {processing && components.length === 0 ? (\n <Skeleton className=\"w-full\" style={{ height: placeholderHeight }} />\n ) : (\n <Renderer nodes={components} />\n )}\n </div>\n );\n};\n\nexport default FragmentComponent;\n"],"mappings":";;;;;;;;AAYA,IAAM,sBAAsB;CAC1B,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;
|
|
1
|
+
{"version":3,"file":"fragment.js","names":[],"sources":["../../../resources/js/core/components/fragment.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { apiJson } from \"@lattice-php/lattice/core/api\";\nimport { Skeleton } from \"@lattice-php/lattice/core/components/skeleton\";\nimport { Renderer } from \"@lattice-php/lattice/core/renderer\";\nimport type { RendererComponent, Schema } from \"@lattice-php/lattice/core/types\";\nimport { toNodes } from \"@lattice-php/lattice/core/nodes\";\nimport { LATTICE_EVENT, type ReloadComponentEvent } from \"@lattice-php/lattice/events/event-names\";\n\ntype FragmentResponse = {\n schema?: Schema;\n};\n\nconst fragmentSizeHeights = {\n lg: 320,\n md: 64,\n sm: 40,\n xl: 384,\n xs: 32,\n \"2xl\": 448,\n \"3xl\": 512,\n \"4xl\": 576,\n} as const;\n\nconst FragmentComponent: RendererComponent<\"fragment\"> = ({ node }) => {\n const endpoint = node.props.endpoint ?? \"\";\n const isLazy = node.props.lazy === true;\n const componentRef = node.props.ref ?? \"\";\n const placeholderHeight = fragmentSizeHeights[node.props.size];\n const [components, setComponents] = useState(() => node.schema ?? []);\n const [hasLoaded, setHasLoaded] = useState(!isLazy);\n const [processing, setProcessing] = useState(isLazy && endpoint !== \"\");\n\n const load = useCallback(async (): Promise<void> => {\n if (!endpoint) {\n return;\n }\n\n setProcessing(true);\n\n try {\n const result = await apiJson<FragmentResponse>(endpoint, { ref: componentRef });\n\n setComponents(toNodes(result.schema));\n setHasLoaded(true);\n } finally {\n setProcessing(false);\n }\n }, [endpoint, componentRef]);\n\n useEffect(() => {\n if (!isLazy || hasLoaded) {\n return;\n }\n\n void load();\n }, [hasLoaded, isLazy, load]);\n\n useEffect(() => {\n function reload(event: Event): void {\n const detail = (event as ReloadComponentEvent).detail;\n\n if (detail?.component !== node.id) {\n return;\n }\n\n void load();\n }\n\n window.addEventListener(LATTICE_EVENT.reloadComponent, reload);\n\n return () => window.removeEventListener(LATTICE_EVENT.reloadComponent, reload);\n }, [load, node.id]);\n\n useEffect(() => {\n function reloadOnLocaleChange(): void {\n if (!hasLoaded) {\n return;\n }\n\n void load();\n }\n\n window.addEventListener(LATTICE_EVENT.localeChange, reloadOnLocaleChange);\n\n return () => window.removeEventListener(LATTICE_EVENT.localeChange, reloadOnLocaleChange);\n }, [hasLoaded, load]);\n\n return (\n <div\n data-lattice-fragment={node.id}\n style={processing && components.length === 0 ? { minHeight: placeholderHeight } : undefined}\n >\n {processing && components.length === 0 ? (\n <Skeleton className=\"w-full\" style={{ height: placeholderHeight }} />\n ) : (\n <Renderer nodes={components} />\n )}\n </div>\n );\n};\n\nexport default FragmentComponent;\n"],"mappings":";;;;;;;;AAYA,IAAM,sBAAsB;CAC1B,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,OAAO;CACP,OAAO;AACT;AAEA,IAAM,qBAAoD,EAAE,WAAW;CACrE,MAAM,WAAW,KAAK,MAAM,YAAY;CACxC,MAAM,SAAS,KAAK,MAAM,SAAS;CACnC,MAAM,eAAe,KAAK,MAAM,OAAO;CACvC,MAAM,oBAAoB,oBAAoB,KAAK,MAAM;CACzD,MAAM,CAAC,YAAY,iBAAiB,eAAe,KAAK,UAAU,CAAC,CAAC;CACpE,MAAM,CAAC,WAAW,gBAAgB,SAAS,CAAC,MAAM;CAClD,MAAM,CAAC,YAAY,iBAAiB,SAAS,UAAU,aAAa,EAAE;CAEtE,MAAM,OAAO,YAAY,YAA2B;EAClD,IAAI,CAAC,UACH;EAGF,cAAc,IAAI;EAElB,IAAI;GAGF,cAAc,SAAQ,MAFD,QAA0B,UAAU,EAAE,KAAK,aAAa,CAAC,GAEjD,MAAM,CAAC;GACpC,aAAa,IAAI;EACnB,UAAU;GACR,cAAc,KAAK;EACrB;CACF,GAAG,CAAC,UAAU,YAAY,CAAC;CAE3B,gBAAgB;EACd,IAAI,CAAC,UAAU,WACb;EAGF,KAAU;CACZ,GAAG;EAAC;EAAW;EAAQ;CAAI,CAAC;CAE5B,gBAAgB;EACd,SAAS,OAAO,OAAoB;GAGlC,IAFgB,MAA+B,QAEnC,cAAc,KAAK,IAC7B;GAGF,KAAU;EACZ;EAEA,OAAO,iBAAiB,cAAc,iBAAiB,MAAM;EAE7D,aAAa,OAAO,oBAAoB,cAAc,iBAAiB,MAAM;CAC/E,GAAG,CAAC,MAAM,KAAK,EAAE,CAAC;CAElB,gBAAgB;EACd,SAAS,uBAA6B;GACpC,IAAI,CAAC,WACH;GAGF,KAAU;EACZ;EAEA,OAAO,iBAAiB,cAAc,cAAc,oBAAoB;EAExE,aAAa,OAAO,oBAAoB,cAAc,cAAc,oBAAoB;CAC1F,GAAG,CAAC,WAAW,IAAI,CAAC;CAEpB,OACE,oBAAC,OAAD;EACE,yBAAuB,KAAK;EAC5B,OAAO,cAAc,WAAW,WAAW,IAAI,EAAE,WAAW,kBAAkB,IAAI,KAAA;YAEjF,cAAc,WAAW,WAAW,IACnC,oBAAC,UAAD;GAAU,WAAU;GAAS,OAAO,EAAE,QAAQ,kBAAkB;EAAI,CAAA,IAEpE,oBAAC,UAAD,EAAU,OAAO,WAAa,CAAA;CAE7B,CAAA;AAET"}
|
|
@@ -7,7 +7,10 @@ var sizeClass = {
|
|
|
7
7
|
sm: "size-lt-icon-sm",
|
|
8
8
|
md: "size-lt-icon-md",
|
|
9
9
|
lg: "size-lt-icon-lg",
|
|
10
|
-
xl: "size-lt-icon-xl"
|
|
10
|
+
xl: "size-lt-icon-xl",
|
|
11
|
+
"2xl": "size-lt-icon-2xl",
|
|
12
|
+
"3xl": "size-lt-icon-3xl",
|
|
13
|
+
"4xl": "size-lt-icon-4xl"
|
|
11
14
|
};
|
|
12
15
|
var colorClass = {
|
|
13
16
|
default: "text-lt-fg",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon.js","names":[],"sources":["../../../resources/js/core/components/icon.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { IconRenderer } from \"@lattice-php/lattice/icons\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport type { Color, Size } from \"@lattice-php/lattice/types/generated\";\n\nconst sizeClass: Record<Size, string> = {\n xs: \"size-lt-icon-xs\",\n sm: \"size-lt-icon-sm\",\n md: \"size-lt-icon-md\",\n lg: \"size-lt-icon-lg\",\n xl: \"size-lt-icon-xl\",\n};\n\nconst colorClass: Record<Color, string> = {\n default: \"text-lt-fg\",\n muted: \"text-lt-muted-fg\",\n primary: \"text-lt-primary\",\n success: \"text-lt-success\",\n info: \"text-lt-info\",\n warning: \"text-lt-warning\",\n danger: \"text-lt-danger\",\n};\n\nconst IconComponent: RendererComponent<\"icon\"> = ({ node }) => {\n const { name, size, color, class: className } = node.props;\n\n return (\n <IconRenderer\n icon={name}\n className={cn(sizeClass[size], color ? colorClass[color] : undefined, className)}\n />\n );\n};\n\nexport default IconComponent;\n"],"mappings":";;;;AAKA,IAAM,YAAkC;CACtC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;
|
|
1
|
+
{"version":3,"file":"icon.js","names":[],"sources":["../../../resources/js/core/components/icon.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { IconRenderer } from \"@lattice-php/lattice/icons\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport type { Color, Size } from \"@lattice-php/lattice/types/generated\";\n\nconst sizeClass: Record<Size, string> = {\n xs: \"size-lt-icon-xs\",\n sm: \"size-lt-icon-sm\",\n md: \"size-lt-icon-md\",\n lg: \"size-lt-icon-lg\",\n xl: \"size-lt-icon-xl\",\n \"2xl\": \"size-lt-icon-2xl\",\n \"3xl\": \"size-lt-icon-3xl\",\n \"4xl\": \"size-lt-icon-4xl\",\n};\n\nconst colorClass: Record<Color, string> = {\n default: \"text-lt-fg\",\n muted: \"text-lt-muted-fg\",\n primary: \"text-lt-primary\",\n success: \"text-lt-success\",\n info: \"text-lt-info\",\n warning: \"text-lt-warning\",\n danger: \"text-lt-danger\",\n};\n\nconst IconComponent: RendererComponent<\"icon\"> = ({ node }) => {\n const { name, size, color, class: className } = node.props;\n\n return (\n <IconRenderer\n icon={name}\n className={cn(sizeClass[size], color ? colorClass[color] : undefined, className)}\n />\n );\n};\n\nexport default IconComponent;\n"],"mappings":";;;;AAKA,IAAM,YAAkC;CACtC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,OAAO;CACP,OAAO;AACT;AAEA,IAAM,aAAoC;CACxC,SAAS;CACT,OAAO;CACP,SAAS;CACT,SAAS;CACT,MAAM;CACN,SAAS;CACT,QAAQ;AACV;AAEA,IAAM,iBAA4C,EAAE,WAAW;CAC7D,MAAM,EAAE,MAAM,MAAM,OAAO,OAAO,cAAc,KAAK;CAErD,OACE,oBAAC,cAAD;EACE,MAAM;EACN,WAAW,GAAG,UAAU,OAAO,QAAQ,WAAW,SAAS,KAAA,GAAW,SAAS;CAChF,CAAA;AAEL"}
|
|
@@ -1,19 +1,40 @@
|
|
|
1
1
|
import { cn } from "../../lib/utils.js";
|
|
2
2
|
import { nodeIdentity } from "../test-id.js";
|
|
3
|
+
import { useAction } from "../../action/use-action.js";
|
|
3
4
|
import { actionMenuItemClassName, useActionMenu } from "../../action/components/action-menu-context.js";
|
|
4
5
|
import { Link } from "@inertiajs/react";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
//#region resources/js/core/components/link.tsx
|
|
8
|
+
var textLinkClassName = "text-lt-fg underline decoration-lt-border underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current! dark:decoration-lt-border";
|
|
7
9
|
function TextLink({ className = "", children, ...props }) {
|
|
8
10
|
return /* @__PURE__ */ jsx(Link, {
|
|
9
|
-
className: cn(
|
|
11
|
+
className: cn(textLinkClassName, className),
|
|
10
12
|
...props,
|
|
11
13
|
children
|
|
12
14
|
});
|
|
13
15
|
}
|
|
16
|
+
function ActionLink({ action, className, children, testId }) {
|
|
17
|
+
const { processing, requestSubmit, overlays } = useAction(action);
|
|
18
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
|
|
19
|
+
className: cn(textLinkClassName, className),
|
|
20
|
+
"data-test": testId,
|
|
21
|
+
disabled: processing,
|
|
22
|
+
onClick: requestSubmit,
|
|
23
|
+
type: "button",
|
|
24
|
+
children
|
|
25
|
+
}), overlays] });
|
|
26
|
+
}
|
|
14
27
|
var LinkComponent = ({ node }) => {
|
|
28
|
+
const isMenuItem = useActionMenu();
|
|
29
|
+
const action = node.props.action;
|
|
30
|
+
if (action) return /* @__PURE__ */ jsx(ActionLink, {
|
|
31
|
+
action,
|
|
32
|
+
className: isMenuItem ? actionMenuItemClassName : void 0,
|
|
33
|
+
testId: nodeIdentity(node),
|
|
34
|
+
children: node.props.label
|
|
35
|
+
});
|
|
15
36
|
return /* @__PURE__ */ jsx(TextLink, {
|
|
16
|
-
className:
|
|
37
|
+
className: isMenuItem ? actionMenuItemClassName : void 0,
|
|
17
38
|
"data-test": nodeIdentity(node),
|
|
18
39
|
href: node.props.href ?? "#",
|
|
19
40
|
method: node.props.method ?? "get",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.js","names":[],"sources":["../../../resources/js/core/components/link.tsx"],"sourcesContent":["import { Link } from \"@inertiajs/react\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport {\n actionMenuItemClassName,\n useActionMenu,\n} from \"@lattice-php/lattice/action/components/action-menu-context\";\n\nfunction TextLink({ className = \"\", children, ...props }: ComponentProps<typeof Link>) {\n return (\n <Link
|
|
1
|
+
{"version":3,"file":"link.js","names":[],"sources":["../../../resources/js/core/components/link.tsx"],"sourcesContent":["import { Link } from \"@inertiajs/react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { useAction } from \"@lattice-php/lattice/action/use-action\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport type { Node, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport {\n actionMenuItemClassName,\n useActionMenu,\n} from \"@lattice-php/lattice/action/components/action-menu-context\";\n\nconst textLinkClassName =\n \"text-lt-fg underline decoration-lt-border underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current! dark:decoration-lt-border\";\n\nfunction TextLink({ className = \"\", children, ...props }: ComponentProps<typeof Link>) {\n return (\n <Link className={cn(textLinkClassName, className)} {...props}>\n {children}\n </Link>\n );\n}\n\nfunction ActionLink({\n action,\n className,\n children,\n testId,\n}: {\n action: Node<\"action\">;\n className?: string;\n children: ReactNode;\n testId?: string;\n}) {\n const { processing, requestSubmit, overlays } = useAction(action);\n\n return (\n <>\n <button\n className={cn(textLinkClassName, className)}\n data-test={testId}\n disabled={processing}\n onClick={requestSubmit}\n type=\"button\"\n >\n {children}\n </button>\n {overlays}\n </>\n );\n}\n\nconst LinkComponent: RendererComponent<\"link\"> = ({ node }) => {\n const isMenuItem = useActionMenu();\n const action = node.props.action;\n\n if (action) {\n return (\n <ActionLink\n action={action as Node<\"action\">}\n className={isMenuItem ? actionMenuItemClassName : undefined}\n testId={nodeIdentity(node)}\n >\n {node.props.label}\n </ActionLink>\n );\n }\n\n return (\n <TextLink\n className={isMenuItem ? actionMenuItemClassName : undefined}\n data-test={nodeIdentity(node)}\n href={node.props.href ?? \"#\"}\n method={node.props.method ?? \"get\"}\n tabIndex={node.props.tabIndex ?? undefined}\n >\n {node.props.label}\n </TextLink>\n );\n};\n\nexport default LinkComponent;\nexport { TextLink };\n"],"mappings":";;;;;;;AAWA,IAAM,oBACJ;AAEF,SAAS,SAAS,EAAE,YAAY,IAAI,UAAU,GAAG,SAAsC;CACrF,OACE,oBAAC,MAAD;EAAM,WAAW,GAAG,mBAAmB,SAAS;EAAG,GAAI;EACpD;CACG,CAAA;AAEV;AAEA,SAAS,WAAW,EAClB,QACA,WACA,UACA,UAMC;CACD,MAAM,EAAE,YAAY,eAAe,aAAa,UAAU,MAAM;CAEhE,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,UAAD;EACE,WAAW,GAAG,mBAAmB,SAAS;EAC1C,aAAW;EACX,UAAU;EACV,SAAS;EACT,MAAK;EAEJ;CACK,CAAA,GACP,QACD,EAAA,CAAA;AAEN;AAEA,IAAM,iBAA4C,EAAE,WAAW;CAC7D,MAAM,aAAa,cAAc;CACjC,MAAM,SAAS,KAAK,MAAM;CAE1B,IAAI,QACF,OACE,oBAAC,YAAD;EACU;EACR,WAAW,aAAa,0BAA0B,KAAA;EAClD,QAAQ,aAAa,IAAI;YAExB,KAAK,MAAM;CACF,CAAA;CAIhB,OACE,oBAAC,UAAD;EACE,WAAW,aAAa,0BAA0B,KAAA;EAClD,aAAW,aAAa,IAAI;EAC5B,MAAM,KAAK,MAAM,QAAQ;EACzB,QAAQ,KAAK,MAAM,UAAU;EAC7B,UAAU,KAAK,MAAM,YAAY,KAAA;YAEhC,KAAK,MAAM;CACJ,CAAA;AAEd"}
|
|
@@ -19,7 +19,10 @@ var textSizes = {
|
|
|
19
19
|
sm: "text-sm leading-6",
|
|
20
20
|
md: "text-base leading-7",
|
|
21
21
|
lg: "text-lg leading-8",
|
|
22
|
-
xl: "text-xl leading-8"
|
|
22
|
+
xl: "text-xl leading-8",
|
|
23
|
+
"2xl": "text-2xl leading-9",
|
|
24
|
+
"3xl": "text-3xl leading-10",
|
|
25
|
+
"4xl": "text-4xl leading-none"
|
|
23
26
|
};
|
|
24
27
|
var TextComponent = ({ node }) => {
|
|
25
28
|
return /* @__PURE__ */ jsx("p", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","names":[],"sources":["../../../resources/js/core/components/text.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport type { Color, Size } from \"@lattice-php/lattice/types/generated\";\n\nconst textAlignments: Record<string, string> = {\n center: \"text-center\",\n left: \"text-left\",\n};\n\nconst textColors: Record<Color, string> = {\n default: \"text-lt-fg\",\n muted: \"text-lt-muted-fg\",\n primary: \"text-lt-primary\",\n success: \"text-lt-success\",\n info: \"text-lt-info\",\n warning: \"text-lt-warning\",\n danger: \"text-lt-danger\",\n};\n\nconst textSizes: Record<Size, string> = {\n xs: \"text-xs leading-5\",\n sm: \"text-sm leading-6\",\n md: \"text-base leading-7\",\n lg: \"text-lg leading-8\",\n xl: \"text-xl leading-8\",\n};\n\nconst TextComponent: RendererComponent<\"text\"> = ({ node }) => {\n const align = node.props.align ?? \"left\";\n\n return (\n <p\n className={cn(\n \"m-0\",\n \"max-w-2xl\",\n textAlignments[align] ?? textAlignments.left,\n textColors[node.props.color],\n textSizes[node.props.size],\n )}\n >\n {node.props.text}\n </p>\n );\n};\n\nexport default TextComponent;\n"],"mappings":";;;AAIA,IAAM,iBAAyC;CAC7C,QAAQ;CACR,MAAM;AACR;AAEA,IAAM,aAAoC;CACxC,SAAS;CACT,OAAO;CACP,SAAS;CACT,SAAS;CACT,MAAM;CACN,SAAS;CACT,QAAQ;AACV;AAEA,IAAM,YAAkC;CACtC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;
|
|
1
|
+
{"version":3,"file":"text.js","names":[],"sources":["../../../resources/js/core/components/text.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport type { Color, Size } from \"@lattice-php/lattice/types/generated\";\n\nconst textAlignments: Record<string, string> = {\n center: \"text-center\",\n left: \"text-left\",\n};\n\nconst textColors: Record<Color, string> = {\n default: \"text-lt-fg\",\n muted: \"text-lt-muted-fg\",\n primary: \"text-lt-primary\",\n success: \"text-lt-success\",\n info: \"text-lt-info\",\n warning: \"text-lt-warning\",\n danger: \"text-lt-danger\",\n};\n\nconst textSizes: Record<Size, string> = {\n xs: \"text-xs leading-5\",\n sm: \"text-sm leading-6\",\n md: \"text-base leading-7\",\n lg: \"text-lg leading-8\",\n xl: \"text-xl leading-8\",\n \"2xl\": \"text-2xl leading-9\",\n \"3xl\": \"text-3xl leading-10\",\n \"4xl\": \"text-4xl leading-none\",\n};\n\nconst TextComponent: RendererComponent<\"text\"> = ({ node }) => {\n const align = node.props.align ?? \"left\";\n\n return (\n <p\n className={cn(\n \"m-0\",\n \"max-w-2xl\",\n textAlignments[align] ?? textAlignments.left,\n textColors[node.props.color],\n textSizes[node.props.size],\n )}\n >\n {node.props.text}\n </p>\n );\n};\n\nexport default TextComponent;\n"],"mappings":";;;AAIA,IAAM,iBAAyC;CAC7C,QAAQ;CACR,MAAM;AACR;AAEA,IAAM,aAAoC;CACxC,SAAS;CACT,OAAO;CACP,SAAS;CACT,SAAS;CACT,MAAM;CACN,SAAS;CACT,QAAQ;AACV;AAEA,IAAM,YAAkC;CACtC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,OAAO;CACP,OAAO;CACP,OAAO;AACT;AAEA,IAAM,iBAA4C,EAAE,WAAW;CAG7D,OACE,oBAAC,KAAD;EACE,WAAW,GACT,OACA,aACA,eAPQ,KAAK,MAAM,SAAS,WAOH,eAAe,MACxC,WAAW,KAAK,MAAM,QACtB,UAAU,KAAK,MAAM,KACvB;YAEC,KAAK,MAAM;CACX,CAAA;AAEP"}
|
package/dist/core/renderer.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { Node } from './types';
|
|
3
|
-
/** Renders a schema (list of nodes) against the active component registry. */
|
|
4
3
|
export declare function Renderer({ nodes }: {
|
|
5
4
|
nodes: Node[];
|
|
6
5
|
}): ReactNode;
|
|
7
|
-
/** Renders a single node against the active component registry. */
|
|
8
6
|
export declare function RenderNode({ node }: {
|
|
9
7
|
node: Node;
|
|
10
8
|
}): ReactNode;
|
package/dist/core/renderer.js
CHANGED
|
@@ -9,11 +9,9 @@ function MissingComponent({ node }) {
|
|
|
9
9
|
function nodeKey(node, index) {
|
|
10
10
|
return node.key ?? node.id ?? `${node.type}-${index}`;
|
|
11
11
|
}
|
|
12
|
-
/** Renders a schema (list of nodes) against the active component registry. */
|
|
13
12
|
function Renderer({ nodes }) {
|
|
14
13
|
return nodes.map((node, index) => /* @__PURE__ */ jsx(NodeRenderer, { node }, nodeKey(node, index)));
|
|
15
14
|
}
|
|
16
|
-
/** Renders a single node against the active component registry. */
|
|
17
15
|
function RenderNode({ node }) {
|
|
18
16
|
return /* @__PURE__ */ jsx(NodeRenderer, { node });
|
|
19
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.js","names":[],"sources":["../../resources/js/core/renderer.tsx"],"sourcesContent":["import { Suspense } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { Node } from \"./types\";\nimport { useCollapsed } from \"./collapsed-context\";\nimport { useComponentRegistry } from \"./registry-context\";\n\nfunction MissingComponent({ node }: { node: Node }) {\n if (!import.meta.env.DEV) {\n return null;\n }\n\n return <div data-lattice-missing-component={node.type}>Missing component: {node.type}</div>;\n}\n\nfunction nodeKey(node: Node, index: number): string {\n return node.key ?? node.id ?? `${node.type}-${index}`;\n}\n\
|
|
1
|
+
{"version":3,"file":"renderer.js","names":[],"sources":["../../resources/js/core/renderer.tsx"],"sourcesContent":["import { Suspense } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { Node } from \"./types\";\nimport { useCollapsed } from \"./collapsed-context\";\nimport { useComponentRegistry } from \"./registry-context\";\n\nfunction MissingComponent({ node }: { node: Node }) {\n if (!import.meta.env.DEV) {\n return null;\n }\n\n return <div data-lattice-missing-component={node.type}>Missing component: {node.type}</div>;\n}\n\nfunction nodeKey(node: Node, index: number): string {\n return node.key ?? node.id ?? `${node.type}-${index}`;\n}\n\nexport function Renderer({ nodes }: { nodes: Node[] }): ReactNode {\n return nodes.map((node, index) => <NodeRenderer key={nodeKey(node, index)} node={node} />);\n}\n\nexport function RenderNode({ node }: { node: Node }): ReactNode {\n return <NodeRenderer node={node} />;\n}\n\nfunction NodeRenderer({ node }: { node: Node }) {\n const collapsed = useCollapsed();\n const registry = useComponentRegistry();\n const registration = registry[node.type];\n\n if (collapsed && node.props?.hideWhenCollapsed === true) {\n return null;\n }\n\n if (!registration) {\n return <MissingComponent node={node} />;\n }\n\n const Component = registration.component;\n const children = node.schema?.length ? <Renderer nodes={node.schema} /> : null;\n const renderedComponent = <Component node={node}>{children}</Component>;\n\n if (registration.mode === \"lazy\") {\n const FallbackComponent = registration.fallback;\n const fallback = FallbackComponent ? (\n <FallbackComponent node={node}>{null}</FallbackComponent>\n ) : null;\n\n return <Suspense fallback={fallback}>{renderedComponent}</Suspense>;\n }\n\n return renderedComponent;\n}\n"],"mappings":";;;;;AAMA,SAAS,iBAAiB,EAAE,QAAwB;CAEhD,OAAO;AAIX;AAEA,SAAS,QAAQ,MAAY,OAAuB;CAClD,OAAO,KAAK,OAAO,KAAK,MAAM,GAAG,KAAK,KAAK,GAAG;AAChD;AAEA,SAAgB,SAAS,EAAE,SAAuC;CAChE,OAAO,MAAM,KAAK,MAAM,UAAU,oBAAC,cAAD,EAA+C,KAAO,GAAnC,QAAQ,MAAM,KAAK,CAAgB,CAAC;AAC3F;AAEA,SAAgB,WAAW,EAAE,QAAmC;CAC9D,OAAO,oBAAC,cAAD,EAAoB,KAAO,CAAA;AACpC;AAEA,SAAS,aAAa,EAAE,QAAwB;CAC9C,MAAM,YAAY,aAAa;CAE/B,MAAM,eADW,qBACI,EAAS,KAAK;CAEnC,IAAI,aAAa,KAAK,OAAO,sBAAsB,MACjD,OAAO;CAGT,IAAI,CAAC,cACH,OAAO,oBAAC,kBAAD,EAAwB,KAAO,CAAA;CAGxC,MAAM,YAAY,aAAa;CAE/B,MAAM,oBAAoB,oBAAC,WAAD;EAAiB;EAAO,UADjC,KAAK,QAAQ,SAAS,oBAAC,UAAD,EAAU,OAAO,KAAK,OAAS,CAAA,IAAI;CACJ,CAAA;CAEtE,IAAI,aAAa,SAAS,QAAQ;EAChC,MAAM,oBAAoB,aAAa;EAKvC,OAAO,oBAAC,UAAD;GAAoB,UAJV,oBACf,oBAAC,mBAAD;IAAyB;cAAO;GAAwB,CAAA,IACtD;aAEkC;EAA4B,CAAA;CACpE;CAEA,OAAO;AACT"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ActionResult, Effect } from '../types/generated';
|
|
2
2
|
import { EffectHandlerRegistry } from './registry';
|
|
3
3
|
export type ActionEffect = Effect;
|
|
4
|
-
/** The server's action response. Fields are optional: a handler may omit any of them. */
|
|
5
4
|
export type ActionResponse = Partial<ActionResult>;
|
|
6
5
|
/**
|
|
7
6
|
* Run each effect through its handler. Handlers default to the built-ins; the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.js","names":[],"sources":["../../resources/js/effects/dispatch.ts"],"sourcesContent":["import type { ActionResult, Effect } from \"@lattice-php/lattice/types/generated\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/events/event-names\";\nimport { builtinEffectHandlers } from \"./registry\";\nimport type { EffectHandlerRegistry } from \"./registry\";\n\nexport type ActionEffect = Effect;\n\
|
|
1
|
+
{"version":3,"file":"dispatch.js","names":[],"sources":["../../resources/js/effects/dispatch.ts"],"sourcesContent":["import type { ActionResult, Effect } from \"@lattice-php/lattice/types/generated\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/events/event-names\";\nimport { builtinEffectHandlers } from \"./registry\";\nimport type { EffectHandlerRegistry } from \"./registry\";\n\nexport type ActionEffect = Effect;\n\nexport type ActionResponse = Partial<ActionResult>;\n\n/**\n * Run each effect through its handler. Handlers default to the built-ins; the\n * Provider passes a merged registry that also includes consumer-registered\n * handlers. An effect with no handler is warned about (dev) and skipped.\n */\nexport function dispatchEffects(\n effects: ActionEffect[],\n handlers: EffectHandlerRegistry = builtinEffectHandlers,\n): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n for (const effect of effects) {\n const handler = handlers[effect.type];\n\n if (handler === undefined) {\n console.warn(`[lattice] No handler registered for effect type \"${effect.type}\".`);\n continue;\n }\n\n handler(effect);\n }\n}\n\nexport function dispatchActionError(error: unknown): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n window.dispatchEvent(new CustomEvent(LATTICE_EVENT.actionError, { detail: { error } }));\n}\n\nexport function getActionEffects(effects: unknown): ActionEffect[] {\n return Array.isArray(effects) ? effects.filter(isActionEffect) : [];\n}\n\n/**\n * Structural guard for an effect on the wire. Intentionally open: it accepts any\n * object with a string `type`, not only the built-in types, so consumer-registered\n * effects pass through getActionEffects() and reach their handlers. Dispatch warns\n * on (and skips) a type with no registered handler.\n */\nexport function isActionEffect(effect: unknown): effect is ActionEffect {\n return (\n typeof effect === \"object\" &&\n effect !== null &&\n \"type\" in effect &&\n typeof (effect as { type: unknown }).type === \"string\"\n );\n}\n"],"mappings":";;;;;;;;AAcA,SAAgB,gBACd,SACA,WAAkC,uBAC5B;CACN,IAAI,OAAO,WAAW,aACpB;CAGF,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,UAAU,SAAS,OAAO;EAEhC,IAAI,YAAY,KAAA,GAAW;GACzB,QAAQ,KAAK,oDAAoD,OAAO,KAAK,GAAG;GAChF;EACF;EAEA,QAAQ,MAAM;CAChB;AACF;AAEA,SAAgB,oBAAoB,OAAsB;CACxD,IAAI,OAAO,WAAW,aACpB;CAGF,OAAO,cAAc,IAAI,YAAY,cAAc,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;AACxF;AAEA,SAAgB,iBAAiB,SAAkC;CACjE,OAAO,MAAM,QAAQ,OAAO,IAAI,QAAQ,OAAO,cAAc,IAAI,CAAC;AACpE;;;;;;;AAQA,SAAgB,eAAe,QAAyC;CACtE,OACE,OAAO,WAAW,YAClB,WAAW,QACX,UAAU,UACV,OAAQ,OAA6B,SAAS;AAElD"}
|
package/dist/effects/registry.js
CHANGED
|
@@ -18,7 +18,6 @@ function triggerDownload(url) {
|
|
|
18
18
|
link.click();
|
|
19
19
|
link.remove();
|
|
20
20
|
}
|
|
21
|
-
/** Re-broadcast an effect as its `lattice:*` DOM event for feature components. */
|
|
22
21
|
function bridge(event) {
|
|
23
22
|
return (effect) => window.dispatchEvent(new CustomEvent(event, { detail: effect }));
|
|
24
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","names":[],"sources":["../../resources/js/effects/registry.ts"],"sourcesContent":["import { router } from \"@inertiajs/react\";\nimport type { ResolveProps } from \"@lattice-php/lattice/core/types\";\nimport type { Effect } from \"@lattice-php/lattice/types/generated\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/events/event-names\";\nimport { setLocale } from \"@lattice-php/lattice/i18n/locale\";\n\n/**\n * Augmentable map of effect `type` → payload (the effect's fields minus `type`).\n * Consumer apps extend it via `declare module \"@lattice-php/lattice\"` so their\n * custom effects type their handler's payload; built-ins resolve through the\n * generated `Effect` union.\n */\nexport interface EffectProps {}\n\
|
|
1
|
+
{"version":3,"file":"registry.js","names":[],"sources":["../../resources/js/effects/registry.ts"],"sourcesContent":["import { router } from \"@inertiajs/react\";\nimport type { ResolveProps } from \"@lattice-php/lattice/core/types\";\nimport type { Effect } from \"@lattice-php/lattice/types/generated\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/events/event-names\";\nimport { setLocale } from \"@lattice-php/lattice/i18n/locale\";\n\n/**\n * Augmentable map of effect `type` → payload (the effect's fields minus `type`).\n * Consumer apps extend it via `declare module \"@lattice-php/lattice\"` so their\n * custom effects type their handler's payload; built-ins resolve through the\n * generated `Effect` union.\n */\nexport interface EffectProps {}\n\ntype EffectPayloads = { [TEffect in Effect as TEffect[\"type\"]]: Omit<TEffect, \"type\"> };\n\ntype EffectPayloadOf<TType extends string> = ResolveProps<\n EffectProps,\n EffectPayloads,\n TType,\n Record<string, unknown>\n>;\n\n/**\n * Resolves an effect `type` to its full shape — `{ type, ...payload }` — the way\n * `Node<T>` pairs a type with its props, so built-ins and consumer effects alike\n * always carry `type`. An unknown type falls back to the loose `Effect` union.\n */\nexport type EffectOf<TType extends string> = string extends TType\n ? Effect\n : { type: TType } & EffectPayloadOf<TType>;\n\nexport type EffectHandler<TType extends string = string> = (effect: EffectOf<TType>) => void;\n\nexport type EffectHandlerRegistry = Record<string, EffectHandler>;\n\n/**\n * Registers a typed effect handler, erasing the type parameter for the registry.\n * Mirrors `eagerComponent`/`columnCell`: author against `EffectHandler<\"my.type\">`\n * for a typed payload, register through this.\n */\nexport function effectHandler<TType extends string>(\n _type: TType,\n fn: EffectHandler<TType>,\n): EffectHandler {\n return fn as unknown as EffectHandler;\n}\n\nfunction triggerDownload(url: string): void {\n const link = document.createElement(\"a\");\n link.href = url;\n link.rel = \"noopener\";\n document.body.appendChild(link);\n link.click();\n link.remove();\n}\n\nfunction bridge(event: string): EffectHandler {\n return (effect) => window.dispatchEvent(new CustomEvent(event, { detail: effect }));\n}\n\n/**\n * Built-in effect handlers. Imperative effects act directly; the rest bridge to\n * the `lattice:*` DOM events that toast/callout/modal/fragment/form subscribe to\n * — preserving today's behavior exactly.\n */\nexport const builtinEffectHandlers: EffectHandlerRegistry = {\n reloadPage: () => router.reload(),\n redirect: effectHandler(\"redirect\", (effect) => router.visit(effect.url)),\n download: effectHandler(\"download\", (effect) => triggerDownload(effect.url)),\n localeChange: effectHandler(\"localeChange\", (effect) => setLocale(effect.locale)),\n toast: bridge(LATTICE_EVENT.toast),\n callout: bridge(LATTICE_EVENT.callout),\n reloadComponent: bridge(LATTICE_EVENT.reloadComponent),\n openModal: bridge(LATTICE_EVENT.openModal),\n closeModal: bridge(LATTICE_EVENT.closeModal),\n resetForm: bridge(LATTICE_EVENT.resetForm),\n toggleSidebar: bridge(LATTICE_EVENT.toggleSidebar),\n};\n\nexport function mergeEffectHandlers(\n ...registries: Array<EffectHandlerRegistry | undefined>\n): EffectHandlerRegistry {\n return registries.reduce<EffectHandlerRegistry>(\n (merged, registry) => ({ ...merged, ...registry }),\n {},\n );\n}\n"],"mappings":";;;;;;;;;AAyCA,SAAgB,cACd,OACA,IACe;CACf,OAAO;AACT;AAEA,SAAS,gBAAgB,KAAmB;CAC1C,MAAM,OAAO,SAAS,cAAc,GAAG;CACvC,KAAK,OAAO;CACZ,KAAK,MAAM;CACX,SAAS,KAAK,YAAY,IAAI;CAC9B,KAAK,MAAM;CACX,KAAK,OAAO;AACd;AAEA,SAAS,OAAO,OAA8B;CAC5C,QAAQ,WAAW,OAAO,cAAc,IAAI,YAAY,OAAO,EAAE,QAAQ,OAAO,CAAC,CAAC;AACpF;;;;;;AAOA,IAAa,wBAA+C;CAC1D,kBAAkB,OAAO,OAAO;CAChC,UAAU,cAAc,aAAa,WAAW,OAAO,MAAM,OAAO,GAAG,CAAC;CACxE,UAAU,cAAc,aAAa,WAAW,gBAAgB,OAAO,GAAG,CAAC;CAC3E,cAAc,cAAc,iBAAiB,WAAW,UAAU,OAAO,MAAM,CAAC;CAChF,OAAO,OAAO,cAAc,KAAK;CACjC,SAAS,OAAO,cAAc,OAAO;CACrC,iBAAiB,OAAO,cAAc,eAAe;CACrD,WAAW,OAAO,cAAc,SAAS;CACzC,YAAY,OAAO,cAAc,UAAU;CAC3C,WAAW,OAAO,cAAc,SAAS;CACzC,eAAe,OAAO,cAAc,aAAa;AACnD;AAEA,SAAgB,oBACd,GAAG,YACoB;CACvB,OAAO,WAAW,QACf,QAAQ,cAAc;EAAE,GAAG;EAAQ,GAAG;CAAS,IAChD,CAAC,CACH;AACF"}
|
|
@@ -3,5 +3,4 @@ import { ComponentProps } from 'react';
|
|
|
3
3
|
export type InputOTPProps = Omit<ComponentProps<typeof OTPInput>, "children" | "maxLength" | "render"> & {
|
|
4
4
|
length: number;
|
|
5
5
|
};
|
|
6
|
-
/** A segmented one-time-code input styled to match Lattice's control surfaces. */
|
|
7
6
|
export declare function InputOTP({ length, containerClassName, pattern, ...props }: InputOTPProps): import("react").JSX.Element;
|
|
@@ -11,7 +11,6 @@ function Slot({ char, hasFakeCaret, isActive }) {
|
|
|
11
11
|
}) : null]
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
|
-
/** A segmented one-time-code input styled to match Lattice's control surfaces. */
|
|
15
14
|
function InputOTP({ length, containerClassName, pattern = REGEXP_ONLY_DIGITS, ...props }) {
|
|
16
15
|
return /* @__PURE__ */ jsx(OTPInput, {
|
|
17
16
|
maxLength: length,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-otp.js","names":[],"sources":["../../../../resources/js/form/components/base/input-otp.tsx"],"sourcesContent":["import { OTPInput, REGEXP_ONLY_DIGITS, type SlotProps } from \"input-otp\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nfunction Slot({ char, hasFakeCaret, isActive }: SlotProps) {\n return (\n <div\n className={cn(\n \"relative flex h-lt-control-md w-10 items-center justify-center border-y border-r border-lt-input text-base shadow-lt-xs transition-all first:rounded-l-lt-sm first:border-l last:rounded-r-lt-sm\",\n isActive && \"z-10 border-lt-ring ring-lt-ring/50 ring-[3px]\",\n )}\n >\n {char}\n {hasFakeCaret ? (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n <div className=\"bg-lt-fg h-5 w-px animate-pulse\" />\n </div>\n ) : null}\n </div>\n );\n}\n\nexport type InputOTPProps = Omit<\n ComponentProps<typeof OTPInput>,\n \"children\" | \"maxLength\" | \"render\"\n> & {\n length: number;\n};\n\
|
|
1
|
+
{"version":3,"file":"input-otp.js","names":[],"sources":["../../../../resources/js/form/components/base/input-otp.tsx"],"sourcesContent":["import { OTPInput, REGEXP_ONLY_DIGITS, type SlotProps } from \"input-otp\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nfunction Slot({ char, hasFakeCaret, isActive }: SlotProps) {\n return (\n <div\n className={cn(\n \"relative flex h-lt-control-md w-10 items-center justify-center border-y border-r border-lt-input text-base shadow-lt-xs transition-all first:rounded-l-lt-sm first:border-l last:rounded-r-lt-sm\",\n isActive && \"z-10 border-lt-ring ring-lt-ring/50 ring-[3px]\",\n )}\n >\n {char}\n {hasFakeCaret ? (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n <div className=\"bg-lt-fg h-5 w-px animate-pulse\" />\n </div>\n ) : null}\n </div>\n );\n}\n\nexport type InputOTPProps = Omit<\n ComponentProps<typeof OTPInput>,\n \"children\" | \"maxLength\" | \"render\"\n> & {\n length: number;\n};\n\nexport function InputOTP({\n length,\n containerClassName,\n pattern = REGEXP_ONLY_DIGITS,\n ...props\n}: InputOTPProps) {\n return (\n <OTPInput\n maxLength={length}\n pattern={pattern}\n containerClassName={cn(\n \"flex items-center gap-2 has-[:disabled]:opacity-50\",\n containerClassName,\n )}\n render={({ slots }) => (\n <div className=\"flex items-center\">\n {slots.map((slot, index) => (\n <Slot key={index} {...slot} />\n ))}\n </div>\n )}\n {...props}\n />\n );\n}\n"],"mappings":";;;;AAIA,SAAS,KAAK,EAAE,MAAM,cAAc,YAAuB;CACzD,OACE,qBAAC,OAAD;EACE,WAAW,GACT,oMACA,YAAY,gDACd;YAJF,CAMG,MACA,eACC,oBAAC,OAAD;GAAK,WAAU;aACb,oBAAC,OAAD,EAAK,WAAU,kCAAmC,CAAA;EAC/C,CAAA,IACH,IACD;;AAET;AASA,SAAgB,SAAS,EACvB,QACA,oBACA,UAAU,oBACV,GAAG,SACa;CAChB,OACE,oBAAC,UAAD;EACE,WAAW;EACF;EACT,oBAAoB,GAClB,sDACA,kBACF;EACA,SAAS,EAAE,YACT,oBAAC,OAAD;GAAK,WAAU;aACZ,MAAM,KAAK,MAAM,UAChB,oBAAC,MAAD,EAAkB,GAAI,KAAO,GAAlB,KAAkB,CAC9B;EACE,CAAA;EAEP,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -24,5 +24,4 @@ export type FieldProps = {
|
|
|
24
24
|
value?: unknown;
|
|
25
25
|
};
|
|
26
26
|
export declare function fieldProps(node: Node): FieldProps;
|
|
27
|
-
/** The single schema traversal shared by the label/value and dependency-watch collectors. */
|
|
28
27
|
export declare function walkFields(nodes: Node[] | undefined, visit: (props: FieldProps, node: Node) => void): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-props.js","names":[],"sources":["../../../resources/js/form/components/field-props.ts"],"sourcesContent":["import type { Node } from \"@lattice-php/lattice/core/types\";\nimport type { FieldConditions } from \"./conditions\";\n\n/**\n * The props every form-field node shares (the PHP Field base). Nodes flow through\n * the form framework loosely typed via the generic schema, so this is the typed\n * lens the shared hooks read them through. Everything is optional because the\n * lens is also applied to non-field nodes while walking the schema.\n */\nexport type FieldProps = {\n conditions?: FieldConditions | null;\n dependsOnAny?: boolean | null;\n dependsOnKeys?: string[] | null;\n disabled?: boolean | null;\n helperText?: string | null;\n hidden?: boolean | null;\n label?: string | null;\n name?: string;\n editablePrefill?: boolean | null;\n prefillRefreshOn?: string[] | null;\n prefillResetOn?: string[] | null;\n readOnly?: boolean | null;\n required?: boolean | null;\n tooltip?: string | null;\n value?: unknown;\n};\n\nexport function fieldProps(node: Node): FieldProps {\n return node.props as FieldProps;\n}\n\
|
|
1
|
+
{"version":3,"file":"field-props.js","names":[],"sources":["../../../resources/js/form/components/field-props.ts"],"sourcesContent":["import type { Node } from \"@lattice-php/lattice/core/types\";\nimport type { FieldConditions } from \"./conditions\";\n\n/**\n * The props every form-field node shares (the PHP Field base). Nodes flow through\n * the form framework loosely typed via the generic schema, so this is the typed\n * lens the shared hooks read them through. Everything is optional because the\n * lens is also applied to non-field nodes while walking the schema.\n */\nexport type FieldProps = {\n conditions?: FieldConditions | null;\n dependsOnAny?: boolean | null;\n dependsOnKeys?: string[] | null;\n disabled?: boolean | null;\n helperText?: string | null;\n hidden?: boolean | null;\n label?: string | null;\n name?: string;\n editablePrefill?: boolean | null;\n prefillRefreshOn?: string[] | null;\n prefillResetOn?: string[] | null;\n readOnly?: boolean | null;\n required?: boolean | null;\n tooltip?: string | null;\n value?: unknown;\n};\n\nexport function fieldProps(node: Node): FieldProps {\n return node.props as FieldProps;\n}\n\nexport function walkFields(\n nodes: Node[] | undefined,\n visit: (props: FieldProps, node: Node) => void,\n): void {\n for (const child of nodes ?? []) {\n visit(fieldProps(child), child);\n walkFields(child.schema, visit);\n }\n}\n"],"mappings":";AA2BA,SAAgB,WAAW,MAAwB;CACjD,OAAO,KAAK;AACd;AAEA,SAAgB,WACd,OACA,OACM;CACN,KAAK,MAAM,SAAS,SAAS,CAAC,GAAG;EAC/B,MAAM,WAAW,KAAK,GAAG,KAAK;EAC9B,WAAW,MAAM,QAAQ,KAAK;CAChC;AACF"}
|