@pixpilot/formily-shadcn 1.15.2 → 1.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.
Files changed (78) hide show
  1. package/dist/components/date-picker/DatePicker.d.cts +3 -3
  2. package/dist/components/date-picker/DatePicker.d.ts +3 -3
  3. package/dist/components/dialog-item/BaseDialogItem.cjs +114 -0
  4. package/dist/components/dialog-item/BaseDialogItem.d.cts +56 -0
  5. package/dist/components/dialog-item/BaseDialogItem.d.ts +56 -0
  6. package/dist/components/dialog-item/BaseDialogItem.js +109 -0
  7. package/dist/components/dialog-item/ConnectedDialogItem.cjs +16 -0
  8. package/dist/components/dialog-item/ConnectedDialogItem.d.cts +15 -0
  9. package/dist/components/dialog-item/ConnectedDialogItem.d.ts +15 -0
  10. package/dist/components/dialog-item/ConnectedDialogItem.js +14 -0
  11. package/dist/components/dialog-item/index.cjs +2 -0
  12. package/dist/components/dialog-item/index.d.cts +2 -0
  13. package/dist/components/dialog-item/index.d.ts +2 -0
  14. package/dist/components/dialog-item/index.js +2 -0
  15. package/dist/components/dialog-item/mcp.js +127 -0
  16. package/dist/components/form/Form.d.cts +2 -2
  17. package/dist/components/form/Form.d.ts +2 -2
  18. package/dist/components/form-grid/FormGrid.d.cts +2 -2
  19. package/dist/components/form-grid/FormGrid.d.ts +2 -2
  20. package/dist/components/form-item/ConnectedFormItem.cjs +2 -34
  21. package/dist/components/form-item/ConnectedFormItem.d.cts +4 -4
  22. package/dist/components/form-item/ConnectedFormItem.d.ts +4 -4
  23. package/dist/components/form-item/ConnectedFormItem.js +3 -34
  24. package/dist/components/form-item/map-form-item-props.cjs +50 -0
  25. package/dist/components/form-item/map-form-item-props.js +47 -0
  26. package/dist/components/object-container/ObjectContainer.cjs +1 -1
  27. package/dist/components/object-container/ObjectContainer.js +1 -1
  28. package/dist/components/overlay-common/OverlayFields.cjs +26 -0
  29. package/dist/components/overlay-common/OverlayFields.d.cts +1 -0
  30. package/dist/components/overlay-common/OverlayFields.d.ts +1 -0
  31. package/dist/components/overlay-common/OverlayFields.js +24 -0
  32. package/dist/components/overlay-common/OverlayTrigger.cjs +27 -0
  33. package/dist/components/overlay-common/OverlayTrigger.d.cts +15 -0
  34. package/dist/components/overlay-common/OverlayTrigger.d.ts +15 -0
  35. package/dist/components/overlay-common/OverlayTrigger.js +23 -0
  36. package/dist/components/overlay-common/constants.cjs +10 -0
  37. package/dist/components/overlay-common/constants.js +9 -0
  38. package/dist/components/overlay-common/index.cjs +5 -0
  39. package/dist/components/overlay-common/index.d.cts +4 -0
  40. package/dist/components/overlay-common/index.d.ts +4 -0
  41. package/dist/components/overlay-common/index.js +5 -0
  42. package/dist/components/overlay-common/is-empty-field-value.cjs +23 -0
  43. package/dist/components/overlay-common/is-empty-field-value.js +22 -0
  44. package/dist/components/overlay-common/overlay-types.d.cts +27 -0
  45. package/dist/components/overlay-common/overlay-types.d.ts +27 -0
  46. package/dist/components/overlay-common/use-overlay.cjs +110 -0
  47. package/dist/components/overlay-common/use-overlay.d.cts +1 -0
  48. package/dist/components/overlay-common/use-overlay.d.ts +1 -0
  49. package/dist/components/overlay-common/use-overlay.js +107 -0
  50. package/dist/components/popover-item/BasePopoverItem.cjs +108 -0
  51. package/dist/components/popover-item/BasePopoverItem.d.cts +57 -0
  52. package/dist/components/popover-item/BasePopoverItem.d.ts +57 -0
  53. package/dist/components/popover-item/BasePopoverItem.js +104 -0
  54. package/dist/components/popover-item/ConnectedPopoverItem.cjs +16 -0
  55. package/dist/components/popover-item/ConnectedPopoverItem.d.cts +15 -0
  56. package/dist/components/popover-item/ConnectedPopoverItem.d.ts +15 -0
  57. package/dist/components/popover-item/ConnectedPopoverItem.js +14 -0
  58. package/dist/components/popover-item/index.cjs +2 -0
  59. package/dist/components/popover-item/index.d.cts +2 -0
  60. package/dist/components/popover-item/index.d.ts +2 -0
  61. package/dist/components/popover-item/index.js +2 -0
  62. package/dist/components/popover-item/mcp.js +127 -0
  63. package/dist/components/radio/Radio.d.ts +2 -2
  64. package/dist/components/row/Row.d.ts +2 -2
  65. package/dist/components/schema-field/schema-field-basics.cjs +8 -2
  66. package/dist/components/schema-field/schema-field-basics.d.cts +337 -263
  67. package/dist/components/schema-field/schema-field-basics.d.ts +344 -270
  68. package/dist/components/schema-field/schema-field-basics.js +8 -2
  69. package/dist/components/schema-field/schema-field-extended.d.cts +497 -423
  70. package/dist/components/schema-field/schema-field-extended.d.ts +498 -424
  71. package/dist/components/schema-field/schema-field.d.cts +431 -357
  72. package/dist/components/schema-field/schema-field.d.ts +431 -357
  73. package/dist/generated/mcp-registry.js +56 -52
  74. package/dist/index.cjs +12 -2
  75. package/dist/index.d.cts +7 -1
  76. package/dist/index.d.ts +7 -1
  77. package/dist/index.js +9 -3
  78. package/package.json +5 -5
