@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 @@
1
+ {"version":3,"file":"Toast.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode"],"sources":["../../src/feedback/Toast.tsx"],"sourcesContent":["/**\n * 轻提示:屏幕中间(或上、下)的一小块黑底文字,过一会儿自己消失。有文字、加载中、成功、失败四种。\n *\n * showToast('已复制');\n * const toast = showLoadingToast('提交中…'); … toast.close();\n * showSuccessToast('保存成功');\n * <Toast _open={show} type=\"fail\">网络不太好</Toast>\n *\n * 命令式的写法渲染在 ConfigProvider 里(页面要包一层);同一时间只有一个,后一个替换前一个。\n */\nimport { CircleCheck, CircleX } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { Teleport, onBeforeUnmount, shallowReactive, watch, type VNodeChild } from 'vue';\nimport { Icon, type IconData } from '../base/Icon';\nimport { useConfig } from '../config/context';\nimport { useHost } from '../utils/host';\nimport { usePresence } from '../utils/presence';\nimport { dataAttrs, mergeAttrs, type PartProps } from '../utils/props';\nimport { Loading } from './Loading';\n\n/** 轻提示的类型 */\nexport interface ToastTypes {\n /** 只有文字 */\n text: unknown;\n /** 加载中:旋转指示,不自动关闭 */\n loading: unknown;\n /** 成功:对勾 */\n success: unknown;\n /** 失败:叉 */\n fail: unknown;\n}\n\n/** 显示的位置 */\nexport interface ToastPositions {\n /** 屏幕中间 */\n middle: unknown;\n /** 靠上 */\n top: unknown;\n /** 靠下 */\n bottom: unknown;\n}\n\n/** 轻提示的选项(组件的 props 与 showToast 的参数共用) */\nexport interface ToastOptions {\n /** 文字 */\n message?: VNodeChild;\n /**\n * 类型\n * @default 'text'\n */\n type?: keyof ToastTypes;\n /** 自定义图标(代替类型自带的) */\n icon?: IconData;\n /**\n * 显示多久(ms);0 表示不自动关闭。加载中默认不自动关闭\n * @default 2000\n */\n duration?: number;\n /**\n * 位置\n * @default 'middle'\n */\n position?: keyof ToastPositions;\n /** 显示期间挡住页面的点击(加载中常用) */\n forbidClick?: boolean;\n /** 关闭之后 */\n onClose?: () => void;\n}\n\n/** 未声明的属性落到提示框(div)上 */\nexport interface ToastProps extends ToastOptions, PartProps<'div', 'role'> {\n /** 是否显示;双向绑定写 `_open={x}`,到时间自动关闭时写回 false */\n _open?: boolean;\n /** 文字(与 message 二选一) */\n children?: VNodeChild;\n}\n\n/** Toast 的样式:root、withIcon、各位置、icon、blocker */\nexport const toastStyles = css.create({\n root: {\n boxSizing: 'border-box',\n position: 'fixed',\n insetInlineStart: '50%',\n zIndex: 3000,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n gap: '_sm',\n maxWidth: '70%',\n paddingBlock: '0.6em',\n paddingInline: '1em',\n borderRadius: '_lg',\n backgroundColor: '_inverseSurface',\n color: '_inverseText',\n fontSize: '_md',\n lineHeight: '1.4',\n textAlign: 'center',\n overflowWrap: 'anywhere',\n pointerEvents: 'none',\n opacity: { default: 0, '[data-state=\"open\"]': 1 },\n transitionProperty: 'opacity, transform',\n transitionDuration: '_md',\n },\n withIcon: { minWidth: '7.5em', minHeight: '7.5em', justifyContent: 'center', padding: '_lg' },\n middle: {\n insetBlockStart: '50%',\n transform: {\n default: 'translate(-50%, -50%) scale(0.92)',\n '[data-state=\"open\"]': 'translate(-50%, -50%)',\n },\n },\n top: { insetBlockStart: '20%', transform: 'translateX(-50%)' },\n bottom: { insetBlockEnd: '20%', transform: 'translateX(-50%)' },\n icon: { fontSize: '2.5em' },\n blocker: { position: 'fixed', inset: 0, zIndex: 3000 },\n});\n\nconst ICONS = { success: CircleCheck, fail: CircleX } as const;\n\n/** 轻提示(div[role=status],渲染到浮层根) */\nexport const Toast = _component(\n ({\n _open: open = _bindable(false),\n message,\n type = 'text',\n icon,\n duration,\n position = 'middle',\n forbidClick = false,\n onClose,\n children,\n ...rest\n }: ToastProps) => {\n const host = useHost();\n const config = useConfig();\n const presence = usePresence(() => open, 240);\n let timer: ReturnType<typeof setTimeout> | undefined;\n const schedule = () => {\n clearTimeout(timer);\n const wait = duration ?? (type === 'loading' ? 0 : 2000);\n if (open && wait > 0)\n timer = setTimeout(() => {\n open = false;\n onClose?.();\n }, wait);\n };\n // 打开、换了文字或类型时重新计时(命令式的后一个替换前一个)\n watch(() => [open, message, type, duration], schedule, { immediate: true });\n onBeforeUnmount(() => clearTimeout(timer));\n return () => {\n if (!presence.mounted) return null;\n const glyph =\n type === 'loading' ? (\n <Loading size={36} />\n ) : icon || type !== 'text' ? (\n <Icon icon={icon ?? ICONS[type as 'success' | 'fail']} sx={toastStyles.icon} />\n ) : null;\n return (\n <Teleport to={host.overlayRoot() as never}>\n {forbidClick && <div {...mergeAttrs<'div'>({ sx: toastStyles.blocker })} />}\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n config.rootSx,\n toastStyles.root,\n toastStyles[position],\n glyph && toastStyles.withIcon,\n ],\n },\n rest,\n {\n role: 'status',\n ...dataAttrs({ 'data-state': presence.visible ? 'open' : 'closed' }),\n },\n )}\n >\n {glyph}\n {message ?? children}\n </div>\n </Teleport>\n );\n };\n },\n);\n\n/** 命令式轻提示的状态:ConfigProvider 里的出口按它渲染 */\nexport const toastState = shallowReactive<{ open: boolean; options: ToastOptions }>({\n open: false,\n options: {},\n});\n\n/** 命令式轻提示的控制器 */\nexport interface ToastHandle {\n /** 关闭这个提示(已经被后一个替换时什么也不做) */\n close(): void;\n}\n\n/** 显示一个轻提示;同一时间只有一个,后一个替换前一个 */\nexport function showToast(options: ToastOptions | string): ToastHandle {\n const next = typeof options === 'string' ? { message: options } : options;\n toastState.options = next;\n toastState.open = true;\n return {\n close() {\n if (toastState.options === next) toastState.open = false;\n },\n };\n}\n\n/** 加载中的轻提示:不自动关闭,默认挡住点击;用返回的 close() 关 */\nexport const showLoadingToast = (options: ToastOptions | string = {}) =>\n showToast({\n forbidClick: true,\n ...(typeof options === 'string' ? { message: options } : options),\n type: 'loading',\n });\n\n/** 成功的轻提示 */\nexport const showSuccessToast = (options: ToastOptions | string) =>\n showToast({ ...(typeof options === 'string' ? { message: options } : options), type: 'success' });\n\n/** 失败的轻提示 */\nexport const showFailToast = (options: ToastOptions | string) =>\n showToast({ ...(typeof options === 'string' ? { message: options } : options), type: 'fail' });\n\n/** 关闭当前的轻提示 */\nexport function closeToast() {\n toastState.open = false;\n}\n"],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { VNodeChild } from 'vue';
2
+ import { type PartProps } from '../utils/props';
3
+ import { type ChoiceDirections, type ChoiceShapes } from './choice';
4
+ /** 选项的值 */
5
+ export type ChoiceValue = string | number;
6
+ /** 角色与状态由组件管理 */
7
+ export type ChoiceManaged = 'role' | 'aria-checked' | 'type' | 'disabled' | 'name';
8
+ /** 未声明的属性落到按钮上 */
9
+ export interface CheckboxProps extends Omit<PartProps<'button', ChoiceManaged>, 'onChange'> {
10
+ /** 是否选中(单独用时);双向绑定写 `_checked={x}` */
11
+ _checked?: boolean;
12
+ /** 在组里时:这一项的值 */
13
+ name?: ChoiceValue;
14
+ /** 半选:全选框在部分选中时 */
15
+ indeterminate?: boolean;
16
+ /** 形状;不给时随组,默认圆 */
17
+ shape?: keyof ChoiceShapes;
18
+ /** 禁用 */
19
+ disabled?: boolean;
20
+ /** 单独用时切换了 */
21
+ onChange?: (checked: boolean) => void;
22
+ /** 文字 */
23
+ children?: VNodeChild;
24
+ /** 框的部件属性 */
25
+ propsBox?: PartProps<'span'>;
26
+ /** 文字的部件属性 */
27
+ propsLabel?: PartProps<'span'>;
28
+ }
29
+ /** 复选框(button[role=checkbox] > 框 + 文字) */
30
+ export declare const Checkbox: import("@zerodep-dev/vue-tsx-pro-tsx").TsxComponent<CheckboxProps>;
31
+ /** 未声明的属性落到组的 div 上 */
32
+ export interface CheckboxGroupProps extends Omit<PartProps<'div', 'role'>, 'onChange'> {
33
+ /** 选中的值;双向绑定写 `_value={x}` */
34
+ _value?: ChoiceValue[];
35
+ /**
36
+ * 排列
37
+ * @default 'vertical'
38
+ */
39
+ direction?: keyof ChoiceDirections;
40
+ /** 最多选几个 */
41
+ max?: number;
42
+ /** 全部禁用 */
43
+ disabled?: boolean;
44
+ /** 各项的形状 */
45
+ shape?: keyof ChoiceShapes;
46
+ /** 选中的变了 */
47
+ onChange?: (value: ChoiceValue[]) => void;
48
+ /** 各个 Checkbox */
49
+ children?: VNodeChild;
50
+ }
51
+ /** 复选框组(div[role=group]) */
52
+ export declare const CheckboxGroup: import("@zerodep-dev/vue-tsx-pro-tsx").TsxComponent<CheckboxGroupProps>;
@@ -0,0 +1,107 @@
1
+ import { mergeAttrs } from "../utils/props.js";
2
+ import { useForm } from "./context.js";
3
+ import { choiceStyles, renderChoice } from "./choice.js";
4
+ import { _component, bindable, childrenProp, createContext, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
5
+ import { createVNode } from "vue";
6
+ //#region src/form/Checkbox.tsx
7
+ /** 选项的值 */
8
+ /** 复选框组提供给各项的 */
9
+ var CheckboxGroupContext = createContext("CheckboxGroup");
10
+ /** 角色与状态由组件管理 */
11
+ /** 未声明的属性落到按钮上 */
12
+ /** 复选框(button[role=checkbox] > 框 + 文字) */
13
+ var Checkbox = /*#__PURE__*/ _component((_props, _ctx) => {
14
+ const checked = bindable(_props, "_checked", () => false, _ctx.emit);
15
+ const name = readonlyProp(_props, "name");
16
+ const indeterminate = readonlyProp(_props, "indeterminate", false);
17
+ const shape = readonlyProp(_props, "shape");
18
+ const disabled = readonlyProp(_props, "disabled");
19
+ const onChange = readonlyProp(_props, "onChange");
20
+ const children = childrenProp(_props);
21
+ const propsBox = readonlyProp(_props, "propsBox");
22
+ const propsLabel = readonlyProp(_props, "propsLabel");
23
+ const rest = restProps(_props, _ctx, false);
24
+ const form = useForm();
25
+ const group = CheckboxGroupContext.inject(null);
26
+ return () => {
27
+ const inGroup = group !== null && name.value !== void 0;
28
+ const selected = inGroup ? group.value.includes(name.value) : checked.value;
29
+ const full = inGroup && !selected && group.max !== void 0 && group.value.length >= group.max;
30
+ const off = disabled.value ?? (group?.disabled || form?.disabled || full || false);
31
+ return renderChoice({
32
+ role: "checkbox",
33
+ checked: selected,
34
+ indeterminate: indeterminate.value,
35
+ disabled: off,
36
+ shape: shape.value ?? group?.shape ?? "round",
37
+ onToggle: () => {
38
+ if (form?.readonly) return;
39
+ if (inGroup) return group.toggle(name.value);
40
+ checked.value = !checked.value;
41
+ onChange.value?.(checked.value);
42
+ }
43
+ }, rest, children.value, {
44
+ propsBox: propsBox.value,
45
+ propsLabel: propsLabel.value
46
+ });
47
+ };
48
+ }, {
49
+ name: "Checkbox",
50
+ props: [
51
+ "_checked",
52
+ "onUpdate:_checked",
53
+ "name",
54
+ "indeterminate",
55
+ "shape",
56
+ "disabled",
57
+ "onChange",
58
+ "propsBox",
59
+ "propsLabel"
60
+ ]
61
+ });
62
+ /** 未声明的属性落到组的 div 上 */
63
+ /** 复选框组(div[role=group]) */
64
+ var CheckboxGroup = /*#__PURE__*/ _component((_props2, _ctx2) => {
65
+ const value = bindable(_props2, "_value", () => [], _ctx2.emit);
66
+ const direction = readonlyProp(_props2, "direction", "vertical");
67
+ const max = readonlyProp(_props2, "max");
68
+ const disabled = readonlyProp(_props2, "disabled", false);
69
+ const shape = readonlyProp(_props2, "shape");
70
+ const onChange = readonlyProp(_props2, "onChange");
71
+ const children = childrenProp(_props2);
72
+ const rest = restProps(_props2, _ctx2, false);
73
+ CheckboxGroupContext.provide({
74
+ get value() {
75
+ return value.value;
76
+ },
77
+ get max() {
78
+ return max.value;
79
+ },
80
+ get disabled() {
81
+ return disabled.value;
82
+ },
83
+ get shape() {
84
+ return shape.value;
85
+ },
86
+ toggle(name) {
87
+ value.value = value.value.includes(name) ? value.value.filter((item) => item !== name) : [...value.value, name];
88
+ onChange.value?.(value.value);
89
+ }
90
+ });
91
+ return () => createVNode("div", mergeAttrs({ sx: [choiceStyles.group, direction.value === "horizontal" && choiceStyles.horizontal] }, rest, { role: "group" }), [children.value]);
92
+ }, {
93
+ name: "CheckboxGroup",
94
+ props: [
95
+ "_value",
96
+ "onUpdate:_value",
97
+ "direction",
98
+ "max",
99
+ "disabled",
100
+ "shape",
101
+ "onChange"
102
+ ]
103
+ });
104
+ //#endregion
105
+ export { Checkbox, CheckboxGroup };
106
+
107
+ //# sourceMappingURL=Checkbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Checkbox.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode"],"sources":["../../src/form/Checkbox.tsx"],"sourcesContent":["/**\n * 复选框与复选框组:从几个选项里选任意多个;单独一个用于“同意协议”这类确认。\n *\n * <Checkbox _checked={agree}>我已阅读并同意《用户协议》</Checkbox>\n * <CheckboxGroup _value={tags} direction=\"horizontal\" max={3}>\n * <Checkbox name=\"spicy\">辣</Checkbox>\n * <Checkbox name=\"sweet\">甜</Checkbox>\n * </CheckboxGroup>\n *\n * 在组里时 name 是选项的值,选中与否由组的 _value 决定;全选框用 indeterminate 表示部分选中。\n */\nimport { _component, createContext } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport type { VNodeChild } from 'vue';\nimport { mergeAttrs, type PartProps } from '../utils/props';\nimport { choiceStyles, renderChoice, type ChoiceDirections, type ChoiceShapes } from './choice';\nimport { useForm } from './context';\n\n/** 选项的值 */\nexport type ChoiceValue = string | number;\n\n/** 复选框组提供给各项的 */\ninterface CheckboxGroupState {\n readonly value: readonly ChoiceValue[];\n readonly max: number | undefined;\n readonly disabled: boolean;\n readonly shape: keyof ChoiceShapes | undefined;\n toggle(name: ChoiceValue): void;\n}\n\nconst CheckboxGroupContext = createContext<CheckboxGroupState>('CheckboxGroup');\n\n/** 角色与状态由组件管理 */\nexport type ChoiceManaged = 'role' | 'aria-checked' | 'type' | 'disabled' | 'name';\n\n/** 未声明的属性落到按钮上 */\nexport interface CheckboxProps extends Omit<PartProps<'button', ChoiceManaged>, 'onChange'> {\n /** 是否选中(单独用时);双向绑定写 `_checked={x}` */\n _checked?: boolean;\n /** 在组里时:这一项的值 */\n name?: ChoiceValue;\n /** 半选:全选框在部分选中时 */\n indeterminate?: boolean;\n /** 形状;不给时随组,默认圆 */\n shape?: keyof ChoiceShapes;\n /** 禁用 */\n disabled?: boolean;\n /** 单独用时切换了 */\n onChange?: (checked: boolean) => void;\n /** 文字 */\n children?: VNodeChild;\n /** 框的部件属性 */\n propsBox?: PartProps<'span'>;\n /** 文字的部件属性 */\n propsLabel?: PartProps<'span'>;\n}\n\n/** 复选框(button[role=checkbox] > 框 + 文字) */\nexport const Checkbox = _component(\n ({\n _checked: checked = _bindable(false),\n name,\n indeterminate = false,\n shape,\n disabled,\n onChange,\n children,\n propsBox,\n propsLabel,\n ...rest\n }: CheckboxProps) => {\n const form = useForm();\n const group = CheckboxGroupContext.inject(null);\n return () => {\n const inGroup = group !== null && name !== undefined;\n const selected = inGroup ? group.value.includes(name) : checked;\n // 选满了:没选中的项不能再选\n const full =\n inGroup && !selected && group.max !== undefined && group.value.length >= group.max;\n const off = disabled ?? (group?.disabled || form?.disabled || full || false);\n return renderChoice(\n {\n role: 'checkbox',\n checked: selected,\n indeterminate,\n disabled: off,\n shape: shape ?? group?.shape ?? 'round',\n onToggle: () => {\n if (form?.readonly) return;\n if (inGroup) return group.toggle(name);\n checked = !checked;\n onChange?.(checked);\n },\n },\n rest,\n children,\n { propsBox, propsLabel },\n );\n };\n },\n);\n\n/** 未声明的属性落到组的 div 上 */\nexport interface CheckboxGroupProps extends Omit<PartProps<'div', 'role'>, 'onChange'> {\n /** 选中的值;双向绑定写 `_value={x}` */\n _value?: ChoiceValue[];\n /**\n * 排列\n * @default 'vertical'\n */\n direction?: keyof ChoiceDirections;\n /** 最多选几个 */\n max?: number;\n /** 全部禁用 */\n disabled?: boolean;\n /** 各项的形状 */\n shape?: keyof ChoiceShapes;\n /** 选中的变了 */\n onChange?: (value: ChoiceValue[]) => void;\n /** 各个 Checkbox */\n children?: VNodeChild;\n}\n\n/** 复选框组(div[role=group]) */\nexport const CheckboxGroup = _component(\n ({\n _value: value = _bindable<ChoiceValue[]>([]),\n direction = 'vertical',\n max,\n disabled = false,\n shape,\n onChange,\n children,\n ...rest\n }: CheckboxGroupProps) => {\n CheckboxGroupContext.provide({\n get value() {\n return value;\n },\n get max() {\n return max;\n },\n get disabled() {\n return disabled;\n },\n get shape() {\n return shape;\n },\n toggle(name) {\n value = value.includes(name) ? value.filter((item) => item !== name) : [...value, name];\n onChange?.(value);\n },\n });\n return () => (\n <div\n {...mergeAttrs<'div'>(\n { sx: [choiceStyles.group, direction === 'horizontal' && choiceStyles.horizontal] },\n rest,\n { role: 'group' },\n )}\n >\n {children}\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;AA6BA,IAAM,uBAAuB,cAAkC,eAAe;;;;AA4B9E,IAAa,WAAW,0BACtB,QAAA,SAWqB;CAAA,MAAA,UAAAA,SAAA,QAAA,kBAVW,OAAK,KAAA,IAAA;CAAA,MAAA,OAAAC,aAAA,QAAA,MAAA;CAAA,MAAA,gBAAAA,aAAA,QAAA,iBAEnB,KAAK;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAAA,WAAAD,aAAA,QAAA,UAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAOlB,OAAIE,UAAA,QAAA,MAAA,KAAA;CAEP,MAAM,OAAO,QAAQ;CACrB,MAAM,QAAQ,qBAAqB,OAAO,IAAI;CAC9C,aAAa;EACX,MAAM,UAAU,UAAU,QAAQ,KAAA,UAAS,KAAA;EAC3C,MAAM,WAAW,UAAU,MAAM,MAAM,SAAQ,KAAA,KAAK,IAAC,QAAA;EAErD,MAAM,OACJ,WAAW,CAAC,YAAY,MAAM,QAAQ,KAAA,KAAa,MAAM,MAAM,UAAU,MAAM;EACjF,MAAM,MAAM,SAAA,UAAa,OAAO,YAAY,MAAM,YAAY,QAAQ;EACtE,OAAO,aACL;GACE,MAAM;GACN,SAAS;GACT,eAAa,cAAA;GACb,UAAU;GACV,OAAO,MAAA,SAAS,OAAO,SAAS;GAChC,gBAAgB;IACd,IAAI,MAAM,UAAU;IACpB,IAAI,SAAS,OAAO,MAAM,OAAM,KAAA,KAAK;IACrC,QAAA,QAAU,CAAA,QAAA;IACV,SAAA,QAAA,QAAA,KAAkB;GACpB;EACF,GACA,MAAI,SAAA,OAEJ;GAAE,UAAQ,SAAA;GAAE,YAAU,WAAA;EAAC,CACzB;CACF;AACF,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH;;;AAwBA,IAAa,gBAAgB,0BAC3B,SAAA,UAS0B;CAAA,MAAA,QAAAH,SAAA,SAAA,gBARiB,CAAA,GAAE,MAAA,IAAA;CAAA,MAAA,YAAAC,aAAA,SAAA,aAC/B,UAAU;CAAA,MAAA,MAAAA,aAAA,SAAA,KAAA;CAAA,MAAA,WAAAA,aAAA,SAAA,YAEX,KAAK;CAAA,MAAA,QAAAA,aAAA,SAAA,OAAA;CAAA,MAAA,WAAAA,aAAA,SAAA,UAAA;CAAA,MAAA,WAAAC,aAAA,OAAA;CAAA,MAIb,OAAIC,UAAA,SAAA,OAAA,KAAA;CAEP,qBAAqB,QAAQ;EAC3B,IAAI,QAAQ;GACV,OAAA,MAAA;EACF;EACA,IAAI,MAAM;GACR,OAAA,IAAA;EACF;EACA,IAAI,WAAW;GACb,OAAA,SAAA;EACF;EACA,IAAI,QAAQ;GACV,OAAA,MAAA;EACF;EACA,OAAO,MAAM;GACX,MAAA,QAAQ,MAAA,MAAM,SAAS,IAAI,IAAI,MAAA,MAAM,QAAQ,SAAS,SAAS,IAAI,IAAI,CAAC,GAAA,MAAA,OAAU,IAAI;GACtF,SAAA,QAAA,MAAA,KAAgB;EAClB;CACF,CAAC;CACD,aAAOC,YAAA,OAEC,WACF,EAAE,IAAI,CAAC,aAAa,OAAO,UAAA,UAAc,gBAAgB,aAAa,UAAU,EAAE,GAClF,MACA,EAAE,MAAM,QAAQ,CAClB,GAAC,CAAA,SAAA,KAAA,CAAA;AAKP,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
@@ -0,0 +1,91 @@
1
+ import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
2
+ import { type VNodeChild } from 'vue';
3
+ import { type IconData, type IconProps } from '../base/Icon';
4
+ import { type PartProps } from '../utils/props';
5
+ import { type FormRule } from './context';
6
+ import { type FormItemLayout } from './FormItem';
7
+ /** 输入的类型 */
8
+ export interface FieldTypes {
9
+ /** 文字(默认) */
10
+ text: unknown;
11
+ /** 密码:输入的字遮住 */
12
+ password: unknown;
13
+ /** 数字,可带小数:数字键盘 */
14
+ number: unknown;
15
+ /** 整数:纯数字键盘 */
16
+ digit: unknown;
17
+ /** 电话号码:拨号键盘 */
18
+ tel: unknown;
19
+ /** 昵称:微信小程序里键盘上方给出微信昵称(type="nickname"),其余同文字 */
20
+ nickname: unknown;
21
+ }
22
+ /** 输入框的属性与事件由组件管理 */
23
+ export type FieldInputManaged = 'value' | 'type' | 'disabled' | 'readonly' | 'maxlength' | 'placeholder';
24
+ /** 未声明的属性落到根元素(div)上 */
25
+ export interface FieldProps extends FormItemLayout, PartProps<'div', 'title' | 'prefix'> {
26
+ /** 输入的内容;双向绑定写 `_value={x}` */
27
+ _value?: string;
28
+ /** 占位文字 */
29
+ placeholder?: string;
30
+ /**
31
+ * 类型
32
+ * @default 'text'
33
+ */
34
+ type?: keyof FieldTypes;
35
+ /** 多行输入 */
36
+ multiline?: boolean;
37
+ /**
38
+ * 多行输入的行数(autosize 时是最少的行数)
39
+ * @default 2
40
+ */
41
+ rows?: number;
42
+ /** 多行输入的高度随内容变 */
43
+ autosize?: boolean;
44
+ /** 最多输入多少个字 */
45
+ maxlength?: number;
46
+ /** 在下面显示字数(要有 maxlength) */
47
+ showWordLimit?: boolean;
48
+ /** 有内容时显示清除按钮 */
49
+ clearable?: boolean;
50
+ /** 禁用;在 Form 里时随 Form */
51
+ disabled?: boolean;
52
+ /** 只读;在 Form 里时随 Form */
53
+ readonly?: boolean;
54
+ /** 输入框里文字的对齐;不给时随 Form */
55
+ inputAlign?: 'left' | 'right';
56
+ /** 输入框前的图标 */
57
+ icon?: IconData;
58
+ /** 输入框前的内容(区号、单位) */
59
+ prefix?: VNodeChild;
60
+ /** 输入框后的内容(按钮、单位) */
61
+ suffix?: VNodeChild;
62
+ /** 字段名:在 Form 里时提交的值以它为键 */
63
+ name?: string;
64
+ /** 校验规则 */
65
+ rules?: FormRule[];
66
+ /** 获得焦点 */
67
+ onFocus?: (event: Event) => void;
68
+ /** 失去焦点 */
69
+ onBlur?: (event: Event) => void;
70
+ /** 点了清除按钮 */
71
+ onClear?: () => void;
72
+ /** 输入框(input / textarea)的部件属性 */
73
+ propsInput?: PartProps<'input', FieldInputManaged>;
74
+ /** 清除按钮的部件属性 */
75
+ propsClear?: PartProps<'button'>;
76
+ /** 图标的部件属性 */
77
+ propsIcon?: Partial<IconProps>;
78
+ }
79
+ /** Field 的样式:input、right、textarea、multiline、icon、affix、clear、count */
80
+ export declare const fieldStyles: Readonly<{
81
+ affix: css.CompiledStyles;
82
+ clear: css.CompiledStyles;
83
+ count: css.CompiledStyles;
84
+ icon: css.CompiledStyles;
85
+ input: css.CompiledStyles;
86
+ multiline: css.CompiledStyles;
87
+ right: css.CompiledStyles;
88
+ textarea: css.CompiledStyles;
89
+ }>;
90
+ /** 输入框(div > 标题 + 输入框 + 消息) */
91
+ export declare const Field: import("@zerodep-dev/vue-tsx-pro-tsx").TsxComponent<FieldProps>;
@@ -0,0 +1,296 @@
1
+ import { useConfig } from "../config/context.js";
2
+ import { dataAttrs, hasContent, mergeAttrs, mergePartProps } from "../utils/props.js";
3
+ import { Icon } from "../base/Icon.js";
4
+ import { isMiniProgram, useHost } from "../utils/host.js";
5
+ import { useFormItem } from "./context.js";
6
+ import { renderFormItem } from "./FormItem.js";
7
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
8
+ import { _component, bindable, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
9
+ import { createVNode, nextTick, ref, watch } from "vue";
10
+ import { CircleX } from "@lucide/icons";
11
+ //#region src/form/Field.tsx
12
+ /**
13
+ * 输入框:表单里的一行,左边标题,右边输入框(或多行输入),可清除、显示字数、带前后缀;在 Form 里时参与校验与提交。
14
+ *
15
+ * <Field label="收货人" _value={name} placeholder="请输入姓名" clearable />
16
+ * <Field label="手机号" _value={phone} type="tel" maxlength={11} rules={[{ required: true }]} name="phone" />
17
+ * <Field label="备注" _value={note} multiline autosize maxlength={200} showWordLimit />
18
+ * <Field label="短信验证码" _value={code} suffix={<Button size="sm">发送</Button>} />
19
+ *
20
+ * 数字用 type="number"(可带小数)或 "digit"(整数):H5 是文本框加 inputmode(不出现上下箭头),小程序是对应的键盘。
21
+ * 拼音输入法组字的过程中不更新值,组完一次写回。
22
+ */
23
+ /** 输入的类型 */
24
+ /** 输入框的属性与事件由组件管理 */
25
+ /** 未声明的属性落到根元素(div)上 */
26
+ /** Field 的样式:input、right、textarea、multiline、icon、affix、clear、count */
27
+ var fieldStyles = css.create({
28
+ input: {
29
+ boxSizing: "border-box",
30
+ flex: "1 1 auto",
31
+ minWidth: 0,
32
+ width: "100%",
33
+ height: "1.5em",
34
+ margin: 0,
35
+ padding: 0,
36
+ borderWidth: 0,
37
+ backgroundColor: "transparent",
38
+ color: {
39
+ default: "_text",
40
+ "[disabled]": "_textDisabled"
41
+ },
42
+ fontFamily: "inherit",
43
+ fontSize: "inherit",
44
+ lineHeight: "inherit",
45
+ outlineStyle: "none"
46
+ },
47
+ right: { textAlign: "end" },
48
+ textarea: {
49
+ height: "auto",
50
+ resize: "none",
51
+ overflowY: "auto"
52
+ },
53
+ multiline: {
54
+ display: "flex",
55
+ flexDirection: "column",
56
+ flex: "1 1 auto",
57
+ minWidth: 0
58
+ },
59
+ icon: {
60
+ flex: "none",
61
+ fontSize: "1.15em",
62
+ color: "_textMuted"
63
+ },
64
+ affix: {
65
+ flex: "none",
66
+ display: "inline-flex",
67
+ alignItems: "center",
68
+ color: "_textMuted"
69
+ },
70
+ clear: {
71
+ flex: "none",
72
+ display: "inline-flex",
73
+ alignItems: "center",
74
+ justifyContent: "center",
75
+ width: "1.5em",
76
+ height: "1.5em",
77
+ margin: 0,
78
+ padding: 0,
79
+ borderWidth: 0,
80
+ backgroundColor: "transparent",
81
+ color: {
82
+ default: "_textPlaceholder",
83
+ ":active": "_textMuted"
84
+ },
85
+ fontSize: "1.05em",
86
+ cursor: "pointer"
87
+ },
88
+ count: {
89
+ alignSelf: "flex-end",
90
+ marginBlockStart: "0.25em",
91
+ fontSize: "_xs",
92
+ color: "_textMuted"
93
+ }
94
+ });
95
+ /** H5 的输入框属性:数字用文本框加 inputmode(type=number 有上下箭头、会吞掉非数字) */
96
+ var INPUT_ATTRS = {
97
+ text: { type: "text" },
98
+ password: { type: "password" },
99
+ number: {
100
+ type: "text",
101
+ inputmode: "decimal"
102
+ },
103
+ digit: {
104
+ type: "text",
105
+ inputmode: "numeric"
106
+ },
107
+ tel: { type: "tel" },
108
+ nickname: {
109
+ type: "text",
110
+ autocomplete: "nickname"
111
+ }
112
+ };
113
+ /** 输入框(div > 标题 + 输入框 + 消息) */
114
+ var Field = /*#__PURE__*/ _component((_props, _ctx) => {
115
+ const value = bindable(_props, "_value", () => "", _ctx.emit);
116
+ const placeholder = readonlyProp(_props, "placeholder");
117
+ const type = readonlyProp(_props, "type", "text");
118
+ const multiline = readonlyProp(_props, "multiline", false);
119
+ const rows = readonlyProp(_props, "rows", 2);
120
+ const autosize = readonlyProp(_props, "autosize", false);
121
+ const maxlength = readonlyProp(_props, "maxlength");
122
+ const showWordLimit = readonlyProp(_props, "showWordLimit", false);
123
+ const clearable = readonlyProp(_props, "clearable", false);
124
+ const disabled = readonlyProp(_props, "disabled");
125
+ const readonly = readonlyProp(_props, "readonly");
126
+ const inputAlign = readonlyProp(_props, "inputAlign");
127
+ const icon = readonlyProp(_props, "icon");
128
+ const prefix = readonlyProp(_props, "prefix");
129
+ const suffix = readonlyProp(_props, "suffix");
130
+ const name = readonlyProp(_props, "name");
131
+ const rules = readonlyProp(_props, "rules");
132
+ const label = readonlyProp(_props, "label");
133
+ const required = readonlyProp(_props, "required");
134
+ const help = readonlyProp(_props, "help");
135
+ const error = readonlyProp(_props, "error");
136
+ const labelPosition = readonlyProp(_props, "labelPosition");
137
+ const labelWidth = readonlyProp(_props, "labelWidth");
138
+ const center = readonlyProp(_props, "center", false);
139
+ const onFocus = readonlyProp(_props, "onFocus");
140
+ const onBlur = readonlyProp(_props, "onBlur");
141
+ const onClear = readonlyProp(_props, "onClear");
142
+ const propsInput = readonlyProp(_props, "propsInput");
143
+ const propsClear = readonlyProp(_props, "propsClear");
144
+ const propsIcon = readonlyProp(_props, "propsIcon");
145
+ const propsLabel = readonlyProp(_props, "propsLabel");
146
+ const propsBody = readonlyProp(_props, "propsBody");
147
+ const propsMessage = readonlyProp(_props, "propsMessage");
148
+ const rest = restProps(_props, _ctx, true);
149
+ const config = useConfig();
150
+ const host = useHost();
151
+ let element = null;
152
+ let input = null;
153
+ let focused = ref(false);
154
+ let composing = false;
155
+ const item = useFormItem({
156
+ name: () => name.value,
157
+ rules: () => rules.value,
158
+ value: () => value.value,
159
+ label: () => label.value,
160
+ element: () => element
161
+ });
162
+ const isDisabled = () => disabled.value ?? item.form?.disabled ?? false;
163
+ const isReadonly = () => readonly.value ?? item.form?.readonly ?? false;
164
+ const resize = () => {
165
+ if (!autosize.value || isMiniProgram(host) || !input) return;
166
+ input.style.height = "auto";
167
+ input.style.height = `${input.scrollHeight}px`;
168
+ };
169
+ watch(() => value.value, () => void nextTick(resize));
170
+ const update = (next) => {
171
+ value.value = maxlength.value !== void 0 ? next.slice(0, maxlength.value) : next;
172
+ if (input && input.value !== value.value) input.value = value.value;
173
+ };
174
+ const clear = () => {
175
+ value.value = "";
176
+ onClear.value?.();
177
+ input?.focus();
178
+ };
179
+ return () => {
180
+ const off = isDisabled();
181
+ const showClear = clearable.value && !off && !isReadonly() && value.value !== "" && focused.value;
182
+ const align = inputAlign.value ?? item.form?.inputAlign;
183
+ const attrs = mergeAttrs({
184
+ sx: [
185
+ fieldStyles.input,
186
+ multiline.value && fieldStyles.textarea,
187
+ align === "right" && fieldStyles.right
188
+ ],
189
+ style: multiline.value ? { [autosize.value ? "minHeight" : "height"]: `${rows.value * 1.5}em` } : void 0
190
+ }, propsInput.value, {
191
+ value: value.value,
192
+ placeholder: placeholder.value,
193
+ disabled: off,
194
+ readonly: isReadonly(),
195
+ maxlength: maxlength.value,
196
+ ...multiline.value ? {} : INPUT_ATTRS[type.value],
197
+ onInput: (event) => {
198
+ if (!composing) update(event.target.value);
199
+ },
200
+ onCompositionstart: () => composing = true,
201
+ onCompositionend: (event) => {
202
+ composing = false;
203
+ update(event.target.value);
204
+ },
205
+ onFocus: (event) => {
206
+ focused.value = true;
207
+ onFocus.value?.(event);
208
+ },
209
+ onBlur: (event) => {
210
+ setTimeout(() => focused.value = false, 150);
211
+ onBlur.value?.(event);
212
+ item.validate("blur");
213
+ },
214
+ onKeydown: (event) => {
215
+ if (event.key === "Enter" && !multiline.value && item.form) item.form.submit();
216
+ },
217
+ ...dataAttrs({ "data-autosize": multiline.value && autosize.value })
218
+ });
219
+ const ref = (node) => input = node;
220
+ const box = multiline.value ? createVNode("textarea", mergeJsxProps(attrs, {
221
+ "rows": rows.value,
222
+ "ref": ref
223
+ }), null) : createVNode("input", mergeJsxProps(attrs, { "ref": ref }), null);
224
+ const control = [
225
+ icon.value && createVNode(Icon, mergePartProps({
226
+ icon: icon.value,
227
+ sx: fieldStyles.icon
228
+ }, propsIcon.value), null),
229
+ hasContent(prefix.value) && createVNode("span", mergeAttrs({ sx: fieldStyles.affix }), [prefix.value]),
230
+ multiline.value ? createVNode("div", mergeAttrs({ sx: fieldStyles.multiline }), [box, showWordLimit.value && maxlength.value !== void 0 && createVNode("span", mergeAttrs({ sx: fieldStyles.count }), [config.lang.wordLimit(value.value.length, maxlength.value)])]) : box,
231
+ showClear && createVNode("button", mergeAttrs({ sx: fieldStyles.clear }, propsClear.value, {
232
+ type: "button",
233
+ "aria-label": config.lang.clear,
234
+ onMousedown: (event) => event.preventDefault(),
235
+ onClick: clear
236
+ }), [createVNode(Icon, { "icon": CircleX }, null)]),
237
+ hasContent(suffix.value) && createVNode("span", mergeAttrs({ sx: fieldStyles.affix }), [suffix.value]),
238
+ !multiline.value && showWordLimit.value && maxlength.value !== void 0 && createVNode("span", mergeAttrs({ sx: fieldStyles.affix }), [config.lang.wordLimit(value.value.length, maxlength.value)])
239
+ ];
240
+ return renderFormItem({
241
+ label: label.value,
242
+ required: required.value ?? item.required,
243
+ help: help.value,
244
+ error: error.value ?? item.error,
245
+ labelPosition: labelPosition.value ?? item.form?.labelPosition,
246
+ labelWidth: labelWidth.value ?? item.form?.labelWidth,
247
+ center: center.value,
248
+ disabled: off,
249
+ propsLabel: propsLabel.value,
250
+ propsBody: propsBody.value,
251
+ propsMessage: propsMessage.value
252
+ }, rest, control, (node) => element = node);
253
+ };
254
+ }, {
255
+ name: "Field",
256
+ props: [
257
+ "_value",
258
+ "onUpdate:_value",
259
+ "placeholder",
260
+ "type",
261
+ "multiline",
262
+ "rows",
263
+ "autosize",
264
+ "maxlength",
265
+ "showWordLimit",
266
+ "clearable",
267
+ "disabled",
268
+ "readonly",
269
+ "inputAlign",
270
+ "icon",
271
+ "prefix",
272
+ "suffix",
273
+ "name",
274
+ "rules",
275
+ "label",
276
+ "required",
277
+ "help",
278
+ "error",
279
+ "labelPosition",
280
+ "labelWidth",
281
+ "center",
282
+ "onFocus",
283
+ "onBlur",
284
+ "onClear",
285
+ "propsInput",
286
+ "propsClear",
287
+ "propsIcon",
288
+ "propsLabel",
289
+ "propsBody",
290
+ "propsMessage"
291
+ ]
292
+ });
293
+ //#endregion
294
+ export { Field, fieldStyles };
295
+
296
+ //# sourceMappingURL=Field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Field.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_vue_ref","_createVNode","_mergeProps"],"sources":["../../src/form/Field.tsx"],"sourcesContent":["/**\n * 输入框:表单里的一行,左边标题,右边输入框(或多行输入),可清除、显示字数、带前后缀;在 Form 里时参与校验与提交。\n *\n * <Field label=\"收货人\" _value={name} placeholder=\"请输入姓名\" clearable />\n * <Field label=\"手机号\" _value={phone} type=\"tel\" maxlength={11} rules={[{ required: true }]} name=\"phone\" />\n * <Field label=\"备注\" _value={note} multiline autosize maxlength={200} showWordLimit />\n * <Field label=\"短信验证码\" _value={code} suffix={<Button size=\"sm\">发送</Button>} />\n *\n * 数字用 type=\"number\"(可带小数)或 \"digit\"(整数):H5 是文本框加 inputmode(不出现上下箭头),小程序是对应的键盘。\n * 拼音输入法组字的过程中不更新值,组完一次写回。\n */\nimport { CircleX } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { nextTick, watch, type VNodeChild } from 'vue';\nimport { Icon, type IconData, type IconProps } from '../base/Icon';\nimport { useConfig } from '../config/context';\nimport { isMiniProgram, useHost } from '../utils/host';\nimport { dataAttrs, hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { useFormItem, type FormRule } from './context';\nimport { renderFormItem, type FormItemLayout } from './FormItem';\n\n/** 输入的类型 */\nexport interface FieldTypes {\n /** 文字(默认) */\n text: unknown;\n /** 密码:输入的字遮住 */\n password: unknown;\n /** 数字,可带小数:数字键盘 */\n number: unknown;\n /** 整数:纯数字键盘 */\n digit: unknown;\n /** 电话号码:拨号键盘 */\n tel: unknown;\n /** 昵称:微信小程序里键盘上方给出微信昵称(type=\"nickname\"),其余同文字 */\n nickname: unknown;\n}\n\n/** 输入框的属性与事件由组件管理 */\nexport type FieldInputManaged =\n 'value' | 'type' | 'disabled' | 'readonly' | 'maxlength' | 'placeholder';\n\n/** 未声明的属性落到根元素(div)上 */\nexport interface FieldProps extends FormItemLayout, PartProps<'div', 'title' | 'prefix'> {\n /** 输入的内容;双向绑定写 `_value={x}` */\n _value?: string;\n /** 占位文字 */\n placeholder?: string;\n /**\n * 类型\n * @default 'text'\n */\n type?: keyof FieldTypes;\n /** 多行输入 */\n multiline?: boolean;\n /**\n * 多行输入的行数(autosize 时是最少的行数)\n * @default 2\n */\n rows?: number;\n /** 多行输入的高度随内容变 */\n autosize?: boolean;\n /** 最多输入多少个字 */\n maxlength?: number;\n /** 在下面显示字数(要有 maxlength) */\n showWordLimit?: boolean;\n /** 有内容时显示清除按钮 */\n clearable?: boolean;\n /** 禁用;在 Form 里时随 Form */\n disabled?: boolean;\n /** 只读;在 Form 里时随 Form */\n readonly?: boolean;\n /** 输入框里文字的对齐;不给时随 Form */\n inputAlign?: 'left' | 'right';\n /** 输入框前的图标 */\n icon?: IconData;\n /** 输入框前的内容(区号、单位) */\n prefix?: VNodeChild;\n /** 输入框后的内容(按钮、单位) */\n suffix?: VNodeChild;\n /** 字段名:在 Form 里时提交的值以它为键 */\n name?: string;\n /** 校验规则 */\n rules?: FormRule[];\n /** 获得焦点 */\n onFocus?: (event: Event) => void;\n /** 失去焦点 */\n onBlur?: (event: Event) => void;\n /** 点了清除按钮 */\n onClear?: () => void;\n /** 输入框(input / textarea)的部件属性 */\n propsInput?: PartProps<'input', FieldInputManaged>;\n /** 清除按钮的部件属性 */\n propsClear?: PartProps<'button'>;\n /** 图标的部件属性 */\n propsIcon?: Partial<IconProps>;\n}\n\n/** Field 的样式:input、right、textarea、multiline、icon、affix、clear、count */\nexport const fieldStyles = css.create({\n input: {\n boxSizing: 'border-box',\n flex: '1 1 auto',\n minWidth: 0,\n width: '100%',\n height: '1.5em',\n margin: 0,\n padding: 0,\n borderWidth: 0,\n backgroundColor: 'transparent',\n color: { default: '_text', '[disabled]': '_textDisabled' },\n fontFamily: 'inherit',\n fontSize: 'inherit',\n lineHeight: 'inherit',\n outlineStyle: 'none',\n },\n right: { textAlign: 'end' },\n textarea: { height: 'auto', resize: 'none', overflowY: 'auto' },\n multiline: { display: 'flex', flexDirection: 'column', flex: '1 1 auto', minWidth: 0 },\n icon: { flex: 'none', fontSize: '1.15em', color: '_textMuted' },\n affix: { flex: 'none', display: 'inline-flex', alignItems: 'center', color: '_textMuted' },\n clear: {\n flex: 'none',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '1.5em',\n height: '1.5em',\n margin: 0,\n padding: 0,\n borderWidth: 0,\n backgroundColor: 'transparent',\n color: { default: '_textPlaceholder', ':active': '_textMuted' },\n fontSize: '1.05em',\n cursor: 'pointer',\n },\n count: {\n alignSelf: 'flex-end',\n marginBlockStart: '0.25em',\n fontSize: '_xs',\n color: '_textMuted',\n },\n});\n\n/** H5 的输入框属性:数字用文本框加 inputmode(type=number 有上下箭头、会吞掉非数字) */\nconst INPUT_ATTRS = {\n text: { type: 'text' },\n password: { type: 'password' },\n number: { type: 'text', inputmode: 'decimal' },\n digit: { type: 'text', inputmode: 'numeric' },\n tel: { type: 'tel' },\n // autocomplete 的 nickname 是标准的自动填充值;小程序运行时按它换成昵称输入框\n nickname: { type: 'text', autocomplete: 'nickname' },\n} as const;\n\n/** 输入框(div > 标题 + 输入框 + 消息) */\nexport const Field = _component(\n ({\n _value: value = _bindable(''),\n placeholder,\n type = 'text',\n multiline = false,\n rows = 2,\n autosize = false,\n maxlength,\n showWordLimit = false,\n clearable = false,\n disabled,\n readonly,\n inputAlign,\n icon,\n prefix,\n suffix,\n name,\n rules,\n label,\n required,\n help,\n error,\n labelPosition,\n labelWidth,\n center = false,\n onFocus,\n onBlur,\n onClear,\n propsInput,\n propsClear,\n propsIcon,\n propsLabel,\n propsBody,\n propsMessage,\n ...rest\n }: FieldProps) => {\n const config = useConfig();\n const host = useHost();\n let element: unknown = null;\n let input: (HTMLInputElement & HTMLTextAreaElement) | null = null;\n let focused = _state(false);\n // 拼音输入法组字中:不写回值\n let composing = false;\n const item = useFormItem({\n name: () => name,\n rules: () => rules,\n value: () => value,\n label: () => label,\n element: () => element,\n });\n const isDisabled = () => disabled ?? item.form?.disabled ?? false;\n const isReadonly = () => readonly ?? item.form?.readonly ?? false;\n\n // H5 的多行自动高度:按内容的 scrollHeight 撑开(小程序的 textarea 有 auto-height)\n const resize = () => {\n if (!autosize || isMiniProgram(host) || !input) return;\n input.style.height = 'auto';\n input.style.height = `${input.scrollHeight}px`;\n };\n watch(\n () => value,\n () => void nextTick(resize),\n );\n\n const update = (next: string) => {\n // 按 UTF-16 的长度截,同浏览器的 maxlength\n value = maxlength !== undefined ? next.slice(0, maxlength) : next;\n // 截掉超出的部分后输入框里还是用户敲的:同步回去\n if (input && input.value !== value) input.value = value;\n };\n const clear = () => {\n value = '';\n onClear?.();\n input?.focus();\n };\n\n return () => {\n const off = isDisabled();\n const showClear = clearable && !off && !isReadonly() && value !== '' && focused;\n const align = inputAlign ?? item.form?.inputAlign;\n const attrs = mergeAttrs<'input'>(\n {\n sx: [\n fieldStyles.input,\n multiline && fieldStyles.textarea,\n align === 'right' && fieldStyles.right,\n ],\n // 多行的高度:autosize 时是最小高度(小程序 auto-height 时 height 不起作用)\n style: multiline ? { [autosize ? 'minHeight' : 'height']: `${rows * 1.5}em` } : undefined,\n },\n propsInput,\n {\n value,\n placeholder,\n disabled: off,\n readonly: isReadonly(),\n maxlength,\n ...(multiline ? {} : INPUT_ATTRS[type]),\n onInput: (event: Event) => {\n if (!composing) update((event.target as HTMLInputElement).value);\n },\n onCompositionstart: () => (composing = true),\n onCompositionend: (event: Event) => {\n composing = false;\n update((event.target as HTMLInputElement).value);\n },\n onFocus: (event: Event) => {\n focused = true;\n onFocus?.(event);\n },\n onBlur: (event: Event) => {\n // 晚一点藏清除按钮:小程序里点它时输入框先失焦,立刻藏掉就点不到了\n setTimeout(() => (focused = false), 150);\n onBlur?.(event);\n void item.validate('blur');\n },\n onKeydown: (event: KeyboardEvent) => {\n // 单行输入框里按确认键(回车):在表单里就提交\n if (event.key === 'Enter' && !multiline && item.form) item.form.submit();\n },\n ...dataAttrs({ 'data-autosize': multiline && autosize }),\n },\n );\n const ref = (node: unknown) => (input = node as typeof input);\n const box = multiline ? (\n // 输入框与多行输入的属性相同,类型上按 textarea 收\n <textarea {...(attrs as PartProps<'textarea'>)} rows={rows} ref={ref} />\n ) : (\n <input {...attrs} ref={ref} />\n );\n const control = [\n icon && <Icon {...mergePartProps<IconProps>({ icon, sx: fieldStyles.icon }, propsIcon)} />,\n hasContent(prefix) && (\n <span {...mergeAttrs<'span'>({ sx: fieldStyles.affix })}>{prefix}</span>\n ),\n multiline ? (\n <div {...mergeAttrs<'div'>({ sx: fieldStyles.multiline })}>\n {box}\n {showWordLimit && maxlength !== undefined && (\n <span {...mergeAttrs<'span'>({ sx: fieldStyles.count })}>\n {config.lang.wordLimit(value.length, maxlength)}\n </span>\n )}\n </div>\n ) : (\n box\n ),\n showClear && (\n <button\n {...mergeAttrs<'button'>({ sx: fieldStyles.clear }, propsClear, {\n type: 'button',\n 'aria-label': config.lang.clear,\n // H5:按下时不让输入框失焦,键盘不收起\n onMousedown: (event: Event) => event.preventDefault(),\n onClick: clear,\n })}\n >\n <Icon icon={CircleX} />\n </button>\n ),\n hasContent(suffix) && (\n <span {...mergeAttrs<'span'>({ sx: fieldStyles.affix })}>{suffix}</span>\n ),\n !multiline && showWordLimit && maxlength !== undefined && (\n <span {...mergeAttrs<'span'>({ sx: fieldStyles.affix })}>\n {config.lang.wordLimit(value.length, maxlength)}\n </span>\n ),\n ];\n return renderFormItem(\n {\n label,\n required: required ?? item.required,\n help,\n error: error ?? item.error,\n labelPosition: labelPosition ?? item.form?.labelPosition,\n labelWidth: labelWidth ?? item.form?.labelWidth,\n center,\n disabled: off,\n propsLabel,\n propsBody,\n propsMessage,\n },\n rest,\n control,\n (node) => (element = node),\n );\n };\n },\n);\n"],"mappings":"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"}