@qynpm/ui 1.0.23 → 1.0.25

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 (136) hide show
  1. package/README.md +194 -20
  2. package/dist/index.cjs +16 -6
  3. package/dist/index.mjs +51 -34
  4. package/dist/qy-action-bar/index.cjs +1 -1
  5. package/dist/qy-action-bar/index.mjs +1 -1
  6. package/dist/qy-button/index.cjs +1 -1
  7. package/dist/qy-button/index.mjs +1 -1
  8. package/dist/qy-checkbox/index.cjs +1 -1
  9. package/dist/qy-checkbox/index.mjs +4 -3
  10. package/dist/qy-checkbox-group/index.cjs +1 -0
  11. package/dist/qy-checkbox-group/index.mjs +7 -0
  12. package/dist/qy-date-picker/index.cjs +1 -1
  13. package/dist/qy-date-picker/index.mjs +4 -3
  14. package/dist/qy-dialog/index.cjs +1 -1
  15. package/dist/qy-dialog/index.mjs +2 -2
  16. package/dist/qy-dropdown/index.cjs +1 -1
  17. package/dist/qy-dropdown/index.mjs +1 -1
  18. package/dist/qy-file-picker/index.cjs +1 -0
  19. package/dist/qy-file-picker/index.mjs +7 -0
  20. package/dist/qy-form-section/index.cjs +1 -1
  21. package/dist/qy-form-section/index.mjs +1 -1
  22. package/dist/qy-image/index.cjs +1 -1
  23. package/dist/qy-image/index.mjs +1 -1
  24. package/dist/qy-image-upload/index.cjs +1 -1
  25. package/dist/qy-image-upload/index.mjs +1 -1
  26. package/dist/qy-input/index.cjs +2 -2
  27. package/dist/qy-input/index.mjs +6 -3
  28. package/dist/qy-input-number/index.cjs +1 -1
  29. package/dist/qy-input-number/index.mjs +5 -3
  30. package/dist/qy-legacy-selection-dialog/index.cjs +1 -1
  31. package/dist/qy-legacy-selection-dialog/index.mjs +2 -2
  32. package/dist/qy-menu-actions/index.cjs +1 -1
  33. package/dist/qy-menu-actions/index.mjs +1 -1
  34. package/dist/qy-money-input/index.cjs +1 -1
  35. package/dist/qy-money-input/index.mjs +2 -2
  36. package/dist/qy-popover/index.cjs +2 -0
  37. package/dist/qy-popover/index.mjs +8 -0
  38. package/dist/qy-radio/index.cjs +1 -0
  39. package/dist/qy-radio/index.mjs +7 -0
  40. package/dist/qy-radio-group/index.cjs +1 -1
  41. package/dist/qy-radio-group/index.mjs +5 -2
  42. package/dist/qy-record-quote-search/index.cjs +1 -1
  43. package/dist/qy-record-quote-search/index.mjs +1 -1
  44. package/dist/qy-remark-image/index.cjs +1 -1
  45. package/dist/qy-remark-image/index.mjs +2 -2
  46. package/dist/qy-remote-select/index.cjs +1 -1
  47. package/dist/qy-remote-select/index.mjs +1 -1
  48. package/dist/qy-search-input/index.cjs +1 -1
  49. package/dist/qy-search-input/index.mjs +2 -2
  50. package/dist/qy-select/index.cjs +1 -1
  51. package/dist/qy-select/index.mjs +4 -3
  52. package/dist/qy-selection-dialog/index.cjs +1 -1
  53. package/dist/qy-selection-dialog/index.mjs +1 -1
  54. package/dist/qy-switch/index.cjs +1 -0
  55. package/dist/qy-switch/index.mjs +7 -0
  56. package/dist/qy-table-column-settings/index.cjs +1 -1
  57. package/dist/qy-table-column-settings/index.mjs +1 -1
  58. package/dist/qy-tag/index.cjs +1 -0
  59. package/dist/qy-tag/index.mjs +7 -0
  60. package/dist/qy-tooltip/index.cjs +2 -0
  61. package/dist/qy-tooltip/index.mjs +8 -0
  62. package/dist/qy-upload/index.cjs +1 -1
  63. package/dist/qy-upload/index.mjs +1 -1
  64. package/dist/shared/index-528z_q7d.cjs +1 -0
  65. package/dist/shared/index-9v7CIwzO.cjs +1 -0
  66. package/dist/shared/{index-D7lMppIb.mjs → index-B7uyWUhS.mjs} +63 -63
  67. package/dist/shared/index-BTPk2zzq.cjs +1 -0
  68. package/dist/shared/index-BcCZMWAj.cjs +1 -0
  69. package/dist/shared/index-C1YwUATr.cjs +1 -0
  70. package/dist/shared/index-C6jcSQSF.mjs +129 -0
  71. package/dist/shared/index-CbCpXtYr.mjs +68 -0
  72. package/dist/shared/index-Cl5cuyVG.mjs +54 -0
  73. package/dist/shared/index-CuusBxhR.cjs +1 -0
  74. package/dist/shared/{index-BXlQSIWX.mjs → index-DZroPZ8B.mjs} +8 -8
  75. package/dist/shared/{index-DyK6vf5h.cjs → index-DmhpD4Cp.cjs} +1 -1
  76. package/dist/shared/index-DrJuMzr1.mjs +90 -0
  77. package/dist/shared/index-Du2IqeCI.mjs +149 -0
  78. package/dist/shared/{index-ZLoAI88M.mjs → index-DvQdcj7u.mjs} +1327 -1389
  79. package/dist/shared/index-EGnVOaC9.cjs +1 -0
  80. package/dist/shared/index-QQkDJv3q.cjs +1 -0
  81. package/dist/shared/index-R5B1rjXo.mjs +225 -0
  82. package/dist/shared/index-yf2Ijz_G.mjs +72 -0
  83. package/dist/shared/index-zJN0M-bx.cjs +1 -0
  84. package/dist/shared/index.vue_vue_type_script_setup_true_lang-C3F8M9sD.cjs +1 -0
  85. package/dist/shared/index.vue_vue_type_script_setup_true_lang-CKZHI_y-.mjs +106 -0
  86. package/dist/shared/index.vue_vue_type_script_setup_true_lang-CsKjCWIN.cjs +1 -0
  87. package/dist/shared/index.vue_vue_type_script_setup_true_lang-N12Nn2uu.mjs +61 -0
  88. package/dist/shared/index.vue_vue_type_style_index_0_lang-1cTut9Ql.cjs +1 -0
  89. package/dist/shared/index.vue_vue_type_style_index_0_lang-BZQLyvw8.cjs +1 -0
  90. package/dist/shared/index.vue_vue_type_style_index_0_lang-BtbAft4t.cjs +1 -0
  91. package/dist/shared/index.vue_vue_type_style_index_0_lang-CJhIFeBC.mjs +166 -0
  92. package/dist/shared/index.vue_vue_type_style_index_0_lang-DSur831A.mjs +68 -0
  93. package/dist/shared/index.vue_vue_type_style_index_0_lang-DVqGYfD9.mjs +132 -0
  94. package/dist/shared/index.vue_vue_type_style_index_0_lang-Dm1r1WBK.cjs +1 -0
  95. package/dist/shared/index.vue_vue_type_style_index_0_lang-Q2gFF0PP.cjs +1 -0
  96. package/dist/shared/index.vue_vue_type_style_index_0_lang-aqtfjdVm.mjs +140 -0
  97. package/dist/shared/index.vue_vue_type_style_index_0_lang-ztD-It-2.mjs +121 -0
  98. package/index.d.ts +145 -7
  99. package/package.json +43 -1
  100. package/qy-autocomplete/index.d.ts +5 -5
  101. package/qy-checkbox/index.d.ts +45 -5
  102. package/qy-checkbox-group/index.d.ts +48 -0
  103. package/qy-date-picker/index.d.ts +137 -2
  104. package/qy-file-picker/index.d.ts +49 -0
  105. package/qy-image/index.d.ts +28 -28
  106. package/qy-image-preview/index.d.ts +20 -20
  107. package/qy-input/index.d.ts +46 -1
  108. package/qy-input-number/index.d.ts +41 -1
  109. package/qy-menu-actions/index.d.ts +29 -29
  110. package/qy-popover/index.d.ts +63 -0
  111. package/qy-radio/index.d.ts +44 -0
  112. package/qy-radio-group/index.d.ts +57 -9
  113. package/qy-select/index.d.ts +64 -2
  114. package/qy-switch/index.d.ts +46 -0
  115. package/qy-table-column-settings/index.d.ts +18 -18
  116. package/qy-tag/index.d.ts +44 -0
  117. package/qy-tooltip/index.d.ts +54 -0
  118. package/qy-tree-select/index.d.ts +5 -5
  119. package/dist/shared/index-B3U7dqMt.cjs +0 -1
  120. package/dist/shared/index-BbpD7hM0.cjs +0 -1
  121. package/dist/shared/index-D3l7tLgw.cjs +0 -1
  122. package/dist/shared/index-NCpeoBUZ.mjs +0 -153
  123. package/dist/shared/index.vue_vue_type_script_setup_true_lang-BJakDlgd.mjs +0 -70
  124. package/dist/shared/index.vue_vue_type_script_setup_true_lang-CelW13DE.cjs +0 -1
  125. package/dist/shared/index.vue_vue_type_script_setup_true_lang-DA1Nh7U1.mjs +0 -130
  126. package/dist/shared/index.vue_vue_type_script_setup_true_lang-DEpXmMj5.mjs +0 -162
  127. package/dist/shared/index.vue_vue_type_script_setup_true_lang-DNEVwqm7.cjs +0 -1
  128. package/dist/shared/index.vue_vue_type_script_setup_true_lang-DfKTEci_.cjs +0 -1
  129. package/dist/shared/index.vue_vue_type_script_setup_true_lang-gTkP1LWg.mjs +0 -61
  130. package/dist/shared/index.vue_vue_type_script_setup_true_lang-svvSFv2K.cjs +0 -1
  131. package/dist/shared/index.vue_vue_type_style_index_0_lang-B_A4Nq6v.cjs +0 -1
  132. package/dist/shared/index.vue_vue_type_style_index_0_lang-DKFiK2fQ.mjs +0 -152
  133. /package/dist/shared/{index-CagHZ25z.mjs → index-BYLXkIxS.mjs} +0 -0
  134. /package/dist/shared/{index-CRZsiNVW.cjs → index-C1p86ezL.cjs} +0 -0
  135. /package/dist/shared/{index-BO5aWk3f.cjs → index-ClUqUsAv.cjs} +0 -0
  136. /package/dist/shared/{index-CSxCewXP.mjs → index-Cy_Glkc-.mjs} +0 -0
