@zerodep-dev/vue-tsx-pro-mobile 0.0.0-stage → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -2
  3. package/dist/area/data.d.ts +10 -0
  4. package/dist/area/data.js +3899 -0
  5. package/dist/area/data.js.map +1 -0
  6. package/dist/area/index.d.ts +22 -0
  7. package/dist/area/index.js +41 -0
  8. package/dist/area/index.js.map +1 -0
  9. package/dist/base/Button.d.ts +170 -0
  10. package/dist/base/Button.js +537 -0
  11. package/dist/base/Button.js.map +1 -0
  12. package/dist/base/Icon.d.ts +38 -0
  13. package/dist/base/Icon.js +65 -0
  14. package/dist/base/Icon.js.map +1 -0
  15. package/dist/capability/PrivacyPrompt.d.ts +1 -0
  16. package/dist/capability/PrivacyPrompt.js +73 -0
  17. package/dist/capability/PrivacyPrompt.js.map +1 -0
  18. package/dist/capability/types.d.ts +92 -0
  19. package/dist/capability/usePermission.d.ts +23 -0
  20. package/dist/capability/usePermission.js +52 -0
  21. package/dist/capability/usePermission.js.map +1 -0
  22. package/dist/capability/useStorage.d.ts +8 -0
  23. package/dist/capability/useStorage.js +19 -0
  24. package/dist/capability/useStorage.js.map +1 -0
  25. package/dist/capability/web.d.ts +18 -0
  26. package/dist/capability/web.js +109 -0
  27. package/dist/capability/web.js.map +1 -0
  28. package/dist/capacitor/index.d.ts +9 -0
  29. package/dist/capacitor/index.js +143 -0
  30. package/dist/capacitor/index.js.map +1 -0
  31. package/dist/config/ConfigProvider.d.ts +37 -0
  32. package/dist/config/ConfigProvider.js +64 -0
  33. package/dist/config/ConfigProvider.js.map +1 -0
  34. package/dist/config/context.d.ts +16 -0
  35. package/dist/config/context.js +20 -0
  36. package/dist/config/context.js.map +1 -0
  37. package/dist/config/lang.d.ts +85 -0
  38. package/dist/config/lang.js +138 -0
  39. package/dist/config/lang.js.map +1 -0
  40. package/dist/display/Badge.d.ts +39 -0
  41. package/dist/display/Badge.js +108 -0
  42. package/dist/display/Badge.js.map +1 -0
  43. package/dist/display/Cell.d.ts +92 -0
  44. package/dist/display/Cell.js +204 -0
  45. package/dist/display/Cell.js.map +1 -0
  46. package/dist/display/Collapse.d.ts +47 -0
  47. package/dist/display/Collapse.js +173 -0
  48. package/dist/display/Collapse.js.map +1 -0
  49. package/dist/display/Empty.d.ts +42 -0
  50. package/dist/display/Empty.js +79 -0
  51. package/dist/display/Empty.js.map +1 -0
  52. package/dist/display/Grid.d.ts +49 -0
  53. package/dist/display/Grid.js +136 -0
  54. package/dist/display/Grid.js.map +1 -0
  55. package/dist/display/Image.d.ts +70 -0
  56. package/dist/display/Image.js +138 -0
  57. package/dist/display/Image.js.map +1 -0
  58. package/dist/display/IndexBar.d.ts +34 -0
  59. package/dist/display/IndexBar.js +158 -0
  60. package/dist/display/IndexBar.js.map +1 -0
  61. package/dist/display/List.d.ts +34 -0
  62. package/dist/display/List.js +105 -0
  63. package/dist/display/List.js.map +1 -0
  64. package/dist/display/NoticeBar.d.ts +57 -0
  65. package/dist/display/NoticeBar.js +172 -0
  66. package/dist/display/NoticeBar.js.map +1 -0
  67. package/dist/display/Steps.d.ts +59 -0
  68. package/dist/display/Steps.js +158 -0
  69. package/dist/display/Steps.js.map +1 -0
  70. package/dist/display/SwipeCell.d.ts +37 -0
  71. package/dist/display/SwipeCell.js +147 -0
  72. package/dist/display/SwipeCell.js.map +1 -0
  73. package/dist/display/Swiper.d.ts +47 -0
  74. package/dist/display/Swiper.js +173 -0
  75. package/dist/display/Swiper.js.map +1 -0
  76. package/dist/display/Tag.d.ts +99 -0
  77. package/dist/display/Tag.js +320 -0
  78. package/dist/display/Tag.js.map +1 -0
  79. package/dist/feedback/Dialog.d.ts +79 -0
  80. package/dist/feedback/Dialog.js +186 -0
  81. package/dist/feedback/Dialog.js.map +1 -0
  82. package/dist/feedback/FeedbackOutlet.d.ts +2 -0
  83. package/dist/feedback/FeedbackOutlet.js +31 -0
  84. package/dist/feedback/FeedbackOutlet.js.map +1 -0
  85. package/dist/feedback/Loading.d.ts +26 -0
  86. package/dist/feedback/Loading.js +68 -0
  87. package/dist/feedback/Loading.js.map +1 -0
  88. package/dist/feedback/Notify.d.ts +48 -0
  89. package/dist/feedback/Notify.js +116 -0
  90. package/dist/feedback/Notify.js.map +1 -0
  91. package/dist/feedback/PullRefresh.d.ts +58 -0
  92. package/dist/feedback/PullRefresh.js +178 -0
  93. package/dist/feedback/PullRefresh.js.map +1 -0
  94. package/dist/feedback/Skeleton.d.ts +56 -0
  95. package/dist/feedback/Skeleton.js +99 -0
  96. package/dist/feedback/Skeleton.js.map +1 -0
  97. package/dist/feedback/Toast.d.ts +89 -0
  98. package/dist/feedback/Toast.js +186 -0
  99. package/dist/feedback/Toast.js.map +1 -0
  100. package/dist/form/Checkbox.d.ts +52 -0
  101. package/dist/form/Checkbox.js +107 -0
  102. package/dist/form/Checkbox.js.map +1 -0
  103. package/dist/form/Field.d.ts +91 -0
  104. package/dist/form/Field.js +296 -0
  105. package/dist/form/Field.js.map +1 -0
  106. package/dist/form/Form.d.ts +50 -0
  107. package/dist/form/Form.js +96 -0
  108. package/dist/form/Form.js.map +1 -0
  109. package/dist/form/FormItem.d.ts +57 -0
  110. package/dist/form/FormItem.js +142 -0
  111. package/dist/form/FormItem.js.map +1 -0
  112. package/dist/form/Radio.d.ts +41 -0
  113. package/dist/form/Radio.js +85 -0
  114. package/dist/form/Radio.js.map +1 -0
  115. package/dist/form/Rate.d.ts +45 -0
  116. package/dist/form/Rate.js +162 -0
  117. package/dist/form/Rate.js.map +1 -0
  118. package/dist/form/Search.d.ts +50 -0
  119. package/dist/form/Search.js +152 -0
  120. package/dist/form/Search.js.map +1 -0
  121. package/dist/form/Slider.d.ts +43 -0
  122. package/dist/form/Slider.js +213 -0
  123. package/dist/form/Slider.js.map +1 -0
  124. package/dist/form/Stepper.d.ts +61 -0
  125. package/dist/form/Stepper.js +222 -0
  126. package/dist/form/Stepper.js.map +1 -0
  127. package/dist/form/Switch.d.ts +33 -0
  128. package/dist/form/Switch.js +116 -0
  129. package/dist/form/Switch.js.map +1 -0
  130. package/dist/form/Uploader.d.ts +67 -0
  131. package/dist/form/Uploader.js +207 -0
  132. package/dist/form/Uploader.js.map +1 -0
  133. package/dist/form/choice.d.ts +42 -0
  134. package/dist/form/choice.js +109 -0
  135. package/dist/form/choice.js.map +1 -0
  136. package/dist/form/context.d.ts +83 -0
  137. package/dist/form/context.js +89 -0
  138. package/dist/form/context.js.map +1 -0
  139. package/dist/index.d.ts +66 -0
  140. package/dist/index.js +59 -0
  141. package/dist/layout/Divider.d.ts +34 -0
  142. package/dist/layout/Divider.js +55 -0
  143. package/dist/layout/Divider.js.map +1 -0
  144. package/dist/layout/Space.d.ts +66 -0
  145. package/dist/layout/Space.js +65 -0
  146. package/dist/layout/Space.js.map +1 -0
  147. package/dist/navigation/BackTop.d.ts +29 -0
  148. package/dist/navigation/BackTop.js +89 -0
  149. package/dist/navigation/BackTop.js.map +1 -0
  150. package/dist/navigation/NavBar.d.ts +46 -0
  151. package/dist/navigation/NavBar.js +141 -0
  152. package/dist/navigation/NavBar.js.map +1 -0
  153. package/dist/navigation/Sticky.d.ts +19 -0
  154. package/dist/navigation/Sticky.js +28 -0
  155. package/dist/navigation/Sticky.js.map +1 -0
  156. package/dist/navigation/TabBar.d.ts +54 -0
  157. package/dist/navigation/TabBar.js +138 -0
  158. package/dist/navigation/TabBar.js.map +1 -0
  159. package/dist/navigation/Tabs.d.ts +45 -0
  160. package/dist/navigation/Tabs.js +206 -0
  161. package/dist/navigation/Tabs.js.map +1 -0
  162. package/dist/overlay/ActionSheet.d.ts +80 -0
  163. package/dist/overlay/ActionSheet.js +164 -0
  164. package/dist/overlay/ActionSheet.js.map +1 -0
  165. package/dist/overlay/Overlay.d.ts +35 -0
  166. package/dist/overlay/Overlay.js +85 -0
  167. package/dist/overlay/Overlay.js.map +1 -0
  168. package/dist/overlay/Popup.d.ts +76 -0
  169. package/dist/overlay/Popup.js +191 -0
  170. package/dist/overlay/Popup.js.map +1 -0
  171. package/dist/picker/Calendar.d.ts +69 -0
  172. package/dist/picker/Calendar.js +213 -0
  173. package/dist/picker/Calendar.js.map +1 -0
  174. package/dist/picker/Cascader.d.ts +50 -0
  175. package/dist/picker/Cascader.js +199 -0
  176. package/dist/picker/Cascader.js.map +1 -0
  177. package/dist/picker/DatePicker.d.ts +52 -0
  178. package/dist/picker/DatePicker.js +135 -0
  179. package/dist/picker/DatePicker.js.map +1 -0
  180. package/dist/picker/DropdownMenu.d.ts +39 -0
  181. package/dist/picker/DropdownMenu.js +242 -0
  182. package/dist/picker/DropdownMenu.js.map +1 -0
  183. package/dist/picker/Picker.d.ts +67 -0
  184. package/dist/picker/Picker.js +185 -0
  185. package/dist/picker/Picker.js.map +1 -0
  186. package/dist/picker/PickerColumn.d.ts +36 -0
  187. package/dist/picker/PickerColumn.js +175 -0
  188. package/dist/picker/PickerColumn.js.map +1 -0
  189. package/dist/theme/dark.d.ts +121 -0
  190. package/dist/theme/dark.js +77 -0
  191. package/dist/theme/dark.js.map +1 -0
  192. package/dist/theme/divider.d.ts +6 -0
  193. package/dist/theme/divider.js +18 -0
  194. package/dist/theme/divider.js.map +1 -0
  195. package/dist/theme/token-names.d.ts +1389 -0
  196. package/dist/theme/tokens.d.ts +549 -0
  197. package/dist/theme/tokens.js +312 -0
  198. package/dist/theme/tokens.js.map +1 -0
  199. package/dist/utils/host.d.ts +97 -0
  200. package/dist/utils/host.js +98 -0
  201. package/dist/utils/host.js.map +1 -0
  202. package/dist/utils/presence.d.ts +11 -0
  203. package/dist/utils/presence.js +34 -0
  204. package/dist/utils/presence.js.map +1 -0
  205. package/dist/utils/props.d.ts +38 -0
  206. package/dist/utils/props.js +115 -0
  207. package/dist/utils/props.js.map +1 -0
  208. package/dist/utils/scales.d.ts +48 -0
  209. package/package.json +106 -3
