@xihan-ui/vue 3.0.0 → 3.2.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/CHANGELOG.md +148 -0
- package/README.md +1 -1
- package/dist/components/carousel/carousel.d.ts +7 -1
- package/dist/components/carousel/carousel.d.ts.map +1 -1
- package/dist/components/carousel/carousel.js +1 -0
- package/dist/components/carousel/carousel.js.map +1 -1
- package/dist/components/cartesian-chart/cartesian-chart.d.ts.map +1 -1
- package/dist/components/cartesian-chart/cartesian-chart.js +2 -2
- package/dist/components/cartesian-chart/cartesian-chart.js.map +1 -1
- package/dist/components/cascader/cascader.d.ts +2 -0
- package/dist/components/cascader/cascader.d.ts.map +1 -1
- package/dist/components/cascader/cascader.js +5 -2
- package/dist/components/cascader/cascader.js.map +1 -1
- package/dist/components/checkbox-group/checkbox-group.d.ts.map +1 -1
- package/dist/components/checkbox-group/checkbox-group.js +30 -11
- package/dist/components/checkbox-group/checkbox-group.js.map +1 -1
- package/dist/components/checkbox-group/use-checkbox-group.d.ts +6 -1
- package/dist/components/checkbox-group/use-checkbox-group.d.ts.map +1 -1
- package/dist/components/checkbox-group/use-checkbox-group.js +7 -3
- package/dist/components/checkbox-group/use-checkbox-group.js.map +1 -1
- package/dist/components/citation/citation.d.ts.map +1 -1
- package/dist/components/citation/citation.js +8 -6
- package/dist/components/citation/citation.js.map +1 -1
- package/dist/components/color-field/color-field.d.ts +2 -0
- package/dist/components/color-field/color-field.d.ts.map +1 -1
- package/dist/components/color-field/color-field.js +3 -1
- package/dist/components/color-field/color-field.js.map +1 -1
- package/dist/components/color-picker/color-picker.d.ts +76 -9
- package/dist/components/color-picker/color-picker.d.ts.map +1 -1
- package/dist/components/color-picker/color-picker.js +89 -7
- package/dist/components/color-picker/color-picker.js.map +1 -1
- package/dist/components/color-picker/context.js +10 -1
- package/dist/components/color-picker/context.js.map +1 -1
- package/dist/components/color-picker/use-color-picker.js +14 -4
- package/dist/components/color-picker/use-color-picker.js.map +1 -1
- package/dist/components/color-swatch-picker/color-swatch-picker.d.ts.map +1 -1
- package/dist/components/color-swatch-picker/color-swatch-picker.js +21 -4
- package/dist/components/color-swatch-picker/color-swatch-picker.js.map +1 -1
- package/dist/components/color-swatch-picker/use-color-swatch-picker.d.ts +6 -1
- package/dist/components/color-swatch-picker/use-color-swatch-picker.d.ts.map +1 -1
- package/dist/components/color-swatch-picker/use-color-swatch-picker.js +7 -3
- package/dist/components/color-swatch-picker/use-color-swatch-picker.js.map +1 -1
- package/dist/components/combobox/combobox.d.ts +2 -0
- package/dist/components/combobox/combobox.d.ts.map +1 -1
- package/dist/components/combobox/combobox.js +6 -4
- package/dist/components/combobox/combobox.js.map +1 -1
- package/dist/components/command/command.d.ts +3 -3
- package/dist/components/context-menu/context-menu.d.ts +9 -1
- package/dist/components/context-menu/context-menu.d.ts.map +1 -1
- package/dist/components/context-menu/context-menu.js +11 -1
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/date-field/date-field.d.ts +6 -2
- package/dist/components/date-field/date-field.d.ts.map +1 -1
- package/dist/components/date-field/date-field.js +5 -2
- package/dist/components/date-field/date-field.js.map +1 -1
- package/dist/components/date-picker/context.js +10 -1
- package/dist/components/date-picker/context.js.map +1 -1
- package/dist/components/date-picker/date-picker.d.ts +58 -3
- package/dist/components/date-picker/date-picker.d.ts.map +1 -1
- package/dist/components/date-picker/date-picker.js +77 -5
- package/dist/components/date-picker/date-picker.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.d.ts +27 -1
- package/dist/components/date-range-picker/date-range-picker.d.ts.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.js +10 -1
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/dialog/dialog.d.ts +12 -1
- package/dist/components/dialog/dialog.d.ts.map +1 -1
- package/dist/components/dialog/dialog.js +14 -4
- package/dist/components/dialog/dialog.js.map +1 -1
- package/dist/components/drawer/drawer.d.ts +12 -1
- package/dist/components/drawer/drawer.d.ts.map +1 -1
- package/dist/components/drawer/drawer.js +14 -4
- package/dist/components/drawer/drawer.js.map +1 -1
- package/dist/components/field/context.d.ts +6 -1
- package/dist/components/field/context.d.ts.map +1 -1
- package/dist/components/field/context.js +10 -1
- package/dist/components/field/context.js.map +1 -1
- package/dist/components/field/field.d.ts +9 -1
- package/dist/components/field/field.d.ts.map +1 -1
- package/dist/components/field/field.js +14 -2
- package/dist/components/field/field.js.map +1 -1
- package/dist/components/field/use-field-control.d.ts +8 -1
- package/dist/components/field/use-field-control.d.ts.map +1 -1
- package/dist/components/field/use-field-control.js +14 -1
- package/dist/components/field/use-field-control.js.map +1 -1
- package/dist/components/file-upload/file-upload.d.ts +2 -0
- package/dist/components/file-upload/file-upload.d.ts.map +1 -1
- package/dist/components/file-upload/file-upload.js +3 -1
- package/dist/components/file-upload/file-upload.js.map +1 -1
- package/dist/components/float-button/float-button.d.ts +26 -1
- package/dist/components/float-button/float-button.d.ts.map +1 -1
- package/dist/components/float-button/float-button.js +17 -5
- package/dist/components/float-button/float-button.js.map +1 -1
- package/dist/components/float-button/use-float-button.js +7 -1
- package/dist/components/float-button/use-float-button.js.map +1 -1
- package/dist/components/floating-panel/floating-panel.d.ts +2 -2
- package/dist/components/floating-panel/floating-panel.js +4 -1
- package/dist/components/floating-panel/floating-panel.js.map +1 -1
- package/dist/components/form/context.js +5 -1
- package/dist/components/form/context.js.map +1 -1
- package/dist/components/form/form.d.ts +8 -0
- package/dist/components/form/form.d.ts.map +1 -1
- package/dist/components/form/form.js +4 -1
- package/dist/components/form/form.js.map +1 -1
- package/dist/components/form/use-form-control.js +1 -1
- package/dist/components/funnel-chart/funnel-chart.d.ts.map +1 -1
- package/dist/components/funnel-chart/funnel-chart.js +2 -2
- package/dist/components/funnel-chart/funnel-chart.js.map +1 -1
- package/dist/components/graph-chart/graph-chart.d.ts.map +1 -1
- package/dist/components/graph-chart/graph-chart.js +2 -2
- package/dist/components/graph-chart/graph-chart.js.map +1 -1
- package/dist/components/hierarchy-chart/hierarchy-chart.d.ts.map +1 -1
- package/dist/components/hierarchy-chart/hierarchy-chart.js +2 -2
- package/dist/components/hierarchy-chart/hierarchy-chart.js.map +1 -1
- package/dist/components/hover-card/hover-card.js +2 -1
- package/dist/components/hover-card/hover-card.js.map +1 -1
- package/dist/components/image-viewer/image-viewer.d.ts +7 -1
- package/dist/components/image-viewer/image-viewer.d.ts.map +1 -1
- package/dist/components/image-viewer/image-viewer.js +1 -0
- package/dist/components/image-viewer/image-viewer.js.map +1 -1
- package/dist/components/mention/mention.d.ts +1 -1
- package/dist/components/mention/mention.js +5 -4
- package/dist/components/mention/mention.js.map +1 -1
- package/dist/components/menu/menu.js +31 -2
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/menubar/context.d.ts.map +1 -1
- package/dist/components/menubar/context.js.map +1 -1
- package/dist/components/menubar/menubar.d.ts +9 -1
- package/dist/components/menubar/menubar.d.ts.map +1 -1
- package/dist/components/menubar/menubar.js +29 -2
- package/dist/components/menubar/menubar.js.map +1 -1
- package/dist/components/pagination/pagination.js +4 -2
- package/dist/components/pagination/pagination.js.map +1 -1
- package/dist/components/pie-chart/pie-chart.d.ts.map +1 -1
- package/dist/components/pie-chart/pie-chart.js +2 -2
- package/dist/components/pie-chart/pie-chart.js.map +1 -1
- package/dist/components/pin-input/pin-input.d.ts.map +1 -1
- package/dist/components/pin-input/pin-input.js +7 -1
- package/dist/components/pin-input/pin-input.js.map +1 -1
- package/dist/components/popconfirm/popconfirm.d.ts +20 -1
- package/dist/components/popconfirm/popconfirm.d.ts.map +1 -1
- package/dist/components/popconfirm/popconfirm.js +9 -1
- package/dist/components/popconfirm/popconfirm.js.map +1 -1
- package/dist/components/popconfirm/use-popconfirm.js +2 -0
- package/dist/components/popconfirm/use-popconfirm.js.map +1 -1
- package/dist/components/popover/popover.d.ts +1 -1
- package/dist/components/popover/popover.js +2 -1
- package/dist/components/popover/popover.js.map +1 -1
- package/dist/components/radar-chart/radar-chart.d.ts.map +1 -1
- package/dist/components/radar-chart/radar-chart.js +2 -2
- package/dist/components/radar-chart/radar-chart.js.map +1 -1
- package/dist/components/radio-group/radio-group.d.ts.map +1 -1
- package/dist/components/radio-group/radio-group.js +25 -6
- package/dist/components/radio-group/radio-group.js.map +1 -1
- package/dist/components/radio-group/use-radio-group.d.ts +5 -0
- package/dist/components/radio-group/use-radio-group.d.ts.map +1 -1
- package/dist/components/radio-group/use-radio-group.js +4 -1
- package/dist/components/radio-group/use-radio-group.js.map +1 -1
- package/dist/components/rating/rating.d.ts.map +1 -1
- package/dist/components/rating/rating.js +7 -1
- package/dist/components/rating/rating.js.map +1 -1
- package/dist/components/sankey-chart/sankey-chart.d.ts.map +1 -1
- package/dist/components/sankey-chart/sankey-chart.js +2 -2
- package/dist/components/sankey-chart/sankey-chart.js.map +1 -1
- package/dist/components/select/select.d.ts +13 -0
- package/dist/components/select/select.d.ts.map +1 -1
- package/dist/components/select/select.js +15 -4
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/side-nav/side-nav.d.ts.map +1 -1
- package/dist/components/side-nav/side-nav.js +8 -2
- package/dist/components/side-nav/side-nav.js.map +1 -1
- package/dist/components/signature-pad/signature-pad.d.ts +2 -0
- package/dist/components/signature-pad/signature-pad.d.ts.map +1 -1
- package/dist/components/signature-pad/signature-pad.js +3 -1
- package/dist/components/signature-pad/signature-pad.js.map +1 -1
- package/dist/components/slider/slider.d.ts.map +1 -1
- package/dist/components/slider/slider.js +7 -1
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/tags-input/tags-input.d.ts +2 -0
- package/dist/components/tags-input/tags-input.d.ts.map +1 -1
- package/dist/components/tags-input/tags-input.js +3 -1
- package/dist/components/tags-input/tags-input.js.map +1 -1
- package/dist/components/text-field/text-field.d.ts +2 -0
- package/dist/components/text-field/text-field.d.ts.map +1 -1
- package/dist/components/text-field/text-field.js +3 -1
- package/dist/components/text-field/text-field.js.map +1 -1
- package/dist/components/time-field/time-field.d.ts +2 -0
- package/dist/components/time-field/time-field.d.ts.map +1 -1
- package/dist/components/time-field/time-field.js +3 -1
- package/dist/components/time-field/time-field.js.map +1 -1
- package/dist/components/time-picker/context.js +10 -1
- package/dist/components/time-picker/context.js.map +1 -1
- package/dist/components/time-picker/time-picker.d.ts +78 -9
- package/dist/components/time-picker/time-picker.d.ts.map +1 -1
- package/dist/components/time-picker/time-picker.js +91 -9
- package/dist/components/time-picker/time-picker.js.map +1 -1
- package/dist/components/time-range-picker/time-range-picker.d.ts +2 -0
- package/dist/components/time-range-picker/time-range-picker.d.ts.map +1 -1
- package/dist/components/time-range-picker/time-range-picker.js +5 -2
- package/dist/components/time-range-picker/time-range-picker.js.map +1 -1
- package/dist/components/toggle-group/toggle-group.d.ts.map +1 -1
- package/dist/components/toggle-group/toggle-group.js +7 -1
- package/dist/components/toggle-group/toggle-group.js.map +1 -1
- package/dist/components/tooltip/tooltip.js +2 -1
- package/dist/components/tooltip/tooltip.js.map +1 -1
- package/dist/components/tour/tour.js +12 -3
- package/dist/components/tour/tour.js.map +1 -1
- package/dist/components/tree/tree.d.ts +2 -2
- package/dist/components/tree/tree.js +1 -1
- package/dist/components/tree/tree.js.map +1 -1
- package/dist/components/tree-select/tree-select.d.ts +2 -0
- package/dist/components/tree-select/tree-select.d.ts.map +1 -1
- package/dist/components/tree-select/tree-select.js +6 -4
- package/dist/components/tree-select/tree-select.js.map +1 -1
- package/dist/components/truncate/truncate.d.ts.map +1 -1
- package/dist/components/truncate/truncate.js +4 -8
- package/dist/components/truncate/truncate.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +8 -8
- package/dist/locale.d.ts +2 -0
- package/dist/locale.js +2 -0
- package/dist/package.js +1 -1
- package/dist/runtime/as-child.js +7 -2
- package/dist/runtime/as-child.js.map +1 -1
- package/dist/runtime/portal.js +13 -1
- package/dist/runtime/portal.js.map +1 -1
- package/dist/runtime/use-overlay-exit.js +6 -1
- package/dist/runtime/use-overlay-exit.js.map +1 -1
- package/dist/runtime/with-handlers.js +25 -0
- package/dist/runtime/with-handlers.js.map +1 -0
- package/dist/services/dialog-service.d.ts +3 -3
- package/dist/services/dialog-service.d.ts.map +1 -1
- package/dist/services/dialog-service.js +8 -6
- package/dist/services/dialog-service.js.map +1 -1
- package/dist/services/service-config.js +2 -1
- package/dist/services/service-config.js.map +1 -1
- package/package.json +19 -15
|
@@ -48,6 +48,14 @@ declare const XhFieldRoot: import("vue").DefineComponent<import("vue").ExtractPr
|
|
|
48
48
|
disabled: boolean;
|
|
49
49
|
readOnly: boolean;
|
|
50
50
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
51
|
+
/**
|
|
52
|
+
* 字段边界:子树里的控件不再继承外层字段的标签、说明、状态与控件 id,表单字段组也一并断开。
|
|
53
|
+
* 组合控件把自己的内部输入(图标选择器里的搜索框、筛选框)包进来,它们就不会被读成外层字段的名字,
|
|
54
|
+
* 两个封装同处一个字段时也不会拿到同一个 id。本身不渲染节点;浮层内容经 Portal 搬走时已自动断开。
|
|
55
|
+
*/
|
|
56
|
+
declare const XhFieldBoundary: import("vue").DefineComponent<{}, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
57
|
+
[key: string]: any;
|
|
58
|
+
}>[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
51
59
|
declare const XhFieldLabel: import("vue").DefineComponent<{}, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
52
60
|
[key: string]: any;
|
|
53
61
|
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -91,5 +99,5 @@ declare const XhFieldErrorText: import("vue").DefineComponent<{}, () => VNode<im
|
|
|
91
99
|
[key: string]: any;
|
|
92
100
|
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
93
101
|
//#endregion
|
|
94
|
-
export { FieldControlSlotProps, XhFieldControl, XhFieldDescription, XhFieldErrorText, XhFieldLabel, XhFieldRoot };
|
|
102
|
+
export { FieldControlSlotProps, XhFieldBoundary, XhFieldControl, XhFieldDescription, XhFieldErrorText, XhFieldLabel, XhFieldRoot };
|
|
95
103
|
//# sourceMappingURL=field.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.d.ts","names":[],"sources":["../../../src/components/field/field.ts"],"mappings":";;cAea,2BAAW,8BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAgBtB;cAEW,4BAAY,0BAAA,oBAAA,4BAAA;;8BAMvB,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;KAGU,wBAAwB;cAiBvB,8BAAc,8BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYb,WAAC,OAAO,0BAA0B;kCAc9C;cAEW,kCAAkB,0BAAA,oBAAA,4BAAA;;8BAM7B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,gCAAgB,0BAAA,oBAAA,4BAAA;;8BAe3B,qCAAA,iDAAA,aAAA,eAAA,oDAAA"}
|
|
1
|
+
{"version":3,"file":"field.d.ts","names":[],"sources":["../../../src/components/field/field.ts"],"mappings":";;cAea,2BAAW,8BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAgBtB;;;;;;cAOW,+BAAe,0BAAA,oBAAA,4BAAA;;4CAM1B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,4BAAY,0BAAA,oBAAA,4BAAA;;8BAMvB,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;KAGU,wBAAwB;cAiBvB,8BAAc,8BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYb,WAAC,OAAO,0BAA0B;kCAc9C;cAEW,kCAAkB,0BAAA,oBAAA,4BAAA;;8BAM7B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,gCAAgB,0BAAA,oBAAA,4BAAA;;8BAe3B,qCAAA,iDAAA,aAAA,eAAA,oDAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isRoleMarker, mergeIntoChild } from "../../runtime/as-child.js";
|
|
2
|
-
import { provideField, useFieldContext } from "./context.js";
|
|
3
2
|
import { useOptionalFormContext, useOptionalFormField } from "../form/context.js";
|
|
3
|
+
import { clearFieldContext, provideField, useFieldContext } from "./context.js";
|
|
4
4
|
import { useFormControlProps } from "../form/use-form-control.js";
|
|
5
5
|
import { useField } from "./use-field.js";
|
|
6
6
|
import { defineComponent, h } from "vue";
|
|
@@ -32,6 +32,18 @@ const XhFieldRoot = defineComponent({
|
|
|
32
32
|
return () => h("div", ctx.api.value.getRootProps(), slots.default?.());
|
|
33
33
|
}
|
|
34
34
|
});
|
|
35
|
+
/**
|
|
36
|
+
* 字段边界:子树里的控件不再继承外层字段的标签、说明、状态与控件 id,表单字段组也一并断开。
|
|
37
|
+
* 组合控件把自己的内部输入(图标选择器里的搜索框、筛选框)包进来,它们就不会被读成外层字段的名字,
|
|
38
|
+
* 两个封装同处一个字段时也不会拿到同一个 id。本身不渲染节点;浮层内容经 Portal 搬走时已自动断开。
|
|
39
|
+
*/
|
|
40
|
+
const XhFieldBoundary = defineComponent({
|
|
41
|
+
name: "XhFieldBoundary",
|
|
42
|
+
setup(_, { slots }) {
|
|
43
|
+
clearFieldContext();
|
|
44
|
+
return () => slots.default?.();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
35
47
|
const XhFieldLabel = defineComponent({
|
|
36
48
|
name: "XhFieldLabel",
|
|
37
49
|
setup(_, { slots }) {
|
|
@@ -95,6 +107,6 @@ const XhFieldErrorText = defineComponent({
|
|
|
95
107
|
}
|
|
96
108
|
});
|
|
97
109
|
//#endregion
|
|
98
|
-
export { XhFieldControl, XhFieldDescription, XhFieldErrorText, XhFieldLabel, XhFieldRoot, wiringOnly };
|
|
110
|
+
export { XhFieldBoundary, XhFieldControl, XhFieldDescription, XhFieldErrorText, XhFieldLabel, XhFieldRoot, wiringOnly };
|
|
99
111
|
|
|
100
112
|
//# sourceMappingURL=field.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.js","names":[],"sources":["../../../src/components/field/field.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 field 相关实现。\n\nimport type { SlotsType, VNode } from 'vue'\nimport { defineComponent, h } from 'vue'\nimport { isRoleMarker, mergeIntoChild } from '../../runtime/as-child'\nimport { useOptionalFormContext, useOptionalFormField } from '../form/context'\nimport { useFormControlProps } from '../form/use-form-control'\nimport { provideField, useFieldContext } from './context'\nimport { useField } from './use-field'\n\nexport const XhFieldRoot = defineComponent({\n name: 'XhFieldRoot',\n // 三个布尔缺省 undefined:在 XhFormFieldGroup 里没写就从表单上下文自取,写了以写的为准\n props: {\n invalid: { type: Boolean, default: undefined },\n required: { type: Boolean, default: undefined },\n disabled: { type: Boolean, default: undefined },\n readOnly: { type: Boolean, default: undefined },\n // 控件节点的 id,不占用根节点自己的 DOM id\n controlId: { type: String },\n },\n setup(props, { slots }) {\n const ctx = useField(useFormControlProps(props))\n provideField(ctx)\n return () => h('div', ctx.api.value.getRootProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFieldLabel = defineComponent({\n name: 'XhFieldLabel',\n setup(_, { slots }) {\n const ctx = useFieldContext()\n return () => h('label', ctx.api.value.getLabelProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 默认插槽的载荷:控件节点应挂载的那组属性,作者把它交给自己渲染的控件。 */\nexport type FieldControlSlotProps = Record<string, unknown>\n\n/**\n * 去掉角色标记,只保留接线属性(id、aria-* 与状态位)。\n *\n * 角色标记含解剖两位与家族标记(data-xh-*):control 投影了 Field Chrome 的视觉盒标记,\n * 落到薄封装的根上会在封装自己的视觉盒外再画一层壳。\n */\nexport function wiringOnly(controlProps: Record<string, unknown>): Record<string, unknown> {\n const rest: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(controlProps)) {\n if (!isRoleMarker(key))\n rest[key] = value\n }\n return rest\n}\n\nexport const XhFieldControl = defineComponent({\n name: 'XhFieldControl',\n props: {\n /**\n * 把接线属性合并到唯一的子节点上,默认开启。\n *\n * 子节点是薄封装(根不是可聚焦元素)时关闭它:属性只经插槽载荷交出,\n * 由封装内部调用 useFieldControl 绑定到真实控件上。\n */\n asChild: { type: Boolean, default: true },\n },\n slots: Object as SlotsType<{\n default?: (props: FieldControlSlotProps) => VNode[]\n }>,\n setup(props, { slots }) {\n const ctx = useFieldContext()\n return () => {\n const controlProps = ctx.api.value.getControlProps() as Record<string, unknown>\n // control props 经 slot props 交给作者,控件节点由作者渲染\n const children = slots.default?.(controlProps) ?? []\n // 手工接线必须显式关闭 asChild,不能根据无效结构猜测作者意图。\n if (!props.asChild)\n return children\n return mergeIntoChild(children, controlProps, 'field/control')\n }\n },\n})\n\nexport const XhFieldDescription = defineComponent({\n name: 'XhFieldDescription',\n setup(_, { slots }) {\n const ctx = useFieldContext()\n return () => h('p', ctx.api.value.getDescriptionProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFieldErrorText = defineComponent({\n name: 'XhFieldErrorText',\n setup(_, { slots }) {\n const ctx = useFieldContext()\n const form = useOptionalFormContext()\n const handle = useOptionalFormField()\n // 节点常挂,靠 hidden 显隐;插槽没给内容时在表单里自取该字段的错误文案\n return () => {\n const kids = slots.default?.()\n const auto = (!kids || kids.length === 0) && form && handle\n ? form.api.value.getFieldError(handle.name())\n : undefined\n return h('p', ctx.api.value.getErrorTextProps() as Record<string, unknown>, kids?.length ? kids : auto)\n }\n },\n})\n"],"mappings":";;;;;;;AAeA,MAAa,cAAc,gBAAgB;CACzC,MAAM;CAEN,OAAO;EACL,SAAS;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAC7C,UAAU;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAC9C,UAAU;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAC9C,UAAU;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAE9C,WAAW,EAAE,MAAM,OAAO;CAC5B;CACA,MAAM,OAAO,EAAE,SAAS;EACtB,MAAM,MAAM,SAAS,oBAAoB,KAAK,CAAC;EAC/C,aAAa,GAAG;EAChB,aAAa,EAAE,OAAO,IAAI,IAAI,MAAM,aAAa,GAA8B,MAAM,UAAU,CAAC;CAClG;AACF,CAAC;AAED,MAAa,eAAe,gBAAgB;CAC1C,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,gBAAgB;EAC5B,aAAa,EAAE,SAAS,IAAI,IAAI,MAAM,cAAc,GAA8B,MAAM,UAAU,CAAC;CACrG;AACF,CAAC;;;;;;;AAWD,SAAgB,WAAW,cAAgE;CACzF,MAAM,OAAgC,CAAC;CACvC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,YAAY,GACpD,IAAI,CAAC,aAAa,GAAG,GACnB,KAAK,OAAO;CAEhB,OAAO;AACT;AAEA,MAAa,iBAAiB,gBAAgB;CAC5C,MAAM;CACN,OAAO;;;;;;;AAOL,SAAS;EAAE,MAAM;EAAS,SAAS;CAAK,EAC1C;CACA,OAAO;CAGP,MAAM,OAAO,EAAE,SAAS;EACtB,MAAM,MAAM,gBAAgB;EAC5B,aAAa;GACX,MAAM,eAAe,IAAI,IAAI,MAAM,gBAAgB;GAEnD,MAAM,WAAW,MAAM,UAAU,YAAY,KAAK,CAAC;GAEnD,IAAI,CAAC,MAAM,SACT,OAAO;GACT,OAAO,eAAe,UAAU,cAAc,eAAe;EAC/D;CACF;AACF,CAAC;AAED,MAAa,qBAAqB,gBAAgB;CAChD,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,gBAAgB;EAC5B,aAAa,EAAE,KAAK,IAAI,IAAI,MAAM,oBAAoB,GAA8B,MAAM,UAAU,CAAC;CACvG;AACF,CAAC;AAED,MAAa,mBAAmB,gBAAgB;CAC9C,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,gBAAgB;EAC5B,MAAM,OAAO,uBAAuB;EACpC,MAAM,SAAS,qBAAqB;EAEpC,aAAa;GACX,MAAM,OAAO,MAAM,UAAU;GAC7B,MAAM,QAAQ,CAAC,QAAQ,KAAK,WAAW,MAAM,QAAQ,SACjD,KAAK,IAAI,MAAM,cAAc,OAAO,KAAK,CAAC,IAC1C,KAAA;GACJ,OAAO,EAAE,KAAK,IAAI,IAAI,MAAM,kBAAkB,GAA8B,MAAM,SAAS,OAAO,IAAI;EACxG;CACF;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"field.js","names":[],"sources":["../../../src/components/field/field.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 field 相关实现。\n\nimport type { SlotsType, VNode } from 'vue'\nimport { defineComponent, h } from 'vue'\nimport { isRoleMarker, mergeIntoChild } from '../../runtime/as-child'\nimport { useOptionalFormContext, useOptionalFormField } from '../form/context'\nimport { useFormControlProps } from '../form/use-form-control'\nimport { clearFieldContext, provideField, useFieldContext } from './context'\nimport { useField } from './use-field'\n\nexport const XhFieldRoot = defineComponent({\n name: 'XhFieldRoot',\n // 三个布尔缺省 undefined:在 XhFormFieldGroup 里没写就从表单上下文自取,写了以写的为准\n props: {\n invalid: { type: Boolean, default: undefined },\n required: { type: Boolean, default: undefined },\n disabled: { type: Boolean, default: undefined },\n readOnly: { type: Boolean, default: undefined },\n // 控件节点的 id,不占用根节点自己的 DOM id\n controlId: { type: String },\n },\n setup(props, { slots }) {\n const ctx = useField(useFormControlProps(props))\n provideField(ctx)\n return () => h('div', ctx.api.value.getRootProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/**\n * 字段边界:子树里的控件不再继承外层字段的标签、说明、状态与控件 id,表单字段组也一并断开。\n * 组合控件把自己的内部输入(图标选择器里的搜索框、筛选框)包进来,它们就不会被读成外层字段的名字,\n * 两个封装同处一个字段时也不会拿到同一个 id。本身不渲染节点;浮层内容经 Portal 搬走时已自动断开。\n */\nexport const XhFieldBoundary = defineComponent({\n name: 'XhFieldBoundary',\n setup(_, { slots }) {\n clearFieldContext()\n return () => slots.default?.()\n },\n})\n\nexport const XhFieldLabel = defineComponent({\n name: 'XhFieldLabel',\n setup(_, { slots }) {\n const ctx = useFieldContext()\n return () => h('label', ctx.api.value.getLabelProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 默认插槽的载荷:控件节点应挂载的那组属性,作者把它交给自己渲染的控件。 */\nexport type FieldControlSlotProps = Record<string, unknown>\n\n/**\n * 去掉角色标记,只保留接线属性(id、aria-* 与状态位)。\n *\n * 角色标记含解剖两位与家族标记(data-xh-*):control 投影了 Field Chrome 的视觉盒标记,\n * 落到薄封装的根上会在封装自己的视觉盒外再画一层壳。\n */\nexport function wiringOnly(controlProps: Record<string, unknown>): Record<string, unknown> {\n const rest: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(controlProps)) {\n if (!isRoleMarker(key))\n rest[key] = value\n }\n return rest\n}\n\nexport const XhFieldControl = defineComponent({\n name: 'XhFieldControl',\n props: {\n /**\n * 把接线属性合并到唯一的子节点上,默认开启。\n *\n * 子节点是薄封装(根不是可聚焦元素)时关闭它:属性只经插槽载荷交出,\n * 由封装内部调用 useFieldControl 绑定到真实控件上。\n */\n asChild: { type: Boolean, default: true },\n },\n slots: Object as SlotsType<{\n default?: (props: FieldControlSlotProps) => VNode[]\n }>,\n setup(props, { slots }) {\n const ctx = useFieldContext()\n return () => {\n const controlProps = ctx.api.value.getControlProps() as Record<string, unknown>\n // control props 经 slot props 交给作者,控件节点由作者渲染\n const children = slots.default?.(controlProps) ?? []\n // 手工接线必须显式关闭 asChild,不能根据无效结构猜测作者意图。\n if (!props.asChild)\n return children\n return mergeIntoChild(children, controlProps, 'field/control')\n }\n },\n})\n\nexport const XhFieldDescription = defineComponent({\n name: 'XhFieldDescription',\n setup(_, { slots }) {\n const ctx = useFieldContext()\n return () => h('p', ctx.api.value.getDescriptionProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFieldErrorText = defineComponent({\n name: 'XhFieldErrorText',\n setup(_, { slots }) {\n const ctx = useFieldContext()\n const form = useOptionalFormContext()\n const handle = useOptionalFormField()\n // 节点常挂,靠 hidden 显隐;插槽没给内容时在表单里自取该字段的错误文案\n return () => {\n const kids = slots.default?.()\n const auto = (!kids || kids.length === 0) && form && handle\n ? form.api.value.getFieldError(handle.name())\n : undefined\n return h('p', ctx.api.value.getErrorTextProps() as Record<string, unknown>, kids?.length ? kids : auto)\n }\n },\n})\n"],"mappings":";;;;;;;AAeA,MAAa,cAAc,gBAAgB;CACzC,MAAM;CAEN,OAAO;EACL,SAAS;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAC7C,UAAU;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAC9C,UAAU;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAC9C,UAAU;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAE9C,WAAW,EAAE,MAAM,OAAO;CAC5B;CACA,MAAM,OAAO,EAAE,SAAS;EACtB,MAAM,MAAM,SAAS,oBAAoB,KAAK,CAAC;EAC/C,aAAa,GAAG;EAChB,aAAa,EAAE,OAAO,IAAI,IAAI,MAAM,aAAa,GAA8B,MAAM,UAAU,CAAC;CAClG;AACF,CAAC;;;;;;AAOD,MAAa,kBAAkB,gBAAgB;CAC7C,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,kBAAkB;EAClB,aAAa,MAAM,UAAU;CAC/B;AACF,CAAC;AAED,MAAa,eAAe,gBAAgB;CAC1C,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,gBAAgB;EAC5B,aAAa,EAAE,SAAS,IAAI,IAAI,MAAM,cAAc,GAA8B,MAAM,UAAU,CAAC;CACrG;AACF,CAAC;;;;;;;AAWD,SAAgB,WAAW,cAAgE;CACzF,MAAM,OAAgC,CAAC;CACvC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,YAAY,GACpD,IAAI,CAAC,aAAa,GAAG,GACnB,KAAK,OAAO;CAEhB,OAAO;AACT;AAEA,MAAa,iBAAiB,gBAAgB;CAC5C,MAAM;CACN,OAAO;;;;;;;AAOL,SAAS;EAAE,MAAM;EAAS,SAAS;CAAK,EAC1C;CACA,OAAO;CAGP,MAAM,OAAO,EAAE,SAAS;EACtB,MAAM,MAAM,gBAAgB;EAC5B,aAAa;GACX,MAAM,eAAe,IAAI,IAAI,MAAM,gBAAgB;GAEnD,MAAM,WAAW,MAAM,UAAU,YAAY,KAAK,CAAC;GAEnD,IAAI,CAAC,MAAM,SACT,OAAO;GACT,OAAO,eAAe,UAAU,cAAc,eAAe;EAC/D;CACF;AACF,CAAC;AAED,MAAa,qBAAqB,gBAAgB;CAChD,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,gBAAgB;EAC5B,aAAa,EAAE,KAAK,IAAI,IAAI,MAAM,oBAAoB,GAA8B,MAAM,UAAU,CAAC;CACvG;AACF,CAAC;AAED,MAAa,mBAAmB,gBAAgB;CAC9C,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,gBAAgB;EAC5B,MAAM,OAAO,uBAAuB;EACpC,MAAM,SAAS,qBAAqB;EAEpC,aAAa;GACX,MAAM,OAAO,MAAM,UAAU;GAC7B,MAAM,QAAQ,CAAC,QAAQ,KAAK,WAAW,MAAM,QAAQ,SACjD,KAAK,IAAI,MAAM,cAAc,OAAO,KAAK,CAAC,IAC1C,KAAA;GACJ,OAAO,EAAE,KAAK,IAAI,IAAI,MAAM,kBAAkB,GAA8B,MAAM,SAAS,OAAO,IAAI;EACxG;CACF;AACF,CAAC"}
|
|
@@ -24,6 +24,13 @@ declare function useFieldControl(): ComputedRef<Record<string, unknown>>;
|
|
|
24
24
|
* 该路径整套属性都落到真实控件上。
|
|
25
25
|
*/
|
|
26
26
|
declare function useFieldStateWiring(): ComputedRef<Record<string, unknown>>;
|
|
27
|
+
/**
|
|
28
|
+
* 组类控件(单选组、复选框组、滑块、评分、分格输入……)只取字段的描述链。
|
|
29
|
+
*
|
|
30
|
+
* 焦点宿主是组根、拇指或格子,名字由 useFieldLabelWiring 并入;校验、必填与只读由组件按字段状态
|
|
31
|
+
* 自己投影(role=group 不接受 aria-invalid / aria-required,组件的 connect 也只在支持它们的角色上发)。
|
|
32
|
+
*/
|
|
33
|
+
declare function useFieldGroupWiring(): ComputedRef<Record<string, unknown>>;
|
|
27
34
|
/**
|
|
28
35
|
* 把字段标签的 id 并入该份属性中的名字链,供库自身的薄封装包在渲染属性外面。
|
|
29
36
|
*
|
|
@@ -37,5 +44,5 @@ declare function useFieldStateWiring(): ComputedRef<Record<string, unknown>>;
|
|
|
37
44
|
*/
|
|
38
45
|
declare function useFieldLabelWiring(): ComputedRef<(props: Record<string, unknown>) => Record<string, unknown>>;
|
|
39
46
|
//#endregion
|
|
40
|
-
export { useFieldControl, useFieldLabelWiring, useFieldStateWiring };
|
|
47
|
+
export { useFieldControl, useFieldGroupWiring, useFieldLabelWiring, useFieldStateWiring };
|
|
41
48
|
//# sourceMappingURL=use-field-control.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-field-control.d.ts","names":[],"sources":["../../../src/components/field/use-field-control.ts"],"mappings":";;;;;;;;;;;;iBAsBgB,mBAAmB,YAAY;;;;;;;;;;;;;iBAqB/B,uBAAuB,YAAY;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"use-field-control.d.ts","names":[],"sources":["../../../src/components/field/use-field-control.ts"],"mappings":";;;;;;;;;;;;iBAsBgB,mBAAmB,YAAY;;;;;;;;;;;;;iBAqB/B,uBAAuB,YAAY;;;;;;;iBAqBnC,uBAAuB,YAAY;;;;;;;;;;;;iBAmBnC,uBAAuB,aAAa,OAAO,4BAA4B"}
|
|
@@ -47,6 +47,19 @@ function useFieldStateWiring() {
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
|
+
* 组类控件(单选组、复选框组、滑块、评分、分格输入……)只取字段的描述链。
|
|
51
|
+
*
|
|
52
|
+
* 焦点宿主是组根、拇指或格子,名字由 useFieldLabelWiring 并入;校验、必填与只读由组件按字段状态
|
|
53
|
+
* 自己投影(role=group 不接受 aria-invalid / aria-required,组件的 connect 也只在支持它们的角色上发)。
|
|
54
|
+
*/
|
|
55
|
+
function useFieldGroupWiring() {
|
|
56
|
+
const ctx = useOptionalFieldContext();
|
|
57
|
+
return computed(() => {
|
|
58
|
+
const describedBy = ctx ? ctx.api.value.getControlProps()["aria-describedby"] : void 0;
|
|
59
|
+
return describedBy === void 0 ? {} : { "aria-describedby": describedBy };
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
50
63
|
* 把字段标签的 id 并入该份属性中的名字链,供库自身的薄封装包在渲染属性外面。
|
|
51
64
|
*
|
|
52
65
|
* 复合控件的可聚焦部件自带 aria-labelledby,指向它自己的 label 部件。放入字段时
|
|
@@ -72,6 +85,6 @@ function useFieldLabelWiring() {
|
|
|
72
85
|
});
|
|
73
86
|
}
|
|
74
87
|
//#endregion
|
|
75
|
-
export { useFieldControl, useFieldLabelWiring, useFieldStateWiring };
|
|
88
|
+
export { useFieldControl, useFieldGroupWiring, useFieldLabelWiring, useFieldStateWiring };
|
|
76
89
|
|
|
77
90
|
//# sourceMappingURL=use-field-control.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-field-control.js","names":[],"sources":["../../../src/components/field/use-field-control.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 use field control 相关实现。\n\nimport type { ComputedRef } from 'vue'\nimport { computed } from 'vue'\nimport { useOptionalFieldContext } from './context'\nimport { wiringOnly } from './field'\n\n/**\n * 在薄封装内部取字段的控件接线属性(id 与 aria-*),把它们绑定到真正可聚焦的节点上。\n *\n * XhFieldControl 默认把属性合并到它唯一的子节点上,而子节点是组件时合并的是组件根:\n * 封装的根往往是一个 div,label 的 for 指向它时无法聚焦(for 只对可标注元素生效),\n * 且这种失效不报错。封装内部调用一次本组合式,接线就落在应落的节点上。\n *\n * 外层要写 `<XhFieldControl :as-child=\"false\">`,否则属性会被合并两遍。\n * 不在字段内时返回空对象,封装仍可单独使用。\n */\nexport function useFieldControl(): ComputedRef<Record<string, unknown>> {\n const ctx = useOptionalFieldContext()\n return computed(() => {\n if (!ctx)\n return {}\n return wiringOnly(ctx.api.value.getControlProps() as Record<string, unknown>)\n })\n}\n\n/**\n * 只取字段的状态接线(说明、校验、只读),不含 id 与名字。\n *\n * 供库自身的薄封装使用:XhFieldControl 默认把整套属性合并到封装根上,id 与\n * aria-labelledby 落在那里是正确的(label 的 for 必须指向一个真实节点);但\n * aria-describedby 与 aria-invalid 落在根上等于未落:焦点进入的是内部的\n * input / button,读屏只朗读焦点所在节点的描述,说明与错误文本因此无法播报。\n * 封装把这几条补到真实控件上,两边不冲突:id 只有一份,描述有两份不影响播报。\n *\n * 作者自行编写封装时使用上面的 useFieldControl(配合 `:as-child=\"false\"`),\n * 该路径整套属性都落到真实控件上。\n */\nexport function useFieldStateWiring(): ComputedRef<Record<string, unknown>> {\n const ctx = useOptionalFieldContext()\n return computed(() => {\n if (!ctx)\n return {}\n const control = ctx.api.value.getControlProps() as Record<string, unknown>\n const wiring: Record<string, unknown> = {}\n for (const key of ['aria-describedby', 'aria-invalid', 'aria-required', 'aria-readonly']) {\n if (control[key] !== undefined)\n wiring[key] = control[key]\n }\n return wiring\n })\n}\n\n/**\n * 把字段标签的 id 并入该份属性中的名字链,供库自身的薄封装包在渲染属性外面。\n *\n * 复合控件的可聚焦部件自带 aria-labelledby,指向它自己的 label 部件。放入字段时\n * 作者使用的是字段的标签、组件的 label 部件并未渲染,该引用于是指向一个不存在的\n * 节点:按 accname 规则悬空 IDREF 直接跳过,而名字也无法回退到 label 的 for:for 指向的\n * 是封装根的 div,只对可标注元素生效。结果是焦点所在的控件没有任何名字。\n *\n * 字段的标签排在最前,控件自己的部分(值文本等)跟在后面,两边都可朗读。\n * 不在字段内时属性原样返回。\n */\nexport function useFieldLabelWiring(): ComputedRef<(props: Record<string, unknown>) => Record<string, unknown>> {\n const ctx = useOptionalFieldContext()\n return computed(() => {\n const labelId = ctx?.api.value.labelId\n return (props: Record<string, unknown>) => {\n if (!labelId)\n return props\n const own = props['aria-labelledby']\n return {\n ...props,\n 'aria-labelledby': typeof own === 'string' && own ? `${labelId} ${own}` : labelId,\n }\n }\n })\n}\n"],"mappings":";;;;;;;;;;;;;;AAsBA,SAAgB,kBAAwD;CACtE,MAAM,MAAM,wBAAwB;CACpC,OAAO,eAAe;EACpB,IAAI,CAAC,KACH,OAAO,CAAC;EACV,OAAO,WAAW,IAAI,IAAI,MAAM,gBAAgB,CAA4B;CAC9E,CAAC;AACH;;;;;;;;;;;;;AAcA,SAAgB,sBAA4D;CAC1E,MAAM,MAAM,wBAAwB;CACpC,OAAO,eAAe;EACpB,IAAI,CAAC,KACH,OAAO,CAAC;EACV,MAAM,UAAU,IAAI,IAAI,MAAM,gBAAgB;EAC9C,MAAM,SAAkC,CAAC;EACzC,KAAK,MAAM,OAAO;GAAC;GAAoB;GAAgB;GAAiB;EAAe,GACrF,IAAI,QAAQ,SAAS,KAAA,GACnB,OAAO,OAAO,QAAQ;EAE1B,OAAO;CACT,CAAC;AACH;;;;;;;;;;;;AAaA,SAAgB,sBAAgG;CAC9G,MAAM,MAAM,wBAAwB;CACpC,OAAO,eAAe;EACpB,MAAM,UAAU,KAAK,IAAI,MAAM;EAC/B,QAAQ,UAAmC;GACzC,IAAI,CAAC,SACH,OAAO;GACT,MAAM,MAAM,MAAM;GAClB,OAAO;IACL,GAAG;IACH,mBAAmB,OAAO,QAAQ,YAAY,MAAM,GAAG,QAAQ,GAAG,QAAQ;GAC5E;EACF;CACF,CAAC;AACH"}
|
|
1
|
+
{"version":3,"file":"use-field-control.js","names":[],"sources":["../../../src/components/field/use-field-control.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 use field control 相关实现。\n\nimport type { ComputedRef } from 'vue'\nimport { computed } from 'vue'\nimport { useOptionalFieldContext } from './context'\nimport { wiringOnly } from './field'\n\n/**\n * 在薄封装内部取字段的控件接线属性(id 与 aria-*),把它们绑定到真正可聚焦的节点上。\n *\n * XhFieldControl 默认把属性合并到它唯一的子节点上,而子节点是组件时合并的是组件根:\n * 封装的根往往是一个 div,label 的 for 指向它时无法聚焦(for 只对可标注元素生效),\n * 且这种失效不报错。封装内部调用一次本组合式,接线就落在应落的节点上。\n *\n * 外层要写 `<XhFieldControl :as-child=\"false\">`,否则属性会被合并两遍。\n * 不在字段内时返回空对象,封装仍可单独使用。\n */\nexport function useFieldControl(): ComputedRef<Record<string, unknown>> {\n const ctx = useOptionalFieldContext()\n return computed(() => {\n if (!ctx)\n return {}\n return wiringOnly(ctx.api.value.getControlProps() as Record<string, unknown>)\n })\n}\n\n/**\n * 只取字段的状态接线(说明、校验、只读),不含 id 与名字。\n *\n * 供库自身的薄封装使用:XhFieldControl 默认把整套属性合并到封装根上,id 与\n * aria-labelledby 落在那里是正确的(label 的 for 必须指向一个真实节点);但\n * aria-describedby 与 aria-invalid 落在根上等于未落:焦点进入的是内部的\n * input / button,读屏只朗读焦点所在节点的描述,说明与错误文本因此无法播报。\n * 封装把这几条补到真实控件上,两边不冲突:id 只有一份,描述有两份不影响播报。\n *\n * 作者自行编写封装时使用上面的 useFieldControl(配合 `:as-child=\"false\"`),\n * 该路径整套属性都落到真实控件上。\n */\nexport function useFieldStateWiring(): ComputedRef<Record<string, unknown>> {\n const ctx = useOptionalFieldContext()\n return computed(() => {\n if (!ctx)\n return {}\n const control = ctx.api.value.getControlProps() as Record<string, unknown>\n const wiring: Record<string, unknown> = {}\n for (const key of ['aria-describedby', 'aria-invalid', 'aria-required', 'aria-readonly']) {\n if (control[key] !== undefined)\n wiring[key] = control[key]\n }\n return wiring\n })\n}\n\n/**\n * 组类控件(单选组、复选框组、滑块、评分、分格输入……)只取字段的描述链。\n *\n * 焦点宿主是组根、拇指或格子,名字由 useFieldLabelWiring 并入;校验、必填与只读由组件按字段状态\n * 自己投影(role=group 不接受 aria-invalid / aria-required,组件的 connect 也只在支持它们的角色上发)。\n */\nexport function useFieldGroupWiring(): ComputedRef<Record<string, unknown>> {\n const ctx = useOptionalFieldContext()\n return computed(() => {\n const describedBy = ctx ? (ctx.api.value.getControlProps() as Record<string, unknown>)['aria-describedby'] : undefined\n return describedBy === undefined ? {} : { 'aria-describedby': describedBy }\n })\n}\n\n/**\n * 把字段标签的 id 并入该份属性中的名字链,供库自身的薄封装包在渲染属性外面。\n *\n * 复合控件的可聚焦部件自带 aria-labelledby,指向它自己的 label 部件。放入字段时\n * 作者使用的是字段的标签、组件的 label 部件并未渲染,该引用于是指向一个不存在的\n * 节点:按 accname 规则悬空 IDREF 直接跳过,而名字也无法回退到 label 的 for:for 指向的\n * 是封装根的 div,只对可标注元素生效。结果是焦点所在的控件没有任何名字。\n *\n * 字段的标签排在最前,控件自己的部分(值文本等)跟在后面,两边都可朗读。\n * 不在字段内时属性原样返回。\n */\nexport function useFieldLabelWiring(): ComputedRef<(props: Record<string, unknown>) => Record<string, unknown>> {\n const ctx = useOptionalFieldContext()\n return computed(() => {\n const labelId = ctx?.api.value.labelId\n return (props: Record<string, unknown>) => {\n if (!labelId)\n return props\n const own = props['aria-labelledby']\n return {\n ...props,\n 'aria-labelledby': typeof own === 'string' && own ? `${labelId} ${own}` : labelId,\n }\n }\n })\n}\n"],"mappings":";;;;;;;;;;;;;;AAsBA,SAAgB,kBAAwD;CACtE,MAAM,MAAM,wBAAwB;CACpC,OAAO,eAAe;EACpB,IAAI,CAAC,KACH,OAAO,CAAC;EACV,OAAO,WAAW,IAAI,IAAI,MAAM,gBAAgB,CAA4B;CAC9E,CAAC;AACH;;;;;;;;;;;;;AAcA,SAAgB,sBAA4D;CAC1E,MAAM,MAAM,wBAAwB;CACpC,OAAO,eAAe;EACpB,IAAI,CAAC,KACH,OAAO,CAAC;EACV,MAAM,UAAU,IAAI,IAAI,MAAM,gBAAgB;EAC9C,MAAM,SAAkC,CAAC;EACzC,KAAK,MAAM,OAAO;GAAC;GAAoB;GAAgB;GAAiB;EAAe,GACrF,IAAI,QAAQ,SAAS,KAAA,GACnB,OAAO,OAAO,QAAQ;EAE1B,OAAO;CACT,CAAC;AACH;;;;;;;AAQA,SAAgB,sBAA4D;CAC1E,MAAM,MAAM,wBAAwB;CACpC,OAAO,eAAe;EACpB,MAAM,cAAc,MAAO,IAAI,IAAI,MAAM,gBAAgB,CAAC,CAA6B,sBAAsB,KAAA;EAC7G,OAAO,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,oBAAoB,YAAY;CAC5E,CAAC;AACH;;;;;;;;;;;;AAaA,SAAgB,sBAAgG;CAC9G,MAAM,MAAM,wBAAwB;CACpC,OAAO,eAAe;EACpB,MAAM,UAAU,KAAK,IAAI,MAAM;EAC/B,QAAQ,UAAmC;GACzC,IAAI,CAAC,SACH,OAAO;GACT,MAAM,MAAM,MAAM;GAClB,OAAO;IACL,GAAG;IACH,mBAAmB,OAAO,QAAQ,YAAY,MAAM,GAAG,QAAQ,GAAG,QAAQ;GAC5E;EACF;CACF,CAAC;AACH"}
|
|
@@ -72,6 +72,7 @@ declare const XhFileUploadRoot: import("vue").DefineComponent<import("vue").Extr
|
|
|
72
72
|
}>, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
73
73
|
[key: string]: any;
|
|
74
74
|
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
75
|
+
clear: () => true;
|
|
75
76
|
'files-change': (_details: PayloadOf<FileUploadProps, "onFilesChange">) => true;
|
|
76
77
|
'update:files': (_files: PayloadOf<FileUploadProps, "onFilesChange">["files"]) => true;
|
|
77
78
|
'file-accept': (_details: PayloadOf<FileUploadProps, "onFileAccept">) => true;
|
|
@@ -146,6 +147,7 @@ declare const XhFileUploadRoot: import("vue").DefineComponent<import("vue").Extr
|
|
|
146
147
|
type: PropType<Partial<FileUploadTranslations>>;
|
|
147
148
|
};
|
|
148
149
|
}>> & Readonly<{
|
|
150
|
+
onClear?: (() => any) | undefined;
|
|
149
151
|
"onFiles-change"?: ((_details: import("@xihan-ui/headless").FileUploadFilesChangeDetails) => any) | undefined;
|
|
150
152
|
"onUpdate:files"?: ((_files: File[]) => any) | undefined;
|
|
151
153
|
"onFile-accept"?: ((_details: import("@xihan-ui/headless").FileUploadFileAcceptDetails) => any) | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-upload.d.ts","names":[],"sources":["../../../src/components/file-upload/file-upload.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"file-upload.d.ts","names":[],"sources":["../../../src/components/file-upload/file-upload.ts"],"mappings":";;;;KAmBK,kBAAkB;;KAGX,0BAA0B,KACpC;cAmBW,gCAAgB,8BAAA;;IAKD,MAAA,SAAS;;;IACF,MAAA,SAAS;;;IACV,MAAA,SAAS;;;IACF,MAAA,SAAS;;;IAClB,MAAA,SAAS;;;;;;;IAEF,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IASL,MAAA,SAAS;;;;;;;IAGZ,MAAA;;;IACK,MAAA,SAAS,QAAQ;;;;;;EAKtB,iBAAA,UAAA,UAAU;EACZ,iBAAA,QAAA,UAAU;EACT,gBAAA,UAAA,UAAU;EACV,gBAAA,UAAA,UAAU;EACF,wBAAA,UAAA,UAAU;EACb,uBAAA,QAAA,UAAU;EACX,oBAAA,UAAA,UAAU;EACb,iBAAA,UAAA,UAAU;EACT,kBAAA,UAAA,UAAU;;;IAhCd,MAAA,SAAS;;;IACF,MAAA,SAAS;;;IACV,MAAA,SAAS;;;IACF,MAAA,SAAS;;;IAClB,MAAA,SAAS;;;;;;;IAEF,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IASL,MAAA,SAAS;;;;;;;IAGZ,MAAA;;;IACK,MAAA,SAAS,QAAQ;;;;;;;;;;;;;;;;;;;;;EAgBvC,WAAC,OAAO,4BAA4B;kCAqChD;cAEW,iCAAiB,0BAAA,oBAAA,4BAAA;;8BAO5B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,oCAAoB,0BAAA,oBAAA,4BAAA;;8BAM/B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,mCAAmB,8BAAA;;;;;;;;;;qCAsB9B;cAEW,uCAAuB,0BAAA,oBAAA,4BAAA;;8BAMlC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,gCAAgB,0BAAA,oBAAA,4BAAA;;8BAM3B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,gCAAgB,8BAAA;;;IAID,MAAA,SAAS;;;;IAEE,MAAA;;;;;;;IAFX,MAAA,SAAS;;;;IAEE,MAAA;;MAqBrC,oDAAA;cAEW,oCAAoB,0BAAA,oBAAA,4BAAA;;8BAY/B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,wCAAwB,0BAAA,oBAAA,4BAAA;;8BAYnC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,uCAAuB,0BAAA,oBAAA,4BAAA;;8BAOlC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,wCAAwB,0BAAA,oBAAA,4BAAA;;8BAOnC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,6CAA6B,0BAAA,oBAAA,4BAAA;;8BAWxC,qCAAA,iDAAA,aAAA,eAAA,oDAAA;cAEW,wCAAwB,0BAAA,oBAAA,4BAAA;;8BAMnC,qCAAA,iDAAA,aAAA,eAAA,oDAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { withXhConfig } from "../../config/config.js";
|
|
2
2
|
import { mergePartProps } from "../../runtime/merge-props.js";
|
|
3
3
|
import { mergeIntoChild } from "../../runtime/as-child.js";
|
|
4
|
+
import { withHandlers } from "../../runtime/with-handlers.js";
|
|
4
5
|
import { useFormControlProps } from "../form/use-form-control.js";
|
|
5
6
|
import { provideFileUpload, provideFileUploadItem, useFileUploadContext, useFileUploadItemContext } from "./context.js";
|
|
6
7
|
import { useFileUpload } from "./use-file-upload.js";
|
|
@@ -46,6 +47,7 @@ const XhFileUploadRoot = defineComponent({
|
|
|
46
47
|
translations: { type: Object }
|
|
47
48
|
},
|
|
48
49
|
emits: {
|
|
50
|
+
"clear": () => true,
|
|
49
51
|
"files-change": (_details) => true,
|
|
50
52
|
"update:files": (_files) => true,
|
|
51
53
|
"file-accept": (_details) => true,
|
|
@@ -71,7 +73,7 @@ const XhFileUploadRoot = defineComponent({
|
|
|
71
73
|
const onUploadComplete = (details) => emit("upload-complete", details);
|
|
72
74
|
const onUploadError = (details) => emit("upload-error", details);
|
|
73
75
|
const onUploadCancel = (details) => emit("upload-cancel", details);
|
|
74
|
-
const ctx = useFileUpload(withXhConfig("file-upload", useFormControlProps(props)), {
|
|
76
|
+
const ctx = useFileUpload(withHandlers(withXhConfig("file-upload", useFormControlProps(props)), { onClear: () => emit("clear") }), {
|
|
75
77
|
onFilesChange,
|
|
76
78
|
onFileAccept,
|
|
77
79
|
onFileReject,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-upload.js","names":[],"sources":["../../../src/components/file-upload/file-upload.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 file upload 相关实现。\n\nimport type { FileUploadApi, FileUploadFile, FileUploadItemProps, FileUploadRemoteFile, FileUploadSchema, FileUploadTranslations } from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { computed, defineComponent, h } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { mergeIntoChild } from '../../runtime/as-child'\nimport { mergePartProps } from '../../runtime/merge-props'\nimport { useFormControlProps } from '../form/use-form-control'\nimport { provideFileUpload, provideFileUploadItem, useFileUploadContext, useFileUploadItemContext } from './context'\nimport { useFileUpload } from './use-file-upload'\n\ntype FileUploadProps = FileUploadSchema['props']\n\n/** 默认插槽的载荷:文件清单与传输快照、投放区与数量状态,以及增删清空、开始上传、拉起选择器等命令。 */\nexport type FileUploadRootSlotProps = Pick<\n FileUploadApi,\n | 'acceptedFiles'\n | 'remoteFiles'\n | 'allFiles'\n | 'uploadOf'\n | 'startUpload'\n | 'cancelUpload'\n | 'dragging'\n | 'empty'\n | 'disabled'\n | 'maxFiles'\n | 'getFileSizeText'\n | 'setFiles'\n | 'addFiles'\n | 'deleteFile'\n | 'clear'\n | 'openFilePicker'\n>\n\nexport const XhFileUploadRoot = defineComponent({\n name: 'XhFileUploadRoot',\n // 有 connect 与机器兜底的 prop:普通类型省略 default,Boolean 显式保留 undefined\n props: {\n // 缺席值 undefined 表示非受控\n files: { type: Array as PropType<File[]> },\n defaultFiles: { type: Array as PropType<File[]> },\n remoteFiles: { type: Array as PropType<FileUploadRemoteFile[]> },\n defaultRemoteFiles: { type: Array as PropType<FileUploadRemoteFile[]> },\n upload: { type: Function as PropType<FileUploadProps['upload']> },\n autoUpload: { type: Boolean, default: undefined },\n accept: { type: [String, Array] as PropType<string | string[]> },\n maxFiles: { type: Number },\n maxFileSize: { type: Number },\n minFileSize: { type: Number },\n disabled: { type: Boolean, default: undefined },\n invalid: { type: Boolean, default: undefined },\n name: { type: String },\n allowDrop: { type: Boolean, default: undefined },\n allowPaste: { type: Boolean, default: undefined },\n validate: { type: Function as PropType<FileUploadProps['validate']> },\n maxConcurrentUploads: { type: Number },\n directory: Boolean,\n capture: { type: String as PropType<'user' | 'environment'> },\n translations: { type: Object as PropType<Partial<FileUploadTranslations>> },\n },\n // files-change 携带 { files },update:files 携带裸数组;file-accept / file-reject 逐个文件报告\n emits: {\n 'files-change': (_details: PayloadOf<FileUploadProps, 'onFilesChange'>) => true,\n 'update:files': (_files: PayloadOf<FileUploadProps, 'onFilesChange'>['files']) => true,\n 'file-accept': (_details: PayloadOf<FileUploadProps, 'onFileAccept'>) => true,\n 'file-reject': (_details: PayloadOf<FileUploadProps, 'onFileReject'>) => true,\n 'remote-files-change': (_details: PayloadOf<FileUploadProps, 'onRemoteFilesChange'>) => true,\n 'update:remoteFiles': (_files: PayloadOf<FileUploadProps, 'onRemoteFilesChange'>['files']) => true,\n 'upload-complete': (_details: PayloadOf<FileUploadProps, 'onUploadComplete'>) => true,\n 'upload-error': (_details: PayloadOf<FileUploadProps, 'onUploadError'>) => true,\n 'upload-cancel': (_details: PayloadOf<FileUploadProps, 'onUploadCancel'>) => true,\n },\n slots: Object as SlotsType<{\n default?: (props: FileUploadRootSlotProps) => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const onFilesChange: FileUploadProps['onFilesChange'] = (details) => {\n emit('files-change', details)\n emit('update:files', details.files)\n }\n const onFileAccept: FileUploadProps['onFileAccept'] = details => emit('file-accept', details)\n const onFileReject: FileUploadProps['onFileReject'] = details => emit('file-reject', details)\n const onRemoteFilesChange: FileUploadProps['onRemoteFilesChange'] = (details) => {\n emit('remote-files-change', details)\n emit('update:remoteFiles', details.files)\n }\n const onUploadComplete: FileUploadProps['onUploadComplete'] = details => emit('upload-complete', details)\n const onUploadError: FileUploadProps['onUploadError'] = details => emit('upload-error', details)\n const onUploadCancel: FileUploadProps['onUploadCancel'] = details => emit('upload-cancel', details)\n const ctx = useFileUpload(withXhConfig('file-upload', useFormControlProps(props)) as FileUploadProps, { onFilesChange, onFileAccept, onFileReject, onRemoteFilesChange, onUploadComplete, onUploadError, onUploadCancel })\n provideFileUpload(ctx)\n return () => h('div', ctx.api.value.getRootProps() as Record<string, unknown>, slots.default?.({\n acceptedFiles: ctx.api.value.acceptedFiles,\n remoteFiles: ctx.api.value.remoteFiles,\n allFiles: ctx.api.value.allFiles,\n uploadOf: ctx.api.value.uploadOf,\n startUpload: ctx.api.value.startUpload,\n cancelUpload: ctx.api.value.cancelUpload,\n dragging: ctx.api.value.dragging,\n empty: ctx.api.value.empty,\n disabled: ctx.api.value.disabled,\n maxFiles: ctx.api.value.maxFiles,\n getFileSizeText: ctx.api.value.getFileSizeText,\n setFiles: ctx.api.value.setFiles,\n addFiles: ctx.api.value.addFiles,\n deleteFile: ctx.api.value.deleteFile,\n clear: ctx.api.value.clear,\n openFilePicker: ctx.api.value.openFilePicker,\n }))\n },\n})\n\nexport const XhFileUploadLabel = defineComponent({\n name: 'XhFileUploadLabel',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n // 用原生 label,getLabelProps 的 for 指向隐藏输入\n return () => h('label', ctx.api.value.getLabelProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFileUploadDropzone = defineComponent({\n name: 'XhFileUploadDropzone',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n return () => h('div', ctx.api.value.getDropzoneProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFileUploadTrigger = defineComponent({\n name: 'XhFileUploadTrigger',\n // 直通属性自己合:Vue 默认把作者的处理器排在部件的后面,这里改成作者先跑\n inheritAttrs: false,\n props: {\n /** 借用作者的子节点作为触发器,不再渲染自己的包裹元素;子节点须恰好一个。 */\n asChild: Boolean,\n },\n setup(props, { slots, attrs }) {\n const ctx = useFileUploadContext()\n return () => {\n const part = mergePartProps(ctx.api.value.getTriggerProps() as Record<string, unknown>, attrs)\n const children = slots.default?.()\n // asChild:把触发器属性合到作者的节点上,不再自己渲染包裹元素\n if (props.asChild) {\n const merged = mergeIntoChild(children, part, 'file-upload')\n if (merged)\n return merged\n }\n return h('button', part, children)\n }\n },\n})\n\nexport const XhFileUploadHiddenInput = defineComponent({\n name: 'XhFileUploadHiddenInput',\n setup() {\n const ctx = useFileUploadContext()\n return () => h('input', ctx.api.value.getHiddenInputProps() as Record<string, unknown>)\n },\n})\n\nexport const XhFileUploadList = defineComponent({\n name: 'XhFileUploadList',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n return () => h('div', ctx.api.value.getListProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFileUploadItem = defineComponent({\n name: 'XhFileUploadItem',\n props: {\n /** 该行显示哪个文件(本地或远程附件)。 */\n file: { type: Object as PropType<FileUploadFile> },\n /** 改用下标从 allFiles(远程在前、本地在后)中取文件,兼收字符串以支持模板中写 index=\"0\"。 */\n index: { type: [Number, String] as PropType<number | string> },\n },\n setup(props, { slots }) {\n const ctx = useFileUploadContext()\n const file = computed<FileUploadFile | undefined>(() => {\n if (props.file)\n return props.file\n if (props.index == null)\n return undefined\n return ctx.api.value.allFiles[Math.trunc(Number(props.index))]\n })\n // 条目上下文,子部件从中取文件\n const item = computed<FileUploadItemProps>(() => ({ file: file.value as FileUploadFile }))\n provideFileUploadItem({ item })\n return () => {\n // 下标指向的文件不存在时只渲染空壳,不打组件属性也不渲染子部件\n if (!file.value)\n return h('div')\n return h('div', ctx.api.value.getItemProps(item.value) as Record<string, unknown>, slots.default?.())\n }\n },\n})\n\nexport const XhFileUploadItemName = defineComponent({\n name: 'XhFileUploadItemName',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n const { item } = useFileUploadItemContext()\n // 有插槽用插槽,否则显示文件名\n return () => h(\n 'span',\n ctx.api.value.getItemNameProps(item.value) as Record<string, unknown>,\n slots.default?.() ?? item.value.file.name,\n )\n },\n})\n\nexport const XhFileUploadItemSizeText = defineComponent({\n name: 'XhFileUploadItemSizeText',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n const { item } = useFileUploadItemContext()\n // 有插槽用插槽,否则显示格式化后的文件大小\n return () => h(\n 'span',\n ctx.api.value.getItemSizeTextProps(item.value) as Record<string, unknown>,\n slots.default?.() ?? ctx.api.value.getFileSizeText(item.value.file),\n )\n },\n})\n\nexport const XhFileUploadItemPreview = defineComponent({\n name: 'XhFileUploadItemPreview',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n const { item } = useFileUploadItemContext()\n return () => h('div', ctx.api.value.getItemPreviewProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFileUploadItemProgress = defineComponent({\n name: 'XhFileUploadItemProgress',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n const { item } = useFileUploadItemContext()\n return () => h('div', ctx.api.value.getItemProgressProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFileUploadItemDeleteTrigger = defineComponent({\n name: 'XhFileUploadItemDeleteTrigger',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n const { item } = useFileUploadItemContext()\n return () => h(\n 'button',\n ctx.api.value.getItemDeleteTriggerProps(item.value) as Record<string, unknown>,\n slots.default?.(),\n )\n },\n})\n\nexport const XhFileUploadClearTrigger = defineComponent({\n name: 'XhFileUploadClearTrigger',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n return () => h('button', ctx.api.value.getClearTriggerProps() as Record<string, unknown>, slots.default?.())\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"file-upload.js","names":[],"sources":["../../../src/components/file-upload/file-upload.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 file upload 相关实现。\n\nimport type { FileUploadApi, FileUploadFile, FileUploadItemProps, FileUploadRemoteFile, FileUploadSchema, FileUploadTranslations } from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { computed, defineComponent, h } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { mergeIntoChild } from '../../runtime/as-child'\nimport { mergePartProps } from '../../runtime/merge-props'\nimport { withHandlers } from '../../runtime/with-handlers'\nimport { useFormControlProps } from '../form/use-form-control'\nimport { provideFileUpload, provideFileUploadItem, useFileUploadContext, useFileUploadItemContext } from './context'\nimport { useFileUpload } from './use-file-upload'\n\ntype FileUploadProps = FileUploadSchema['props']\n\n/** 默认插槽的载荷:文件清单与传输快照、投放区与数量状态,以及增删清空、开始上传、拉起选择器等命令。 */\nexport type FileUploadRootSlotProps = Pick<\n FileUploadApi,\n | 'acceptedFiles'\n | 'remoteFiles'\n | 'allFiles'\n | 'uploadOf'\n | 'startUpload'\n | 'cancelUpload'\n | 'dragging'\n | 'empty'\n | 'disabled'\n | 'maxFiles'\n | 'getFileSizeText'\n | 'setFiles'\n | 'addFiles'\n | 'deleteFile'\n | 'clear'\n | 'openFilePicker'\n>\n\nexport const XhFileUploadRoot = defineComponent({\n name: 'XhFileUploadRoot',\n // 有 connect 与机器兜底的 prop:普通类型省略 default,Boolean 显式保留 undefined\n props: {\n // 缺席值 undefined 表示非受控\n files: { type: Array as PropType<File[]> },\n defaultFiles: { type: Array as PropType<File[]> },\n remoteFiles: { type: Array as PropType<FileUploadRemoteFile[]> },\n defaultRemoteFiles: { type: Array as PropType<FileUploadRemoteFile[]> },\n upload: { type: Function as PropType<FileUploadProps['upload']> },\n autoUpload: { type: Boolean, default: undefined },\n accept: { type: [String, Array] as PropType<string | string[]> },\n maxFiles: { type: Number },\n maxFileSize: { type: Number },\n minFileSize: { type: Number },\n disabled: { type: Boolean, default: undefined },\n invalid: { type: Boolean, default: undefined },\n name: { type: String },\n allowDrop: { type: Boolean, default: undefined },\n allowPaste: { type: Boolean, default: undefined },\n validate: { type: Function as PropType<FileUploadProps['validate']> },\n maxConcurrentUploads: { type: Number },\n directory: Boolean,\n capture: { type: String as PropType<'user' | 'environment'> },\n translations: { type: Object as PropType<Partial<FileUploadTranslations>> },\n },\n // files-change 携带 { files },update:files 携带裸数组;file-accept / file-reject 逐个文件报告\n emits: {\n 'clear': () => true,\n 'files-change': (_details: PayloadOf<FileUploadProps, 'onFilesChange'>) => true,\n 'update:files': (_files: PayloadOf<FileUploadProps, 'onFilesChange'>['files']) => true,\n 'file-accept': (_details: PayloadOf<FileUploadProps, 'onFileAccept'>) => true,\n 'file-reject': (_details: PayloadOf<FileUploadProps, 'onFileReject'>) => true,\n 'remote-files-change': (_details: PayloadOf<FileUploadProps, 'onRemoteFilesChange'>) => true,\n 'update:remoteFiles': (_files: PayloadOf<FileUploadProps, 'onRemoteFilesChange'>['files']) => true,\n 'upload-complete': (_details: PayloadOf<FileUploadProps, 'onUploadComplete'>) => true,\n 'upload-error': (_details: PayloadOf<FileUploadProps, 'onUploadError'>) => true,\n 'upload-cancel': (_details: PayloadOf<FileUploadProps, 'onUploadCancel'>) => true,\n },\n slots: Object as SlotsType<{\n default?: (props: FileUploadRootSlotProps) => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const onFilesChange: FileUploadProps['onFilesChange'] = (details) => {\n emit('files-change', details)\n emit('update:files', details.files)\n }\n const onFileAccept: FileUploadProps['onFileAccept'] = details => emit('file-accept', details)\n const onFileReject: FileUploadProps['onFileReject'] = details => emit('file-reject', details)\n const onRemoteFilesChange: FileUploadProps['onRemoteFilesChange'] = (details) => {\n emit('remote-files-change', details)\n emit('update:remoteFiles', details.files)\n }\n const onUploadComplete: FileUploadProps['onUploadComplete'] = details => emit('upload-complete', details)\n const onUploadError: FileUploadProps['onUploadError'] = details => emit('upload-error', details)\n const onUploadCancel: FileUploadProps['onUploadCancel'] = details => emit('upload-cancel', details)\n const ctx = useFileUpload(withHandlers(withXhConfig('file-upload', useFormControlProps(props)), { onClear: () => emit('clear') }) as FileUploadProps, { onFilesChange, onFileAccept, onFileReject, onRemoteFilesChange, onUploadComplete, onUploadError, onUploadCancel })\n provideFileUpload(ctx)\n return () => h('div', ctx.api.value.getRootProps() as Record<string, unknown>, slots.default?.({\n acceptedFiles: ctx.api.value.acceptedFiles,\n remoteFiles: ctx.api.value.remoteFiles,\n allFiles: ctx.api.value.allFiles,\n uploadOf: ctx.api.value.uploadOf,\n startUpload: ctx.api.value.startUpload,\n cancelUpload: ctx.api.value.cancelUpload,\n dragging: ctx.api.value.dragging,\n empty: ctx.api.value.empty,\n disabled: ctx.api.value.disabled,\n maxFiles: ctx.api.value.maxFiles,\n getFileSizeText: ctx.api.value.getFileSizeText,\n setFiles: ctx.api.value.setFiles,\n addFiles: ctx.api.value.addFiles,\n deleteFile: ctx.api.value.deleteFile,\n clear: ctx.api.value.clear,\n openFilePicker: ctx.api.value.openFilePicker,\n }))\n },\n})\n\nexport const XhFileUploadLabel = defineComponent({\n name: 'XhFileUploadLabel',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n // 用原生 label,getLabelProps 的 for 指向隐藏输入\n return () => h('label', ctx.api.value.getLabelProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFileUploadDropzone = defineComponent({\n name: 'XhFileUploadDropzone',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n return () => h('div', ctx.api.value.getDropzoneProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFileUploadTrigger = defineComponent({\n name: 'XhFileUploadTrigger',\n // 直通属性自己合:Vue 默认把作者的处理器排在部件的后面,这里改成作者先跑\n inheritAttrs: false,\n props: {\n /** 借用作者的子节点作为触发器,不再渲染自己的包裹元素;子节点须恰好一个。 */\n asChild: Boolean,\n },\n setup(props, { slots, attrs }) {\n const ctx = useFileUploadContext()\n return () => {\n const part = mergePartProps(ctx.api.value.getTriggerProps() as Record<string, unknown>, attrs)\n const children = slots.default?.()\n // asChild:把触发器属性合到作者的节点上,不再自己渲染包裹元素\n if (props.asChild) {\n const merged = mergeIntoChild(children, part, 'file-upload')\n if (merged)\n return merged\n }\n return h('button', part, children)\n }\n },\n})\n\nexport const XhFileUploadHiddenInput = defineComponent({\n name: 'XhFileUploadHiddenInput',\n setup() {\n const ctx = useFileUploadContext()\n return () => h('input', ctx.api.value.getHiddenInputProps() as Record<string, unknown>)\n },\n})\n\nexport const XhFileUploadList = defineComponent({\n name: 'XhFileUploadList',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n return () => h('div', ctx.api.value.getListProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFileUploadItem = defineComponent({\n name: 'XhFileUploadItem',\n props: {\n /** 该行显示哪个文件(本地或远程附件)。 */\n file: { type: Object as PropType<FileUploadFile> },\n /** 改用下标从 allFiles(远程在前、本地在后)中取文件,兼收字符串以支持模板中写 index=\"0\"。 */\n index: { type: [Number, String] as PropType<number | string> },\n },\n setup(props, { slots }) {\n const ctx = useFileUploadContext()\n const file = computed<FileUploadFile | undefined>(() => {\n if (props.file)\n return props.file\n if (props.index == null)\n return undefined\n return ctx.api.value.allFiles[Math.trunc(Number(props.index))]\n })\n // 条目上下文,子部件从中取文件\n const item = computed<FileUploadItemProps>(() => ({ file: file.value as FileUploadFile }))\n provideFileUploadItem({ item })\n return () => {\n // 下标指向的文件不存在时只渲染空壳,不打组件属性也不渲染子部件\n if (!file.value)\n return h('div')\n return h('div', ctx.api.value.getItemProps(item.value) as Record<string, unknown>, slots.default?.())\n }\n },\n})\n\nexport const XhFileUploadItemName = defineComponent({\n name: 'XhFileUploadItemName',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n const { item } = useFileUploadItemContext()\n // 有插槽用插槽,否则显示文件名\n return () => h(\n 'span',\n ctx.api.value.getItemNameProps(item.value) as Record<string, unknown>,\n slots.default?.() ?? item.value.file.name,\n )\n },\n})\n\nexport const XhFileUploadItemSizeText = defineComponent({\n name: 'XhFileUploadItemSizeText',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n const { item } = useFileUploadItemContext()\n // 有插槽用插槽,否则显示格式化后的文件大小\n return () => h(\n 'span',\n ctx.api.value.getItemSizeTextProps(item.value) as Record<string, unknown>,\n slots.default?.() ?? ctx.api.value.getFileSizeText(item.value.file),\n )\n },\n})\n\nexport const XhFileUploadItemPreview = defineComponent({\n name: 'XhFileUploadItemPreview',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n const { item } = useFileUploadItemContext()\n return () => h('div', ctx.api.value.getItemPreviewProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFileUploadItemProgress = defineComponent({\n name: 'XhFileUploadItemProgress',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n const { item } = useFileUploadItemContext()\n return () => h('div', ctx.api.value.getItemProgressProps(item.value) as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFileUploadItemDeleteTrigger = defineComponent({\n name: 'XhFileUploadItemDeleteTrigger',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n const { item } = useFileUploadItemContext()\n return () => h(\n 'button',\n ctx.api.value.getItemDeleteTriggerProps(item.value) as Record<string, unknown>,\n slots.default?.(),\n )\n },\n})\n\nexport const XhFileUploadClearTrigger = defineComponent({\n name: 'XhFileUploadClearTrigger',\n setup(_, { slots }) {\n const ctx = useFileUploadContext()\n return () => h('button', ctx.api.value.getClearTriggerProps() as Record<string, unknown>, slots.default?.())\n },\n})\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PayloadOf } from "../../runtime/payload.js";
|
|
2
2
|
import { PropType, SlotsType, VNode } from "vue";
|
|
3
3
|
import { ActionVariant, Direction, Size, Tone } from "@xihan-ui/core";
|
|
4
|
-
import { FloatButtonApi, FloatButtonExpandTrigger, FloatButtonPlacement, FloatButtonProps, FloatButtonTranslations } from "@xihan-ui/headless";
|
|
4
|
+
import { FloatButtonApi, FloatButtonExpandTrigger, FloatButtonPlacement, FloatButtonPosition, FloatButtonProps, FloatButtonSnap, FloatButtonTranslations } from "@xihan-ui/headless";
|
|
5
5
|
//#region src/components/float-button/float-button.d.ts
|
|
6
6
|
/** 默认插槽的载荷:展开组当前是否显示,以及改写展开状态的动作。 */
|
|
7
7
|
type FloatButtonRootSlotProps = Pick<FloatButtonApi, 'open' | 'setOpen'>;
|
|
@@ -22,6 +22,16 @@ declare const XhFloatButtonRoot: import("vue").DefineComponent<import("vue").Ext
|
|
|
22
22
|
offset: {
|
|
23
23
|
type: NumberConstructor;
|
|
24
24
|
};
|
|
25
|
+
draggable: BooleanConstructor;
|
|
26
|
+
snap: {
|
|
27
|
+
type: PropType<FloatButtonSnap>;
|
|
28
|
+
};
|
|
29
|
+
position: {
|
|
30
|
+
type: PropType<FloatButtonPosition>;
|
|
31
|
+
};
|
|
32
|
+
defaultPosition: {
|
|
33
|
+
type: PropType<FloatButtonPosition>;
|
|
34
|
+
};
|
|
25
35
|
expandTrigger: {
|
|
26
36
|
type: PropType<FloatButtonExpandTrigger>;
|
|
27
37
|
};
|
|
@@ -42,6 +52,8 @@ declare const XhFloatButtonRoot: import("vue").DefineComponent<import("vue").Ext
|
|
|
42
52
|
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
43
53
|
'open-change': (_details: PayloadOf<FloatButtonProps, "onOpenChange">) => true;
|
|
44
54
|
'update:open': (_open: PayloadOf<FloatButtonProps, "onOpenChange">["open"]) => true;
|
|
55
|
+
'position-change': (_details: PayloadOf<FloatButtonProps, "onPositionChange">) => true;
|
|
56
|
+
'update:position': (_position: PayloadOf<FloatButtonProps, "onPositionChange">["position"]) => true;
|
|
45
57
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
46
58
|
open: {
|
|
47
59
|
type: BooleanConstructor;
|
|
@@ -58,6 +70,16 @@ declare const XhFloatButtonRoot: import("vue").DefineComponent<import("vue").Ext
|
|
|
58
70
|
offset: {
|
|
59
71
|
type: NumberConstructor;
|
|
60
72
|
};
|
|
73
|
+
draggable: BooleanConstructor;
|
|
74
|
+
snap: {
|
|
75
|
+
type: PropType<FloatButtonSnap>;
|
|
76
|
+
};
|
|
77
|
+
position: {
|
|
78
|
+
type: PropType<FloatButtonPosition>;
|
|
79
|
+
};
|
|
80
|
+
defaultPosition: {
|
|
81
|
+
type: PropType<FloatButtonPosition>;
|
|
82
|
+
};
|
|
61
83
|
expandTrigger: {
|
|
62
84
|
type: PropType<FloatButtonExpandTrigger>;
|
|
63
85
|
};
|
|
@@ -76,10 +98,13 @@ declare const XhFloatButtonRoot: import("vue").DefineComponent<import("vue").Ext
|
|
|
76
98
|
}>> & Readonly<{
|
|
77
99
|
"onOpen-change"?: ((_details: import("@xihan-ui/headless").CollapsibleOpenChangeDetails) => any) | undefined;
|
|
78
100
|
"onUpdate:open"?: ((_open: boolean) => any) | undefined;
|
|
101
|
+
"onPosition-change"?: ((_details: import("@xihan-ui/headless").FloatButtonPositionChangeDetails) => any) | undefined;
|
|
102
|
+
"onUpdate:position"?: ((_position: FloatButtonPosition) => any) | undefined;
|
|
79
103
|
}>, {
|
|
80
104
|
disabled: boolean;
|
|
81
105
|
open: boolean;
|
|
82
106
|
defaultOpen: boolean;
|
|
107
|
+
draggable: boolean;
|
|
83
108
|
}, SlotsType<{
|
|
84
109
|
default?: (props: FloatButtonRootSlotProps) => VNode[];
|
|
85
110
|
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"float-button.d.ts","names":[],"sources":["../../../src/components/float-button/float-button.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"float-button.d.ts","names":[],"sources":["../../../src/components/float-button/float-button.ts"],"mappings":";;;;;;KA0BY,2BAA2B,KAAK;;cAG/B,iCAAiB,8BAAA;;;;;;;;IAOH,MAAA,SAAS;;;IACH,MAAA,SAAS;;;;;;;IAGd,MAAA,SAAS;;;IACL,MAAA,SAAS;;;IACF,MAAA,SAAS;;;IACX,MAAA,SAAS;;;IACf,MAAA,SAAS;;;IACZ,MAAA,SAAS;;;IACT,MAAA,SAAS;;;IACD,MAAA,SAAS,QAAQ;;;;;EAIvB,gBAAA,UAAA,UAAU;EACb,gBAAA,OAAA,UAAU;EACH,oBAAA,UAAA,UAAU;EACT,oBAAA,WAAA,UAAU;;;;;;;;;IAlBlB,MAAA,SAAS;;;IACH,MAAA,SAAS;;;;;;;IAGd,MAAA,SAAS;;;IACL,MAAA,SAAS;;;IACF,MAAA,SAAS;;;IACX,MAAA,SAAS;;;IACf,MAAA,SAAS;;;IACZ,MAAA,SAAS;;;IACT,MAAA,SAAS;;;IACD,MAAA,SAAS,QAAQ;;;;;;;;;;;;;EAUvC,WAAC,OAAO,6BAA6B;kCAoBjD;;cAGW,oCAAoB,0BAAA,oBAAA,4BAAA;;8BAM/B,qCAAA,iDAAA,aAAA,eAAA,oDAAA;;cAGW,iCAAiB,0BAAA,oBAAA,4BAAA;;8BAM5B,qCAAA,iDAAA,aAAA,eAAA,oDAAA"}
|
|
@@ -16,6 +16,10 @@ const XhFloatButtonRoot = defineComponent({
|
|
|
16
16
|
dir: { type: String },
|
|
17
17
|
placement: { type: String },
|
|
18
18
|
offset: { type: Number },
|
|
19
|
+
draggable: Boolean,
|
|
20
|
+
snap: { type: String },
|
|
21
|
+
position: { type: Object },
|
|
22
|
+
defaultPosition: { type: Object },
|
|
19
23
|
expandTrigger: { type: String },
|
|
20
24
|
variant: { type: String },
|
|
21
25
|
tone: { type: String },
|
|
@@ -24,14 +28,22 @@ const XhFloatButtonRoot = defineComponent({
|
|
|
24
28
|
},
|
|
25
29
|
emits: {
|
|
26
30
|
"open-change": (_details) => true,
|
|
27
|
-
"update:open": (_open) => true
|
|
31
|
+
"update:open": (_open) => true,
|
|
32
|
+
"position-change": (_details) => true,
|
|
33
|
+
"update:position": (_position) => true
|
|
28
34
|
},
|
|
29
35
|
slots: Object,
|
|
30
36
|
setup(props, { slots, emit }) {
|
|
31
|
-
const ctx = useFloatButton(withXhConfig("float-button", props), {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
const ctx = useFloatButton(withXhConfig("float-button", props), {
|
|
38
|
+
onOpenChange: (details) => {
|
|
39
|
+
emit("open-change", details);
|
|
40
|
+
emit("update:open", details.open);
|
|
41
|
+
},
|
|
42
|
+
onPositionChange: (details) => {
|
|
43
|
+
emit("position-change", details);
|
|
44
|
+
emit("update:position", details.position);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
35
47
|
provideFloatButton(ctx);
|
|
36
48
|
return () => h("div", {
|
|
37
49
|
...ctx.api.value.getRootProps(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"float-button.js","names":[],"sources":["../../../src/components/float-button/float-button.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 float button 相关实现。\n\nimport type { ActionVariant, Direction, Size, Tone } from '@xihan-ui/core'\nimport type {\n FloatButtonApi,\n FloatButtonExpandTrigger,\n FloatButtonNotifiers,\n FloatButtonPlacement,\n FloatButtonProps,\n FloatButtonTranslations,\n} from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { provideFloatButton, useFloatButtonContext } from './context'\nimport { useFloatButton } from './use-float-button'\n\n/** 默认插槽的载荷:展开组当前是否显示,以及改写展开状态的动作。 */\nexport type FloatButtonRootSlotProps = Pick<FloatButtonApi, 'open' | 'setOpen'>\n\n/** 根节点是定位壳:把整组固定在视口一角,悬停展开时以进出它为准。 */\nexport const XhFloatButtonRoot = defineComponent({\n name: 'XhFloatButtonRoot',\n // 缺省值由机器与 connect 决定;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n open: { type: Boolean, default: undefined },\n defaultOpen: Boolean,\n disabled: Boolean,\n dir: { type: String as PropType<Direction> },\n placement: { type: String as PropType<FloatButtonPlacement> },\n offset: { type: Number },\n expandTrigger: { type: String as PropType<FloatButtonExpandTrigger> },\n variant: { type: String as PropType<ActionVariant> },\n tone: { type: String as PropType<Tone> },\n size: { type: String as PropType<Size> },\n translations: { type: Object as PropType<Partial<FloatButtonTranslations>> },\n },\n // open-change 携带 { open },update:open
|
|
1
|
+
{"version":3,"file":"float-button.js","names":[],"sources":["../../../src/components/float-button/float-button.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 float button 相关实现。\n\nimport type { ActionVariant, Direction, Size, Tone } from '@xihan-ui/core'\nimport type {\n FloatButtonApi,\n FloatButtonExpandTrigger,\n FloatButtonNotifiers,\n FloatButtonPlacement,\n FloatButtonPosition,\n FloatButtonProps,\n FloatButtonSnap,\n FloatButtonTranslations,\n} from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { provideFloatButton, useFloatButtonContext } from './context'\nimport { useFloatButton } from './use-float-button'\n\n/** 默认插槽的载荷:展开组当前是否显示,以及改写展开状态的动作。 */\nexport type FloatButtonRootSlotProps = Pick<FloatButtonApi, 'open' | 'setOpen'>\n\n/** 根节点是定位壳:把整组固定在视口一角,悬停展开时以进出它为准。 */\nexport const XhFloatButtonRoot = defineComponent({\n name: 'XhFloatButtonRoot',\n // 缺省值由机器与 connect 决定;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n open: { type: Boolean, default: undefined },\n defaultOpen: Boolean,\n disabled: Boolean,\n dir: { type: String as PropType<Direction> },\n placement: { type: String as PropType<FloatButtonPlacement> },\n offset: { type: Number },\n draggable: Boolean,\n snap: { type: String as PropType<FloatButtonSnap> },\n position: { type: Object as PropType<FloatButtonPosition> },\n defaultPosition: { type: Object as PropType<FloatButtonPosition> },\n expandTrigger: { type: String as PropType<FloatButtonExpandTrigger> },\n variant: { type: String as PropType<ActionVariant> },\n tone: { type: String as PropType<Tone> },\n size: { type: String as PropType<Size> },\n translations: { type: Object as PropType<Partial<FloatButtonTranslations>> },\n },\n // open-change 携带 { open },update:open 携带裸布尔;position-change 携带 { position },update:position 携带裸位置\n emits: {\n 'open-change': (_details: PayloadOf<FloatButtonProps, 'onOpenChange'>) => true,\n 'update:open': (_open: PayloadOf<FloatButtonProps, 'onOpenChange'>['open']) => true,\n 'position-change': (_details: PayloadOf<FloatButtonProps, 'onPositionChange'>) => true,\n 'update:position': (_position: PayloadOf<FloatButtonProps, 'onPositionChange'>['position']) => true,\n },\n slots: Object as SlotsType<{\n default?: (props: FloatButtonRootSlotProps) => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const notify: FloatButtonNotifiers = {\n onOpenChange: (details) => {\n emit('open-change', details)\n emit('update:open', details.open)\n },\n onPositionChange: (details) => {\n emit('position-change', details)\n emit('update:position', details.position)\n },\n }\n const ctx = useFloatButton(withXhConfig('float-button', props) as FloatButtonProps, notify)\n provideFloatButton(ctx)\n return () => h('div', { ...ctx.api.value.getRootProps() as Record<string, unknown>, ref: ctx.rootRef }, slots.default?.({\n open: ctx.api.value.open,\n setOpen: ctx.api.value.setOpen,\n }))\n },\n})\n\n/** 原生 button:Enter / Space 的激活与 Tab 停靠都由平台提供。 */\nexport const XhFloatButtonTrigger = defineComponent({\n name: 'XhFloatButtonTrigger',\n setup(_, { slots }) {\n const ctx = useFloatButtonContext()\n return () => h('button', ctx.api.value.getTriggerProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\n/** 展开的动作组;收起时带 hidden,其中的按钮一并退出 Tab 序列。 */\nexport const XhFloatButtonList = defineComponent({\n name: 'XhFloatButtonList',\n setup(_, { slots }) {\n const ctx = useFloatButtonContext()\n return () => h('div', ctx.api.value.getListProps() as Record<string, unknown>, slots.default?.())\n },\n})\n"],"mappings":";;;;;;AA6BA,MAAa,oBAAoB,gBAAgB;CAC/C,MAAM;CAEN,OAAO;EACL,MAAM;GAAE,MAAM;GAAS,SAAS,KAAA;EAAU;EAC1C,aAAa;EACb,UAAU;EACV,KAAK,EAAE,MAAM,OAA8B;EAC3C,WAAW,EAAE,MAAM,OAAyC;EAC5D,QAAQ,EAAE,MAAM,OAAO;EACvB,WAAW;EACX,MAAM,EAAE,MAAM,OAAoC;EAClD,UAAU,EAAE,MAAM,OAAwC;EAC1D,iBAAiB,EAAE,MAAM,OAAwC;EACjE,eAAe,EAAE,MAAM,OAA6C;EACpE,SAAS,EAAE,MAAM,OAAkC;EACnD,MAAM,EAAE,MAAM,OAAyB;EACvC,MAAM,EAAE,MAAM,OAAyB;EACvC,cAAc,EAAE,MAAM,OAAqD;CAC7E;CAEA,OAAO;EACL,gBAAgB,aAA0D;EAC1E,gBAAgB,UAA+D;EAC/E,oBAAoB,aAA8D;EAClF,oBAAoB,cAA2E;CACjG;CACA,OAAO;CAGP,MAAM,OAAO,EAAE,OAAO,QAAQ;EAW5B,MAAM,MAAM,eAAe,aAAa,gBAAgB,KAAK,GAAuB;GATlF,eAAe,YAAY;IACzB,KAAK,eAAe,OAAO;IAC3B,KAAK,eAAe,QAAQ,IAAI;GAClC;GACA,mBAAmB,YAAY;IAC7B,KAAK,mBAAmB,OAAO;IAC/B,KAAK,mBAAmB,QAAQ,QAAQ;GAC1C;EAEuF,CAAC;EAC1F,mBAAmB,GAAG;EACtB,aAAa,EAAE,OAAO;GAAE,GAAG,IAAI,IAAI,MAAM,aAAa;GAA8B,KAAK,IAAI;EAAQ,GAAG,MAAM,UAAU;GACtH,MAAM,IAAI,IAAI,MAAM;GACpB,SAAS,IAAI,IAAI,MAAM;EACzB,CAAC,CAAC;CACJ;AACF,CAAC;;AAGD,MAAa,uBAAuB,gBAAgB;CAClD,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,sBAAsB;EAClC,aAAa,EAAE,UAAU,IAAI,IAAI,MAAM,gBAAgB,GAA8B,MAAM,UAAU,CAAC;CACxG;AACF,CAAC;;AAGD,MAAa,oBAAoB,gBAAgB;CAC/C,MAAM;CACN,MAAM,GAAG,EAAE,SAAS;EAClB,MAAM,MAAM,sBAAsB;EAClC,aAAa,EAAE,OAAO,IAAI,IAAI,MAAM,aAAa,GAA8B,MAAM,UAAU,CAAC;CAClG;AACF,CAAC"}
|
|
@@ -17,7 +17,13 @@ function useFloatButton(props, notify) {
|
|
|
17
17
|
defaultOpen: props.defaultOpen,
|
|
18
18
|
disabled: props.disabled,
|
|
19
19
|
expandTrigger: props.expandTrigger,
|
|
20
|
-
|
|
20
|
+
offset: props.offset,
|
|
21
|
+
draggable: props.draggable,
|
|
22
|
+
snap: props.snap,
|
|
23
|
+
position: props.position,
|
|
24
|
+
defaultPosition: props.defaultPosition,
|
|
25
|
+
onOpenChange: notify?.onOpenChange,
|
|
26
|
+
onPositionChange: notify?.onPositionChange
|
|
21
27
|
}), scope);
|
|
22
28
|
let config = null;
|
|
23
29
|
if (typeof document !== "undefined") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-float-button.js","names":[],"sources":["../../../src/components/float-button/use-float-button.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 use float button 相关实现。\n\nimport type { Layer, RuntimeConfig, Service } from '@xihan-ui/core'\nimport type { FloatButtonApi, FloatButtonNotifiers, FloatButtonProps, FloatButtonSchema } from '@xihan-ui/headless'\nimport type { ComputedRef, Ref } from 'vue'\nimport { createRuntimeConfig, createScope } from '@xihan-ui/core'\nimport { connectFloatButton, floatButtonMachine } from '@xihan-ui/headless'\nimport { computed, ref } from 'vue'\nimport { vueNormalize } from '../../runtime/normalize-props'\nimport { useMachine } from '../../runtime/use-machine'\nimport { createVueIdGenerator } from '../../runtime/vue-id'\n\nexport interface FloatButtonContext {\n api: ComputedRef<FloatButtonApi>\n service: Service<FloatButtonSchema>\n rootRef: Ref<HTMLElement | null>\n}\n\n/**\n * 专用状态机持有开合与逻辑层生命周期;Vue 只桥接所属 Document 的配置、登记函数与 root ref。\n */\nexport function useFloatButton(\n props: FloatButtonProps,\n notify?: FloatButtonNotifiers,\n): FloatButtonContext {\n const idGen = createVueIdGenerator()\n const scope = createScope(null, idGen)\n const rootRef = ref<HTMLElement | null>(null)\n\n const service = useMachine(floatButtonMachine, (): FloatButtonSchema['props'] => ({\n open: props.open,\n defaultOpen: props.defaultOpen,\n disabled: props.disabled,\n expandTrigger: props.expandTrigger,\n onOpenChange: notify?.onOpenChange,\n }), scope)\n\n let config: RuntimeConfig | null = null\n if (typeof document !== 'undefined') {\n config = createRuntimeConfig({ scope, idGenerator: idGen })\n const registerLayer = (\n layer: Omit<Layer, 'id'>,\n ): ReturnType<RuntimeConfig['layerRegistry']['register']> => config!.layerRegistry.register(layer)\n service.refs.set('config', config)\n service.refs.set('registerLayer', registerLayer)\n }\n service.refs.set('getRootEl', () => rootRef.value)\n\n const api = computed(() => connectFloatButton(service, props, vueNormalize))\n return { api, service, rootRef }\n}\n"],"mappings":";;;;;;;;;;AA0BA,SAAgB,eACd,OACA,QACoB;CACpB,MAAM,QAAQ,qBAAqB;CACnC,MAAM,QAAQ,YAAY,MAAM,KAAK;CACrC,MAAM,UAAU,IAAwB,IAAI;CAE5C,MAAM,UAAU,WAAW,2BAAuD;EAChF,MAAM,MAAM;EACZ,aAAa,MAAM;EACnB,UAAU,MAAM;EAChB,eAAe,MAAM;EACrB,cAAc,QAAQ;
|
|
1
|
+
{"version":3,"file":"use-float-button.js","names":[],"sources":["../../../src/components/float-button/use-float-button.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 use float button 相关实现。\n\nimport type { Layer, RuntimeConfig, Service } from '@xihan-ui/core'\nimport type { FloatButtonApi, FloatButtonNotifiers, FloatButtonProps, FloatButtonSchema } from '@xihan-ui/headless'\nimport type { ComputedRef, Ref } from 'vue'\nimport { createRuntimeConfig, createScope } from '@xihan-ui/core'\nimport { connectFloatButton, floatButtonMachine } from '@xihan-ui/headless'\nimport { computed, ref } from 'vue'\nimport { vueNormalize } from '../../runtime/normalize-props'\nimport { useMachine } from '../../runtime/use-machine'\nimport { createVueIdGenerator } from '../../runtime/vue-id'\n\nexport interface FloatButtonContext {\n api: ComputedRef<FloatButtonApi>\n service: Service<FloatButtonSchema>\n rootRef: Ref<HTMLElement | null>\n}\n\n/**\n * 专用状态机持有开合与逻辑层生命周期;Vue 只桥接所属 Document 的配置、登记函数与 root ref。\n */\nexport function useFloatButton(\n props: FloatButtonProps,\n notify?: FloatButtonNotifiers,\n): FloatButtonContext {\n const idGen = createVueIdGenerator()\n const scope = createScope(null, idGen)\n const rootRef = ref<HTMLElement | null>(null)\n\n const service = useMachine(floatButtonMachine, (): FloatButtonSchema['props'] => ({\n open: props.open,\n defaultOpen: props.defaultOpen,\n disabled: props.disabled,\n expandTrigger: props.expandTrigger,\n offset: props.offset,\n draggable: props.draggable,\n snap: props.snap,\n position: props.position,\n defaultPosition: props.defaultPosition,\n onOpenChange: notify?.onOpenChange,\n onPositionChange: notify?.onPositionChange,\n }), scope)\n\n let config: RuntimeConfig | null = null\n if (typeof document !== 'undefined') {\n config = createRuntimeConfig({ scope, idGenerator: idGen })\n const registerLayer = (\n layer: Omit<Layer, 'id'>,\n ): ReturnType<RuntimeConfig['layerRegistry']['register']> => config!.layerRegistry.register(layer)\n service.refs.set('config', config)\n service.refs.set('registerLayer', registerLayer)\n }\n service.refs.set('getRootEl', () => rootRef.value)\n\n const api = computed(() => connectFloatButton(service, props, vueNormalize))\n return { api, service, rootRef }\n}\n"],"mappings":";;;;;;;;;;AA0BA,SAAgB,eACd,OACA,QACoB;CACpB,MAAM,QAAQ,qBAAqB;CACnC,MAAM,QAAQ,YAAY,MAAM,KAAK;CACrC,MAAM,UAAU,IAAwB,IAAI;CAE5C,MAAM,UAAU,WAAW,2BAAuD;EAChF,MAAM,MAAM;EACZ,aAAa,MAAM;EACnB,UAAU,MAAM;EAChB,eAAe,MAAM;EACrB,QAAQ,MAAM;EACd,WAAW,MAAM;EACjB,MAAM,MAAM;EACZ,UAAU,MAAM;EAChB,iBAAiB,MAAM;EACvB,cAAc,QAAQ;EACtB,kBAAkB,QAAQ;CAC5B,IAAI,KAAK;CAET,IAAI,SAA+B;CACnC,IAAI,OAAO,aAAa,aAAa;EACnC,SAAS,oBAAoB;GAAE;GAAO,aAAa;EAAM,CAAC;EAC1D,MAAM,iBACJ,UAC2D,OAAQ,cAAc,SAAS,KAAK;EACjG,QAAQ,KAAK,IAAI,UAAU,MAAM;EACjC,QAAQ,KAAK,IAAI,iBAAiB,aAAa;CACjD;CACA,QAAQ,KAAK,IAAI,mBAAmB,QAAQ,KAAK;CAGjD,OAAO;EAAE,KADG,eAAe,mBAAmB,SAAS,OAAO,YAAY,CAC/D;EAAG;EAAS;CAAQ;AACjC"}
|
|
@@ -115,10 +115,10 @@ declare const XhFloatingPanelRoot: import("vue").DefineComponent<import("vue").E
|
|
|
115
115
|
}>> & Readonly<{
|
|
116
116
|
"onOpen-change"?: ((_details: import("@xihan-ui/headless").FloatingPanelOpenChangeDetails) => any) | undefined;
|
|
117
117
|
"onUpdate:open"?: ((_open: boolean) => any) | undefined;
|
|
118
|
-
"onPosition-change"?: ((_details: import("@xihan-ui/headless").FloatingPanelPositionChangeDetails) => any) | undefined;
|
|
119
|
-
"onUpdate:position"?: ((_position: FloatingPanelPosition) => any) | undefined;
|
|
120
118
|
"onDimensions-change"?: ((_details: import("@xihan-ui/headless").FloatingPanelDimensionsChangeDetails) => any) | undefined;
|
|
121
119
|
"onUpdate:dimensions"?: ((_dimensions: FloatingPanelSize) => any) | undefined;
|
|
120
|
+
"onPosition-change"?: ((_details: import("@xihan-ui/headless").FloatingPanelPositionChangeDetails) => any) | undefined;
|
|
121
|
+
"onUpdate:position"?: ((_position: FloatingPanelPosition) => any) | undefined;
|
|
122
122
|
"onWindow-state-change"?: ((_details: import("@xihan-ui/headless").FloatingPanelWindowStateChangeDetails) => any) | undefined;
|
|
123
123
|
"onUpdate:windowState"?: ((_windowState: FloatingPanelWindowState) => any) | undefined;
|
|
124
124
|
}>, {
|
|
@@ -99,7 +99,10 @@ container: { type: Object } },
|
|
|
99
99
|
inheritAttrs: false,
|
|
100
100
|
setup(props, { slots, attrs }) {
|
|
101
101
|
const ctx = useFloatingPanelContext();
|
|
102
|
-
return () => h(XhPortal, {
|
|
102
|
+
return () => h(XhPortal, {
|
|
103
|
+
to: props.container ?? ctx.portalTarget.value,
|
|
104
|
+
present: ctx.visible.value
|
|
105
|
+
}, () => [h("div", {
|
|
103
106
|
...mergeProps(ctx.api.value.getPositionerProps(), attrs, ctx.visible.value ? {} : { style: { display: "none" } }),
|
|
104
107
|
ref: (el) => {
|
|
105
108
|
ctx.positionerRef.value = el;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floating-panel.js","names":[],"sources":["../../../src/components/floating-panel/floating-panel.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 floating panel 相关实现。\n\nimport type {\n FloatingPanelApi,\n FloatingPanelPosition,\n FloatingPanelResizeEdge,\n FloatingPanelSchema,\n FloatingPanelSize,\n FloatingPanelWindowState,\n} from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h, mergeProps } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { XhPortal } from '../../runtime/portal'\nimport { provideFloatingPanel, useFloatingPanelContext } from './context'\nimport { useFloatingPanel } from './use-floating-panel'\n\ntype FloatingPanelProps = FloatingPanelSchema['props']\n\n/** 默认插槽的载荷:开合、形态与矩形,以及修改这四项的动作。 */\nexport type FloatingPanelRootSlotProps = Pick<\n FloatingPanelApi,\n 'open' | 'windowState' | 'position' | 'dimensions' | 'dragging' | 'resizing' | 'canDrag' | 'canResize'\n | 'setOpen' | 'setPosition' | 'setDimensions' | 'setWindowState'\n>\n\nexport const XhFloatingPanelRoot = defineComponent({\n name: 'XhFloatingPanelRoot',\n // 缺省值由 connect 与机器决定;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n open: { type: Boolean, default: undefined },\n defaultOpen: { type: Boolean, default: undefined },\n position: { type: Object as PropType<FloatingPanelPosition> },\n defaultPosition: { type: Object as PropType<FloatingPanelPosition> },\n dimensions: { type: Object as PropType<FloatingPanelSize> },\n defaultDimensions: { type: Object as PropType<FloatingPanelSize> },\n minSize: { type: Object as PropType<FloatingPanelSize> },\n maxSize: { type: Object as PropType<FloatingPanelSize> },\n windowState: { type: String as PropType<FloatingPanelWindowState> },\n defaultWindowState: { type: String as PropType<FloatingPanelWindowState> },\n // 缺省为真的两个开关:写成裸 Boolean 会被 Vue 的布尔 casting 永久关死\n draggable: { type: Boolean, default: undefined },\n resizable: { type: Boolean, default: undefined },\n disabled: { type: Boolean, default: undefined },\n translations: { type: Object as PropType<FloatingPanelProps['translations']> },\n },\n // 语义事件收整个 details,update: 收裸值\n emits: {\n 'open-change': (_details: PayloadOf<FloatingPanelProps, 'onOpenChange'>) => true,\n 'update:open': (_open: PayloadOf<FloatingPanelProps, 'onOpenChange'>['open']) => true,\n 'position-change': (_details: PayloadOf<FloatingPanelProps, 'onPositionChange'>) => true,\n 'update:position': (_position: PayloadOf<FloatingPanelProps, 'onPositionChange'>['position']) => true,\n 'dimensions-change': (_details: PayloadOf<FloatingPanelProps, 'onDimensionsChange'>) => true,\n 'update:dimensions': (_dimensions: PayloadOf<FloatingPanelProps, 'onDimensionsChange'>['dimensions']) => true,\n 'window-state-change': (_details: PayloadOf<FloatingPanelProps, 'onWindowStateChange'>) => true,\n 'update:windowState': (_windowState: PayloadOf<FloatingPanelProps, 'onWindowStateChange'>['windowState']) => true,\n },\n slots: Object as SlotsType<{\n default?: (props: FloatingPanelRootSlotProps) => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const ctx = useFloatingPanel(withXhConfig('floating-panel', props) as FloatingPanelProps, {\n onOpenChange: (details) => {\n emit('open-change', details)\n emit('update:open', details.open)\n },\n onPositionChange: (details) => {\n emit('position-change', details)\n emit('update:position', details.position)\n },\n onDimensionsChange: (details) => {\n emit('dimensions-change', details)\n emit('update:dimensions', details.dimensions)\n },\n onWindowStateChange: (details) => {\n emit('window-state-change', details)\n emit('update:windowState', details.windowState)\n },\n })\n provideFloatingPanel(ctx)\n return () => h('div', ctx.api.value.getRootProps() as Record<string, unknown>, slots.default?.({\n open: ctx.api.value.open,\n windowState: ctx.api.value.windowState,\n position: ctx.api.value.position,\n dimensions: ctx.api.value.dimensions,\n dragging: ctx.api.value.dragging,\n resizing: ctx.api.value.resizing,\n canDrag: ctx.api.value.canDrag,\n canResize: ctx.api.value.canResize,\n setOpen: ctx.api.value.setOpen,\n setPosition: ctx.api.value.setPosition,\n setDimensions: ctx.api.value.setDimensions,\n setWindowState: ctx.api.value.setWindowState,\n }))\n },\n})\n\nexport const XhFloatingPanelTrigger = defineComponent({\n name: 'XhFloatingPanelTrigger',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n // 用原生 button,激活交给平台\n return () => h('button', ctx.api.value.getTriggerProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFloatingPanelPositioner = defineComponent({\n name: 'XhFloatingPanelPositioner',\n props: {\n /** 本实例的 Portal 容器;优先于应用级配置。 */\n container: { type: Object as PropType<Element> },\n },\n // 根是 Teleport,Vue 不会把直通属性合上去,作者写的 class 与 style 得自己接住落到 positioner 上\n inheritAttrs: false,\n setup(props, { slots, attrs }) {\n const ctx = useFloatingPanelContext()\n // 定位层搬到 portal 落点,逃开祖先的层叠上下文\n return () => h(XhPortal, { to: props.container ?? ctx.portalTarget.value }, () => [\n h(\n 'div',\n {\n ...mergeProps(\n ctx.api.value.getPositionerProps() as Record<string, unknown>,\n attrs,\n // 收起跟着退场闸门走:皮肤刻意没给 positioner 补 [hidden]{display:none}(补了\n // 退场就一帧都播不出来),所以真正的收起落成内联 display\n ctx.visible.value ? {} : { style: { display: 'none' } },\n ),\n ref: (el: unknown) => { ctx.positionerRef.value = el as HTMLElement },\n },\n slots.default?.(),\n ),\n ])\n },\n})\n\nexport const XhFloatingPanelContent = defineComponent({\n name: 'XhFloatingPanelContent',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n // 节点交给机器:跟手期间的指针监听要挂在它所在的那个文档上\n return () => h(\n 'div',\n { ...ctx.api.value.getContentProps() as Record<string, unknown>, ref: ctx.contentRef },\n slots.default?.(),\n )\n },\n})\n\nexport const XhFloatingPanelHeader = defineComponent({\n name: 'XhFloatingPanelHeader',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h('div', ctx.api.value.getHeaderProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFloatingPanelTitle = defineComponent({\n name: 'XhFloatingPanelTitle',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h('h2', ctx.api.value.getTitleProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFloatingPanelDragTrigger = defineComponent({\n name: 'XhFloatingPanelDragTrigger',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h('button', ctx.api.value.getDragTriggerProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFloatingPanelResizeTrigger = defineComponent({\n name: 'XhFloatingPanelResizeTrigger',\n props: {\n /** 该把手负责哪条边:n / e / s / w 四条边与 ne / nw / se / sw 四个角。 */\n edge: { type: String as PropType<FloatingPanelResizeEdge>, required: true },\n },\n setup(props, { slots }) {\n const ctx = useFloatingPanelContext()\n // 把手是 role=separator 的元素而不是按钮:方向键推边,按钮的激活键在这里没有语义\n return () => h(\n 'div',\n ctx.api.value.getResizeTriggerProps({ edge: props.edge }) as Record<string, unknown>,\n slots.default?.(),\n )\n },\n})\n\nexport const XhFloatingPanelWindowStateTrigger = defineComponent({\n name: 'XhFloatingPanelWindowStateTrigger',\n props: {\n /** 按下它切换到哪个形态;已处于该形态时再按一次回到常规。 */\n windowState: { type: String as PropType<FloatingPanelWindowState>, required: true },\n },\n setup(props, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h(\n 'button',\n ctx.api.value.getWindowStateTriggerProps({ windowState: props.windowState }) as Record<string, unknown>,\n slots.default?.(),\n )\n },\n})\n\nexport const XhFloatingPanelCloseTrigger = defineComponent({\n name: 'XhFloatingPanelCloseTrigger',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h('button', ctx.api.value.getCloseTriggerProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFloatingPanelBody = defineComponent({\n name: 'XhFloatingPanelBody',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h('div', ctx.api.value.getBodyProps() as Record<string, unknown>, slots.default?.())\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"floating-panel.js","names":[],"sources":["../../../src/components/floating-panel/floating-panel.ts"],"sourcesContent":["/*\n * Copyright (c) 2021-Present XiHanFun and contributors.\n * Licensed under the MIT License. See LICENSE in the project root for license information.\n */\n\n// 提供 floating panel 相关实现。\n\nimport type {\n FloatingPanelApi,\n FloatingPanelPosition,\n FloatingPanelResizeEdge,\n FloatingPanelSchema,\n FloatingPanelSize,\n FloatingPanelWindowState,\n} from '@xihan-ui/headless'\nimport type { PropType, SlotsType, VNode } from 'vue'\nimport type { PayloadOf } from '../../runtime/payload'\nimport { defineComponent, h, mergeProps } from 'vue'\nimport { withXhConfig } from '../../config/config'\nimport { XhPortal } from '../../runtime/portal'\nimport { provideFloatingPanel, useFloatingPanelContext } from './context'\nimport { useFloatingPanel } from './use-floating-panel'\n\ntype FloatingPanelProps = FloatingPanelSchema['props']\n\n/** 默认插槽的载荷:开合、形态与矩形,以及修改这四项的动作。 */\nexport type FloatingPanelRootSlotProps = Pick<\n FloatingPanelApi,\n 'open' | 'windowState' | 'position' | 'dimensions' | 'dragging' | 'resizing' | 'canDrag' | 'canResize'\n | 'setOpen' | 'setPosition' | 'setDimensions' | 'setWindowState'\n>\n\nexport const XhFloatingPanelRoot = defineComponent({\n name: 'XhFloatingPanelRoot',\n // 缺省值由 connect 与机器决定;普通类型省略 default,Boolean 显式保留 undefined\n props: {\n open: { type: Boolean, default: undefined },\n defaultOpen: { type: Boolean, default: undefined },\n position: { type: Object as PropType<FloatingPanelPosition> },\n defaultPosition: { type: Object as PropType<FloatingPanelPosition> },\n dimensions: { type: Object as PropType<FloatingPanelSize> },\n defaultDimensions: { type: Object as PropType<FloatingPanelSize> },\n minSize: { type: Object as PropType<FloatingPanelSize> },\n maxSize: { type: Object as PropType<FloatingPanelSize> },\n windowState: { type: String as PropType<FloatingPanelWindowState> },\n defaultWindowState: { type: String as PropType<FloatingPanelWindowState> },\n // 缺省为真的两个开关:写成裸 Boolean 会被 Vue 的布尔 casting 永久关死\n draggable: { type: Boolean, default: undefined },\n resizable: { type: Boolean, default: undefined },\n disabled: { type: Boolean, default: undefined },\n translations: { type: Object as PropType<FloatingPanelProps['translations']> },\n },\n // 语义事件收整个 details,update: 收裸值\n emits: {\n 'open-change': (_details: PayloadOf<FloatingPanelProps, 'onOpenChange'>) => true,\n 'update:open': (_open: PayloadOf<FloatingPanelProps, 'onOpenChange'>['open']) => true,\n 'position-change': (_details: PayloadOf<FloatingPanelProps, 'onPositionChange'>) => true,\n 'update:position': (_position: PayloadOf<FloatingPanelProps, 'onPositionChange'>['position']) => true,\n 'dimensions-change': (_details: PayloadOf<FloatingPanelProps, 'onDimensionsChange'>) => true,\n 'update:dimensions': (_dimensions: PayloadOf<FloatingPanelProps, 'onDimensionsChange'>['dimensions']) => true,\n 'window-state-change': (_details: PayloadOf<FloatingPanelProps, 'onWindowStateChange'>) => true,\n 'update:windowState': (_windowState: PayloadOf<FloatingPanelProps, 'onWindowStateChange'>['windowState']) => true,\n },\n slots: Object as SlotsType<{\n default?: (props: FloatingPanelRootSlotProps) => VNode[]\n }>,\n setup(props, { slots, emit }) {\n const ctx = useFloatingPanel(withXhConfig('floating-panel', props) as FloatingPanelProps, {\n onOpenChange: (details) => {\n emit('open-change', details)\n emit('update:open', details.open)\n },\n onPositionChange: (details) => {\n emit('position-change', details)\n emit('update:position', details.position)\n },\n onDimensionsChange: (details) => {\n emit('dimensions-change', details)\n emit('update:dimensions', details.dimensions)\n },\n onWindowStateChange: (details) => {\n emit('window-state-change', details)\n emit('update:windowState', details.windowState)\n },\n })\n provideFloatingPanel(ctx)\n return () => h('div', ctx.api.value.getRootProps() as Record<string, unknown>, slots.default?.({\n open: ctx.api.value.open,\n windowState: ctx.api.value.windowState,\n position: ctx.api.value.position,\n dimensions: ctx.api.value.dimensions,\n dragging: ctx.api.value.dragging,\n resizing: ctx.api.value.resizing,\n canDrag: ctx.api.value.canDrag,\n canResize: ctx.api.value.canResize,\n setOpen: ctx.api.value.setOpen,\n setPosition: ctx.api.value.setPosition,\n setDimensions: ctx.api.value.setDimensions,\n setWindowState: ctx.api.value.setWindowState,\n }))\n },\n})\n\nexport const XhFloatingPanelTrigger = defineComponent({\n name: 'XhFloatingPanelTrigger',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n // 用原生 button,激活交给平台\n return () => h('button', ctx.api.value.getTriggerProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFloatingPanelPositioner = defineComponent({\n name: 'XhFloatingPanelPositioner',\n props: {\n /** 本实例的 Portal 容器;优先于应用级配置。 */\n container: { type: Object as PropType<Element> },\n },\n // 根是 Teleport,Vue 不会把直通属性合上去,作者写的 class 与 style 得自己接住落到 positioner 上\n inheritAttrs: false,\n setup(props, { slots, attrs }) {\n const ctx = useFloatingPanelContext()\n // 定位层搬到 portal 落点,逃开祖先的层叠上下文\n return () => h(XhPortal, { to: props.container ?? ctx.portalTarget.value, present: ctx.visible.value }, () => [\n h(\n 'div',\n {\n ...mergeProps(\n ctx.api.value.getPositionerProps() as Record<string, unknown>,\n attrs,\n // 收起跟着退场闸门走:皮肤刻意没给 positioner 补 [hidden]{display:none}(补了\n // 退场就一帧都播不出来),所以真正的收起落成内联 display\n ctx.visible.value ? {} : { style: { display: 'none' } },\n ),\n ref: (el: unknown) => { ctx.positionerRef.value = el as HTMLElement },\n },\n slots.default?.(),\n ),\n ])\n },\n})\n\nexport const XhFloatingPanelContent = defineComponent({\n name: 'XhFloatingPanelContent',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n // 节点交给机器:跟手期间的指针监听要挂在它所在的那个文档上\n return () => h(\n 'div',\n { ...ctx.api.value.getContentProps() as Record<string, unknown>, ref: ctx.contentRef },\n slots.default?.(),\n )\n },\n})\n\nexport const XhFloatingPanelHeader = defineComponent({\n name: 'XhFloatingPanelHeader',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h('div', ctx.api.value.getHeaderProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFloatingPanelTitle = defineComponent({\n name: 'XhFloatingPanelTitle',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h('h2', ctx.api.value.getTitleProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFloatingPanelDragTrigger = defineComponent({\n name: 'XhFloatingPanelDragTrigger',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h('button', ctx.api.value.getDragTriggerProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFloatingPanelResizeTrigger = defineComponent({\n name: 'XhFloatingPanelResizeTrigger',\n props: {\n /** 该把手负责哪条边:n / e / s / w 四条边与 ne / nw / se / sw 四个角。 */\n edge: { type: String as PropType<FloatingPanelResizeEdge>, required: true },\n },\n setup(props, { slots }) {\n const ctx = useFloatingPanelContext()\n // 把手是 role=separator 的元素而不是按钮:方向键推边,按钮的激活键在这里没有语义\n return () => h(\n 'div',\n ctx.api.value.getResizeTriggerProps({ edge: props.edge }) as Record<string, unknown>,\n slots.default?.(),\n )\n },\n})\n\nexport const XhFloatingPanelWindowStateTrigger = defineComponent({\n name: 'XhFloatingPanelWindowStateTrigger',\n props: {\n /** 按下它切换到哪个形态;已处于该形态时再按一次回到常规。 */\n windowState: { type: String as PropType<FloatingPanelWindowState>, required: true },\n },\n setup(props, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h(\n 'button',\n ctx.api.value.getWindowStateTriggerProps({ windowState: props.windowState }) as Record<string, unknown>,\n slots.default?.(),\n )\n },\n})\n\nexport const XhFloatingPanelCloseTrigger = defineComponent({\n name: 'XhFloatingPanelCloseTrigger',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h('button', ctx.api.value.getCloseTriggerProps() as Record<string, unknown>, slots.default?.())\n },\n})\n\nexport const XhFloatingPanelBody = defineComponent({\n name: 'XhFloatingPanelBody',\n setup(_, { slots }) {\n const ctx = useFloatingPanelContext()\n return () => h('div', ctx.api.value.getBodyProps() as Record<string, unknown>, slots.default?.())\n },\n})\n"],"mappings":"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"}
|