package/README.md CHANGED
@@ -36,6 +36,11 @@ app.use(QyUI)
36
36
  ```ts
37
37
  import {
38
38
  QyUpload,
39
+ QyFilePicker,
40
+ QySwitch,
41
+ QyTag,
42
+ QyTooltip,
43
+ QyPopover,
39
44
  QyImage,
40
45
  QyImagePreview,
41
46
  QyImageUpload,
@@ -48,6 +53,7 @@ import {
48
53
  QyMoneyInput,
49
54
  QyDatePicker,
50
55
  QyCheckbox,
56
+ QyRadio,
51
57
  QyAutocomplete,
52
58
  QyMenuActions,
53
59
  QyTableColumnSettings,
@@ -81,6 +87,11 @@ import QySearchInput from '@qynpm/ui/qy-search-input'
81
87
  import QyRecordQuoteSearch from '@qynpm/ui/qy-record-quote-search'
82
88
  import QyDialog from '@qynpm/ui/qy-dialog'
83
89
  import QyUpload from '@qynpm/ui/qy-upload'
90
+ import QyFilePicker from '@qynpm/ui/qy-file-picker'
91
+ import QySwitch from '@qynpm/ui/qy-switch'
92
+ import QyTag from '@qynpm/ui/qy-tag'
93
+ import QyTooltip from '@qynpm/ui/qy-tooltip'
94
+ import QyPopover from '@qynpm/ui/qy-popover'
84
95
  import QyImage from '@qynpm/ui/qy-image'
85
96
  import QyImagePreview from '@qynpm/ui/qy-image-preview'
86
97
  import QyImageUpload from '@qynpm/ui/qy-image-upload'
@@ -88,14 +99,15 @@ import QyRemarkImage from '@qynpm/ui/qy-remark-image'
88
99
  import QyInputNumber from '@qynpm/ui/qy-input-number'
89
100
  import QyDatePicker from '@qynpm/ui/qy-date-picker'
90
101
  import QyCheckbox from '@qynpm/ui/qy-checkbox'
102
+ import QyRadio from '@qynpm/ui/qy-radio'
91
103
  import QyAutocomplete from '@qynpm/ui/qy-autocomplete'
92
104
  import QyMenuActions from '@qynpm/ui/qy-menu-actions'
93
- import QyTableColumnSettings from '@qynpm/ui/qy-table-column-settings'
94
- ```
95
-
96
- 后台公共包必须通过 `@qynpm/ui/<子组件>` 使用 UI 能力。每个被后台公共包消费的子入口必须是自包含入口,直接组装对应组件并保留该子入口的命名导出,禁止再转发到 `../index.js` 加载 UI 根入口。这样可以保证发布包按需加载,也能让本地源码联调稳定解析到唯一物理模块。
97
-
98
- 本地 file 依赖联调说明:单组件入口的 `package.json exports` 指向 `dist/qy-*/index.mjs` 和 `dist/qy-*/index.cjs`,而 `dist` 不提交到仓库。消费项目如果通过 `file:../qy-components/packages/ui` 引用本包,必须先在 `qy-components` 执行:
105
+ import QyTableColumnSettings from '@qynpm/ui/qy-table-column-settings'
106
+ ```
107
+
108
+ 后台公共包必须通过 `@qynpm/ui/<子组件>` 使用 UI 能力。每个被后台公共包消费的子入口必须是自包含入口,直接组装对应组件并保留该子入口的命名导出,禁止再转发到 `../index.js` 加载 UI 根入口。这样可以保证发布包按需加载,也能让本地源码联调稳定解析到唯一物理模块。
109
+
110
+ 本地 file 依赖联调说明:单组件入口的 `package.json exports` 指向 `dist/qy-*/index.mjs` 和 `dist/qy-*/index.cjs`,而 `dist` 不提交到仓库。消费项目如果通过 `file:../qy-components/packages/ui` 引用本包,必须先在 `qy-components` 执行:
99
111
 
100
112
  ```bash