@@ -0,0 +1,158 @@
1
+ import { t } from "../theme/tokens.js";
2
+ import { dataAttrs, hasContent, mergeAttrs } from "../utils/props.js";
3
+ import { Icon } from "../base/Icon.js";
4
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
5
+ import { _component, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
6
+ import { createVNode } from "vue";
7
+ import { Check, X } from "@lucide/icons";
8
+ //#region src/display/Steps.tsx
9
+ /**
10
+ * 步骤条:一件事分几步,标出已完成、进行中、未开始(下单流程、物流进度)。横排放标题;竖排可带说明与时间,常用于物流。
11
+ *
12
+ * <Steps active={1} items={[{ title: '下单' }, { title: '付款' }, { title: '发货' }, { title: '收货' }]} />
13
+ * <Steps direction="vertical" active={0} items={[{ title: '已签收', description: '2026-10-30 09:12' }, …]} />
14
+ */
15
+ /** 一步的状态 */
16
+ /** 一步 */
17
+ /** 未声明的属性落到根元素(div)上 */
18
+ /** Steps 的样式 */
19
+ var stepsStyles = css.create({
20
+ root: {
21
+ display: "flex",
22
+ paddingBlock: "_md",
23
+ paddingInline: "_sm",
24
+ backgroundColor: "_surface"
25
+ },
26
+ vertical: {
27
+ flexDirection: "column",
28
+ paddingInline: "_lg"
29
+ },
30
+ item: {
31
+ position: "relative",
32
+ flex: "1 1 0",
33
+ minWidth: 0,
34
+ display: "flex",
35
+ flexDirection: "column",
36
+ alignItems: "center",
37
+ gap: "0.4em",
38
+ fontSize: "_xs",
39
+ textAlign: "center",
40
+ color: {
41
+ default: "_textMuted",
42
+ "[data-status=\"process\"]": "_accentText",
43
+ "[data-status=\"done\"]": "_text",
44
+ "[data-status=\"error\"]": "_dangerText"
45
+ }
46
+ },
47
+ itemVertical: {
48
+ flexDirection: "row",
49
+ alignItems: "flex-start",
50
+ gap: "_md",
51
+ paddingBlockEnd: "1.2em",
52
+ textAlign: "start",
53
+ fontSize: "_sm"
54
+ },
55
+ line: {
56
+ position: "absolute",
57
+ insetBlockStart: "0.65em",
58
+ insetInlineStart: "50%",
59
+ width: "100%",
60
+ height: t.borderWidths.hairline,
61
+ backgroundColor: {
62
+ default: "_border",
63
+ "[data-done]": "_accent"
64
+ }
65
+ },
66
+ lineVertical: {
67
+ insetBlockStart: "1.4em",
68
+ insetBlockEnd: "-0.1em",
69
+ insetInlineStart: "0.65em",
70
+ width: t.borderWidths.hairline,
71
+ height: "auto"
72
+ },
73
+ dot: {
74
+ boxSizing: "border-box",
75
+ position: "relative",
76
+ zIndex: 1,
77
+ flex: "none",
78
+ display: "inline-flex",
79
+ alignItems: "center",
80
+ justifyContent: "center",
81
+ width: "1.3em",
82
+ height: "1.3em",
83
+ borderRadius: "_full",
84
+ color: "_accentContrast",
85
+ fontSize: "1em"
86
+ },
87
+ wait: {
88
+ borderWidth: "_xs",
89
+ borderStyle: "solid",
90
+ borderColor: "_borderStrong",
91
+ backgroundColor: "_surface"
92
+ },
93
+ process: {
94
+ backgroundColor: "_accent",
95
+ boxShadow: `0 0 0 0.25em ${t.colors.accentSoft}`
96
+ },
97
+ done: { backgroundColor: "_accent" },
98
+ error: {
99
+ backgroundColor: "_danger",
100
+ color: "_dangerContrast"
101
+ },
102
+ body: {
103
+ display: "flex",
104
+ flexDirection: "column",
105
+ gap: "0.2em",
106
+ minWidth: 0,
107
+ overflowWrap: "anywhere"
108
+ },
109
+ title: { lineHeight: "1.4" },
110
+ description: {
111
+ fontSize: "_xs",
112
+ color: "_textMuted"
113
+ }
114
+ });
115
+ /** 步骤条(div[role=list] > 各步) */
116
+ var Steps = /*#__PURE__*/ _component((_props, _ctx) => {
117
+ const items = readonlyProp(_props, "items");
118
+ const active = readonlyProp(_props, "active", 0);
119
+ const direction = readonlyProp(_props, "direction", "horizontal");
120
+ const propsItem = readonlyProp(_props, "propsItem");
121
+ const rest = restProps(_props, _ctx, true);
122
+ return () => {
123
+ const vertical = direction.value === "vertical";
124
+ return createVNode("div", mergeAttrs({ sx: [stepsStyles.root, vertical && stepsStyles.vertical] }, rest, { role: "list" }), [items.value.map((item, index) => {
125
+ const status = item.status ?? (index < active.value ? "done" : index === active.value ? "process" : "wait");
126
+ const last = index === items.value.length - 1;
127
+ return createVNode("div", mergeAttrs({ sx: [stepsStyles.item, vertical && stepsStyles.itemVertical] }, propsItem.value, {
128
+ role: "listitem",
129
+ "aria-current": status === "process" ? "step" : void 0,
130
+ ...dataAttrs({ "data-status": status })
131
+ }), [
132
+ !last && createVNode("span", mergeAttrs({ sx: [stepsStyles.line, vertical && stepsStyles.lineVertical] }, dataAttrs({ "data-done": status === "done" })), null),
133
+ createVNode("span", mergeAttrs({ sx: [stepsStyles.dot, stepsStyles[status]] }), [status === "done" && createVNode(Icon, {
134
+ "icon": Check,
135
+ "strokeWidth": 3,
136
+ "size": 11
137
+ }, null), status === "error" && createVNode(Icon, {
138
+ "icon": X,
139
+ "strokeWidth": 3,
140
+ "size": 11
141
+ }, null)]),
142
+ createVNode("span", mergeAttrs({ sx: stepsStyles.body }), [createVNode("span", mergeAttrs({ sx: stepsStyles.title }), [item.title]), vertical && hasContent(item.description) && createVNode("span", mergeAttrs({ sx: stepsStyles.description }), [item.description])])
143
+ ]);
144
+ })]);
145
+ };
146
+ }, {
147
+ name: "Steps",
148
+ props: [
149
+ "items",
150
+ "active",
151
+ "direction",
152
+ "propsItem"
153
+ ]
154
+ });
155
+ //#endregion
156
+ export { Steps, stepsStyles };
157
+
158
+ //# sourceMappingURL=Steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Steps.js","names":["_vtp_readonlyProp","_vtp_restProps","_createVNode"],"sources":["../../src/display/Steps.tsx"],"sourcesContent":["/**\n * 步骤条:一件事分几步,标出已完成、进行中、未开始(下单流程、物流进度)。横排放标题;竖排可带说明与时间,常用于物流。\n *\n * <Steps active={1} items={[{ title: '下单' }, { title: '付款' }, { title: '发货' }, { title: '收货' }]} />\n * <Steps direction=\"vertical\" active={0} items={[{ title: '已签收', description: '2026-10-30 09:12' }, …]} />\n */\nimport { Check, X } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { Icon } from '../base/Icon';\nimport { t } from '../theme/tokens';\nimport { dataAttrs, hasContent, mergeAttrs, type PartProps } from '../utils/props';\n\n/** 一步的状态 */\nexport interface StepStatuses {\n /** 已完成:对勾 */\n done: unknown;\n /** 进行中:实心的主色圆点 */\n process: unknown;\n /** 未开始:灰色圆点 */\n wait: unknown;\n /** 出错:叉 */\n error: unknown;\n}\n\n/** 一步 */\nexport interface StepItem {\n /** 标题 */\n title: VNodeChild;\n /** 说明(竖排时显示在标题下面) */\n description?: VNodeChild;\n /** 状态;不给时按 active 算 */\n status?: keyof StepStatuses;\n}\n\n/** 未声明的属性落到根元素(div)上 */\nexport interface StepsProps extends PartProps<'div', 'role'> {\n /** 各步 */\n items: StepItem[];\n /**\n * 当前是第几步(从 0 开始):之前的是已完成,这一步是进行中\n * @default 0\n */\n active?: number;\n /**\n * 方向\n * @default 'horizontal'\n */\n direction?: 'horizontal' | 'vertical';\n /** 每一步的部件属性 */\n propsItem?: PartProps<'div'>;\n}\n\n/** Steps 的样式 */\nexport const stepsStyles = css.create({\n root: { display: 'flex', paddingBlock: '_md', paddingInline: '_sm', backgroundColor: '_surface' },\n vertical: { flexDirection: 'column', paddingInline: '_lg' },\n item: {\n position: 'relative',\n flex: '1 1 0',\n minWidth: 0,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '0.4em',\n fontSize: '_xs',\n textAlign: 'center',\n color: {\n default: '_textMuted',\n '[data-status=\"process\"]': '_accentText',\n '[data-status=\"done\"]': '_text',\n '[data-status=\"error\"]': '_dangerText',\n },\n },\n itemVertical: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n gap: '_md',\n paddingBlockEnd: '1.2em',\n textAlign: 'start',\n fontSize: '_sm',\n },\n // 连接线:横排在圆点中线上、从这一步的中心连到下一步的中心;竖排在圆点下面\n line: {\n position: 'absolute',\n insetBlockStart: '0.65em',\n insetInlineStart: '50%',\n width: '100%',\n height: t.borderWidths.hairline,\n backgroundColor: { default: '_border', '[data-done]': '_accent' },\n },\n lineVertical: {\n insetBlockStart: '1.4em',\n insetBlockEnd: '-0.1em',\n insetInlineStart: '0.65em',\n width: t.borderWidths.hairline,\n height: 'auto',\n },\n dot: {\n boxSizing: 'border-box',\n position: 'relative',\n zIndex: 1,\n flex: 'none',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '1.3em',\n height: '1.3em',\n borderRadius: '_full',\n color: '_accentContrast',\n fontSize: '1em',\n },\n wait: {\n borderWidth: '_xs',\n borderStyle: 'solid',\n borderColor: '_borderStrong',\n backgroundColor: '_surface',\n },\n process: { backgroundColor: '_accent', boxShadow: `0 0 0 0.25em ${t.colors.accentSoft}` },\n done: { backgroundColor: '_accent' },\n error: { backgroundColor: '_danger', color: '_dangerContrast' },\n body: {\n display: 'flex',\n flexDirection: 'column',\n gap: '0.2em',\n minWidth: 0,\n overflowWrap: 'anywhere',\n },\n title: { lineHeight: '1.4' },\n description: { fontSize: '_xs', color: '_textMuted' },\n});\n\n/** 步骤条(div[role=list] > 各步) */\nexport const Steps = _component(\n ({ items, active = 0, direction = 'horizontal', propsItem, ...rest }: StepsProps) =>\n () => {\n const vertical = direction === 'vertical';\n return (\n <div\n {...mergeAttrs<'div'>(\n { sx: [stepsStyles.root, vertical && stepsStyles.vertical] },\n rest,\n {\n role: 'list',\n },\n )}\n >\n {items.map((item, index) => {\n const status =\n item.status ?? (index < active ? 'done' : index === active ? 'process' : 'wait');\n const last = index === items.length - 1;\n return (\n <div\n {...mergeAttrs<'div'>(\n { sx: [stepsStyles.item, vertical && stepsStyles.itemVertical] },\n propsItem,\n {\n role: 'listitem',\n 'aria-current': status === 'process' ? 'step' : undefined,\n ...dataAttrs({ 'data-status': status }),\n },\n )}\n >\n {!last && (\n <span\n {...mergeAttrs<'span'>(\n { sx: [stepsStyles.line, vertical && stepsStyles.lineVertical] },\n dataAttrs({ 'data-done': status === 'done' }),\n )}\n />\n )}\n <span {...mergeAttrs<'span'>({ sx: [stepsStyles.dot, stepsStyles[status]] })}>\n {status === 'done' && <Icon icon={Check} strokeWidth={3} size={11} />}\n {status === 'error' && <Icon icon={X} strokeWidth={3} size={11} />}\n </span>\n <span {...mergeAttrs<'span'>({ sx: stepsStyles.body })}>\n <span {...mergeAttrs<'span'>({ sx: stepsStyles.title })}>{item.title}</span>\n {vertical && hasContent(item.description) && (\n <span {...mergeAttrs<'span'>({ sx: stepsStyles.description })}>\n {item.description}\n </span>\n )}\n </span>\n </div>\n );\n })}\n </div>\n );\n },\n);\n"],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
2
+ import { type VNodeChild } from 'vue';
3
+ import { type PartProps } from '../utils/props';
4
+ /** 打开的一边 */
5
+ export type SwipeCellSide = 'left' | 'right';
6
+ /** 未声明的属性落到根元素(div)上 */
7
+ export interface SwipeCellProps extends PartProps<'div'> {
8
+ /** 打开的一边,false 是收起;双向绑定写 `_open={x}` */
9
+ _open?: SwipeCellSide | false;
10
+ /** 左边藏着的内容(往右滑露出) */
11
+ left?: VNodeChild;
12
+ /** 右边藏着的内容(往左滑露出) */
13
+ right?: VNodeChild;
14
+ /** 不能滑 */
15
+ disabled?: boolean;
16
+ /** 打开或收起 */
17
+ onOpenChange?: (open: SwipeCellSide | false) => void;
18
+ /** 内容 */
19
+ children?: VNodeChild;
20
+ /** 滑动层(内容与两边)的部件属性 */
21
+ propsTrack?: PartProps<'div'>;
22
+ /** 左边的部件属性 */
23
+ propsLeft?: PartProps<'div'>;
24
+ /** 右边的部件属性 */
25
+ propsRight?: PartProps<'div'>;
26
+ }
27
+ /** SwipeCell 的样式:root、track、dragging、side、left、right */
28
+ export declare const swipeCellStyles: Readonly<{
29
+ dragging: css.CompiledStyles;
30
+ left: css.CompiledStyles;
31
+ right: css.CompiledStyles;
32
+ root: css.CompiledStyles;
33
+ side: css.CompiledStyles;
34
+ track: css.CompiledStyles;
35
+ }>;
36
+ /** 滑动单元格(div > 滑动层:左边 + 内容 + 右边) */
37
+ export declare const SwipeCell: import("@zerodep-dev/vue-tsx-pro-tsx").TsxComponent<SwipeCellProps>;
@@ -0,0 +1,147 @@
1
+ import { dataAttrs, hasContent, mergeAttrs } from "../utils/props.js";
2
+ import { useHost } from "../utils/host.js";
3
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
4
+ import { _component, bindable, childrenProp, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
5
+ import { createVNode, onMounted, ref } from "vue";
6
+ //#region src/display/SwipeCell.tsx
7
+ /** 打开的一边 */
8
+ /** 未声明的属性落到根元素(div)上 */
9
+ /** SwipeCell 的样式:root、track、dragging、side、left、right */
10
+ var swipeCellStyles = css.create({
11
+ root: {
12
+ position: "relative",
13
+ overflow: "hidden",
14
+ touchAction: "pan-y",
15
+ userSelect: "none"
16
+ },
17
+ track: {
18
+ position: "relative",
19
+ transitionProperty: "transform",
20
+ transitionDuration: "_md",
21
+ transitionTimingFunction: "_standard"
22
+ },
23
+ dragging: { transitionDuration: "0s" },
24
+ side: {
25
+ position: "absolute",
26
+ insetBlock: 0,
27
+ display: "flex",
28
+ alignItems: "stretch"
29
+ },
30
+ left: { insetInlineEnd: "100%" },
31
+ right: { insetInlineStart: "100%" }
32
+ });
33
+ var LOCK_DISTANCE = 8;
34
+ /** 滑动单元格(div > 滑动层:左边 + 内容 + 右边) */
35
+ var SwipeCell = /*#__PURE__*/ _component((_props, _ctx) => {
36
+ const _cache = [];
37
+ const open = bindable(_props, "_open", () => false, _ctx.emit);
38
+ const left = readonlyProp(_props, "left");
39
+ const right = readonlyProp(_props, "right");
40
+ const disabled = readonlyProp(_props, "disabled", false);
41
+ const onOpenChange = readonlyProp(_props, "onOpenChange");
42
+ const children = childrenProp(_props);
43
+ const propsTrack = readonlyProp(_props, "propsTrack");
44
+ const propsLeft = readonlyProp(_props, "propsLeft");
45
+ const propsRight = readonlyProp(_props, "propsRight");
46
+ const rest = restProps(_props, _ctx, false);
47
+ const host = useHost();
48
+ const widths = ref({
49
+ left: 0,
50
+ right: 0
51
+ });
52
+ let leftNode = null;
53
+ let rightNode = null;
54
+ const measure = async () => {
55
+ const [l, r] = await Promise.all([host.measure(leftNode), host.measure(rightNode)]);
56
+ widths.value.left = l?.width ?? 0;
57
+ widths.value.right = r?.width ?? 0;
58
+ };
59
+ onMounted(measure);
60
+ let drag = ref(null);
61
+ let horizontal = ref(false);
62
+ let start = {
63
+ x: 0,
64
+ y: 0,
65
+ offset: 0
66
+ };
67
+ let direction = null;
68
+ const restingOffset = () => open.value === "left" ? widths.value.left : open.value === "right" ? -widths.value.right : 0;
69
+ const setOpen = (next) => {
70
+ if (next === open.value) return;
71
+ open.value = next;
72
+ onOpenChange.value?.(next);
73
+ };
74
+ const onTouchstart = (event) => {
75
+ if (disabled.value) return;
76
+ measure();
77
+ const touch = event.touches[0];
78
+ start = {
79
+ x: touch.clientX,
80
+ y: touch.clientY,
81
+ offset: restingOffset()
82
+ };
83
+ direction = null;
84
+ };
85
+ const onTouchmove = (event) => {
86
+ if (disabled.value) return;
87
+ const touch = event.touches[0];
88
+ const dx = touch.clientX - start.x;
89
+ const dy = touch.clientY - start.y;
90
+ if (!direction) {
91
+ if (Math.abs(dx) < LOCK_DISTANCE && Math.abs(dy) < LOCK_DISTANCE) return;
92
+ direction = Math.abs(dx) > Math.abs(dy) ? "h" : "v";
93
+ horizontal.value = direction === "h";
94
+ }
95
+ if (direction !== "h") return;
96
+ drag.value = Math.min(widths.value.left, Math.max(-widths.value.right, start.offset + dx));
97
+ };
98
+ const onTouchend = () => {
99
+ horizontal.value = false;
100
+ if (drag.value === null) return;
101
+ const offset = drag.value;
102
+ drag.value = null;
103
+ const threshold = (width) => open.value ? width * .7 : width * .3;
104
+ if (offset > 0 && widths.value.left && offset > threshold(widths.value.left)) setOpen("left");
105
+ else if (offset < 0 && widths.value.right && -offset > threshold(widths.value.right)) setOpen("right");
106
+ else setOpen(false);
107
+ };
108
+ const onClick = () => open.value && setOpen(false);
109
+ return () => {
110
+ const offset = drag.value ?? restingOffset();
111
+ return createVNode("div", mergeAttrs({ sx: swipeCellStyles.root }, rest, {
112
+ onTouchstart,
113
+ onTouchmove,
114
+ onTouchend,
115
+ onTouchcancel: onTouchend,
116
+ onClick,
117
+ ...dataAttrs({
118
+ "data-touch-move": horizontal.value ? "catch" : true,
119
+ "data-open": open.value || void 0
120
+ })
121
+ }), [createVNode("div", mergeAttrs({
122
+ sx: [swipeCellStyles.track, drag.value !== null && swipeCellStyles.dragging],
123
+ style: { transform: `translateX(${offset}px)` }
124
+ }, propsTrack.value), [
125
+ hasContent(left.value) && createVNode("div", mergeJsxProps(mergeAttrs({ sx: [swipeCellStyles.side, swipeCellStyles.left] }, propsLeft.value), { "ref": _cache[0] || (_cache[0] = (node) => leftNode = node) }), [left.value]),
126
+ children.value,
127
+ hasContent(right.value) && createVNode("div", mergeJsxProps(mergeAttrs({ sx: [swipeCellStyles.side, swipeCellStyles.right] }, propsRight.value), { "ref": _cache[1] || (_cache[1] = (node) => rightNode = node) }), [right.value])
128
+ ])]);
129
+ };
130
+ }, {
131
+ name: "SwipeCell",
132
+ props: [
133
+ "_open",
134
+ "onUpdate:_open",
135
+ "left",
136
+ "right",
137
+ "disabled",
138
+ "onOpenChange",
139
+ "propsTrack",
140
+ "propsLeft",
141
+ "propsRight"
142
+ ]
143
+ });
144
+ //#endregion
145
+ export { SwipeCell, swipeCellStyles };
146
+
147
+ //# sourceMappingURL=SwipeCell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwipeCell.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_vue_ref","_createVNode","_mergeProps"],"sources":["../../src/display/SwipeCell.tsx"],"sourcesContent":["/**\n * 滑动单元格:内容往左(右)滑,露出藏在另一边的操作按钮(删除、收藏……)。列表里一行一个。\n *\n * <SwipeCell right={<Button tone=\"danger\" radius=\"none\" onClick={remove}>删除</Button>}>\n * <Cell title=\"订单 1024\" value=\"待付款\" />\n * </SwipeCell>\n * <SwipeCell _open={side} left={…} right={…} /> 双向绑定:'left' | 'right' | false\n *\n * 横滑才接管手势,竖滑照常滚动页面(H5 靠 touch-action,小程序在横滑期间把 touchmove 换成 catch)。\n * 打开时点任意位置(包括露出的按钮,在它自己的点击之后)收起。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { onMounted, type VNodeChild } from 'vue';\nimport { useHost } from '../utils/host';\nimport { dataAttrs, hasContent, mergeAttrs, type PartProps } from '../utils/props';\n\n/** 打开的一边 */\nexport type SwipeCellSide = 'left' | 'right';\n\n/** 未声明的属性落到根元素(div)上 */\nexport interface SwipeCellProps extends PartProps<'div'> {\n /** 打开的一边,false 是收起;双向绑定写 `_open={x}` */\n _open?: SwipeCellSide | false;\n /** 左边藏着的内容(往右滑露出) */\n left?: VNodeChild;\n /** 右边藏着的内容(往左滑露出) */\n right?: VNodeChild;\n /** 不能滑 */\n disabled?: boolean;\n /** 打开或收起 */\n onOpenChange?: (open: SwipeCellSide | false) => void;\n /** 内容 */\n children?: VNodeChild;\n /** 滑动层(内容与两边)的部件属性 */\n propsTrack?: PartProps<'div'>;\n /** 左边的部件属性 */\n propsLeft?: PartProps<'div'>;\n /** 右边的部件属性 */\n propsRight?: PartProps<'div'>;\n}\n\n/** SwipeCell 的样式:root、track、dragging、side、left、right */\nexport const swipeCellStyles = css.create({\n root: {\n position: 'relative',\n overflow: 'hidden',\n // 竖滑交给浏览器滚动页面,横滑交给组件\n touchAction: 'pan-y',\n userSelect: 'none',\n },\n track: {\n position: 'relative',\n transitionProperty: 'transform',\n transitionDuration: '_md',\n transitionTimingFunction: '_standard',\n },\n // 拖动时跟手,不要过渡\n dragging: { transitionDuration: '0s' },\n side: { position: 'absolute', insetBlock: 0, display: 'flex', alignItems: 'stretch' },\n left: { insetInlineEnd: '100%' },\n right: { insetInlineStart: '100%' },\n});\n\n// 横竖方向的判定:移动超过这个距离(px)才判定\nconst LOCK_DISTANCE = 8;\n\n/** 滑动单元格(div > 滑动层:左边 + 内容 + 右边) */\nexport const SwipeCell = _component(\n ({\n _open: open = _bindable<SwipeCellSide | false>(false),\n left,\n right,\n disabled = false,\n onOpenChange,\n children,\n propsTrack,\n propsLeft,\n propsRight,\n ...rest\n }: SwipeCellProps) => {\n const host = useHost();\n // 两边的宽度:挂上时量一次,每次按下时再量(内容可能变了;小程序里只能异步量,按下到开始滑动之间来得及)\n const widths = _state({ left: 0, right: 0 });\n let leftNode: unknown = null;\n let rightNode: unknown = null;\n const measure = async () => {\n const [l, r] = await Promise.all([host.measure(leftNode), host.measure(rightNode)]);\n widths.left = l?.width ?? 0;\n widths.right = r?.width ?? 0;\n };\n onMounted(measure);\n\n // 拖动中的偏移;不拖动时由 open 决定\n let drag = _state<number | null>(null);\n let horizontal = _state(false);\n let start = { x: 0, y: 0, offset: 0 };\n let direction: 'h' | 'v' | null = null;\n\n const restingOffset = () =>\n open === 'left' ? widths.left : open === 'right' ? -widths.right : 0;\n const setOpen = (next: SwipeCellSide | false) => {\n if (next === open) return;\n open = next;\n onOpenChange?.(next);\n };\n\n const onTouchstart = (event: TouchEvent) => {\n if (disabled) return;\n void measure();\n const touch = event.touches[0]!;\n start = { x: touch.clientX, y: touch.clientY, offset: restingOffset() };\n direction = null;\n };\n const onTouchmove = (event: TouchEvent) => {\n if (disabled) return;\n const touch = event.touches[0]!;\n const dx = touch.clientX - start.x;\n const dy = touch.clientY - start.y;\n if (!direction) {\n if (Math.abs(dx) < LOCK_DISTANCE && Math.abs(dy) < LOCK_DISTANCE) return;\n direction = Math.abs(dx) > Math.abs(dy) ? 'h' : 'v';\n horizontal = direction === 'h';\n }\n if (direction !== 'h') return;\n drag = Math.min(widths.left, Math.max(-widths.right, start.offset + dx));\n };\n const onTouchend = () => {\n horizontal = false;\n if (drag === null) return;\n const offset = drag;\n drag = null;\n // 从收起往外拉过三成就打开;从打开往回推过三成就收起\n const threshold = (width: number) => (open ? width * 0.7 : width * 0.3);\n if (offset > 0 && widths.left && offset > threshold(widths.left)) setOpen('left');\n else if (offset < 0 && widths.right && -offset > threshold(widths.right)) setOpen('right');\n else setOpen(false);\n };\n // 滑动不会触发点击(浏览器与小程序都是),所以这里的点击都是点按:打开时收起\n const onClick = () => open && setOpen(false);\n\n return () => {\n const offset = drag ?? restingOffset();\n return (\n <div\n {...mergeAttrs<'div'>({ sx: swipeCellStyles.root }, rest, {\n onTouchstart,\n onTouchmove,\n onTouchend,\n onTouchcancel: onTouchend,\n onClick,\n ...dataAttrs({\n // 小程序:收 touchmove;横滑期间 catch,页面不跟着滚\n 'data-touch-move': horizontal ? 'catch' : true,\n 'data-open': open || undefined,\n }),\n })}\n >\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [swipeCellStyles.track, drag !== null && swipeCellStyles.dragging],\n style: { transform: `translateX(${offset}px)` },\n },\n propsTrack,\n )}\n >\n {hasContent(left) && (\n <div\n {...mergeAttrs<'div'>(\n { sx: [swipeCellStyles.side, swipeCellStyles.left] },\n propsLeft,\n )}\n ref={(node: unknown) => (leftNode = node)}\n >\n {left}\n </div>\n )}\n {children}\n {hasContent(right) && (\n <div\n {...mergeAttrs<'div'>(\n { sx: [swipeCellStyles.side, swipeCellStyles.right] },\n propsRight,\n )}\n ref={(node: unknown) => (rightNode = node)}\n >\n {right}\n </div>\n )}\n </div>\n </div>\n );\n };\n },\n);\n"],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
2
+ import { type VNodeChild } from 'vue';
3
+ import { type PartProps } from '../utils/props';
4
+ /** 未声明的属性落到根元素(div)上 */
5
+ export interface SwiperProps extends Omit<PartProps<'div'>, 'onChange'> {
6
+ /** 当前是第几张(从 0 开始);双向绑定写 `_value={x}` */
7
+ _value?: number;
8
+ /** 自动切换的间隔(ms);0 不自动切换 */
9
+ autoplay?: number;
10
+ /**
11
+ * 首尾相连:最后一张往后是第一张
12
+ * @default true
13
+ */
14
+ loop?: boolean;
15
+ /**
16
+ * 显示指示的圆点
17
+ * @default true
18
+ */
19
+ indicators?: boolean;
20
+ /** 高度(CSS 长度);不给时随内容 */
21
+ height?: string;
22
+ /** 换了一张 */
23
+ onChange?: (index: number) => void;
24
+ /** 各个 SwiperItem */
25
+ children?: VNodeChild;
26
+ /** 指示圆点那一排的部件属性 */
27
+ propsIndicators?: PartProps<'div'>;
28
+ }
29
+ /** Swiper 的样式 */
30
+ export declare const swiperStyles: Readonly<{
31
+ active: css.CompiledStyles;
32
+ dot: css.CompiledStyles;
33
+ dragging: css.CompiledStyles;
34
+ indicators: css.CompiledStyles;
35
+ item: css.CompiledStyles;
36
+ root: css.CompiledStyles;
37
+ track: css.CompiledStyles;
38
+ }>;
39
+ /** 轮播(div > 滑动层:各项 + 指示圆点) */
40
+ export declare const Swiper: import("@zerodep-dev/vue-tsx-pro-tsx").TsxComponent<SwiperProps>;
41
+ /** 未声明的属性落到这一项(div)上 */
42
+ export interface SwiperItemProps extends PartProps<'div'> {
43
+ /** 内容 */
44
+ children?: VNodeChild;
45
+ }
46
+ /** 轮播的一项(div) */
47
+ export declare const SwiperItem: import("@zerodep-dev/vue-tsx-pro-tsx").TsxComponent<SwiperItemProps>;
@@ -0,0 +1,173 @@
1
+ import { dataAttrs, mergeAttrs } from "../utils/props.js";
2
+ import { useHost } from "../utils/host.js";
3
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
4
+ import { _component, bindable, childrenProp, createContext, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
5
+ import { createVNode, onBeforeUnmount, onMounted, ref, shallowReactive, watch } from "vue";
6
+ //#region src/display/Swiper.tsx
7
+ /** 轮播提供给各项的 */
8
+ var SwiperContext = createContext("Swiper");
9
+ /** 未声明的属性落到根元素(div)上 */
10
+ /** Swiper 的样式 */
11
+ var swiperStyles = css.create({
12
+ root: {
13
+ position: "relative",
14
+ overflow: "hidden",
15
+ touchAction: "pan-y",
16
+ userSelect: "none"
17
+ },
18
+ track: {
19
+ display: "flex",
20
+ height: "100%",
21
+ transitionProperty: "transform",
22
+ transitionDuration: "_lg",
23
+ transitionTimingFunction: "_standard"
24
+ },
25
+ dragging: { transitionDuration: "0s" },
26
+ item: {
27
+ flex: "none",
28
+ width: "100%",
29
+ height: "100%"
30
+ },
31
+ indicators: {
32
+ position: "absolute",
33
+ insetInline: 0,
34
+ insetBlockEnd: "0.6em",
35
+ display: "flex",
36
+ justifyContent: "center",
37
+ gap: "0.35em",
38
+ pointerEvents: "none"
39
+ },
40
+ dot: {
41
+ width: "0.4em",
42
+ height: "0.4em",
43
+ borderRadius: "_full",
44
+ backgroundColor: "rgba(255, 255, 255, 0.55)",
45
+ transitionProperty: "width, background-color",
46
+ transitionDuration: "_md"
47
+ },
48
+ active: {
49
+ width: "1em",
50
+ backgroundColor: "#fff"
51
+ }
52
+ });
53
+ var LOCK_DISTANCE = 6;
54
+ var SWITCH_RATIO = .2;
55
+ /** 轮播(div > 滑动层:各项 + 指示圆点) */
56
+ var Swiper = /*#__PURE__*/ _component((_props, _ctx) => {
57
+ const _cache = [];
58
+ const value = bindable(_props, "_value", () => 0, _ctx.emit);
59
+ const autoplay = readonlyProp(_props, "autoplay", 0);
60
+ const loop = readonlyProp(_props, "loop", true);
61
+ const indicators = readonlyProp(_props, "indicators", true);
62
+ const height = readonlyProp(_props, "height");
63
+ const onChange = readonlyProp(_props, "onChange");
64
+ const children = childrenProp(_props);
65
+ const propsIndicators = readonlyProp(_props, "propsIndicators");
66
+ const rest = restProps(_props, _ctx, false);
67
+ const host = useHost();
68
+ const items = shallowReactive([]);
69
+ SwiperContext.provide({ register(item) {
70
+ items.push(item);
71
+ return () => items.splice(items.indexOf(item), 1);
72
+ } });
73
+ const go = (index) => {
74
+ const count = items.length;
75
+ if (!count) return;
76
+ const next = loop.value ? (index + count) % count : Math.min(count - 1, Math.max(0, index));
77
+ if (next === value.value) return;
78
+ value.value = next;
79
+ onChange.value?.(next);
80
+ };
81
+ let timer;
82
+ const startAutoplay = () => {
83
+ clearInterval(timer);
84
+ if (autoplay.value > 0) timer = setInterval(() => go(value.value + 1), autoplay.value);
85
+ };
86
+ onMounted(() => {
87
+ startAutoplay();
88
+ measure();
89
+ });
90
+ watch(() => autoplay.value, startAutoplay);
91
+ onBeforeUnmount(() => clearInterval(timer));
92
+ let root = null;
93
+ let width = 0;
94
+ const measure = async () => {
95
+ width = (await host.measure(root))?.width ?? width;
96
+ };
97
+ let drag = ref(null);
98
+ let horizontal = ref(false);
99
+ let start = {
100
+ x: 0,
101
+ y: 0
102
+ };
103
+ let direction = null;
104
+ const onTouchstart = (event) => {
105
+ const touch = event.touches[0];
106
+ start = {
107
+ x: touch.clientX,
108
+ y: touch.clientY
109
+ };
110
+ direction = null;
111
+ clearInterval(timer);
112
+ measure();
113
+ };
114
+ const onTouchmove = (event) => {
115
+ const touch = event.touches[0];
116
+ const dx = touch.clientX - start.x;
117
+ const dy = touch.clientY - start.y;
118
+ if (!direction) {
119
+ if (Math.abs(dx) < LOCK_DISTANCE && Math.abs(dy) < LOCK_DISTANCE) return;
120
+ direction = Math.abs(dx) > Math.abs(dy) ? "h" : "v";
121
+ horizontal.value = direction === "h";
122
+ }
123
+ if (direction === "h") drag.value = dx;
124
+ };
125
+ const onTouchend = () => {
126
+ const dx = drag.value ?? 0;
127
+ drag.value = null;
128
+ horizontal.value = false;
129
+ if (width && Math.abs(dx) > width * SWITCH_RATIO) go(value.value + (dx < 0 ? 1 : -1));
130
+ startAutoplay();
131
+ };
132
+ return () => {
133
+ const offset = drag.value === null ? "" : ` + ${drag.value}px`;
134
+ return createVNode("div", mergeJsxProps(mergeAttrs({
135
+ sx: swiperStyles.root,
136
+ style: height.value ? { height: height.value } : void 0
137
+ }, rest, {
138
+ onTouchstart,
139
+ onTouchmove,
140
+ onTouchend,
141
+ onTouchcancel: onTouchend,
142
+ ...dataAttrs({ "data-touch-move": horizontal.value ? "catch" : true })
143
+ }), { "ref": _cache[0] || (_cache[0] = (node) => root = node) }), [createVNode("div", mergeAttrs({
144
+ sx: [swiperStyles.track, drag.value !== null && swiperStyles.dragging],
145
+ style: { transform: `translateX(calc(${-value.value * 100}%${offset}))` }
146
+ }), [children.value]), indicators.value && items.length > 1 && createVNode("div", mergeJsxProps(mergeAttrs({ sx: swiperStyles.indicators }, propsIndicators.value), { "aria-hidden": "true" }), [items.map((_, index) => createVNode("span", mergeAttrs({ sx: [swiperStyles.dot, index === value.value && swiperStyles.active] }), null))])]);
147
+ };
148
+ }, {
149
+ name: "Swiper",
150
+ props: [
151
+ "_value",
152
+ "onUpdate:_value",
153
+ "autoplay",
154
+ "loop",
155
+ "indicators",
156
+ "height",
157
+ "onChange",
158
+ "propsIndicators"
159
+ ]
160
+ });
161
+ /** 未声明的属性落到这一项(div)上 */
162
+ /** 轮播的一项(div) */
163
+ var SwiperItem = /*#__PURE__*/ _component((_props2, _ctx2) => {
164
+ const children = childrenProp(_props2);
165
+ const rest = restProps(_props2, _ctx2, false);
166
+ const swiper = SwiperContext.inject();
167
+ onBeforeUnmount(swiper.register({}));
168
+ return () => createVNode("div", mergeAttrs({ sx: swiperStyles.item }, rest), [children.value]);
169
+ }, { name: "SwiperItem" });
170
+ //#endregion
171
+ export { Swiper, SwiperItem, swiperStyles };
172
+
173
+ //# sourceMappingURL=Swiper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Swiper.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_vue_ref","_createVNode","_mergeProps"],"sources":["../../src/display/Swiper.tsx"],"sourcesContent":["/**\n * 轮播:一组横排的卡片(首页的广告图、商品的多张图),左右滑或自动切换,下面一排圆点指示当前是第几张。\n *\n * <Swiper autoplay={3000} height=\"10em\">\n * <SwiperItem><Image src={banner1} width=\"100%\" height=\"100%\" fit=\"cover\" /></SwiperItem>\n * <SwiperItem>…</SwiperItem>\n * </Swiper>\n *\n * 横滑才接管手势(竖滑照常滚动页面);loop 时最后一张再往后回到第一张(倒着滑回去,不复制首尾)。\n */\nimport { _component, createContext } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { onBeforeUnmount, onMounted, shallowReactive, watch, type VNodeChild } from 'vue';\nimport { useHost } from '../utils/host';\nimport { dataAttrs, mergeAttrs, type PartProps } from '../utils/props';\n\n/** 轮播提供给各项的 */\ninterface SwiperState {\n register(item: object): () => void;\n}\n\nconst SwiperContext = createContext<SwiperState>('Swiper');\n\n/** 未声明的属性落到根元素(div)上 */\nexport interface SwiperProps extends Omit<PartProps<'div'>, 'onChange'> {\n /** 当前是第几张(从 0 开始);双向绑定写 `_value={x}` */\n _value?: number;\n /** 自动切换的间隔(ms);0 不自动切换 */\n autoplay?: number;\n /**\n * 首尾相连:最后一张往后是第一张\n * @default true\n */\n loop?: boolean;\n /**\n * 显示指示的圆点\n * @default true\n */\n indicators?: boolean;\n /** 高度(CSS 长度);不给时随内容 */\n height?: string;\n /** 换了一张 */\n onChange?: (index: number) => void;\n /** 各个 SwiperItem */\n children?: VNodeChild;\n /** 指示圆点那一排的部件属性 */\n propsIndicators?: PartProps<'div'>;\n}\n\n/** Swiper 的样式 */\nexport const swiperStyles = css.create({\n root: { position: 'relative', overflow: 'hidden', touchAction: 'pan-y', userSelect: 'none' },\n track: {\n display: 'flex',\n height: '100%',\n transitionProperty: 'transform',\n transitionDuration: '_lg',\n transitionTimingFunction: '_standard',\n },\n dragging: { transitionDuration: '0s' },\n item: { flex: 'none', width: '100%', height: '100%' },\n indicators: {\n position: 'absolute',\n insetInline: 0,\n insetBlockEnd: '0.6em',\n display: 'flex',\n justifyContent: 'center',\n gap: '0.35em',\n pointerEvents: 'none',\n },\n dot: {\n width: '0.4em',\n height: '0.4em',\n borderRadius: '_full',\n // 圆点画在图片上:两套主题里都是白的\n backgroundColor: 'rgba(255, 255, 255, 0.55)',\n transitionProperty: 'width, background-color',\n transitionDuration: '_md',\n },\n active: { width: '1em', backgroundColor: '#fff' },\n});\n\n// 判定横竖的移动距离(px);松手时滑过宽度的这个比例就换一张\nconst LOCK_DISTANCE = 6;\nconst SWITCH_RATIO = 0.2;\n\n/** 轮播(div > 滑动层:各项 + 指示圆点) */\nexport const Swiper = _component(\n ({\n _value: value = _bindable(0),\n autoplay = 0,\n loop = true,\n indicators = true,\n height,\n onChange,\n children,\n propsIndicators,\n ...rest\n }: SwiperProps) => {\n const host = useHost();\n const items = shallowReactive<object[]>([]);\n SwiperContext.provide({\n register(item) {\n items.push(item);\n return () => items.splice(items.indexOf(item), 1);\n },\n });\n\n const go = (index: number) => {\n const count = items.length;\n if (!count) return;\n const next = loop ? (index + count) % count : Math.min(count - 1, Math.max(0, index));\n if (next === value) return;\n value = next;\n onChange?.(next);\n };\n\n // 自动切换:拖动时停下,松手后重新计时\n let timer: ReturnType<typeof setInterval> | undefined;\n const startAutoplay = () => {\n clearInterval(timer);\n if (autoplay > 0) timer = setInterval(() => go(value + 1), autoplay);\n };\n onMounted(() => {\n startAutoplay();\n void measure();\n });\n watch(() => autoplay, startAutoplay);\n onBeforeUnmount(() => clearInterval(timer));\n\n // 拖动:挂上时量一次宽度,每次按下时再量(转屏、布局变了)\n let root: unknown = null;\n let width = 0;\n const measure = async () => {\n width = (await host.measure(root))?.width ?? width;\n };\n let drag = _state<number | null>(null);\n let horizontal = _state(false);\n let start = { x: 0, y: 0 };\n let direction: 'h' | 'v' | null = null;\n const onTouchstart = (event: TouchEvent) => {\n const touch = event.touches[0]!;\n start = { x: touch.clientX, y: touch.clientY };\n direction = null;\n clearInterval(timer);\n void measure();\n };\n const onTouchmove = (event: TouchEvent) => {\n const touch = event.touches[0]!;\n const dx = touch.clientX - start.x;\n const dy = touch.clientY - start.y;\n if (!direction) {\n if (Math.abs(dx) < LOCK_DISTANCE && Math.abs(dy) < LOCK_DISTANCE) return;\n direction = Math.abs(dx) > Math.abs(dy) ? 'h' : 'v';\n horizontal = direction === 'h';\n }\n if (direction === 'h') drag = dx;\n };\n const onTouchend = () => {\n const dx = drag ?? 0;\n drag = null;\n horizontal = false;\n if (width && Math.abs(dx) > width * SWITCH_RATIO) go(value + (dx < 0 ? 1 : -1));\n startAutoplay();\n };\n\n return () => {\n const offset = drag === null ? '' : ` + ${drag}px`;\n return (\n <div\n {...mergeAttrs<'div'>(\n { sx: swiperStyles.root, style: height ? { height } : undefined },\n rest,\n {\n onTouchstart,\n onTouchmove,\n onTouchend,\n onTouchcancel: onTouchend,\n ...dataAttrs({ 'data-touch-move': horizontal ? 'catch' : true }),\n },\n )}\n ref={(node: unknown) => (root = node)}\n >\n <div\n {...mergeAttrs<'div'>({\n sx: [swiperStyles.track, drag !== null && swiperStyles.dragging],\n style: { transform: `translateX(calc(${-value * 100}%${offset}))` },\n })}\n >\n {children}\n </div>\n {indicators && items.length > 1 && (\n <div\n {...mergeAttrs<'div'>({ sx: swiperStyles.indicators }, propsIndicators)}\n aria-hidden=\"true\"\n >\n {items.map((_, index) => (\n <span\n {...mergeAttrs<'span'>({\n sx: [swiperStyles.dot, index === value && swiperStyles.active],\n })}\n />\n ))}\n </div>\n )}\n </div>\n );\n };\n },\n);\n\n/** 未声明的属性落到这一项(div)上 */\nexport interface SwiperItemProps extends PartProps<'div'> {\n /** 内容 */\n children?: VNodeChild;\n}\n\n/** 轮播的一项(div) */\nexport const SwiperItem = _component(({ children, ...rest }: SwiperItemProps) => {\n const swiper = SwiperContext.inject();\n onBeforeUnmount(swiper.register({}));\n return () => <div {...mergeAttrs<'div'>({ sx: swiperStyles.item }, rest)}>{children}</div>;\n});\n"],"mappings":"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"}