@@ -1,47 +1,15 @@
1
1
  const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
2
  const require_BaseFormItem = require('./BaseFormItem.cjs');
3
+ const require_map_form_item_props = require('./map-form-item-props.cjs');
3
4
  let __formily_react = require("@formily/react");
4
5
  __formily_react = require_rolldown_runtime.__toESM(__formily_react);
5
- let __formily_core = require("@formily/core");
6
- __formily_core = require_rolldown_runtime.__toESM(__formily_core);
7
6
 
8
7
  //#region src/components/form-item/ConnectedFormItem.tsx
9
8
  /**
10
9
  * FormItem component connected to Formily field state.
11
10
  * Automatically maps field validation state to component props.
12
11
  */
13
- const FormItem = (0, __formily_react.connect)(require_BaseFormItem.BaseFormItem, (0, __formily_react.mapProps)((props, field) => {
14
- const schema = (0, __formily_react.useFieldSchema)();
15
- if ((0, __formily_core.isVoidField)(field)) return {
16
- label: field.title ?? props.label,
17
- description: props.description ?? field.description,
18
- requiredMark: props.requiredMark !== void 0 ? props.requiredMark : props.asterisk
19
- };
20
- const takeFeedbackStatus = () => {
21
- if (field.validating) return void 0;
22
- if (field.selfErrors?.length) return "error";
23
- if (field.selfWarnings?.length) return "warning";
24
- if (field.selfSuccesses?.length) return "success";
25
- };
26
- const takeFeedbackText = () => {
27
- if (field.validating) return void 0;
28
- if (props.feedbackText != null) return props.feedbackText;
29
- if (field.selfErrors?.length) return field.selfErrors.join(", ");
30
- if (field.selfWarnings?.length) return field.selfWarnings.join(", ");
31
- if (field.selfSuccesses?.length) return field.selfSuccesses.join(", ");
32
- };
33
- let resolvedRequiredMark = props.requiredMark;
34
- if (resolvedRequiredMark === void 0) if (props.asterisk !== void 0) resolvedRequiredMark = Boolean(props.asterisk);
35
- else if (schema.parent && Array.isArray(schema.parent.required) && schema.parent.required.includes(schema.name)) resolvedRequiredMark = true;
36
- else resolvedRequiredMark = field.required && field.pattern !== "readPretty";
37
- return {
38
- label: props.label ?? field.title,
39
- description: props.description ?? field.description,
40
- feedbackStatus: takeFeedbackStatus(),
41
- feedbackText: takeFeedbackText(),
42
- requiredMark: resolvedRequiredMark
43
- };
44
- }));
12
+ const FormItem = (0, __formily_react.connect)(require_BaseFormItem.BaseFormItem, (0, __formily_react.mapProps)(require_map_form_item_props.mapFormItemProps));
45
13
 