101
113
  pnpm --filter @qynpm/ui build
@@ -111,6 +123,88 @@ pnpm install --frozen-lockfile --ignore-scripts
111
123
 
112
124
  ## 组件说明
113
125
 
126
+ ### `QyFilePicker`
127
+
128
+ 单文件选择组件,支持点击选择、拖拽、替换、清空以及后缀和大小校验。
129
+
130
+ - `v-model` 只输出浏览器原始 `File | null`。
131
+ - `extensions` 忽略大小写,可传 `xls` 或 `.xlsx`。
132
+ - `maxSizeMb` 的边界值允许,默认 20MB。
133
+ - 校验失败触发 `invalid`,并保留原有 `modelValue`。
134
+ - 组件只选择本地文件,不发送请求、不读取 token、不生成或保存 URL,也不复用 `QyUpload` 的业务上传协议。
135
+
136
+ ```vue
137
+ <QyFilePicker
138
+ v-model="file"
139
+ :extensions="['xls', 'xlsx']"
140
+ :max-size-mb="20"
141
+ placeholder="选择或拖拽 Excel 文件"
142
+ @invalid="handleInvalid"
143
+ />
144
+ ```
145
+
146
+ ### `QySwitch`
147
+
148
+ 受控开关组件,`modelValue`、`activeValue`、`inactiveValue` 和 `update:modelValue` / `change` payload 均为 `boolean | string | number`,不进行隐式布尔化。
149
+
150
+ ```vue
151
+ <QySwitch
152
+ v-model="enabled"
153
+ active-text="启用"
154
+ inactive-text="停用"
155
+ @change="handleChange"
156
+ />
157
+ ```
158
+
159
+ 支持 `disabled`、`loading`、`size`、`inlinePrompt`、`name`、`id`、`tabindex` 和 `ariaLabel`,以及 `class`、`style`、`role`、`title`、`data-*`、其它 `aria-*` 安全属性。只发出 `update:modelValue`、`change`、`focus`、`blur`;不提供 `beforeChange`、`input`、图标/slot 或底层实例、focus/blur 等命令式方法。
160
+
161
+ ### `QyTag`
162
+
163
+ 通用紧凑标签,内部使用 `ElTag`,公开 `tone`、`size`、`effect`、`closable`、`round`、`disabled` 和默认 slot。`tone` 支持 `neutral`、`primary`、`success`、`warning`、`danger`、`info`;`size` 为 `sm`、`md`、`lg`,默认分别映射为 Element Plus 的 `small`、`default`、`large`。
164
+
165
+ ```vue
166
+ <QyTag tone="success" size="sm" closable @close="removeTag">
167
+ 已完成
168
+ </QyTag>
169
+ ```
170
+
171
+ `disabled` 会设置 `aria-disabled="true"`、隐藏关闭按钮并抑制 `click` / `close`;非禁用状态下这两个事件各发出一次 `MouseEvent`。支持 `class`、`style`、`title`、`role`、`data-*`、`aria-*` 安全属性,不公开 `color`、`hit`、`disableTransitions` 或底层 Element Plus 实例。QyTag 不是按钮,不新增键盘按钮语义;需要动作语义时使用 `QyButton`。
172
+
173
+ ### `QyTooltip`
174
+
175
+ 只读提示组件。默认插槽是唯一触发内容,不增加触发元素包装 DOM;`content` 插槽(content slot)优先于 `content` 属性。组件支持 hover / focus、完整 `placement`、`light` / `dark` effect、延迟、偏移和可收缩的 `maxWidth`。
176
+
177
+ ```vue
178
+ <QyTooltip content="说明文字" placement="top-start">
179
+ <button type="button">查看提示</button>
180
+ </QyTooltip>
181
+
182
+ <QyTooltip content="属性内容">
183
+ <button type="button">插槽内容</button>
184
+ <template #content>只读插槽内容</template>
185
+ </QyTooltip>
186
+ ```
187
+
188
+ 默认值为 `placement="top"`、`effect="dark"`、`disabled=false`、`showDelay=0`、`hideDelay=200`、`offset=12`、`maxWidth=320`。事件只有 `open` / `close`,且只在实际可见状态转换时各发一次;不公开 `trigger`、受控 `open`、raw HTML、交互内容、Element Plus attrs/listeners 或实例方法。
189
+
190
+ ### `QyPopover`
191
+
192
+ 交互浮层组件。`reference` 插槽是触发元素,默认插槽是可交互面板内容,不增加触发元素包装 DOM;支持 `click`、`hover`、`focus`、`contextmenu`、完整 `placement`、`light` / `dark` effect、数字或 CSS 字符串 `width`、延迟、偏移、箭头和窄视口收缩。
193
+
194
+ ```vue
195
+ <QyPopover placement="bottom-start" :width="280" @open-change="onOpenChange">
196
+ <template #reference><button type="button">打开操作</button></template>
197
+ <button type="button" @click="submit">确认</button>
198
+ </QyPopover>
199
+
200
+ <QyPopover v-model:open="open" trigger="contextmenu">
201
+ <template #reference><div>右键区域</div></template>
202
+ <div>受控交互内容</div>
203
+ </QyPopover>
204
+ ```
205
+
206
+ 默认值为 `trigger="click"`、`placement="bottom"`、`effect="light"`、`width=240`、`offset=12`、`showDelay=0`、`hideDelay=200`、`showArrow=true`、`disabled=false`。`open` 未传时组件内部管理状态,传入时通过 `v-model:open` 由父级回传决定状态;`update:open` 是状态意图,`open-change` / `open` / `close` 只在实际显隐转换时发出。唯一暴露的方法是 `close()`,不公开 Element Plus 实例、定位更新、`teleported`、`appendTo` 或 `popperOptions`。
207
+
114
208
  ### `QyUpload`
