@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.
- package/dist/components/date-picker/DatePicker.d.cts +3 -3
- package/dist/components/date-picker/DatePicker.d.ts +3 -3
- package/dist/components/dialog-item/BaseDialogItem.cjs +114 -0
- package/dist/components/dialog-item/BaseDialogItem.d.cts +56 -0
- package/dist/components/dialog-item/BaseDialogItem.d.ts +56 -0
- package/dist/components/dialog-item/BaseDialogItem.js +109 -0
- package/dist/components/dialog-item/ConnectedDialogItem.cjs +16 -0
- package/dist/components/dialog-item/ConnectedDialogItem.d.cts +15 -0
- package/dist/components/dialog-item/ConnectedDialogItem.d.ts +15 -0
- package/dist/components/dialog-item/ConnectedDialogItem.js +14 -0
- package/dist/components/dialog-item/index.cjs +2 -0
- package/dist/components/dialog-item/index.d.cts +2 -0
- package/dist/components/dialog-item/index.d.ts +2 -0
- package/dist/components/dialog-item/index.js +2 -0
- package/dist/components/dialog-item/mcp.js +127 -0
- package/dist/components/form/Form.d.cts +2 -2
- package/dist/components/form/Form.d.ts +2 -2
- package/dist/components/form-grid/FormGrid.d.cts +2 -2
- package/dist/components/form-grid/FormGrid.d.ts +2 -2
- package/dist/components/form-item/ConnectedFormItem.cjs +2 -34
- package/dist/components/form-item/ConnectedFormItem.d.cts +4 -4
- package/dist/components/form-item/ConnectedFormItem.d.ts +4 -4
- package/dist/components/form-item/ConnectedFormItem.js +3 -34
- package/dist/components/form-item/map-form-item-props.cjs +50 -0
- package/dist/components/form-item/map-form-item-props.js +47 -0
- package/dist/components/object-container/ObjectContainer.cjs +1 -1
- package/dist/components/object-container/ObjectContainer.js +1 -1
- package/dist/components/overlay-common/OverlayFields.cjs +26 -0
- package/dist/components/overlay-common/OverlayFields.d.cts +1 -0
- package/dist/components/overlay-common/OverlayFields.d.ts +1 -0
- package/dist/components/overlay-common/OverlayFields.js +24 -0
- package/dist/components/overlay-common/OverlayTrigger.cjs +27 -0
- package/dist/components/overlay-common/OverlayTrigger.d.cts +15 -0
- package/dist/components/overlay-common/OverlayTrigger.d.ts +15 -0
- package/dist/components/overlay-common/OverlayTrigger.js +23 -0
- package/dist/components/overlay-common/constants.cjs +10 -0
- package/dist/components/overlay-common/constants.js +9 -0
- package/dist/components/overlay-common/index.cjs +5 -0
- package/dist/components/overlay-common/index.d.cts +4 -0
- package/dist/components/overlay-common/index.d.ts +4 -0
- package/dist/components/overlay-common/index.js +5 -0
- package/dist/components/overlay-common/is-empty-field-value.cjs +23 -0
- package/dist/components/overlay-common/is-empty-field-value.js +22 -0
- package/dist/components/overlay-common/overlay-types.d.cts +27 -0
- package/dist/components/overlay-common/overlay-types.d.ts +27 -0
- package/dist/components/overlay-common/use-overlay.cjs +110 -0
- package/dist/components/overlay-common/use-overlay.d.cts +1 -0
- package/dist/components/overlay-common/use-overlay.d.ts +1 -0
- package/dist/components/overlay-common/use-overlay.js +107 -0
- package/dist/components/popover-item/BasePopoverItem.cjs +108 -0
- package/dist/components/popover-item/BasePopoverItem.d.cts +57 -0
- package/dist/components/popover-item/BasePopoverItem.d.ts +57 -0
- package/dist/components/popover-item/BasePopoverItem.js +104 -0
- package/dist/components/popover-item/ConnectedPopoverItem.cjs +16 -0
- package/dist/components/popover-item/ConnectedPopoverItem.d.cts +15 -0
- package/dist/components/popover-item/ConnectedPopoverItem.d.ts +15 -0
- package/dist/components/popover-item/ConnectedPopoverItem.js +14 -0
- package/dist/components/popover-item/index.cjs +2 -0
- package/dist/components/popover-item/index.d.cts +2 -0
- package/dist/components/popover-item/index.d.ts +2 -0
- package/dist/components/popover-item/index.js +2 -0
- package/dist/components/popover-item/mcp.js +127 -0
- package/dist/components/radio/Radio.d.ts +2 -2
- package/dist/components/row/Row.d.ts +2 -2
- package/dist/components/schema-field/schema-field-basics.cjs +8 -2
- package/dist/components/schema-field/schema-field-basics.d.cts +337 -263
- package/dist/components/schema-field/schema-field-basics.d.ts +344 -270
- package/dist/components/schema-field/schema-field-basics.js +8 -2
- package/dist/components/schema-field/schema-field-extended.d.cts +497 -423
- package/dist/components/schema-field/schema-field-extended.d.ts +498 -424
- package/dist/components/schema-field/schema-field.d.cts +431 -357
- package/dist/components/schema-field/schema-field.d.ts +431 -357
- package/dist/generated/mcp-registry.js +56 -52
- package/dist/index.cjs +12 -2
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +9 -3
- package/package.json +5 -5
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_resolve_responsive_space = require('../../utils/resolve-responsive-space.cjs');
|
|
3
|
+
const require_use_description = require('../../hooks/use-description.cjs');
|
|
4
|
+
const require_use_form_context = require('../../hooks/use-form-context.cjs');
|
|
5
|
+
const require_use_label = require('../../hooks/use-label.cjs');
|
|
6
|
+
require('../../hooks/index.cjs');
|
|
7
|
+
const require_use_shake_animation = require('../array-common/use-shake-animation.cjs');
|
|
8
|
+
require('../array-common/index.cjs');
|
|
9
|
+
const require_constants = require('./constants.cjs');
|
|
10
|
+
const require_is_empty_field_value = require('./is-empty-field-value.cjs');
|
|
11
|
+
let __formily_react = require("@formily/react");
|
|
12
|
+
__formily_react = require_rolldown_runtime.__toESM(__formily_react);
|
|
13
|
+
let react = require("react");
|
|
14
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
15
|
+
|
|
16
|
+
//#region src/components/overlay-common/use-overlay.ts
|
|
17
|
+
/**
|
|
18
|
+
* Formily glob matching the field itself and every descendant, and nothing
|
|
19
|
+
* else — `*(a,a.*)` matches `a`, `a.b`, and `a.b.c`, but not the sibling `ab`.
|
|
20
|
+
* One pattern covers both shapes an overlay can hold: a single input (validate
|
|
21
|
+
* the field) and an object's form (validate its fields), at any depth.
|
|
22
|
+
*/
|
|
23
|
+
function buildValidationPattern(address) {
|
|
24
|
+
return `*(${address},${address}.*)`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Shared state for fields that render their input(s) inside an overlay
|
|
28
|
+
* (dialog or popover) opened from a trigger button.
|
|
29
|
+
*
|
|
30
|
+
* Fields render in the parent form (no draft copy), so edits commit as the
|
|
31
|
+
* user types. This mirrors the autoSave mode of ArrayDialog/ArrayPopover:
|
|
32
|
+
* validation on close is scoped to the overlay's own fields so unrelated
|
|
33
|
+
* fields elsewhere in the form are not validated.
|
|
34
|
+
*/
|
|
35
|
+
function useOverlay(options = {}) {
|
|
36
|
+
const { label, description, trigger, open, defaultOpen, onOpenChange, validateOnClose = true } = options;
|
|
37
|
+
const effectiveLabel = require_use_label.useLabel(label);
|
|
38
|
+
const effectiveDescription = require_use_description.useDescription(description);
|
|
39
|
+
const [uncontrolledOpen, setUncontrolledOpen] = react.default.useState(defaultOpen ?? false);
|
|
40
|
+
const isControlled = open !== void 0;
|
|
41
|
+
const isOpen = isControlled ? open : uncontrolledOpen;
|
|
42
|
+
const setOpen = react.default.useCallback((next) => {
|
|
43
|
+
if (!isControlled) setUncontrolledOpen(next);
|
|
44
|
+
onOpenChange?.(next);
|
|
45
|
+
}, [isControlled, onOpenChange]);
|
|
46
|
+
const { layout } = require_use_form_context.useFormContext();
|
|
47
|
+
const gapClass = require_resolve_responsive_space.resolveResponsiveGapClass({ density: layout?.density });
|
|
48
|
+
const field = (0, __formily_react.useField)();
|
|
49
|
+
const hasError = field.errors.length > 0;
|
|
50
|
+
const validationPath = buildValidationPattern(field.address.toString());
|
|
51
|
+
const noun = (0, __formily_react.useFieldSchema)().title ?? require_constants.DEFAULT_TRIGGER_NOUN;
|
|
52
|
+
const isEmpty = require_is_empty_field_value.isEmptyFieldValue(field.value);
|
|
53
|
+
const resolvedTrigger = {
|
|
54
|
+
...trigger,
|
|
55
|
+
label: trigger?.label ?? (isEmpty ? `Add ${noun}` : `Edit ${noun}`)
|
|
56
|
+
};
|
|
57
|
+
const { shouldShake, triggerShake } = require_use_shake_animation.useShakeAnimation();
|
|
58
|
+
const revalidateOnOpenRef = react.default.useRef(false);
|
|
59
|
+
react.default.useEffect(() => {
|
|
60
|
+
if (!isOpen || !revalidateOnOpenRef.current) return;
|
|
61
|
+
revalidateOnOpenRef.current = false;
|
|
62
|
+
Promise.resolve(field.form.validate(validationPath)).catch(() => void 0);
|
|
63
|
+
}, [
|
|
64
|
+
field.form,
|
|
65
|
+
isOpen,
|
|
66
|
+
validationPath
|
|
67
|
+
]);
|
|
68
|
+
const requestClose = react.default.useCallback(() => {
|
|
69
|
+
if (!validateOnClose) {
|
|
70
|
+
setOpen(false);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
Promise.resolve(field.form.validate(validationPath)).then(() => {
|
|
74
|
+
setOpen(false);
|
|
75
|
+
}).catch(() => {
|
|
76
|
+
triggerShake();
|
|
77
|
+
});
|
|
78
|
+
}, [
|
|
79
|
+
field.form,
|
|
80
|
+
setOpen,
|
|
81
|
+
triggerShake,
|
|
82
|
+
validateOnClose,
|
|
83
|
+
validationPath
|
|
84
|
+
]);
|
|
85
|
+
return {
|
|
86
|
+
label: effectiveLabel,
|
|
87
|
+
description: effectiveDescription,
|
|
88
|
+
trigger: resolvedTrigger,
|
|
89
|
+
open: isOpen,
|
|
90
|
+
gapClass,
|
|
91
|
+
hasError,
|
|
92
|
+
shouldShake,
|
|
93
|
+
handleOpenChange: react.default.useCallback((next) => {
|
|
94
|
+
if (next) {
|
|
95
|
+
revalidateOnOpenRef.current = hasError;
|
|
96
|
+
setOpen(true);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
requestClose();
|
|
100
|
+
}, [
|
|
101
|
+
hasError,
|
|
102
|
+
requestClose,
|
|
103
|
+
setOpen
|
|
104
|
+
]),
|
|
105
|
+
requestClose
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//#endregion
|
|
110
|
+
exports.useOverlay = useOverlay;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./OverlayTrigger.cjs";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./OverlayTrigger.js";
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { resolveResponsiveGapClass } from "../../utils/resolve-responsive-space.js";
|
|
2
|
+
import { useDescription } from "../../hooks/use-description.js";
|
|
3
|
+
import { useFormContext } from "../../hooks/use-form-context.js";
|
|
4
|
+
import { useLabel } from "../../hooks/use-label.js";
|
|
5
|
+
import "../../hooks/index.js";
|
|
6
|
+
import { useShakeAnimation } from "../array-common/use-shake-animation.js";
|
|
7
|
+
import "../array-common/index.js";
|
|
8
|
+
import { DEFAULT_TRIGGER_NOUN } from "./constants.js";
|
|
9
|
+
import { isEmptyFieldValue } from "./is-empty-field-value.js";
|
|
10
|
+
import { useField, useFieldSchema } from "@formily/react";
|
|
11
|
+
import React from "react";
|
|
12
|
+
|
|
13
|
+
//#region src/components/overlay-common/use-overlay.ts
|
|
14
|
+
/**
|
|
15
|
+
* Formily glob matching the field itself and every descendant, and nothing
|
|
16
|
+
* else — `*(a,a.*)` matches `a`, `a.b`, and `a.b.c`, but not the sibling `ab`.
|
|
17
|
+
* One pattern covers both shapes an overlay can hold: a single input (validate
|
|
18
|
+
* the field) and an object's form (validate its fields), at any depth.
|
|
19
|
+
*/
|
|
20
|
+
function buildValidationPattern(address) {
|
|
21
|
+
return `*(${address},${address}.*)`;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Shared state for fields that render their input(s) inside an overlay
|
|
25
|
+
* (dialog or popover) opened from a trigger button.
|
|
26
|
+
*
|
|
27
|
+
* Fields render in the parent form (no draft copy), so edits commit as the
|
|
28
|
+
* user types. This mirrors the autoSave mode of ArrayDialog/ArrayPopover:
|
|
29
|
+
* validation on close is scoped to the overlay's own fields so unrelated
|
|
30
|
+
* fields elsewhere in the form are not validated.
|
|
31
|
+
*/
|
|
32
|
+
function useOverlay(options = {}) {
|
|
33
|
+
const { label, description, trigger, open, defaultOpen, onOpenChange, validateOnClose = true } = options;
|
|
34
|
+
const effectiveLabel = useLabel(label);
|
|
35
|
+
const effectiveDescription = useDescription(description);
|
|
36
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen ?? false);
|
|
37
|
+
const isControlled = open !== void 0;
|
|
38
|
+
const isOpen = isControlled ? open : uncontrolledOpen;
|
|
39
|
+
const setOpen = React.useCallback((next) => {
|
|
40
|
+
if (!isControlled) setUncontrolledOpen(next);
|
|
41
|
+
onOpenChange?.(next);
|
|
42
|
+
}, [isControlled, onOpenChange]);
|
|
43
|
+
const { layout } = useFormContext();
|
|
44
|
+
const gapClass = resolveResponsiveGapClass({ density: layout?.density });
|
|
45
|
+
const field = useField();
|
|
46
|
+
const hasError = field.errors.length > 0;
|
|
47
|
+
const validationPath = buildValidationPattern(field.address.toString());
|
|
48
|
+
const noun = useFieldSchema().title ?? DEFAULT_TRIGGER_NOUN;
|
|
49
|
+
const isEmpty = isEmptyFieldValue(field.value);
|
|
50
|
+
const resolvedTrigger = {
|
|
51
|
+
...trigger,
|
|
52
|
+
label: trigger?.label ?? (isEmpty ? `Add ${noun}` : `Edit ${noun}`)
|
|
53
|
+
};
|
|
54
|
+
const { shouldShake, triggerShake } = useShakeAnimation();
|
|
55
|
+
const revalidateOnOpenRef = React.useRef(false);
|
|
56
|
+
React.useEffect(() => {
|
|
57
|
+
if (!isOpen || !revalidateOnOpenRef.current) return;
|
|
58
|
+
revalidateOnOpenRef.current = false;
|
|
59
|
+
Promise.resolve(field.form.validate(validationPath)).catch(() => void 0);
|
|
60
|
+
}, [
|
|
61
|
+
field.form,
|
|
62
|
+
isOpen,
|
|
63
|
+
validationPath
|
|
64
|
+
]);
|
|
65
|
+
const requestClose = React.useCallback(() => {
|
|
66
|
+
if (!validateOnClose) {
|
|
67
|
+
setOpen(false);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
Promise.resolve(field.form.validate(validationPath)).then(() => {
|
|
71
|
+
setOpen(false);
|
|
72
|
+
}).catch(() => {
|
|
73
|
+
triggerShake();
|
|
74
|
+
});
|
|
75
|
+
}, [
|
|
76
|
+
field.form,
|
|
77
|
+
setOpen,
|
|
78
|
+
triggerShake,
|
|
79
|
+
validateOnClose,
|
|
80
|
+
validationPath
|
|
81
|
+
]);
|
|
82
|
+
return {
|
|
83
|
+
label: effectiveLabel,
|
|
84
|
+
description: effectiveDescription,
|
|
85
|
+
trigger: resolvedTrigger,
|
|
86
|
+
open: isOpen,
|
|
87
|
+
gapClass,
|
|
88
|
+
hasError,
|
|
89
|
+
shouldShake,
|
|
90
|
+
handleOpenChange: React.useCallback((next) => {
|
|
91
|
+
if (next) {
|
|
92
|
+
revalidateOnOpenRef.current = hasError;
|
|
93
|
+
setOpen(true);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
requestClose();
|
|
97
|
+
}, [
|
|
98
|
+
hasError,
|
|
99
|
+
requestClose,
|
|
100
|
+
setOpen
|
|
101
|
+
]),
|
|
102
|
+
requestClose
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
//#endregion
|
|
107
|
+
export { useOverlay };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_ShakeStyles = require('../array-common/ShakeStyles.cjs');
|
|
3
|
+
require('../array-common/index.cjs');
|
|
4
|
+
const require_BaseFormItem = require('../form-item/BaseFormItem.cjs');
|
|
5
|
+
require('../form-item/index.cjs');
|
|
6
|
+
const require_OverlayFields = require('../overlay-common/OverlayFields.cjs');
|
|
7
|
+
const require_OverlayTrigger = require('../overlay-common/OverlayTrigger.cjs');
|
|
8
|
+
const require_use_overlay = require('../overlay-common/use-overlay.cjs');
|
|
9
|
+
require('../overlay-common/index.cjs');
|
|
10
|
+
let react = require("react");
|
|
11
|
+
react = require_rolldown_runtime.__toESM(react);
|
|
12
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
13
|
+
react_jsx_runtime = require_rolldown_runtime.__toESM(react_jsx_runtime);
|
|
14
|
+
let __pixpilot_shadcn = require("@pixpilot/shadcn");
|
|
15
|
+
__pixpilot_shadcn = require_rolldown_runtime.__toESM(__pixpilot_shadcn);
|
|
16
|
+
|
|
17
|
+
//#region src/components/popover-item/BasePopoverItem.tsx
|
|
18
|
+
/**
|
|
19
|
+
* Formily decorator that edits a single field inside a popover.
|
|
20
|
+
*
|
|
21
|
+
* Used in place of FormItem (`x-decorator: 'PopoverItem'`), it renders the
|
|
22
|
+
* field's label, description, and validation feedback exactly as FormItem
|
|
23
|
+
* does, but puts a trigger button where the input would sit and moves the
|
|
24
|
+
* input itself into a popover. The field keeps its own component, so
|
|
25
|
+
* validation and x-reactions behave as they do under FormItem.
|
|
26
|
+
*/
|
|
27
|
+
const BasePopoverItem = ({ children, label, description, trigger: triggerProp, open: openProp, defaultOpen, onOpenChange, validateOnClose, modal = false, popover, feedbackStatus, feedbackText,...formItemProps }) => {
|
|
28
|
+
const { label: effectiveLabel, description: desc, trigger, open, gapClass, hasError, shouldShake, handleOpenChange, requestClose } = require_use_overlay.useOverlay({
|
|
29
|
+
label,
|
|
30
|
+
description,
|
|
31
|
+
trigger: triggerProp,
|
|
32
|
+
open: openProp,
|
|
33
|
+
defaultOpen,
|
|
34
|
+
onOpenChange,
|
|
35
|
+
validateOnClose
|
|
36
|
+
});
|
|
37
|
+
const title = popover?.title ?? effectiveLabel;
|
|
38
|
+
const overlayDescription = popover?.description ?? desc;
|
|
39
|
+
const slots = popover?.slots;
|
|
40
|
+
const hasHeader = title != null || overlayDescription != null;
|
|
41
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Popover, {
|
|
42
|
+
open,
|
|
43
|
+
onOpenChange: handleOpenChange,
|
|
44
|
+
modal,
|
|
45
|
+
children: [
|
|
46
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_BaseFormItem.BaseFormItem, {
|
|
47
|
+
...formItemProps,
|
|
48
|
+
label,
|
|
49
|
+
description,
|
|
50
|
+
feedbackStatus,
|
|
51
|
+
feedbackText,
|
|
52
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.PopoverTrigger, {
|
|
53
|
+
asChild: true,
|
|
54
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_OverlayTrigger.OverlayTrigger, {
|
|
55
|
+
invalid: hasError,
|
|
56
|
+
...trigger
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
}),
|
|
60
|
+
!open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_OverlayFields.OverlayFields, { children }),
|
|
61
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.PopoverContent, {
|
|
62
|
+
align: "start",
|
|
63
|
+
...slots?.content,
|
|
64
|
+
className: (0, __pixpilot_shadcn.cn)("w-(--radix-popover-trigger-width) min-w-72", shouldShake && "pp-shake", slots?.content?.className),
|
|
65
|
+
onInteractOutside: (event) => {
|
|
66
|
+
slots?.content?.onInteractOutside?.(event);
|
|
67
|
+
if (event.defaultPrevented) return;
|
|
68
|
+
event.preventDefault();
|
|
69
|
+
requestClose();
|
|
70
|
+
},
|
|
71
|
+
onEscapeKeyDown: (event) => {
|
|
72
|
+
slots?.content?.onEscapeKeyDown?.(event);
|
|
73
|
+
if (event.defaultPrevented) return;
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
requestClose();
|
|
76
|
+
},
|
|
77
|
+
children: [
|
|
78
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ShakeStyles.ShakeStyles, {}),
|
|
79
|
+
hasHeader && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
80
|
+
...slots?.header,
|
|
81
|
+
className: (0, __pixpilot_shadcn.cn)("space-y-1 pb-3", slots?.header?.className),
|
|
82
|
+
children: [title != null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
83
|
+
...slots?.title,
|
|
84
|
+
className: (0, __pixpilot_shadcn.cn)("font-medium leading-none", slots?.title?.className),
|
|
85
|
+
children: title
|
|
86
|
+
}), overlayDescription != null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
87
|
+
...slots?.description,
|
|
88
|
+
className: (0, __pixpilot_shadcn.cn)("text-muted-foreground text-sm", slots?.description?.className),
|
|
89
|
+
children: overlayDescription
|
|
90
|
+
})]
|
|
91
|
+
}),
|
|
92
|
+
open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
93
|
+
...slots?.body,
|
|
94
|
+
className: (0, __pixpilot_shadcn.cn)("grid", gapClass, slots?.body?.className),
|
|
95
|
+
children: [children, feedbackText != null && feedbackText !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
96
|
+
className: (0, __pixpilot_shadcn.cn)("text-[0.8rem]", feedbackStatus === "error" && "text-destructive font-medium", feedbackStatus === "warning" && "text-amber-600", feedbackStatus === "success" && "text-green-600"),
|
|
97
|
+
children: feedbackText
|
|
98
|
+
})]
|
|
99
|
+
})
|
|
100
|
+
]
|
|
101
|
+
})
|
|
102
|
+
]
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
BasePopoverItem.displayName = "BasePopoverItem";
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
exports.BasePopoverItem = BasePopoverItem;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { FormItemProps } from "../form-item/form-item-types.cjs";
|
|
2
|
+
import "../form-item/index.cjs";
|
|
3
|
+
import { OverlayBaseSlots, OverlayProps } from "../overlay-common/overlay-types.cjs";
|
|
4
|
+
import { OverlayTriggerProps } from "../overlay-common/OverlayTrigger.cjs";
|
|
5
|
+
import "../overlay-common/index.cjs";
|
|
6
|
+
import React from "react";
|
|
7
|
+
import { PopoverContent } from "@pixpilot/shadcn";
|
|
8
|
+
|
|
9
|
+
//#region src/components/popover-item/BasePopoverItem.d.ts
|
|
10
|
+
interface PopoverItemProps extends Omit<FormItemProps, 'popover'> {
|
|
11
|
+
/**
|
|
12
|
+
* Props for the trigger button, e.g. `{ label: 'Write a bio' }`. Without a
|
|
13
|
+
* label it reads `Add <title>` when the field is empty and `Edit <title>`
|
|
14
|
+
* once it holds a value. Settable from an x-reaction via
|
|
15
|
+
* `decoratorProps.trigger`.
|
|
16
|
+
*/
|
|
17
|
+
trigger?: OverlayTriggerProps;
|
|
18
|
+
/** Controlled open state of the popover. */
|
|
19
|
+
open?: boolean;
|
|
20
|
+
/** Initial open state when uncontrolled. */
|
|
21
|
+
defaultOpen?: boolean;
|
|
22
|
+
onOpenChange?: (open: boolean) => void;
|
|
23
|
+
/**
|
|
24
|
+
* When false, the popover closes without validating the field first.
|
|
25
|
+
* Default is true.
|
|
26
|
+
*/
|
|
27
|
+
validateOnClose?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* If true, interaction outside the popover is blocked while it is open.
|
|
30
|
+
* Default is false.
|
|
31
|
+
*/
|
|
32
|
+
modal?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The popover itself — its `title`, `description`, and `slots`, e.g.
|
|
35
|
+
* `{ title: 'Notes', slots: { content: { className: 'w-96' } } }`. Title and
|
|
36
|
+
* description default to the field's label and description.
|
|
37
|
+
*/
|
|
38
|
+
popover?: PopoverItemPopoverProps;
|
|
39
|
+
}
|
|
40
|
+
interface PopoverItemPopoverSlots extends OverlayBaseSlots {
|
|
41
|
+
content?: React.ComponentProps<typeof PopoverContent>;
|
|
42
|
+
title?: React.ComponentProps<'h4'>;
|
|
43
|
+
description?: React.ComponentProps<'p'>;
|
|
44
|
+
}
|
|
45
|
+
type PopoverItemPopoverProps = OverlayProps<PopoverItemPopoverSlots>;
|
|
46
|
+
/**
|
|
47
|
+
* Formily decorator that edits a single field inside a popover.
|
|
48
|
+
*
|
|
49
|
+
* Used in place of FormItem (`x-decorator: 'PopoverItem'`), it renders the
|
|
50
|
+
* field's label, description, and validation feedback exactly as FormItem
|
|
51
|
+
* does, but puts a trigger button where the input would sit and moves the
|
|
52
|
+
* input itself into a popover. The field keeps its own component, so
|
|
53
|
+
* validation and x-reactions behave as they do under FormItem.
|
|
54
|
+
*/
|
|
55
|
+
declare const BasePopoverItem: React.FC<React.PropsWithChildren<PopoverItemProps>>;
|
|
56
|
+
//#endregion
|
|
57
|
+
export { BasePopoverItem, PopoverItemProps };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { FormItemProps } from "../form-item/form-item-types.js";
|
|
2
|
+
import "../form-item/index.js";
|
|
3
|
+
import { OverlayBaseSlots, OverlayProps } from "../overlay-common/overlay-types.js";
|
|
4
|
+
import { OverlayTriggerProps } from "../overlay-common/OverlayTrigger.js";
|
|
5
|
+
import "../overlay-common/index.js";
|
|
6
|
+
import React from "react";
|
|
7
|
+
import { PopoverContent } from "@pixpilot/shadcn";
|
|
8
|
+
|
|
9
|
+
//#region src/components/popover-item/BasePopoverItem.d.ts
|
|
10
|
+
interface PopoverItemProps extends Omit<FormItemProps, 'popover'> {
|
|
11
|
+
/**
|
|
12
|
+
* Props for the trigger button, e.g. `{ label: 'Write a bio' }`. Without a
|
|
13
|
+
* label it reads `Add <title>` when the field is empty and `Edit <title>`
|
|
14
|
+
* once it holds a value. Settable from an x-reaction via
|
|
15
|
+
* `decoratorProps.trigger`.
|
|
16
|
+
*/
|
|
17
|
+
trigger?: OverlayTriggerProps;
|
|
18
|
+
/** Controlled open state of the popover. */
|
|
19
|
+
open?: boolean;
|
|
20
|
+
/** Initial open state when uncontrolled. */
|
|
21
|
+
defaultOpen?: boolean;
|
|
22
|
+
onOpenChange?: (open: boolean) => void;
|
|
23
|
+
/**
|
|
24
|
+
* When false, the popover closes without validating the field first.
|
|
25
|
+
* Default is true.
|
|
26
|
+
*/
|
|
27
|
+
validateOnClose?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* If true, interaction outside the popover is blocked while it is open.
|
|
30
|
+
* Default is false.
|
|
31
|
+
*/
|
|
32
|
+
modal?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The popover itself — its `title`, `description`, and `slots`, e.g.
|
|
35
|
+
* `{ title: 'Notes', slots: { content: { className: 'w-96' } } }`. Title and
|
|
36
|
+
* description default to the field's label and description.
|
|
37
|
+
*/
|
|
38
|
+
popover?: PopoverItemPopoverProps;
|
|
39
|
+
}
|
|
40
|
+
interface PopoverItemPopoverSlots extends OverlayBaseSlots {
|
|
41
|
+
content?: React.ComponentProps<typeof PopoverContent>;
|
|
42
|
+
title?: React.ComponentProps<'h4'>;
|
|
43
|
+
description?: React.ComponentProps<'p'>;
|
|
44
|
+
}
|
|
45
|
+
type PopoverItemPopoverProps = OverlayProps<PopoverItemPopoverSlots>;
|
|
46
|
+
/**
|
|
47
|
+
* Formily decorator that edits a single field inside a popover.
|
|
48
|
+
*
|
|
49
|
+
* Used in place of FormItem (`x-decorator: 'PopoverItem'`), it renders the
|
|
50
|
+
* field's label, description, and validation feedback exactly as FormItem
|
|
51
|
+
* does, but puts a trigger button where the input would sit and moves the
|
|
52
|
+
* input itself into a popover. The field keeps its own component, so
|
|
53
|
+
* validation and x-reactions behave as they do under FormItem.
|
|
54
|
+
*/
|
|
55
|
+
declare const BasePopoverItem: React.FC<React.PropsWithChildren<PopoverItemProps>>;
|
|
56
|
+
//#endregion
|
|
57
|
+
export { BasePopoverItem, PopoverItemProps };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { ShakeStyles } from "../array-common/ShakeStyles.js";
|
|
2
|
+
import "../array-common/index.js";
|
|
3
|
+
import { BaseFormItem } from "../form-item/BaseFormItem.js";
|
|
4
|
+
import "../form-item/index.js";
|
|
5
|
+
import { OverlayFields } from "../overlay-common/OverlayFields.js";
|
|
6
|
+
import { OverlayTrigger } from "../overlay-common/OverlayTrigger.js";
|
|
7
|
+
import { useOverlay } from "../overlay-common/use-overlay.js";
|
|
8
|
+
import "../overlay-common/index.js";
|
|
9
|
+
import React from "react";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { Popover, PopoverContent, PopoverTrigger, cn } from "@pixpilot/shadcn";
|
|
12
|
+
|
|
13
|
+
//#region src/components/popover-item/BasePopoverItem.tsx
|
|
14
|
+
/**
|
|
15
|
+
* Formily decorator that edits a single field inside a popover.
|
|
16
|
+
*
|
|
17
|
+
* Used in place of FormItem (`x-decorator: 'PopoverItem'`), it renders the
|
|
18
|
+
* field's label, description, and validation feedback exactly as FormItem
|
|
19
|
+
* does, but puts a trigger button where the input would sit and moves the
|
|
20
|
+
* input itself into a popover. The field keeps its own component, so
|
|
21
|
+
* validation and x-reactions behave as they do under FormItem.
|
|
22
|
+
*/
|
|
23
|
+
const BasePopoverItem = ({ children, label, description, trigger: triggerProp, open: openProp, defaultOpen, onOpenChange, validateOnClose, modal = false, popover, feedbackStatus, feedbackText,...formItemProps }) => {
|
|
24
|
+
const { label: effectiveLabel, description: desc, trigger, open, gapClass, hasError, shouldShake, handleOpenChange, requestClose } = useOverlay({
|
|
25
|
+
label,
|
|
26
|
+
description,
|
|
27
|
+
trigger: triggerProp,
|
|
28
|
+
open: openProp,
|
|
29
|
+
defaultOpen,
|
|
30
|
+
onOpenChange,
|
|
31
|
+
validateOnClose
|
|
32
|
+
});
|
|
33
|
+
const title = popover?.title ?? effectiveLabel;
|
|
34
|
+
const overlayDescription = popover?.description ?? desc;
|
|
35
|
+
const slots = popover?.slots;
|
|
36
|
+
const hasHeader = title != null || overlayDescription != null;
|
|
37
|
+
return /* @__PURE__ */ jsxs(Popover, {
|
|
38
|
+
open,
|
|
39
|
+
onOpenChange: handleOpenChange,
|
|
40
|
+
modal,
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ jsx(BaseFormItem, {
|
|
43
|
+
...formItemProps,
|
|
44
|
+
label,
|
|
45
|
+
description,
|
|
46
|
+
feedbackStatus,
|
|
47
|
+
feedbackText,
|
|
48
|
+
children: /* @__PURE__ */ jsx(PopoverTrigger, {
|
|
49
|
+
asChild: true,
|
|
50
|
+
children: /* @__PURE__ */ jsx(OverlayTrigger, {
|
|
51
|
+
invalid: hasError,
|
|
52
|
+
...trigger
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
}),
|
|
56
|
+
!open && /* @__PURE__ */ jsx(OverlayFields, { children }),
|
|
57
|
+
/* @__PURE__ */ jsxs(PopoverContent, {
|
|
58
|
+
align: "start",
|
|
59
|
+
...slots?.content,
|
|
60
|
+
className: cn("w-(--radix-popover-trigger-width) min-w-72", shouldShake && "pp-shake", slots?.content?.className),
|
|
61
|
+
onInteractOutside: (event) => {
|
|
62
|
+
slots?.content?.onInteractOutside?.(event);
|
|
63
|
+
if (event.defaultPrevented) return;
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
requestClose();
|
|
66
|
+
},
|
|
67
|
+
onEscapeKeyDown: (event) => {
|
|
68
|
+
slots?.content?.onEscapeKeyDown?.(event);
|
|
69
|
+
if (event.defaultPrevented) return;
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
requestClose();
|
|
72
|
+
},
|
|
73
|
+
children: [
|
|
74
|
+
/* @__PURE__ */ jsx(ShakeStyles, {}),
|
|
75
|
+
hasHeader && /* @__PURE__ */ jsxs("div", {
|
|
76
|
+
...slots?.header,
|
|
77
|
+
className: cn("space-y-1 pb-3", slots?.header?.className),
|
|
78
|
+
children: [title != null && /* @__PURE__ */ jsx("h4", {
|
|
79
|
+
...slots?.title,
|
|
80
|
+
className: cn("font-medium leading-none", slots?.title?.className),
|
|
81
|
+
children: title
|
|
82
|
+
}), overlayDescription != null && /* @__PURE__ */ jsx("p", {
|
|
83
|
+
...slots?.description,
|
|
84
|
+
className: cn("text-muted-foreground text-sm", slots?.description?.className),
|
|
85
|
+
children: overlayDescription
|
|
86
|
+
})]
|
|
87
|
+
}),
|
|
88
|
+
open && /* @__PURE__ */ jsxs("div", {
|
|
89
|
+
...slots?.body,
|
|
90
|
+
className: cn("grid", gapClass, slots?.body?.className),
|
|
91
|
+
children: [children, feedbackText != null && feedbackText !== "" && /* @__PURE__ */ jsx("p", {
|
|
92
|
+
className: cn("text-[0.8rem]", feedbackStatus === "error" && "text-destructive font-medium", feedbackStatus === "warning" && "text-amber-600", feedbackStatus === "success" && "text-green-600"),
|
|
93
|
+
children: feedbackText
|
|
94
|
+
})]
|
|
95
|
+
})
|
|
96
|
+
]
|
|
97
|
+
})
|
|
98
|
+
]
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
BasePopoverItem.displayName = "BasePopoverItem";
|
|
102
|
+
|
|
103
|
+
//#endregion
|
|
104
|
+
export { BasePopoverItem };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_map_form_item_props = require('../form-item/map-form-item-props.cjs');
|
|
3
|
+
const require_BasePopoverItem = require('./BasePopoverItem.cjs');
|
|
4
|
+
let __formily_react = require("@formily/react");
|
|
5
|
+
__formily_react = require_rolldown_runtime.__toESM(__formily_react);
|
|
6
|
+
|
|
7
|
+
//#region src/components/popover-item/ConnectedPopoverItem.tsx
|
|
8
|
+
/**
|
|
9
|
+
* PopoverItem decorator connected to Formily field state.
|
|
10
|
+
* Maps field label, description, and validation state onto the decorator the
|
|
11
|
+
* same way FormItem does.
|
|
12
|
+
*/
|
|
13
|
+
const PopoverItem = (0, __formily_react.connect)(require_BasePopoverItem.BasePopoverItem, (0, __formily_react.mapProps)(require_map_form_item_props.mapFormItemProps));
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
exports.PopoverItem = PopoverItem;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PopoverItemProps } from "./BasePopoverItem.cjs";
|
|
2
|
+
import * as react4 from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/popover-item/ConnectedPopoverItem.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* PopoverItem decorator connected to Formily field state.
|
|
8
|
+
* Maps field label, description, and validation state onto the decorator the
|
|
9
|
+
* same way FormItem does.
|
|
10
|
+
*/
|
|
11
|
+
declare const PopoverItem: react4.ForwardRefExoticComponent<Omit<Partial<PopoverItemProps & {
|
|
12
|
+
children?: react4.ReactNode | undefined;
|
|
13
|
+
}>, "ref"> & react4.RefAttributes<unknown>>;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { PopoverItem };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PopoverItemProps } from "./BasePopoverItem.js";
|
|
2
|
+
import * as react0 from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/popover-item/ConnectedPopoverItem.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* PopoverItem decorator connected to Formily field state.
|
|
8
|
+
* Maps field label, description, and validation state onto the decorator the
|
|
9
|
+
* same way FormItem does.
|
|
10
|
+
*/
|
|
11
|
+
declare const PopoverItem: react0.ForwardRefExoticComponent<Omit<Partial<PopoverItemProps & {
|
|
12
|
+
children?: react0.ReactNode | undefined;
|
|
13
|
+
}>, "ref"> & react0.RefAttributes<unknown>>;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { PopoverItem };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { mapFormItemProps } from "../form-item/map-form-item-props.js";
|
|
2
|
+
import { BasePopoverItem } from "./BasePopoverItem.js";
|
|
3
|
+
import { connect, mapProps } from "@formily/react";
|
|
4
|
+
|
|
5
|
+
//#region src/components/popover-item/ConnectedPopoverItem.tsx
|
|
6
|
+
/**
|
|
7
|
+
* PopoverItem decorator connected to Formily field state.
|
|
8
|
+
* Maps field label, description, and validation state onto the decorator the
|
|
9
|
+
* same way FormItem does.
|
|
10
|
+
*/
|
|
11
|
+
const PopoverItem = connect(BasePopoverItem, mapProps(mapFormItemProps));
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { PopoverItem };
|