46
14
  //#endregion
47
15
  exports.FormItem = FormItem;
@@ -1,13 +1,13 @@
1
1
  import { FormItemProps } from "./form-item-types.cjs";
2
- import * as react1246 from "react";
2
+ import * as react1450 from "react";
3
3
 
4
4
  //#region src/components/form-item/ConnectedFormItem.d.ts
5
5
  /**
6
6
  * FormItem component connected to Formily field state.
7
7
  * Automatically maps field validation state to component props.
8
8
  */
9
- declare const FormItem: react1246.ForwardRefExoticComponent<Omit<Partial<FormItemProps & {
10
- children?: react1246.ReactNode | undefined;
11
- }>, "ref"> & react1246.RefAttributes<unknown>>;
9
+ declare const FormItem: react1450.ForwardRefExoticComponent<Omit<Partial<FormItemProps & {
10
+ children?: react1450.ReactNode | undefined;
11
+ }>, "ref"> & react1450.RefAttributes<unknown>>;
12
12
  //#endregion
13
13
  export { FormItem };
@@ -1,13 +1,13 @@
1
1
  import { FormItemProps } from "./form-item-types.js";
2
- import * as react1246 from "react";
2
+ import * as react1450 from "react";
3
3
 
4
4
  //#region src/components/form-item/ConnectedFormItem.d.ts
5
5
  /**
6
6
  * FormItem component connected to Formily field state.
7
7
  * Automatically maps field validation state to component props.
8
8
  */
9
- declare const FormItem: react1246.ForwardRefExoticComponent<Omit<Partial<FormItemProps & {
10
- children?: react1246.ReactNode | undefined;
11
- }>, "ref"> & react1246.RefAttributes<unknown>>;
9
+ declare const FormItem: react1450.ForwardRefExoticComponent<Omit<Partial<FormItemProps & {
10
+ children?: react1450.ReactNode | undefined;
11
+ }>, "ref"> & react1450.RefAttributes<unknown>>;
12
12
  //#endregion
13
13
  export { FormItem };
@@ -1,44 +1,13 @@
1
1
  import { BaseFormItem } from "./BaseFormItem.js";
2
- import { connect, mapProps, useFieldSchema } from "@formily/react";
3
- import { isVoidField } from "@formily/core";
2
+ import { mapFormItemProps } from "./map-form-item-props.js";
3
+ import { connect, mapProps } from "@formily/react";
4
4
 
5
5
  //#region src/components/form-item/ConnectedFormItem.tsx
6
6
  /**
7
7
  * FormItem component connected to Formily field state.
8
8
  * Automatically maps field validation state to component props.
9
9
  */
10
- const FormItem = connect(BaseFormItem, mapProps((props, field) => {
11
- const schema = useFieldSchema();
12
- if (isVoidField(field)) return {
13
- label: field.title ?? props.label,
14
- description: props.description ?? field.description,
15
- requiredMark: props.requiredMark !== void 0 ? props.requiredMark : props.asterisk
16
- };
17
- const takeFeedbackStatus = () => {
18
- if (field.validating) return void 0;
19
- if (field.selfErrors?.length) return "error";
20
- if (field.selfWarnings?.length) return "warning";
21
- if (field.selfSuccesses?.length) return "success";
22
- };
23
- const takeFeedbackText = () => {
24
- if (field.validating) return void 0;
25
- if (props.feedbackText != null) return props.feedbackText;
26
- if (field.selfErrors?.length) return field.selfErrors.join(", ");
27
- if (field.selfWarnings?.length) return field.selfWarnings.join(", ");
28
- if (field.selfSuccesses?.length) return field.selfSuccesses.join(", ");
29
- };
30
- let resolvedRequiredMark = props.requiredMark;
31
- if (resolvedRequiredMark === void 0) if (props.asterisk !== void 0) resolvedRequiredMark = Boolean(props.asterisk);
32
- else if (schema.parent && Array.isArray(schema.parent.required) && schema.parent.required.includes(schema.name)) resolvedRequiredMark = true;
33
- else resolvedRequiredMark = field.required && field.pattern !== "readPretty";
34
- return {
35
- label: props.label ?? field.title,
36
- description: props.description ?? field.description,
37
- feedbackStatus: takeFeedbackStatus(),
38
- feedbackText: takeFeedbackText(),
39
- requiredMark: resolvedRequiredMark
40
- };
41
- }));
10
+ const FormItem = connect(BaseFormItem, mapProps(mapFormItemProps));
42
11
 