115
209
 
116
210
  上传组件,支持:
@@ -244,9 +338,53 @@ type QyImageProps = {
244
338
 
245
339
  ### `QyCheckbox`
246
340
 
247
- 复选框基础组件,基于 `ElCheckbox` 做薄封装,统一 `v-model`、`change`、`focus`、`blur` 事件和单组件入口。
341
+ 受控复选框基础组件,基于 `ElCheckbox` 做隔离适配,`modelValue`、`trueValue`、`falseValue` 和事件 payload 均保持 `boolean | string | number` 原始类型,不做隐式布尔转换。
248
342
 
249
- 主要用于普通表单复选框,以及 `@qynpm/table-schema` `edit-checkbox` 渲染器底座。
343
+ 支持 `value`(为后续 `QyCheckboxGroup` 保留的选项值)、只读展示状态 `indeterminate`、`disabled`、`size` 和默认 slot。事件只有 `update:modelValue`、`change`、`focus`、`blur`;禁用状态不产生值变更意图,也不公开 Element Plus 实例或命令式方法。
344
+
345
+ ```vue
346
+ <QyCheckbox
347
+ v-model="ticketValue"
348
+ true-value="Y"
349
+ false-value="N"
350
+ aria-label="开票"
351
+ @change="handleChange"
352
+ >
353
+ 开票
354
+ </QyCheckbox>
355
+ ```
356
+
357
+ `class`、`style`、`id`、`name`、`role`、`title`、`data-*` 和 `aria-*` 会安全透传;桌面交互区域保持紧凑,窄屏下提升到至少 40px。`QyCheckboxGroup`、全选/级联和 `CheckboxButton` 不属于 V1。
358
+
359
+ ### `QyRadio`
360
+
361
+ 受控单选框基础组件,基于 `ElRadio` 做隔离适配。`value` 表示选中值,`label` 只负责展示;默认 slot 优先。`modelValue` 与事件 payload 保持 `boolean | string | number` 原始类型,父级不回写时组件不会自行改变状态,也不会通过再次点击取消选中。
362
+
363
+ 支持 `disabled`、`size`、`name`、`border` 以及 `update:modelValue`、`change`、`focus`、`blur` 事件;安全透传 `class`、`style`、`role`、`title`、`data-*` 和 `aria-*`,不公开 Element Plus 实例或命令式方法。
364
+
365
+ ```vue
366
+ <QyRadio
367
+ v-model="ticketType"
368
+ value="invoice"
369
+ label="开票"
370
+ name="ticket-type"
371
+ border
372
+ @change="handleChange"
373
+ />
374
+ ```
375
+
376
+ ### `QyCheckboxGroup`
377
+
378
+ 受控复选框组,统一管理 `QyCheckboxValue[]`。支持默认 slot 或 `options`(两者同时存在时 slot 优先),并透传 `disabled`、`min`、`max`、`size`。事件只有 `update:modelValue` 和 `change`,每次更新都返回新数组。
379
+
380
+ ```vue
381
+ <QyCheckboxGroup v-model="selected" :options="[
382
+ { label: '阅读', value: 'read' },
383
+ { label: '写作', value: 'write', disabled: true }
384
+ ]" />
385
+ ```
386
+
387
+ options 模式物理复用 `QyCheckbox`;不提供 CheckboxButton、全选、indeterminate 推导、树形/层级选择、布局 props 或 Element Plus 实例。
250
388
 
251
389
  ### `QyAutocomplete`
252
390
 
@@ -441,7 +579,11 @@ type QyImageProps = {
441
579
  - `trimMode`
442
580
  - `enter`
443
581
  - `textarea`
444
- - 兼容常见 slots expose 方法
582
+ - `modelValue` 支持 `string | number | null | undefined`,用户编辑事件统一输出 `string`
583
+ - 兼容 `text`、`textarea`、`password`、`search` 和 Element Plus 常用属性
584
+ - 兼容 `prefix`、`suffix`、`prepend`、`append` slots
585
+ - 类型出口包含 `QyInputValue`、`QyInputModelValue`、`QyInputProps`、`QyInputEmits` 和 `QyInputExposed`
586
+ - 只公开 `focus`、`blur`、`select`、`clear`、`resizeTextarea` 方法
445
587
 
446
588
  ### `QyMoneyInput`
447
589
 
@@ -464,6 +606,10 @@ type QyImageProps = {
464
606
  - `step-strictly`
465
607
  - `precision`
466
608
  - `controls / controls-position`
609
+ - `valueOnClear`(默认 `null`,也支持 `min / max / number`)
610
+ - `readonly / disabled / formatter / parser / inputmode / align`
611
+ - `prefix / suffix / increase-icon / decrease-icon` slots
612
+ - `update:modelValue / input / change / focus / blur` 显式事件
467
613
  - 兼容 `focus / blur` expose 方法
468
614
 
469
615
  金额、费用、税费等财务录入场景请优先使用 `QyMoneyInput`,不要用 `QyInputNumber` 做金额格式化。
@@ -478,11 +624,13 @@ type QyImageProps = {
478
624
  - `default-time`
479
625
  - `shortcuts`
480
626
  - `disabled-date`
481
- - 默认弹层挂载到 `body`
482
- - `normalize-range-end-time` 查询场景结束时间归一化
483
- - 兼容 `focus / blur / handleOpen / handleClose` expose 方法
627
+ - `year / month / date / dates / datetime / week / daterange / datetimerange / monthrange`
628
+ - `clearable / disabled / readonly / teleported / append-to / popper-class`
629
+ - `update:modelValue / change / clear / calendar-change / panel-change / visible-change / focus / blur`
630
+ - `default / range-separator / prev-month / next-month / prev-year / next-year` slots
631
+ - 仅公开 `focus() / blur() / open() / close()` expose 方法
484
632
 
485
- `normalize-range-end-time` 默认关闭。只有查询表单需要把范围结束值从当天 `00:00:00` 归一为 `23:59:59` 时再显式开启,避免影响普通日期选择。
633
+ `normalize-range-end-time` 默认关闭。开启后只处理范围第二项:精确 `00:00:00.000` `Date` 克隆为 `23:59:59.000`,带明确午夜时间的普通/ISO 字符串只替换时间并保留格式及 zone suffix;date-only 字符串、number、非午夜和非范围值保持原引用,不修改父数组或父 `Date`。
486
634
 
487
635
  ### `QyRadioGroup`
488
636
 
@@ -502,16 +650,30 @@ type QyImageProps = {
502
650
  - `value`:映射后的选项值
503
651
  - `disabled`:是否禁用
504
652
 
653
+ 普通 `options` 模式物理复用 `QyRadio`;`type="button"` 继续使用内部 Element Plus button adapter。已发布的 `getRadioGroupInstance()` 仅为兼容保留并标记为 deprecated,不新增实例能力。
654
+
505
655
  ### `QySelect`
506
656
 
507
- 选择器组件,第一版定位为 `ElSelect` 的轻量包装层,重点支持:
657
+ 受控选择器组件。string、number、boolean、对象值和多选数组会原样通过 `update:modelValue` / `change` 返回;组件不会排序、克隆或隐式转换,父级 `modelValue` 始终是最终状态权威。
508
658
 
509
- - `options` 直出
510
- - `labelKey / valueKey / disabledKey` 映射
511
- - 单选 / 多选
512
- - `collapse-tags`
513
- - 默认弹层挂载策略
514
- - 保留原生 slot 扩展
659
+ - `options` 支持 `labelKey / valueKey / disabledKey` 字段映射;默认 slot 有实际内容时优先。
660
+ - `valueKey` 只决定 option 的值字段;对象值需要稳定回显时,使用 `objectIdentityKey` 指定对象身份字段。
661
+ - 支持单选、多选、disabled、clearable、filterable、loading、collapse tags、弹层挂载和 popper class。
662
+ - `autoSelectSingle` 只在 options 模式、当前值为空且唯一 option 未禁用时触发一次 `update:modelValue` 后再触发一次 `change`;父值变为非空后再次清空可重新触发。
663
+ - 保留 prefix、empty、loading、tag 和 default slots,以及 clear、visible-change、focus、blur 事件。
664
+ - 只公开 `focus()` / `blur()`,不公开 Element Plus 实例或 DOM 引用。
665
+
666
+ ```vue
667
+ <QySelect
668
+ v-model="selectedUser"
669
+ :options="userOptions"
670
+ label-key="name"
671
+ value-key="user"
672
+ object-identity-key="id"
673
+ />
674
+ ```
675
+
676
+ 远程请求、防抖和已选项缓存仍由 `QyRemoteSelect` 负责;`QySelect` 不承接业务字典或请求状态编排。
515
677
 
516
678
  ### `QyTreeSelect`
517
679
 
@@ -942,6 +1104,18 @@ function handleSelect(item) {
942
1104
  </template>
943
1105
  ```
944
1106
 
1107
+ ### QyRadio
1108
+
1109
+ ```vue
1110
+ <template>
1111
+ <QyRadio
1112
+ v-model="ticketType"
1113
+ value="invoice"
1114
+ label="开票"
1115
+ />
1116
+ </template>
1117
+ ```
1118
+
945
1119
  ### QyRadioGroup
946
1120
 
947
1121
  ```vue