@lattice-php/lattice 0.15.0 → 0.17.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-form.js +1 -1
- package/dist/action/use-action.js +1 -1
- package/dist/chat/types.d.ts +2 -10
- package/dist/core/components/button.js +34 -18
- package/dist/core/components/button.js.map +1 -1
- package/dist/core/components/chart.js +49 -2
- package/dist/core/components/chart.js.map +1 -1
- package/dist/core/components/control.d.ts +1 -3
- package/dist/core/components/control.js.map +1 -1
- package/dist/core/components/link.js +25 -29
- package/dist/core/components/link.js.map +1 -1
- package/dist/core/types.d.ts +22 -42
- package/dist/core/use-click-behavior.d.ts +42 -0
- package/dist/core/use-click-behavior.js +46 -0
- package/dist/core/use-click-behavior.js.map +1 -0
- package/dist/create-app.d.ts +8 -2
- package/dist/create-app.js +4 -2
- package/dist/create-app.js.map +1 -1
- package/dist/effects/registry.d.ts +9 -20
- package/dist/effects/registry.js +4 -6
- package/dist/effects/registry.js.map +1 -1
- package/dist/events/event-bridge.d.ts +1 -1
- package/dist/events/event-bridge.js +1 -1
- package/dist/events/event-bridge.js.map +1 -1
- package/dist/form/components/base/input-otp.d.ts +2 -1
- package/dist/form/components/base/input-otp.js.map +1 -1
- package/dist/form/components/conditions.d.ts +1 -1
- package/dist/form/components/conditions.js.map +1 -1
- package/dist/form/components/field-props.d.ts +2 -1
- package/dist/form/components/field-props.js.map +1 -1
- package/dist/form/components/field-scope.d.ts +2 -1
- package/dist/form/components/field-scope.js.map +1 -1
- package/dist/form/components/fields/date-picker-control.js +11 -13
- package/dist/form/components/fields/date-picker-control.js.map +1 -1
- package/dist/form/components/fields/row-action-menu.d.ts +2 -1
- package/dist/form/components/fields/row-action-menu.js.map +1 -1
- package/dist/form/components/fields/row-item.d.ts +2 -1
- package/dist/form/components/fields/row-item.js.map +1 -1
- package/dist/form/components/fields/table-rows.d.ts +2 -1
- package/dist/form/components/fields/table-rows.js.map +1 -1
- package/dist/form/components/fields/time-input.js +54 -15
- package/dist/form/components/fields/time-input.js.map +1 -1
- package/dist/form/components/fields/time-picker-columns.d.ts +24 -0
- package/dist/form/components/fields/time-picker-columns.js +76 -0
- package/dist/form/components/fields/time-picker-columns.js.map +1 -0
- package/dist/form/components/fields/time-picker.d.ts +18 -0
- package/dist/form/components/fields/time-picker.js +132 -0
- package/dist/form/components/fields/time-picker.js.map +1 -0
- package/dist/form/components/fields/use-row-collection.d.ts +2 -1
- package/dist/form/components/fields/use-row-collection.js.map +1 -1
- package/dist/form/components/form-path.d.ts +0 -1
- package/dist/form/components/form-path.js +1 -1
- package/dist/form/components/form-path.js.map +1 -1
- package/dist/form/components/prefill-targets.d.ts +1 -1
- package/dist/form/components/prefill-targets.js.map +1 -1
- package/dist/form/components/types.d.ts +5 -1
- package/dist/form/components/use-field-commit.d.ts +2 -1
- package/dist/form/components/use-field-commit.js.map +1 -1
- package/dist/form/components/use-form-resolver.d.ts +2 -1
- package/dist/form/components/use-form-resolver.js.map +1 -1
- package/dist/format/date-time.d.ts +12 -0
- package/dist/format/date-time.js +30 -0
- package/dist/format/date-time.js.map +1 -0
- package/dist/format/number.d.ts +2 -0
- package/dist/format/number.js +23 -0
- package/dist/format/number.js.map +1 -0
- package/dist/{table/components/cells → format}/numeric.js +1 -1
- package/dist/format/numeric.js.map +1 -0
- package/dist/format/value.d.ts +6 -0
- package/dist/format/value.js +17 -0
- package/dist/format/value.js.map +1 -0
- package/dist/i18n/config.d.ts +2 -1
- package/dist/i18n/config.js.map +1 -1
- package/dist/i18n/date-time.js +1 -1
- package/dist/i18n/date-time.js.map +1 -1
- package/dist/i18n/instance.d.ts +1 -1
- package/dist/i18n/instance.js.map +1 -1
- package/dist/i18n/locale-reload.d.ts +2 -1
- package/dist/i18n/locale-reload.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/layout/components.js +1 -1
- package/dist/layout/menu-item.js +43 -49
- package/dist/layout/menu-item.js.map +1 -1
- package/dist/notifications/api.d.ts +6 -0
- package/dist/notifications/api.js +21 -0
- package/dist/notifications/api.js.map +1 -0
- package/dist/notifications/components/empty-state.d.ts +1 -0
- package/dist/notifications/components/empty-state.js +21 -0
- package/dist/notifications/components/empty-state.js.map +1 -0
- package/dist/notifications/components/notification-item.d.ts +6 -0
- package/dist/notifications/components/notification-item.js +65 -0
- package/dist/notifications/components/notification-item.js.map +1 -0
- package/dist/notifications/components/notification-list.d.ts +10 -0
- package/dist/notifications/components/notification-list.js +38 -0
- package/dist/notifications/components/notification-list.js.map +1 -0
- package/dist/notifications/components/notifications-echo.d.ts +5 -0
- package/dist/notifications/components/notifications-echo.js +22 -0
- package/dist/notifications/components/notifications-echo.js.map +1 -0
- package/dist/notifications/components/notifications.d.ts +3 -0
- package/dist/notifications/components/notifications.js +109 -0
- package/dist/notifications/components/notifications.js.map +1 -0
- package/dist/notifications/index.d.ts +1 -0
- package/dist/notifications/index.js +11 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/store.d.ts +25 -0
- package/dist/notifications/store.js +100 -0
- package/dist/notifications/store.js.map +1 -0
- package/dist/notifications/types.d.ts +10 -0
- package/dist/notifications/types.js +0 -0
- package/dist/realtime/build-effects.d.ts +2 -1
- package/dist/realtime/build-effects.js.map +1 -1
- package/dist/realtime/subscriptions.js.map +1 -1
- package/dist/registry/eager.js +2 -1
- package/dist/registry/eager.js.map +1 -1
- package/dist/registry/lazy.js +2 -1
- package/dist/registry/lazy.js.map +1 -1
- package/dist/table/bulk.d.ts +2 -1
- package/dist/table/bulk.js.map +1 -1
- package/dist/table/components/bulk-bar.js +2 -2
- package/dist/table/components/cells/money-cell.js +11 -12
- package/dist/table/components/cells/money-cell.js.map +1 -1
- package/dist/table/components/cells/number-cell.js +11 -11
- package/dist/table/components/cells/number-cell.js.map +1 -1
- package/dist/table/components/cells/text-cell.js +1 -1
- package/dist/table/components/filter-controls.d.ts +0 -4
- package/dist/table/components/filter-controls.js.map +1 -1
- package/dist/table/components/table-cell.js.map +1 -1
- package/dist/table/format.d.ts +1 -10
- package/dist/table/format.js +2 -24
- package/dist/table/format.js.map +1 -1
- package/dist/table/types.d.ts +7 -17
- package/dist/types/generated.d.ts +137 -290
- package/dist/types/index.d.ts +1 -1
- package/dist/vite-client.d.ts +8 -0
- package/dist/vite.d.ts +35 -1
- package/dist/vite.js +60 -2
- package/dist/vite.js.map +1 -1
- package/package.json +13 -2
- package/resources/icons/bell.svg +16 -0
- package/resources/icons/clock.svg +16 -0
- package/dist/table/components/cells/numeric.js.map +0 -1
- /package/dist/{table/components/cells → format}/numeric.d.ts +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Renderer } from "../../core/renderer.js";
|
|
2
2
|
import { useT } from "../../i18n/instance.js";
|
|
3
|
-
import { dispatchActionError } from "../../effects/dispatch.js";
|
|
4
3
|
import { Button } from "../../core/components/button.js";
|
|
5
4
|
import { Dialog, DialogContent, DialogHeader } from "../../core/components/dialog.js";
|
|
6
5
|
import { Spinner } from "../../core/components/spinner.js";
|
|
6
|
+
import { dispatchActionError } from "../../effects/dispatch.js";
|
|
7
7
|
import { apiFetch } from "../../core/api.js";
|
|
8
8
|
import { Skeleton } from "../../core/components/skeleton.js";
|
|
9
9
|
import { FormProvider } from "../../form/components/context.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { withHeaders } from "../core/headers.js";
|
|
2
|
+
import { ConfirmDialog } from "../core/components/confirm-dialog.js";
|
|
2
3
|
import { getActionEffects } from "../effects/dispatch.js";
|
|
3
4
|
import { useEffectDispatcher } from "../effects/use-effect-dispatcher.js";
|
|
4
|
-
import { ConfirmDialog } from "../core/components/confirm-dialog.js";
|
|
5
5
|
import { runAction } from "./run-action.js";
|
|
6
6
|
import { ActionForm, useLazyActionForm } from "./components/action-form.js";
|
|
7
7
|
import { router, useHttp } from "@inertiajs/react";
|
package/dist/chat/types.d.ts
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import { Node } from '../core/types';
|
|
2
|
-
import { ChatMessage
|
|
3
|
-
export type { ChatRole };
|
|
4
|
-
/**
|
|
5
|
-
* The generated message shape, but `parts` is widened from the generated
|
|
6
|
-
* `ChatNode` union to open `Node`s — a part is just a component node rendered by
|
|
7
|
-
* `type`, so a message can also carry a consumer's custom part.
|
|
8
|
-
*/
|
|
9
|
-
export type ChatMessage = Omit<GeneratedChatMessage, "parts"> & {
|
|
10
|
-
parts: Node[];
|
|
11
|
-
};
|
|
2
|
+
import { ChatMessage, ChatRole } from '../types/generated';
|
|
3
|
+
export type { ChatMessage, ChatRole };
|
|
12
4
|
export type ChatStatus = "idle" | "submitted" | "streaming" | "error";
|
|
13
5
|
export type ChatFrame = {
|
|
14
6
|
type: "text";
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { cn } from "../../lib/utils.js";
|
|
2
2
|
import { IconRenderer } from "../../icons/icon-renderer.js";
|
|
3
3
|
import { nodeIdentity } from "../test-id.js";
|
|
4
|
-
import {
|
|
5
|
-
import { useEffectDispatcher } from "../../effects/use-effect-dispatcher.js";
|
|
4
|
+
import { ActionTrigger, useClickBehavior } from "../use-click-behavior.js";
|
|
6
5
|
import { Link } from "@inertiajs/react";
|
|
7
6
|
import "react";
|
|
8
7
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -45,34 +44,51 @@ function Button({ className, variant, size, asChild = false, ...props }) {
|
|
|
45
44
|
});
|
|
46
45
|
}
|
|
47
46
|
var ButtonComponent = ({ node }) => {
|
|
48
|
-
const {
|
|
49
|
-
const effects = node.props.effects ?? [];
|
|
47
|
+
const { label, icon } = node.props;
|
|
50
48
|
const variant = node.props.variant ?? "default";
|
|
51
49
|
const testId = nodeIdentity(node);
|
|
52
|
-
const
|
|
53
|
-
|
|
50
|
+
const behavior = useClickBehavior(node.props);
|
|
51
|
+
const size = icon ? "icon" : "default";
|
|
52
|
+
const content = icon ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(IconRenderer, {
|
|
53
|
+
className: "size-lt-icon-md",
|
|
54
|
+
icon
|
|
55
|
+
}), label ? /* @__PURE__ */ jsx("span", {
|
|
56
|
+
className: "sr-only",
|
|
57
|
+
children: label
|
|
58
|
+
}) : null] }) : label;
|
|
59
|
+
const triggerButton = ({ onClick, processing }) => /* @__PURE__ */ jsx(Button, {
|
|
60
|
+
"data-test": testId,
|
|
61
|
+
disabled: processing,
|
|
62
|
+
onClick,
|
|
63
|
+
size,
|
|
64
|
+
variant,
|
|
65
|
+
children: content
|
|
66
|
+
});
|
|
67
|
+
if (behavior.kind === "navigate") return /* @__PURE__ */ jsx(Button, {
|
|
54
68
|
asChild: true,
|
|
55
69
|
"data-test": testId,
|
|
56
70
|
variant,
|
|
57
|
-
size
|
|
71
|
+
size,
|
|
58
72
|
children: /* @__PURE__ */ jsx(Link, {
|
|
59
|
-
href,
|
|
60
|
-
|
|
73
|
+
href: behavior.href,
|
|
74
|
+
method: behavior.method,
|
|
75
|
+
children: content
|
|
61
76
|
})
|
|
62
77
|
});
|
|
78
|
+
if (behavior.kind === "action") return /* @__PURE__ */ jsx(ActionTrigger, {
|
|
79
|
+
action: behavior.action,
|
|
80
|
+
children: triggerButton
|
|
81
|
+
});
|
|
82
|
+
if (behavior.kind === "effects") return triggerButton({
|
|
83
|
+
onClick: behavior.onClick,
|
|
84
|
+
processing: false
|
|
85
|
+
});
|
|
63
86
|
return /* @__PURE__ */ jsx(Button, {
|
|
64
87
|
"data-test": testId,
|
|
65
|
-
|
|
66
|
-
size: icon ? "icon" : "default",
|
|
88
|
+
size,
|
|
67
89
|
type: node.props.buttonType,
|
|
68
90
|
variant,
|
|
69
|
-
children:
|
|
70
|
-
className: "size-lt-icon-md",
|
|
71
|
-
icon
|
|
72
|
-
}), label ? /* @__PURE__ */ jsx("span", {
|
|
73
|
-
className: "sr-only",
|
|
74
|
-
children: label
|
|
75
|
-
}) : null] }) : label
|
|
91
|
+
children: content
|
|
76
92
|
});
|
|
77
93
|
};
|
|
78
94
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","names":[],"sources":["../../../resources/js/core/components/button.tsx"],"sourcesContent":["import { Link } from \"@inertiajs/react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport {
|
|
1
|
+
{"version":3,"file":"button.js","names":[],"sources":["../../../resources/js/core/components/button.tsx"],"sourcesContent":["import { Link } from \"@inertiajs/react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { IconRenderer } from \"@lattice-php/lattice/icons\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport {\n ActionTrigger,\n type TriggerState,\n useClickBehavior,\n} from \"@lattice-php/lattice/core/use-click-behavior\";\nimport type { ButtonVariant } from \"@lattice-php/lattice/types/generated\";\n\nexport type { ButtonVariant };\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lt-sm text-base font-medium transition-[color,box-shadow] disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-lt-icon-md [&_svg]:shrink-0 outline-none focus-visible:border-lt-ring focus-visible:ring-lt-ring/50 focus-visible:ring-[3px] aria-invalid:ring-lt-danger/20 dark:aria-invalid:ring-lt-danger/40 aria-invalid:border-lt-danger\",\n {\n variants: {\n variant: {\n default:\n \"bg-lt-primary text-lt-primary-fg shadow-lt-xs hover:bg-lt-primary-hover active:bg-lt-primary-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n destructive:\n \"bg-lt-danger text-lt-danger-fg shadow-lt-xs hover:bg-lt-danger-hover active:bg-lt-danger-active focus-visible:ring-lt-danger/20 dark:focus-visible:ring-lt-danger/40 disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n success:\n \"bg-lt-success text-lt-success-fg shadow-lt-xs hover:bg-lt-success-hover active:bg-lt-success-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n info: \"bg-lt-info text-lt-info-fg shadow-lt-xs hover:bg-lt-info-hover active:bg-lt-info-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n outline:\n \"border border-lt-input bg-lt-bg shadow-lt-xs hover:bg-lt-accent hover:text-lt-accent-fg disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:border-transparent disabled:shadow-none\",\n secondary:\n \"bg-lt-secondary text-lt-secondary-fg shadow-lt-xs hover:bg-lt-secondary-hover active:bg-lt-secondary-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n ghost: \"hover:bg-lt-accent hover:text-lt-accent-fg disabled:text-lt-disabled-fg\",\n link: \"text-lt-primary underline-offset-4 hover:underline disabled:text-lt-disabled-fg disabled:no-underline\",\n },\n size: {\n default: \"h-lt-control-md px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-lt-control-sm rounded-lt-sm px-3 has-[>svg]:px-2.5\",\n lg: \"h-lt-control-lg rounded-lt-sm px-6 has-[>svg]:px-4\",\n icon: \"size-lt-control-md\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nconst ButtonComponent: RendererComponent<\"button\"> = ({ node }) => {\n const { label, icon } = node.props;\n const variant = node.props.variant ?? \"default\";\n const testId = nodeIdentity(node);\n const behavior = useClickBehavior(node.props);\n const size = icon ? \"icon\" : \"default\";\n const content = icon ? (\n <>\n <IconRenderer className=\"size-lt-icon-md\" icon={icon} />\n {label ? <span className=\"sr-only\">{label}</span> : null}\n </>\n ) : (\n label\n );\n\n const triggerButton = ({ onClick, processing }: TriggerState) => (\n <Button\n data-test={testId}\n disabled={processing}\n onClick={onClick}\n size={size}\n variant={variant}\n >\n {content}\n </Button>\n );\n\n if (behavior.kind === \"navigate\") {\n return (\n <Button asChild data-test={testId} variant={variant} size={size}>\n <Link href={behavior.href} method={behavior.method}>\n {content}\n </Link>\n </Button>\n );\n }\n\n if (behavior.kind === \"action\") {\n return <ActionTrigger action={behavior.action}>{triggerButton}</ActionTrigger>;\n }\n\n if (behavior.kind === \"effects\") {\n return triggerButton({ onClick: behavior.onClick, processing: false });\n }\n\n return (\n <Button data-test={testId} size={size} type={node.props.buttonType} variant={variant}>\n {content}\n </Button>\n );\n};\n\nexport default ButtonComponent;\nexport { Button, buttonVariants };\n"],"mappings":";;;;;;;;;;AAiBA,IAAM,iBAAiB,IACrB,+bACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,aACE;GACF,SACE;GACF,MAAM;GACN,SACE;GACF,WACE;GACF,OAAO;GACP,MAAM;EACR;EACA,MAAM;GACJ,SAAS;GACT,IAAI;GACJ,IAAI;GACJ,MAAM;EACR;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CACF;AAEA,SAAS,OAAO,EACd,WACA,SACA,MACA,UAAU,OACV,GAAG,SAIA;CAGH,OACE,oBAHW,UAAU,OAAO,UAG5B;EACE,aAAU;EACV,WAAW,GAAG,eAAe;GAAE;GAAS;GAAM;EAAU,CAAC,CAAC;EAC1D,GAAI;CACL,CAAA;AAEL;AAEA,IAAM,mBAAgD,EAAE,WAAW;CACjE,MAAM,EAAE,OAAO,SAAS,KAAK;CAC7B,MAAM,UAAU,KAAK,MAAM,WAAW;CACtC,MAAM,SAAS,aAAa,IAAI;CAChC,MAAM,WAAW,iBAAiB,KAAK,KAAK;CAC5C,MAAM,OAAO,OAAO,SAAS;CAC7B,MAAM,UAAU,OACd,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,cAAD;EAAc,WAAU;EAAwB;CAAO,CAAA,GACtD,QAAQ,oBAAC,QAAD;EAAM,WAAU;YAAW;CAAY,CAAA,IAAI,IACpD,EAAA,CAAA,IAEF;CAGF,MAAM,iBAAiB,EAAE,SAAS,iBAChC,oBAAC,QAAD;EACE,aAAW;EACX,UAAU;EACD;EACH;EACG;YAER;CACK,CAAA;CAGV,IAAI,SAAS,SAAS,YACpB,OACE,oBAAC,QAAD;EAAQ,SAAA;EAAQ,aAAW;EAAiB;EAAe;YACzD,oBAAC,MAAD;GAAM,MAAM,SAAS;GAAM,QAAQ,SAAS;aACzC;EACG,CAAA;CACA,CAAA;CAIZ,IAAI,SAAS,SAAS,UACpB,OAAO,oBAAC,eAAD;EAAe,QAAQ,SAAS;YAAS;CAA6B,CAAA;CAG/E,IAAI,SAAS,SAAS,WACpB,OAAO,cAAc;EAAE,SAAS,SAAS;EAAS,YAAY;CAAM,CAAC;CAGvE,OACE,oBAAC,QAAD;EAAQ,aAAW;EAAc;EAAM,MAAM,KAAK,MAAM;EAAqB;YAC1E;CACK,CAAA;AAEZ"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { useLocale } from "../../i18n/locale.js";
|
|
2
|
+
import { useTimezone } from "../../i18n/timezone.js";
|
|
1
3
|
import { nodeIdentity } from "../test-id.js";
|
|
4
|
+
import { formatValue } from "../../format/value.js";
|
|
2
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
6
|
import { Area, AreaChart, Bar, BarChart, CartesianGrid, Cell, ComposedChart, Legend, Line, LineChart, Pie, PieChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
|
|
4
7
|
//#region resources/js/core/components/chart.tsx
|
|
@@ -20,6 +23,18 @@ var compactLegendProps = {
|
|
|
20
23
|
}
|
|
21
24
|
};
|
|
22
25
|
var axisTick = { fontSize: 10 };
|
|
26
|
+
var tooltipProps = {
|
|
27
|
+
contentStyle: {
|
|
28
|
+
background: "var(--lt-surface)",
|
|
29
|
+
border: "1px solid var(--lt-border)",
|
|
30
|
+
borderRadius: "var(--lt-radius-sm)",
|
|
31
|
+
boxShadow: "var(--lt-shadow-sm)",
|
|
32
|
+
color: "var(--lt-surface-fg)",
|
|
33
|
+
fontSize: 12
|
|
34
|
+
},
|
|
35
|
+
itemStyle: { color: "var(--lt-surface-fg)" },
|
|
36
|
+
labelStyle: { color: "var(--lt-muted-fg)" }
|
|
37
|
+
};
|
|
23
38
|
var palette = [
|
|
24
39
|
"var(--lt-primary)",
|
|
25
40
|
"var(--lt-success)",
|
|
@@ -70,6 +85,21 @@ function ChartFrame({ children, description, id, title }) {
|
|
|
70
85
|
function CartesianChart({ props }) {
|
|
71
86
|
const series = props.series.filter(isCartesianSeries);
|
|
72
87
|
const RechartsChart = cartesianChartFor(series);
|
|
88
|
+
const { locale } = useLocale();
|
|
89
|
+
const { timezone } = useTimezone();
|
|
90
|
+
const ctx = {
|
|
91
|
+
locale,
|
|
92
|
+
timezone
|
|
93
|
+
};
|
|
94
|
+
const formatCategory = (value) => formatValue(value, props.categoryFormat, ctx);
|
|
95
|
+
const formatValueTick = (value) => formatValue(value, props.valueFormat, ctx);
|
|
96
|
+
const tooltipCursor = series.some((item) => item.type === "bar") ? {
|
|
97
|
+
fill: "var(--lt-muted-fg)",
|
|
98
|
+
fillOpacity: .15
|
|
99
|
+
} : {
|
|
100
|
+
stroke: "var(--lt-muted-fg)",
|
|
101
|
+
strokeOpacity: .4
|
|
102
|
+
};
|
|
73
103
|
return /* @__PURE__ */ jsx(ResponsiveContainer, {
|
|
74
104
|
width: "100%",
|
|
75
105
|
height: props.height,
|
|
@@ -86,15 +116,22 @@ function CartesianChart({ props }) {
|
|
|
86
116
|
dataKey: props.categoryKey,
|
|
87
117
|
stroke: "var(--lt-muted-fg)",
|
|
88
118
|
tick: axisTick,
|
|
119
|
+
tickFormatter: formatCategory,
|
|
89
120
|
tickLine: false
|
|
90
121
|
}),
|
|
91
122
|
props.yAxis && /* @__PURE__ */ jsx(YAxis, {
|
|
92
123
|
stroke: "var(--lt-muted-fg)",
|
|
93
124
|
tick: axisTick,
|
|
125
|
+
tickFormatter: formatValueTick,
|
|
94
126
|
tickLine: false,
|
|
95
127
|
width: 42
|
|
96
128
|
}),
|
|
97
|
-
props.tooltip && /* @__PURE__ */ jsx(Tooltip, {
|
|
129
|
+
props.tooltip && /* @__PURE__ */ jsx(Tooltip, {
|
|
130
|
+
...tooltipProps,
|
|
131
|
+
cursor: tooltipCursor,
|
|
132
|
+
formatter: formatValueTick,
|
|
133
|
+
labelFormatter: formatCategory
|
|
134
|
+
}),
|
|
98
135
|
props.legend && /* @__PURE__ */ jsx(Legend, { ...compactLegendProps }),
|
|
99
136
|
series.map((item, index) => {
|
|
100
137
|
const color = item.color ?? colorAt(index);
|
|
@@ -134,6 +171,12 @@ function CartesianChart({ props }) {
|
|
|
134
171
|
});
|
|
135
172
|
}
|
|
136
173
|
function PieChartView({ props, series }) {
|
|
174
|
+
const { locale } = useLocale();
|
|
175
|
+
const { timezone } = useTimezone();
|
|
176
|
+
const ctx = {
|
|
177
|
+
locale,
|
|
178
|
+
timezone
|
|
179
|
+
};
|
|
137
180
|
return /* @__PURE__ */ jsx(ResponsiveContainer, {
|
|
138
181
|
width: "100%",
|
|
139
182
|
height: props.height,
|
|
@@ -141,7 +184,11 @@ function PieChartView({ props, series }) {
|
|
|
141
184
|
children: /* @__PURE__ */ jsxs(PieChart, {
|
|
142
185
|
margin: chartMargin,
|
|
143
186
|
children: [
|
|
144
|
-
props.tooltip && /* @__PURE__ */ jsx(Tooltip, {
|
|
187
|
+
props.tooltip && /* @__PURE__ */ jsx(Tooltip, {
|
|
188
|
+
...tooltipProps,
|
|
189
|
+
formatter: (value) => formatValue(value, props.valueFormat, ctx),
|
|
190
|
+
labelFormatter: (value) => formatValue(value, props.categoryFormat, ctx)
|
|
191
|
+
}),
|
|
145
192
|
props.legend && /* @__PURE__ */ jsx(Legend, { ...compactLegendProps }),
|
|
146
193
|
/* @__PURE__ */ jsx(Pie, {
|
|
147
194
|
data: props.data,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart.js","names":[],"sources":["../../../resources/js/core/components/chart.tsx"],"sourcesContent":["import {\n Area,\n AreaChart,\n Bar,\n BarChart,\n CartesianGrid,\n Cell,\n ComposedChart,\n Legend,\n Line,\n LineChart,\n Pie,\n PieChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport type { PropsOf, RendererComponent } from \"@lattice-php/lattice/core/types\";\n\ntype ChartProps = PropsOf<\"chart\">;\ntype ChartSeries = ChartProps[\"series\"][number];\ntype ChartDatum = ChartProps[\"data\"][number];\ntype CartesianSeries = ChartSeries & { type: \"area\" | \"bar\" | \"line\" };\ntype ChartMargin = { bottom: number; left: number; right: number; top: number };\ntype CartesianChartComponent = ComponentType<{\n children: ReactNode;\n data: ChartProps[\"data\"];\n margin?: ChartMargin;\n}>;\n\nconst chartMargin: ChartMargin = { bottom: 0, left: 0, right: 16, top: 8 };\nconst compactLegendProps = {\n align: \"center\" as const,\n height: 24,\n iconSize: 7,\n verticalAlign: \"top\" as const,\n wrapperStyle: { fontSize: 11, lineHeight: \"14px\", paddingBottom: 6 },\n};\nconst axisTick = { fontSize: 10 };\n\nconst palette = [\n \"var(--lt-primary)\",\n \"var(--lt-success)\",\n \"var(--lt-info)\",\n \"var(--lt-warning)\",\n \"var(--lt-danger)\",\n \"var(--lt-muted-fg)\",\n];\n\nfunction colorAt(index: number): string {\n return palette[index % palette.length] ?? \"var(--lt-primary)\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction datumColor(datum: ChartDatum, series: ChartSeries, index: number): string {\n if (isRecord(datum) && typeof datum.color === \"string\") {\n return datum.color;\n }\n\n return series.color ?? colorAt(index);\n}\n\nfunction isCartesianSeries(series: ChartSeries): series is CartesianSeries {\n return series.type === \"area\" || series.type === \"bar\" || series.type === \"line\";\n}\n\nfunction cartesianChartFor(series: CartesianSeries[]): CartesianChartComponent {\n const types = new Set(series.map((item) => item.type));\n const firstSeries = series[0];\n\n if (firstSeries === undefined || types.size !== 1) {\n return ComposedChart;\n }\n\n switch (firstSeries.type) {\n case \"area\":\n return AreaChart;\n case \"bar\":\n return BarChart;\n case \"line\":\n return LineChart;\n }\n}\n\nfunction ChartFrame({\n children,\n description,\n id,\n title,\n}: {\n children: ReactNode;\n description: string | null;\n id?: string;\n title: string | null;\n}) {\n const hasHeader = title !== null || description !== null;\n\n return (\n <div\n className=\"flex flex-col gap-3 rounded-lt border border-lt-border bg-lt-surface p-4 text-lt-surface-fg shadow-lt-sm\"\n data-lattice-component={id}\n >\n {hasHeader && (\n <div className=\"flex min-w-0 flex-col gap-1.5\">\n {title !== null && <div className=\"text-sm font-semibold leading-tight\">{title}</div>}\n {description !== null && (\n <div className=\"text-xs leading-5 text-lt-muted-fg\">{description}</div>\n )}\n </div>\n )}\n {children}\n </div>\n );\n}\n\nfunction CartesianChart({ props }: { props: ChartProps }) {\n const series = props.series.filter(isCartesianSeries);\n const RechartsChart = cartesianChartFor(series);\n\n return (\n <ResponsiveContainer width=\"100%\" height={props.height} debounce={100}>\n <RechartsChart data={props.data} margin={chartMargin}>\n {props.grid && <CartesianGrid strokeDasharray=\"3 3\" stroke=\"var(--lt-border)\" />}\n {props.xAxis && props.categoryKey !== null && (\n <XAxis\n dataKey={props.categoryKey}\n stroke=\"var(--lt-muted-fg)\"\n tick={axisTick}\n tickLine={false}\n />\n )}\n {props.yAxis && (\n <YAxis stroke=\"var(--lt-muted-fg)\" tick={axisTick} tickLine={false} width={42} />\n )}\n {props.tooltip && <Tooltip />}\n {props.legend && <Legend {...compactLegendProps} />}\n {series.map((item, index) => {\n const color = item.color ?? colorAt(index);\n const key = `${item.type}:${item.dataKey}`;\n\n if (item.type === \"area\") {\n return (\n <Area\n key={key}\n dataKey={item.dataKey}\n fill={color}\n fillOpacity={0.16}\n name={item.name ?? undefined}\n stackId={item.stackId ?? undefined}\n stroke={color}\n type=\"monotone\"\n />\n );\n }\n\n if (item.type === \"bar\") {\n return (\n <Bar\n key={key}\n dataKey={item.dataKey}\n fill={color}\n name={item.name ?? undefined}\n radius={[4, 4, 0, 0]}\n stackId={item.stackId ?? undefined}\n />\n );\n }\n\n return (\n <Line\n key={key}\n dataKey={item.dataKey}\n dot={false}\n name={item.name ?? undefined}\n stroke={color}\n strokeWidth={2}\n type=\"monotone\"\n />\n );\n })}\n </RechartsChart>\n </ResponsiveContainer>\n );\n}\n\nfunction PieChartView({ props, series }: { props: ChartProps; series: ChartSeries }) {\n return (\n <ResponsiveContainer width=\"100%\" height={props.height} debounce={100}>\n <PieChart margin={chartMargin}>\n {props.tooltip && <Tooltip />}\n {props.legend && <Legend {...compactLegendProps} />}\n <Pie\n data={props.data}\n dataKey={series.dataKey}\n name={series.name ?? undefined}\n nameKey={series.nameKey ?? undefined}\n outerRadius=\"68%\"\n >\n {props.data.map((datum, index) => (\n <Cell key={index} fill={datumColor(datum, series, index)} />\n ))}\n </Pie>\n </PieChart>\n </ResponsiveContainer>\n );\n}\n\nconst ChartComponent: RendererComponent<\"chart\"> = ({ node }) => {\n const props = node.props;\n const pieSeries = props.series.find((series) => series.type === \"pie\");\n const hasCartesianSeries = props.series.some(isCartesianSeries);\n\n return (\n <ChartFrame description={props.description} id={nodeIdentity(node)} title={props.title}>\n <div className=\"min-h-0 w-full\">\n {pieSeries && !hasCartesianSeries ? (\n <PieChartView props={props} series={pieSeries} />\n ) : (\n <CartesianChart props={props} />\n )}\n </div>\n </ChartFrame>\n );\n};\n\nexport default ChartComponent;\n"],"mappings":";;;;AAiCA,IAAM,cAA2B;CAAE,QAAQ;CAAG,MAAM;CAAG,OAAO;CAAI,KAAK;AAAE;AACzE,IAAM,qBAAqB;CACzB,OAAO;CACP,QAAQ;CACR,UAAU;CACV,eAAe;CACf,cAAc;EAAE,UAAU;EAAI,YAAY;EAAQ,eAAe;CAAE;AACrE;AACA,IAAM,WAAW,EAAE,UAAU,GAAG;AAEhC,IAAM,UAAU;CACd;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAS,QAAQ,OAAuB;CACtC,OAAO,QAAQ,QAAQ,QAAQ,WAAW;AAC5C;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,WAAW,OAAmB,QAAqB,OAAuB;CACjF,IAAI,SAAS,KAAK,KAAK,OAAO,MAAM,UAAU,UAC5C,OAAO,MAAM;CAGf,OAAO,OAAO,SAAS,QAAQ,KAAK;AACtC;AAEA,SAAS,kBAAkB,QAAgD;CACzE,OAAO,OAAO,SAAS,UAAU,OAAO,SAAS,SAAS,OAAO,SAAS;AAC5E;AAEA,SAAS,kBAAkB,QAAoD;CAC7E,MAAM,QAAQ,IAAI,IAAI,OAAO,KAAK,SAAS,KAAK,IAAI,CAAC;CACrD,MAAM,cAAc,OAAO;CAE3B,IAAI,gBAAgB,KAAA,KAAa,MAAM,SAAS,GAC9C,OAAO;CAGT,QAAQ,YAAY,MAApB;EACE,KAAK,QACH,OAAO;EACT,KAAK,OACH,OAAO;EACT,KAAK,QACH,OAAO;CACX;AACF;AAEA,SAAS,WAAW,EAClB,UACA,aACA,IACA,SAMC;CAGD,OACE,qBAAC,OAAD;EACE,WAAU;EACV,0BAAwB;YAF1B,EAHgB,UAAU,QAAQ,gBAAgB,SAQ9C,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,UAAU,QAAQ,oBAAC,OAAD;IAAK,WAAU;cAAuC;GAAW,CAAA,GACnF,gBAAgB,QACf,oBAAC,OAAD;IAAK,WAAU;cAAsC;GAAiB,CAAA,CAErE;MAEN,QACE;;AAET;AAEA,SAAS,eAAe,EAAE,SAAgC;CACxD,MAAM,SAAS,MAAM,OAAO,OAAO,iBAAiB;CACpD,MAAM,gBAAgB,kBAAkB,MAAM;CAE9C,OACE,oBAAC,qBAAD;EAAqB,OAAM;EAAO,QAAQ,MAAM;EAAQ,UAAU;YAChE,qBAAC,eAAD;GAAe,MAAM,MAAM;GAAM,QAAQ;aAAzC;IACG,MAAM,QAAQ,oBAAC,eAAD;KAAe,iBAAgB;KAAM,QAAO;IAAoB,CAAA;IAC9E,MAAM,SAAS,MAAM,gBAAgB,QACpC,oBAAC,OAAD;KACE,SAAS,MAAM;KACf,QAAO;KACP,MAAM;KACN,UAAU;IACX,CAAA;IAEF,MAAM,SACL,oBAAC,OAAD;KAAO,QAAO;KAAqB,MAAM;KAAU,UAAU;KAAO,OAAO;IAAK,CAAA;IAEjF,MAAM,WAAW,oBAAC,SAAD,CAAU,CAAA;IAC3B,MAAM,UAAU,oBAAC,QAAD,EAAQ,GAAI,mBAAqB,CAAA;IACjD,OAAO,KAAK,MAAM,UAAU;KAC3B,MAAM,QAAQ,KAAK,SAAS,QAAQ,KAAK;KACzC,MAAM,MAAM,GAAG,KAAK,KAAK,GAAG,KAAK;KAEjC,IAAI,KAAK,SAAS,QAChB,OACE,oBAAC,MAAD;MAEE,SAAS,KAAK;MACd,MAAM;MACN,aAAa;MACb,MAAM,KAAK,QAAQ,KAAA;MACnB,SAAS,KAAK,WAAW,KAAA;MACzB,QAAQ;MACR,MAAK;KACN,GARM,GAQN;KAIL,IAAI,KAAK,SAAS,OAChB,OACE,oBAAC,KAAD;MAEE,SAAS,KAAK;MACd,MAAM;MACN,MAAM,KAAK,QAAQ,KAAA;MACnB,QAAQ;OAAC;OAAG;OAAG;OAAG;MAAC;MACnB,SAAS,KAAK,WAAW,KAAA;KAC1B,GANM,GAMN;KAIL,OACE,oBAAC,MAAD;MAEE,SAAS,KAAK;MACd,KAAK;MACL,MAAM,KAAK,QAAQ,KAAA;MACnB,QAAQ;MACR,aAAa;MACb,MAAK;KACN,GAPM,GAON;IAEL,CAAC;GACY;;CACI,CAAA;AAEzB;AAEA,SAAS,aAAa,EAAE,OAAO,UAAsD;CACnF,OACE,oBAAC,qBAAD;EAAqB,OAAM;EAAO,QAAQ,MAAM;EAAQ,UAAU;YAChE,qBAAC,UAAD;GAAU,QAAQ;aAAlB;IACG,MAAM,WAAW,oBAAC,SAAD,CAAU,CAAA;IAC3B,MAAM,UAAU,oBAAC,QAAD,EAAQ,GAAI,mBAAqB,CAAA;IAClD,oBAAC,KAAD;KACE,MAAM,MAAM;KACZ,SAAS,OAAO;KAChB,MAAM,OAAO,QAAQ,KAAA;KACrB,SAAS,OAAO,WAAW,KAAA;KAC3B,aAAY;eAEX,MAAM,KAAK,KAAK,OAAO,UACtB,oBAAC,MAAD,EAAkB,MAAM,WAAW,OAAO,QAAQ,KAAK,EAAI,GAAhD,KAAgD,CAC5D;IACE,CAAA;GACG;;CACS,CAAA;AAEzB;AAEA,IAAM,kBAA8C,EAAE,WAAW;CAC/D,MAAM,QAAQ,KAAK;CACnB,MAAM,YAAY,MAAM,OAAO,MAAM,WAAW,OAAO,SAAS,KAAK;CACrE,MAAM,qBAAqB,MAAM,OAAO,KAAK,iBAAiB;CAE9D,OACE,oBAAC,YAAD;EAAY,aAAa,MAAM;EAAa,IAAI,aAAa,IAAI;EAAG,OAAO,MAAM;YAC/E,oBAAC,OAAD;GAAK,WAAU;aACZ,aAAa,CAAC,qBACb,oBAAC,cAAD;IAAqB;IAAO,QAAQ;GAAY,CAAA,IAEhD,oBAAC,gBAAD,EAAuB,MAAQ,CAAA;EAE9B,CAAA;CACK,CAAA;AAEhB"}
|
|
1
|
+
{"version":3,"file":"chart.js","names":[],"sources":["../../../resources/js/core/components/chart.tsx"],"sourcesContent":["import {\n Area,\n AreaChart,\n Bar,\n BarChart,\n CartesianGrid,\n Cell,\n ComposedChart,\n Legend,\n Line,\n LineChart,\n Pie,\n PieChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport type { PropsOf, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useLocale, useTimezone } from \"@lattice-php/lattice/i18n\";\nimport { formatValue } from \"../../format/value\";\n\ntype ChartProps = PropsOf<\"chart\">;\ntype ChartSeries = ChartProps[\"series\"][number];\ntype ChartDatum = ChartProps[\"data\"][number];\ntype CartesianSeries = ChartSeries & { type: \"area\" | \"bar\" | \"line\" };\ntype ChartMargin = { bottom: number; left: number; right: number; top: number };\ntype CartesianChartComponent = ComponentType<{\n children: ReactNode;\n data: ChartProps[\"data\"];\n margin?: ChartMargin;\n}>;\n\nconst chartMargin: ChartMargin = { bottom: 0, left: 0, right: 16, top: 8 };\nconst compactLegendProps = {\n align: \"center\" as const,\n height: 24,\n iconSize: 7,\n verticalAlign: \"top\" as const,\n wrapperStyle: { fontSize: 11, lineHeight: \"14px\", paddingBottom: 6 },\n};\nconst axisTick = { fontSize: 10 };\nconst tooltipProps = {\n contentStyle: {\n background: \"var(--lt-surface)\",\n border: \"1px solid var(--lt-border)\",\n borderRadius: \"var(--lt-radius-sm)\",\n boxShadow: \"var(--lt-shadow-sm)\",\n color: \"var(--lt-surface-fg)\",\n fontSize: 12,\n },\n itemStyle: { color: \"var(--lt-surface-fg)\" },\n labelStyle: { color: \"var(--lt-muted-fg)\" },\n} as const;\n\nconst palette = [\n \"var(--lt-primary)\",\n \"var(--lt-success)\",\n \"var(--lt-info)\",\n \"var(--lt-warning)\",\n \"var(--lt-danger)\",\n \"var(--lt-muted-fg)\",\n];\n\nfunction colorAt(index: number): string {\n return palette[index % palette.length] ?? \"var(--lt-primary)\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction datumColor(datum: ChartDatum, series: ChartSeries, index: number): string {\n if (isRecord(datum) && typeof datum.color === \"string\") {\n return datum.color;\n }\n\n return series.color ?? colorAt(index);\n}\n\nfunction isCartesianSeries(series: ChartSeries): series is CartesianSeries {\n return series.type === \"area\" || series.type === \"bar\" || series.type === \"line\";\n}\n\nfunction cartesianChartFor(series: CartesianSeries[]): CartesianChartComponent {\n const types = new Set(series.map((item) => item.type));\n const firstSeries = series[0];\n\n if (firstSeries === undefined || types.size !== 1) {\n return ComposedChart;\n }\n\n switch (firstSeries.type) {\n case \"area\":\n return AreaChart;\n case \"bar\":\n return BarChart;\n case \"line\":\n return LineChart;\n }\n}\n\nfunction ChartFrame({\n children,\n description,\n id,\n title,\n}: {\n children: ReactNode;\n description: string | null;\n id?: string;\n title: string | null;\n}) {\n const hasHeader = title !== null || description !== null;\n\n return (\n <div\n className=\"flex flex-col gap-3 rounded-lt border border-lt-border bg-lt-surface p-4 text-lt-surface-fg shadow-lt-sm\"\n data-lattice-component={id}\n >\n {hasHeader && (\n <div className=\"flex min-w-0 flex-col gap-1.5\">\n {title !== null && <div className=\"text-sm font-semibold leading-tight\">{title}</div>}\n {description !== null && (\n <div className=\"text-xs leading-5 text-lt-muted-fg\">{description}</div>\n )}\n </div>\n )}\n {children}\n </div>\n );\n}\n\nfunction CartesianChart({ props }: { props: ChartProps }) {\n const series = props.series.filter(isCartesianSeries);\n const RechartsChart = cartesianChartFor(series);\n const { locale } = useLocale();\n const { timezone } = useTimezone();\n const ctx = { locale, timezone };\n const formatCategory = (value: unknown) => formatValue(value, props.categoryFormat, ctx);\n const formatValueTick = (value: unknown) => formatValue(value, props.valueFormat, ctx);\n const hasBarSeries = series.some((item) => item.type === \"bar\");\n const tooltipCursor = hasBarSeries\n ? { fill: \"var(--lt-muted-fg)\", fillOpacity: 0.15 }\n : { stroke: \"var(--lt-muted-fg)\", strokeOpacity: 0.4 };\n\n return (\n <ResponsiveContainer width=\"100%\" height={props.height} debounce={100}>\n <RechartsChart data={props.data} margin={chartMargin}>\n {props.grid && <CartesianGrid strokeDasharray=\"3 3\" stroke=\"var(--lt-border)\" />}\n {props.xAxis && props.categoryKey !== null && (\n <XAxis\n dataKey={props.categoryKey}\n stroke=\"var(--lt-muted-fg)\"\n tick={axisTick}\n tickFormatter={formatCategory}\n tickLine={false}\n />\n )}\n {props.yAxis && (\n <YAxis\n stroke=\"var(--lt-muted-fg)\"\n tick={axisTick}\n tickFormatter={formatValueTick}\n tickLine={false}\n width={42}\n />\n )}\n {props.tooltip && (\n <Tooltip\n {...tooltipProps}\n cursor={tooltipCursor}\n formatter={formatValueTick}\n labelFormatter={formatCategory}\n />\n )}\n {props.legend && <Legend {...compactLegendProps} />}\n {series.map((item, index) => {\n const color = item.color ?? colorAt(index);\n const key = `${item.type}:${item.dataKey}`;\n\n if (item.type === \"area\") {\n return (\n <Area\n key={key}\n dataKey={item.dataKey}\n fill={color}\n fillOpacity={0.16}\n name={item.name ?? undefined}\n stackId={item.stackId ?? undefined}\n stroke={color}\n type=\"monotone\"\n />\n );\n }\n\n if (item.type === \"bar\") {\n return (\n <Bar\n key={key}\n dataKey={item.dataKey}\n fill={color}\n name={item.name ?? undefined}\n radius={[4, 4, 0, 0]}\n stackId={item.stackId ?? undefined}\n />\n );\n }\n\n return (\n <Line\n key={key}\n dataKey={item.dataKey}\n dot={false}\n name={item.name ?? undefined}\n stroke={color}\n strokeWidth={2}\n type=\"monotone\"\n />\n );\n })}\n </RechartsChart>\n </ResponsiveContainer>\n );\n}\n\nfunction PieChartView({ props, series }: { props: ChartProps; series: ChartSeries }) {\n const { locale } = useLocale();\n const { timezone } = useTimezone();\n const ctx = { locale, timezone };\n\n return (\n <ResponsiveContainer width=\"100%\" height={props.height} debounce={100}>\n <PieChart margin={chartMargin}>\n {props.tooltip && (\n <Tooltip\n {...tooltipProps}\n formatter={(value) => formatValue(value, props.valueFormat, ctx)}\n labelFormatter={(value) => formatValue(value, props.categoryFormat, ctx)}\n />\n )}\n {props.legend && <Legend {...compactLegendProps} />}\n <Pie\n data={props.data}\n dataKey={series.dataKey}\n name={series.name ?? undefined}\n nameKey={series.nameKey ?? undefined}\n outerRadius=\"68%\"\n >\n {props.data.map((datum, index) => (\n <Cell key={index} fill={datumColor(datum, series, index)} />\n ))}\n </Pie>\n </PieChart>\n </ResponsiveContainer>\n );\n}\n\nconst ChartComponent: RendererComponent<\"chart\"> = ({ node }) => {\n const props = node.props;\n const pieSeries = props.series.find((series) => series.type === \"pie\");\n const hasCartesianSeries = props.series.some(isCartesianSeries);\n\n return (\n <ChartFrame description={props.description} id={nodeIdentity(node)} title={props.title}>\n <div className=\"min-h-0 w-full\">\n {pieSeries && !hasCartesianSeries ? (\n <PieChartView props={props} series={pieSeries} />\n ) : (\n <CartesianChart props={props} />\n )}\n </div>\n </ChartFrame>\n );\n};\n\nexport default ChartComponent;\n"],"mappings":"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"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { VariantProps } from 'class-variance-authority';
|
|
2
1
|
export declare const FOCUS_RING = "focus-visible:border-lt-ring focus-visible:ring-lt-ring/50 focus-visible:ring-[3px]";
|
|
3
2
|
/**
|
|
4
3
|
* The shared chrome for single-line form/table controls (text inputs, native
|
|
@@ -7,6 +6,5 @@ export declare const FOCUS_RING = "focus-visible:border-lt-ring focus-visible:ri
|
|
|
7
6
|
* border, focus ring, invalid, and disabled treatment are unified.
|
|
8
7
|
*/
|
|
9
8
|
export declare const controlSurface: (props?: ({
|
|
10
|
-
density?: "
|
|
9
|
+
density?: "compact" | "comfortable" | null | undefined;
|
|
11
10
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
12
|
-
export type ControlSurfaceVariants = VariantProps<typeof controlSurface>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.js","names":[],"sources":["../../../resources/js/core/components/control.ts"],"sourcesContent":["import { cva
|
|
1
|
+
{"version":3,"file":"control.js","names":[],"sources":["../../../resources/js/core/components/control.ts"],"sourcesContent":["import { cva } 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"],"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,7 +1,7 @@
|
|
|
1
1
|
import { cn } from "../../lib/utils.js";
|
|
2
2
|
import { IconRenderer } from "../../icons/icon-renderer.js";
|
|
3
3
|
import { nodeIdentity } from "../test-id.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ActionTrigger, useClickBehavior } from "../use-click-behavior.js";
|
|
5
5
|
import { actionMenuItemClassName, useActionMenu } from "../../action/components/action-menu-context.js";
|
|
6
6
|
import { Link } from "@inertiajs/react";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -14,18 +14,6 @@ function TextLink({ className = "", children, ...props }) {
|
|
|
14
14
|
children
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
|
-
function ActionLink({ action, ariaLabel, className, children, testId }) {
|
|
18
|
-
const { processing, requestSubmit, overlays } = useAction(action);
|
|
19
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("button", {
|
|
20
|
-
"aria-label": ariaLabel,
|
|
21
|
-
className: cn(textLinkClassName, className),
|
|
22
|
-
"data-test": testId,
|
|
23
|
-
disabled: processing,
|
|
24
|
-
onClick: requestSubmit,
|
|
25
|
-
type: "button",
|
|
26
|
-
children
|
|
27
|
-
}), overlays] });
|
|
28
|
-
}
|
|
29
17
|
function LinkAffix({ affix, className }) {
|
|
30
18
|
if (affix.icon) return /* @__PURE__ */ jsx(IconRenderer, {
|
|
31
19
|
className: cn("size-lt-icon-md shrink-0", className),
|
|
@@ -69,12 +57,10 @@ function labelWithTextAffixes(label, prefix, suffix) {
|
|
|
69
57
|
}
|
|
70
58
|
var LinkComponent = ({ node }) => {
|
|
71
59
|
const isMenuItem = useActionMenu();
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
const suffix = node.props.suffix;
|
|
77
|
-
const iconOnly = Boolean(icon);
|
|
60
|
+
const { icon, label, prefix, suffix } = node.props;
|
|
61
|
+
const behavior = useClickBehavior(node.props);
|
|
62
|
+
const className = isMenuItem ? actionMenuItemClassName : void 0;
|
|
63
|
+
const testId = nodeIdentity(node);
|
|
78
64
|
const content = /* @__PURE__ */ jsx(LinkContent, {
|
|
79
65
|
icon,
|
|
80
66
|
isMenuItem,
|
|
@@ -82,20 +68,30 @@ var LinkComponent = ({ node }) => {
|
|
|
82
68
|
prefix,
|
|
83
69
|
suffix
|
|
84
70
|
});
|
|
85
|
-
const ariaLabel =
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
71
|
+
const ariaLabel = icon ? label : labelWithTextAffixes(label, prefix, suffix);
|
|
72
|
+
const triggerButton = ({ onClick, processing }) => /* @__PURE__ */ jsx("button", {
|
|
73
|
+
"aria-label": ariaLabel,
|
|
74
|
+
className: cn(textLinkClassName, className),
|
|
75
|
+
"data-test": testId,
|
|
76
|
+
disabled: processing,
|
|
77
|
+
onClick,
|
|
78
|
+
type: "button",
|
|
91
79
|
children: content
|
|
92
80
|
});
|
|
81
|
+
if (behavior.kind === "action") return /* @__PURE__ */ jsx(ActionTrigger, {
|
|
82
|
+
action: behavior.action,
|
|
83
|
+
children: triggerButton
|
|
84
|
+
});
|
|
85
|
+
if (behavior.kind === "effects") return triggerButton({
|
|
86
|
+
onClick: behavior.onClick,
|
|
87
|
+
processing: false
|
|
88
|
+
});
|
|
93
89
|
return /* @__PURE__ */ jsx(TextLink, {
|
|
94
90
|
"aria-label": ariaLabel,
|
|
95
|
-
className
|
|
96
|
-
"data-test":
|
|
97
|
-
href:
|
|
98
|
-
method:
|
|
91
|
+
className,
|
|
92
|
+
"data-test": testId,
|
|
93
|
+
href: behavior.kind === "navigate" ? behavior.href : "#",
|
|
94
|
+
method: behavior.kind === "navigate" ? behavior.method : "get",
|
|
99
95
|
tabIndex: node.props.tabIndex ?? void 0,
|
|
100
96
|
children: content
|
|
101
97
|
});
|
|
@@ -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
|
|
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 ActionTrigger,\n type TriggerState,\n useClickBehavior,\n} from \"@lattice-php/lattice/core/use-click-behavior\";\nimport { IconRenderer } from \"@lattice-php/lattice/icons\";\nimport type { Affix } from \"@lattice-php/lattice/types/generated\";\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 LinkAffix({ affix, className }: { affix: Affix; className?: string }) {\n if (affix.icon) {\n return <IconRenderer className={cn(\"size-lt-icon-md shrink-0\", className)} icon={affix.icon} />;\n }\n\n return <span className={cn(\"shrink-0 text-sm text-lt-muted-fg\", className)}>{affix.text}</span>;\n}\n\nfunction LinkContent({\n icon,\n isMenuItem,\n label,\n prefix,\n suffix,\n}: {\n icon?: string | null;\n isMenuItem: boolean;\n label: string;\n prefix?: Affix | null;\n suffix?: Affix | null;\n}) {\n if (icon) {\n return <IconRenderer className=\"size-lt-icon-md shrink-0\" icon={icon} />;\n }\n\n if (isMenuItem) {\n return (\n <>\n {prefix ? <LinkAffix affix={prefix} /> : null}\n <span>{label}</span>\n {suffix ? <LinkAffix affix={suffix} className=\"ml-auto\" /> : null}\n </>\n );\n }\n\n if (prefix || suffix) {\n return (\n <span className=\"inline-flex items-center gap-1.5 align-baseline\">\n {prefix ? <LinkAffix affix={prefix} /> : null}\n <span>{label}</span>\n {suffix ? <LinkAffix affix={suffix} /> : null}\n </span>\n );\n }\n\n return label;\n}\n\nfunction labelWithTextAffixes(label: string, prefix?: Affix | null, suffix?: Affix | null) {\n if (!prefix?.text && !suffix?.text) {\n return undefined;\n }\n\n return [prefix?.text, label, suffix?.text]\n .filter((part): part is string => Boolean(part))\n .join(\" \");\n}\n\nconst LinkComponent: RendererComponent<\"link\"> = ({ node }) => {\n const isMenuItem = useActionMenu();\n const { icon, label, prefix, suffix } = node.props;\n const behavior = useClickBehavior(node.props);\n const className = isMenuItem ? actionMenuItemClassName : undefined;\n const testId = nodeIdentity(node);\n const content = (\n <LinkContent\n icon={icon}\n isMenuItem={isMenuItem}\n label={label}\n prefix={prefix}\n suffix={suffix}\n />\n );\n const ariaLabel = icon ? label : labelWithTextAffixes(label, prefix, suffix);\n\n const triggerButton = ({ onClick, processing }: TriggerState) => (\n <button\n aria-label={ariaLabel}\n className={cn(textLinkClassName, className)}\n data-test={testId}\n disabled={processing}\n onClick={onClick}\n type=\"button\"\n >\n {content}\n </button>\n );\n\n if (behavior.kind === \"action\") {\n return <ActionTrigger action={behavior.action}>{triggerButton}</ActionTrigger>;\n }\n\n if (behavior.kind === \"effects\") {\n return triggerButton({ onClick: behavior.onClick, processing: false });\n }\n\n return (\n <TextLink\n aria-label={ariaLabel}\n className={className}\n data-test={testId}\n href={behavior.kind === \"navigate\" ? behavior.href : \"#\"}\n method={behavior.kind === \"navigate\" ? behavior.method : \"get\"}\n tabIndex={node.props.tabIndex ?? undefined}\n >\n {content}\n </TextLink>\n );\n};\n\nexport default LinkComponent;\nexport { TextLink };\n"],"mappings":";;;;;;;;AAiBA,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,UAAU,EAAE,OAAO,aAAmD;CAC7E,IAAI,MAAM,MACR,OAAO,oBAAC,cAAD;EAAc,WAAW,GAAG,4BAA4B,SAAS;EAAG,MAAM,MAAM;CAAO,CAAA;CAGhG,OAAO,oBAAC,QAAD;EAAM,WAAW,GAAG,qCAAqC,SAAS;YAAI,MAAM;CAAW,CAAA;AAChG;AAEA,SAAS,YAAY,EACnB,MACA,YACA,OACA,QACA,UAOC;CACD,IAAI,MACF,OAAO,oBAAC,cAAD;EAAc,WAAU;EAAiC;CAAO,CAAA;CAGzE,IAAI,YACF,OACE,qBAAA,UAAA,EAAA,UAAA;EACG,SAAS,oBAAC,WAAD,EAAW,OAAO,OAAS,CAAA,IAAI;EACzC,oBAAC,QAAD,EAAA,UAAO,MAAY,CAAA;EAClB,SAAS,oBAAC,WAAD;GAAW,OAAO;GAAQ,WAAU;EAAW,CAAA,IAAI;CAC7D,EAAA,CAAA;CAIN,IAAI,UAAU,QACZ,OACE,qBAAC,QAAD;EAAM,WAAU;YAAhB;GACG,SAAS,oBAAC,WAAD,EAAW,OAAO,OAAS,CAAA,IAAI;GACzC,oBAAC,QAAD,EAAA,UAAO,MAAY,CAAA;GAClB,SAAS,oBAAC,WAAD,EAAW,OAAO,OAAS,CAAA,IAAI;EACrC;;CAIV,OAAO;AACT;AAEA,SAAS,qBAAqB,OAAe,QAAuB,QAAuB;CACzF,IAAI,CAAC,QAAQ,QAAQ,CAAC,QAAQ,MAC5B;CAGF,OAAO;EAAC,QAAQ;EAAM;EAAO,QAAQ;CAAI,EACtC,QAAQ,SAAyB,QAAQ,IAAI,CAAC,EAC9C,KAAK,GAAG;AACb;AAEA,IAAM,iBAA4C,EAAE,WAAW;CAC7D,MAAM,aAAa,cAAc;CACjC,MAAM,EAAE,MAAM,OAAO,QAAQ,WAAW,KAAK;CAC7C,MAAM,WAAW,iBAAiB,KAAK,KAAK;CAC5C,MAAM,YAAY,aAAa,0BAA0B,KAAA;CACzD,MAAM,SAAS,aAAa,IAAI;CAChC,MAAM,UACJ,oBAAC,aAAD;EACQ;EACM;EACL;EACC;EACA;CACT,CAAA;CAEH,MAAM,YAAY,OAAO,QAAQ,qBAAqB,OAAO,QAAQ,MAAM;CAE3E,MAAM,iBAAiB,EAAE,SAAS,iBAChC,oBAAC,UAAD;EACE,cAAY;EACZ,WAAW,GAAG,mBAAmB,SAAS;EAC1C,aAAW;EACX,UAAU;EACD;EACT,MAAK;YAEJ;CACK,CAAA;CAGV,IAAI,SAAS,SAAS,UACpB,OAAO,oBAAC,eAAD;EAAe,QAAQ,SAAS;YAAS;CAA6B,CAAA;CAG/E,IAAI,SAAS,SAAS,WACpB,OAAO,cAAc;EAAE,SAAS,SAAS;EAAS,YAAY;CAAM,CAAC;CAGvE,OACE,oBAAC,UAAD;EACE,cAAY;EACD;EACX,aAAW;EACX,MAAM,SAAS,SAAS,aAAa,SAAS,OAAO;EACrD,QAAQ,SAAS,SAAS,aAAa,SAAS,SAAS;EACzD,UAAU,KAAK,MAAM,YAAY,KAAA;YAEhC;CACO,CAAA;AAEd"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,58 +1,33 @@
|
|
|
1
1
|
import { ComponentType as ReactComponentType, ReactNode } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
export type { KnownPageContainer, NodeType, WireNode };
|
|
4
|
-
/** Loose props bag for nodes whose `type` is not a generated built-in. */
|
|
2
|
+
import { ComponentPropsMap, NodeType, Option, PageContainer as KnownPageContainer, WireNode, ListenerPayload } from '../types/generated';
|
|
3
|
+
export type { KnownPageContainer, NodeType, Option, WireNode };
|
|
5
4
|
export type NodeProps = Record<string, unknown>;
|
|
6
5
|
export type CommonNodeProps = {
|
|
7
6
|
dataBindings?: Record<string, string> | null;
|
|
8
7
|
hideWhenCollapsed?: boolean | null;
|
|
9
8
|
};
|
|
10
|
-
/** A `{ label, value }` pair used by the choice, select and segmented controls. */
|
|
11
|
-
export type { Option };
|
|
12
9
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
props?: NodeProps;
|
|
20
|
-
schema?: Schema;
|
|
21
|
-
type: TType;
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Augmentable map of wire `type` string → props. Consumer apps extend it via
|
|
25
|
-
* `declare module "@lattice-php/lattice"` so their custom components gain strong
|
|
26
|
-
* prop types; the entries are generated by `php artisan lattice:typescript`.
|
|
27
|
-
* Built-in components resolve through the generated `WireNode` union below, so
|
|
28
|
-
* this interface starts empty. Types listed in neither fall back to a loose bag.
|
|
10
|
+
* Augmentable map of wire `type` string → props for consumer components. Apps
|
|
11
|
+
* extend it via `declare module "@lattice-php/lattice"` so their custom components
|
|
12
|
+
* gain strong prop types; the entries are generated by `php artisan lattice:typescript`.
|
|
13
|
+
* Built-in components resolve through the generated `ComponentPropsMap` below, the
|
|
14
|
+
* same way `ColumnProps` augments `ColumnPropsMap`. Types in neither fall back to a
|
|
15
|
+
* loose bag.
|
|
29
16
|
*/
|
|
30
17
|
export interface ComponentProps {
|
|
31
18
|
}
|
|
32
19
|
/**
|
|
33
|
-
* Resolves a
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* every extensible kind resolves the same way.
|
|
20
|
+
* Resolves a `type` string to its payload: consumer augmentations (`TAugment`)
|
|
21
|
+
* win over generated built-ins (`TBuiltins`), then a loose fallback. The one
|
|
22
|
+
* resolver behind the component, column and effect maps.
|
|
37
23
|
*/
|
|
38
24
|
export type ResolveProps<TAugment, TBuiltins, TType extends string, TFallback> = TType extends keyof TAugment ? TAugment[TType] : TType extends keyof TBuiltins ? TBuiltins[TType] : TFallback;
|
|
39
|
-
type
|
|
40
|
-
[TNode in WireNode as TNode["type"]]: TNode extends {
|
|
41
|
-
props: infer TProps;
|
|
42
|
-
} ? TProps : never;
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
|
-
* Resolves a wire `type` to its props: consumer augmentations
|
|
46
|
-
* (`ComponentProps`) first, then generated built-ins, then a loose bag.
|
|
47
|
-
*/
|
|
48
|
-
export type PropsOf<TType extends string> = ResolveProps<ComponentProps, WireNodeProps, TType, NodeProps> & CommonNodeProps;
|
|
25
|
+
export type PropsOf<TType extends string> = ResolveProps<ComponentProps, ComponentPropsMap, TType, NodeProps> & CommonNodeProps;
|
|
49
26
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* components still type-check. Built-in `props` is always present — the wire
|
|
53
|
-
* serializes the full prop object, so reads need no optional chaining.
|
|
27
|
+
* Built-in `props` is required, not optional — the wire serializes the full prop
|
|
28
|
+
* object, so reads need no optional chaining. Unknown types fall back to `WireNode`.
|
|
54
29
|
*/
|
|
55
|
-
export type NodeOfType<TType extends string = string> = string extends TType ?
|
|
30
|
+
export type NodeOfType<TType extends string = string> = string extends TType ? WireNode : {
|
|
56
31
|
id?: string;
|
|
57
32
|
key?: string;
|
|
58
33
|
props: PropsOf<TType>;
|
|
@@ -60,9 +35,14 @@ export type NodeOfType<TType extends string = string> = string extends TType ? L
|
|
|
60
35
|
type: TType;
|
|
61
36
|
};
|
|
62
37
|
export type Node<TType extends string = string> = NodeOfType<TType>;
|
|
63
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Distributes so `NodeUnionOf<"a" | "b">` is `NodeOfType<"a"> | NodeOfType<"b">`
|
|
40
|
+
* — a discriminated union where `node.type` narrows `node.props`. Domains build
|
|
41
|
+
* their node union from a generated `…NodeType` string union with this.
|
|
42
|
+
*/
|
|
43
|
+
export type NodeUnionOf<TTypes extends string> = TTypes extends string ? NodeOfType<TTypes> : never;
|
|
64
44
|
export type Schema = Node[];
|
|
65
|
-
/**
|
|
45
|
+
/** Its `schema` holds exactly one Outlet node. */
|
|
66
46
|
export type LayoutPayload = {
|
|
67
47
|
key: string;
|
|
68
48
|
schema: Schema;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Method } from '@inertiajs/core';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { Node } from './types';
|
|
4
|
+
import { Effect } from '../types/generated';
|
|
5
|
+
export type ClickBehavior = {
|
|
6
|
+
kind: "navigate";
|
|
7
|
+
href: string;
|
|
8
|
+
method: Method;
|
|
9
|
+
} | {
|
|
10
|
+
kind: "action";
|
|
11
|
+
action: Node<"action">;
|
|
12
|
+
} | {
|
|
13
|
+
kind: "effects";
|
|
14
|
+
onClick: () => void;
|
|
15
|
+
} | {
|
|
16
|
+
kind: "none";
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The shared click model for Link/Button/MenuItem: a clickable carries exactly
|
|
20
|
+
* one behavior — navigate to an href, run a server action, or dispatch client
|
|
21
|
+
* effects. This resolves it without touching the action machinery, so plain
|
|
22
|
+
* links/labels stay cheap; the `action` behavior renders through {@link ActionTrigger}.
|
|
23
|
+
*/
|
|
24
|
+
export declare function useClickBehavior(props: {
|
|
25
|
+
href?: string | null;
|
|
26
|
+
method?: Method | null;
|
|
27
|
+
action?: Node | null;
|
|
28
|
+
effects?: Effect[] | null;
|
|
29
|
+
}): ClickBehavior;
|
|
30
|
+
export type TriggerState = {
|
|
31
|
+
onClick: () => void;
|
|
32
|
+
processing: boolean;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Runs a server action's gate (confirm/form) and renders its overlays, handing
|
|
36
|
+
* the host a click handler + processing state to render its own element with.
|
|
37
|
+
* Only mounted for the `action` behavior, so a plain link never runs `useAction`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function ActionTrigger({ action, children, }: {
|
|
40
|
+
action: Node<"action">;
|
|
41
|
+
children: (trigger: TriggerState) => ReactNode;
|
|
42
|
+
}): import("react").JSX.Element;
|