43
12
  //#endregion
44
13
  export { FormItem };
@@ -0,0 +1,50 @@
1
+ const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
+ let __formily_react = require("@formily/react");
3
+ __formily_react = require_rolldown_runtime.__toESM(__formily_react);
4
+ let __formily_core = require("@formily/core");
5
+ __formily_core = require_rolldown_runtime.__toESM(__formily_core);
6
+
7
+ //#region src/components/form-item/map-form-item-props.ts
8
+ /**
9
+ * Maps Formily field state onto FormItem props (label, description, validation
10
+ * feedback, required mark).
11
+ *
12
+ * Shared by every decorator that presents a field the way FormItem does —
13
+ * FormItem itself plus the overlay decorators — so they stay in step.
14
+ * Runs inside `mapProps`, which is why calling hooks here is allowed.
15
+ */
16
+ function mapFormItemProps(props, field) {
17
+ const schema = (0, __formily_react.useFieldSchema)();
18
+ if ((0, __formily_core.isVoidField)(field)) return {
19
+ label: field.title ?? props.label,
20
+ description: props.description ?? field.description,
21
+ requiredMark: props.requiredMark !== void 0 ? props.requiredMark : props.asterisk
22
+ };
23
+ const takeFeedbackStatus = () => {
24
+ if (field.validating) return void 0;
25
+ if (field.selfErrors?.length) return "error";
26
+ if (field.selfWarnings?.length) return "warning";
27
+ if (field.selfSuccesses?.length) return "success";
28
+ };
29
+ const takeFeedbackText = () => {
30
+ if (field.validating) return void 0;
31
+ if (props.feedbackText != null) return props.feedbackText;
32
+ if (field.selfErrors?.length) return field.selfErrors.join(", ");
33
+ if (field.selfWarnings?.length) return field.selfWarnings.join(", ");
34
+ if (field.selfSuccesses?.length) return field.selfSuccesses.join(", ");
35
+ };
36
+ let resolvedRequiredMark = props.requiredMark;
37
+ if (resolvedRequiredMark === void 0) if (props.asterisk !== void 0) resolvedRequiredMark = Boolean(props.asterisk);
38
+ else if (schema.parent && Array.isArray(schema.parent.required) && schema.parent.required.includes(schema.name)) resolvedRequiredMark = true;
39
+ else resolvedRequiredMark = field.required && field.pattern !== "readPretty";
40
+ return {
41
+ label: props.label ?? field.title,
42
+ description: props.description ?? field.description,
43
+ feedbackStatus: takeFeedbackStatus(),
44
+ feedbackText: takeFeedbackText(),
45
+ requiredMark: resolvedRequiredMark
46
+ };
47
+ }
48
+
49
+ //#endregion
50
+ exports.mapFormItemProps = mapFormItemProps;
@@ -0,0 +1,47 @@
1
+ import { useFieldSchema } from "@formily/react";
2
+ import { isVoidField } from "@formily/core";
3
+
4
+ //#region src/components/form-item/map-form-item-props.ts
5
+ /**
6
+ * Maps Formily field state onto FormItem props (label, description, validation
7
+ * feedback, required mark).
8
+ *
9
+ * Shared by every decorator that presents a field the way FormItem does —
10
+ * FormItem itself plus the overlay decorators — so they stay in step.
11
+ * Runs inside `mapProps`, which is why calling hooks here is allowed.
12
+ */
13
+ function mapFormItemProps(props, field) {
14
+ const schema = useFieldSchema();
15
+ if (isVoidField(field)) return {
16
+ label: field.title ?? props.label,
17
+ description: props.description ?? field.description,
18
+ requiredMark: props.requiredMark !== void 0 ? props.requiredMark : props.asterisk
19
+ };
20
+ const takeFeedbackStatus = () => {
21
+ if (field.validating) return void 0;
22
+ if (field.selfErrors?.length) return "error";
23
+ if (field.selfWarnings?.length) return "warning";
24
+ if (field.selfSuccesses?.length) return "success";
25
+ };
26
+ const takeFeedbackText = () => {
27
+ if (field.validating) return void 0;
28
+ if (props.feedbackText != null) return props.feedbackText;
29
+ if (field.selfErrors?.length) return field.selfErrors.join(", ");
30
+ if (field.selfWarnings?.length) return field.selfWarnings.join(", ");
31
+ if (field.selfSuccesses?.length) return field.selfSuccesses.join(", ");
32
+ };
33
+ let resolvedRequiredMark = props.requiredMark;
34
+ if (resolvedRequiredMark === void 0) if (props.asterisk !== void 0) resolvedRequiredMark = Boolean(props.asterisk);
35
+ else if (schema.parent && Array.isArray(schema.parent.required) && schema.parent.required.includes(schema.name)) resolvedRequiredMark = true;
36
+ else resolvedRequiredMark = field.required && field.pattern !== "readPretty";
37
+ return {
38
+ label: props.label ?? field.title,
39
+ description: props.description ?? field.description,
40
+ feedbackStatus: takeFeedbackStatus(),
41
+ feedbackText: takeFeedbackText(),
42
+ requiredMark: resolvedRequiredMark
43
+ };
44
+ }
45
+
46
+ //#endregion
47
+ export { mapFormItemProps };
@@ -112,7 +112,7 @@ const ObjectContainer = ({ className, children, label, description, variant: var
112
112
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_FormItemContainer.FormItemContainer, {
113
113
  ...mergedContentProps,
114
114
  as: __pixpilot_shadcn.CardContent,
115
- className: (0, __pixpilot_shadcn.cn)("form-object-content", mergedContentProps.className, isFlat && "px-0"),
115
+ className: (0, __pixpilot_shadcn.cn)("grid form-object-content", mergedContentProps.className, isFlat && "px-0"),
116
116
  children
117
117
  })]
118
118
  });
@@ -109,7 +109,7 @@ const ObjectContainer = ({ className, children, label, description, variant: var
109
109
  }), /* @__PURE__ */ jsx(FormItemContainer, {
110
110
  ...mergedContentProps,
111
111
  as: CardContent,
112
- className: cn("form-object-content", mergedContentProps.className, isFlat && "px-0"),
112
+ className: cn("grid form-object-content", mergedContentProps.className, isFlat && "px-0"),
113
113
  children
114
114
  })]
115
115
  });
@@ -0,0 +1,26 @@
1
+ const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
+ let react_jsx_runtime = require("react/jsx-runtime");
3
+ react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
4
+
5
+ //#region src/components/overlay-common/OverlayFields.tsx
6
+ /**
7
+ * Keeps an object's fields mounted while its overlay (dialog/popover) is closed.
8
+ *
9
+ * Formily destroys a field instance when its component unmounts, and the fields
10
+ * inside a closed overlay are unmounted. Without this, `form.submit()` would
11
+ * skip them entirely — a required field the user never opened would pass
12
+ * validation. Rendering them in a hidden container keeps the field instances
13
+ * alive so form-level validation still covers them.
14
+ *
15
+ * `hidden` (rather than unmounting) is the same approach ListItem uses to keep
16
+ * array item fields attached while a row is collapsed.
17
+ */
18
+ const OverlayFields = ({ children }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
19
+ hidden: true,
20
+ "aria-hidden": "true",
21
+ children
22
+ });
23
+ OverlayFields.displayName = "OverlayFields";
24
+
25
+ //#endregion
26
+ exports.OverlayFields = OverlayFields;
@@ -0,0 +1 @@
1
+ import React from "react";
@@ -0,0 +1 @@
1
+ import React from "react";
@@ -0,0 +1,24 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+
3
+ //#region src/components/overlay-common/OverlayFields.tsx
4
+ /**
5
+ * Keeps an object's fields mounted while its overlay (dialog/popover) is closed.
6
+ *
7
+ * Formily destroys a field instance when its component unmounts, and the fields
8
+ * inside a closed overlay are unmounted. Without this, `form.submit()` would
9
+ * skip them entirely — a required field the user never opened would pass
10
+ * validation. Rendering them in a hidden container keeps the field instances
11
+ * alive so form-level validation still covers them.
12
+ *
13
+ * `hidden` (rather than unmounting) is the same approach ListItem uses to keep
14
+ * array item fields attached while a row is collapsed.
15
+ */
16
+ const OverlayFields = ({ children }) => /* @__PURE__ */ jsx("div", {
17
+ hidden: true,
18
+ "aria-hidden": "true",
19
+ children
20
+ });
21
+ OverlayFields.displayName = "OverlayFields";
22
+
23
+ //#endregion
24
+ export { OverlayFields };
@@ -0,0 +1,27 @@
1
+ const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
+ let lucide_react = require("lucide-react");
3
+ lucide_react = require_rolldown_runtime.__toESM(lucide_react);
4
+ let react_jsx_runtime = require("react/jsx-runtime");
5
+ react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
6
+ let __pixpilot_shadcn = require("@pixpilot/shadcn");
7
+ __pixpilot_shadcn = require_rolldown_runtime.__toESM(__pixpilot_shadcn);
8
+
9
+ //#region src/components/overlay-common/OverlayTrigger.tsx
10
+ /**
11
+ * Button that opens an object overlay (dialog or popover).
12
+ */
13
+ const OverlayTrigger = ({ label, icon, invalid, className,...rest }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Button, {
14
+ type: "button",
15
+ variant: "outline",
16
+ "aria-invalid": invalid === true ? true : void 0,
17
+ ...rest,
18
+ className: (0, __pixpilot_shadcn.cn)("form-object-trigger w-full justify-between gap-4 font-normal", invalid === true && "border-destructive text-destructive", className),
19
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
20
+ className: "min-w-0 truncate text-left",
21
+ children: label
22
+ }), icon ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronRightIcon, { className: "size-4 shrink-0 opacity-50" })]
23
+ });
24
+ OverlayTrigger.displayName = "OverlayTrigger";
25
+
26
+ //#endregion
27
+ exports.OverlayTrigger = OverlayTrigger;
@@ -0,0 +1,15 @@
1
+ import { SyncReactNode } from "../../types/react.cjs";
2
+ import React from "react";
3
+ import { Button } from "@pixpilot/shadcn";
4
+
5
+ //#region src/components/overlay-common/OverlayTrigger.d.ts
6
+ interface OverlayTriggerProps extends Omit<React.ComponentProps<typeof Button>, 'children'> {
7
+ /** Text of the trigger button. */
8
+ label?: SyncReactNode;
9
+ /** Icon rendered at the trailing edge. Defaults to a chevron. */
10
+ icon?: React.ReactNode;
11
+ /** Renders the trigger in an error state. */
12
+ invalid?: boolean;
13
+ }
14
+ //#endregion
15
+ export { OverlayTriggerProps };
@@ -0,0 +1,15 @@
1
+ import { SyncReactNode } from "../../types/react.js";
2
+ import React from "react";
3
+ import { Button } from "@pixpilot/shadcn";
4
+
5
+ //#region src/components/overlay-common/OverlayTrigger.d.ts
6
+ interface OverlayTriggerProps extends Omit<React.ComponentProps<typeof Button>, 'children'> {
7
+ /** Text of the trigger button. */
8
+ label?: SyncReactNode;
9
+ /** Icon rendered at the trailing edge. Defaults to a chevron. */
10
+ icon?: React.ReactNode;
11
+ /** Renders the trigger in an error state. */
12
+ invalid?: boolean;
13
+ }
14
+ //#endregion
15
+ export { OverlayTriggerProps };
@@ -0,0 +1,23 @@
1
+ import { ChevronRightIcon } from "lucide-react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { Button, cn } from "@pixpilot/shadcn";
4
+
5
+ //#region src/components/overlay-common/OverlayTrigger.tsx
6
+ /**
7
+ * Button that opens an object overlay (dialog or popover).
8
+ */
9
+ const OverlayTrigger = ({ label, icon, invalid, className,...rest }) => /* @__PURE__ */ jsxs(Button, {
10
+ type: "button",
11
+ variant: "outline",
12
+ "aria-invalid": invalid === true ? true : void 0,
13
+ ...rest,
14
+ className: cn("form-object-trigger w-full justify-between gap-4 font-normal", invalid === true && "border-destructive text-destructive", className),
15
+ children: [/* @__PURE__ */ jsx("span", {
16
+ className: "min-w-0 truncate text-left",
17
+ children: label
18
+ }), icon ?? /* @__PURE__ */ jsx(ChevronRightIcon, { className: "size-4 shrink-0 opacity-50" })]
19
+ });
20
+ OverlayTrigger.displayName = "OverlayTrigger";
21
+
22
+ //#endregion
23
+ export { OverlayTrigger };
@@ -0,0 +1,10 @@
1
+
2
+ //#region src/components/overlay-common/constants.ts
3
+ /**
4
+ * Fallback noun for the DialogItem / PopoverItem trigger when the field has
5
+ * no title — e.g. "Add item" / "Edit item".
6
+ */
7
+ const DEFAULT_TRIGGER_NOUN = "item";
8
+
9
+ //#endregion
10
+ exports.DEFAULT_TRIGGER_NOUN = DEFAULT_TRIGGER_NOUN;
@@ -0,0 +1,9 @@
1
+ //#region src/components/overlay-common/constants.ts
2
+ /**
3
+ * Fallback noun for the DialogItem / PopoverItem trigger when the field has
4
+ * no title — e.g. "Add item" / "Edit item".
5
+ */
6
+ const DEFAULT_TRIGGER_NOUN = "item";
7
+
8
+ //#endregion
9
+ export { DEFAULT_TRIGGER_NOUN };
@@ -0,0 +1,5 @@
1
+ const require_constants = require('./constants.cjs');
2
+ const require_is_empty_field_value = require('./is-empty-field-value.cjs');
3
+ const require_OverlayFields = require('./OverlayFields.cjs');
4
+ const require_OverlayTrigger = require('./OverlayTrigger.cjs');
5
+ const require_use_overlay = require('./use-overlay.cjs');
@@ -0,0 +1,4 @@
1
+ import { OverlayBaseSlots, OverlayProps } from "./overlay-types.cjs";
2
+ import "./OverlayFields.cjs";
3
+ import { OverlayTriggerProps } from "./OverlayTrigger.cjs";
4
+ import "./use-overlay.cjs";
@@ -0,0 +1,4 @@
1
+ import { OverlayBaseSlots, OverlayProps } from "./overlay-types.js";
2
+ import "./OverlayFields.js";
3
+ import { OverlayTriggerProps } from "./OverlayTrigger.js";
4
+ import "./use-overlay.js";
@@ -0,0 +1,5 @@
1
+ import { DEFAULT_TRIGGER_NOUN } from "./constants.js";
2
+ import { isEmptyFieldValue } from "./is-empty-field-value.js";
3
+ import { OverlayFields } from "./OverlayFields.js";
4
+ import { OverlayTrigger } from "./OverlayTrigger.js";
5
+ import { useOverlay } from "./use-overlay.js";
@@ -0,0 +1,23 @@
1
+
2
+ //#region src/components/overlay-common/is-empty-field-value.ts
3
+ /**
4
+ * Whether a field value holds nothing the user would consider data.
5
+ *
6
+ * Used to pick the trigger verb: an object with no data reads "Add <title>",
7
+ * one with data reads "Edit <title>".
8
+ *
9
+ * Comparing `value` against `initialValue` does not work here: Formily gives an
10
+ * object field an initial value of `{}` while its `initialValue` stays
11
+ * undefined, so an untouched object would always look changed. Empty strings
12
+ * count as empty because clearing an input leaves `''` behind, but `false` and
13
+ * `0` are real values.
14
+ */
15
+ function isEmptyFieldValue(value) {
16
+ if (value == null || value === "") return true;
17
+ if (Array.isArray(value)) return value.every(isEmptyFieldValue);
18
+ if (typeof value === "object") return Object.values(value).every(isEmptyFieldValue);
19
+ return false;
20
+ }
21
+
22
+ //#endregion
23
+ exports.isEmptyFieldValue = isEmptyFieldValue;
@@ -0,0 +1,22 @@
1
+ //#region src/components/overlay-common/is-empty-field-value.ts
2
+ /**
3
+ * Whether a field value holds nothing the user would consider data.
4
+ *
5
+ * Used to pick the trigger verb: an object with no data reads "Add <title>",
6
+ * one with data reads "Edit <title>".
7
+ *
8
+ * Comparing `value` against `initialValue` does not work here: Formily gives an
9
+ * object field an initial value of `{}` while its `initialValue` stays
10
+ * undefined, so an untouched object would always look changed. Empty strings
11
+ * count as empty because clearing an input leaves `''` behind, but `false` and
12
+ * `0` are real values.
13
+ */
14
+ function isEmptyFieldValue(value) {
15
+ if (value == null || value === "") return true;
16
+ if (Array.isArray(value)) return value.every(isEmptyFieldValue);
17
+ if (typeof value === "object") return Object.values(value).every(isEmptyFieldValue);
18
+ return false;
19
+ }
20
+
21
+ //#endregion
22
+ export { isEmptyFieldValue };
@@ -0,0 +1,27 @@
1
+ import { SyncReactNode } from "../../types/react.cjs";
2
+ import React from "react";
3
+
4
+ //#region src/components/overlay-common/overlay-types.d.ts
5
+
6
+ /**
7
+ * The overlay itself — the `dialog` prop on DialogItem and the `popover` prop
8
+ * on PopoverItem.
9
+ *
10
+ * `TSlots` differs per overlay (only a dialog has a footer), so each component
11
+ * supplies its own slot map.
12
+ */
13
+ interface OverlayProps<TSlots> {
14
+ /** Heading inside the overlay. Defaults to the field label. */
15
+ title?: SyncReactNode;
16
+ /** Description inside the overlay. Defaults to the field description. */
17
+ description?: SyncReactNode;
18
+ /** Props for the overlay's internal parts. */
19
+ slots?: TSlots;
20
+ }
21
+ /** Slots every overlay has, whatever kind it is. */
22
+ interface OverlayBaseSlots {
23
+ header?: React.ComponentProps<'div'>;
24
+ body?: React.ComponentProps<'div'>;
25
+ }
26
+ //#endregion
27
+ export { OverlayBaseSlots, OverlayProps };
@@ -0,0 +1,27 @@
1
+ import { SyncReactNode } from "../../types/react.js";
2
+ import React from "react";
3
+
4
+ //#region src/components/overlay-common/overlay-types.d.ts
5
+
6
+ /**
7
+ * The overlay itself — the `dialog` prop on DialogItem and the `popover` prop
8
+ * on PopoverItem.
9
+ *
10
+ * `TSlots` differs per overlay (only a dialog has a footer), so each component
11
+ * supplies its own slot map.
12
+ */
13
+ interface OverlayProps<TSlots> {
14
+ /** Heading inside the overlay. Defaults to the field label. */
15
+ title?: SyncReactNode;
16
+ /** Description inside the overlay. Defaults to the field description. */
17
+ description?: SyncReactNode;
18
+ /** Props for the overlay's internal parts. */
19
+ slots?: TSlots;
20
+ }
21
+ /** Slots every overlay has, whatever kind it is. */
22
+ interface OverlayBaseSlots {
23
+ header?: React.ComponentProps<'div'>;
24
+ body?: React.ComponentProps<'div'>;
25
+ }
26
+ //#endregion
27
+ export { OverlayBaseSlots, OverlayProps };