@qynpm/ui 1.0.32 → 1.0.34

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 (178) hide show
  1. package/README.md +184 -86
  2. package/dist/index.cjs +7 -4
  3. package/dist/index.mjs +79 -72
  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 +1 -1
  10. package/dist/qy-checkbox-group/index.cjs +1 -1
  11. package/dist/qy-checkbox-group/index.mjs +1 -1
  12. package/dist/qy-collapse/index.cjs +1 -1
  13. package/dist/qy-collapse/index.mjs +1 -1
  14. package/dist/qy-color-picker/index.cjs +1 -0
  15. package/dist/qy-color-picker/index.mjs +7 -0
  16. package/dist/qy-dialog/index.cjs +1 -1
  17. package/dist/qy-dialog/index.mjs +2 -2
  18. package/dist/qy-drawer/index.cjs +1 -1
  19. package/dist/qy-drawer/index.mjs +1 -1
  20. package/dist/qy-dropdown/index.cjs +1 -1
  21. package/dist/qy-dropdown/index.mjs +1 -1
  22. package/dist/qy-file-picker/index.cjs +1 -1
  23. package/dist/qy-file-picker/index.mjs +1 -1
  24. package/dist/qy-form-section/index.cjs +1 -1
  25. package/dist/qy-form-section/index.mjs +1 -1
  26. package/dist/qy-fullscreen/index.cjs +1 -1
  27. package/dist/qy-fullscreen/index.mjs +1 -1
  28. package/dist/qy-icon/index.cjs +1 -1
  29. package/dist/qy-icon/index.mjs +2 -2
  30. package/dist/qy-icon-picker/index.cjs +1 -1
  31. package/dist/qy-icon-picker/index.mjs +1 -1
  32. package/dist/qy-iframe/index.cjs +1 -0
  33. package/dist/qy-iframe/index.mjs +7 -0
  34. package/dist/qy-image/index.cjs +1 -1
  35. package/dist/qy-image/index.mjs +1 -1
  36. package/dist/qy-image-upload/index.cjs +1 -1
  37. package/dist/qy-image-upload/index.mjs +1 -1
  38. package/dist/qy-input/index.cjs +1 -1
  39. package/dist/qy-input/index.mjs +1 -1
  40. package/dist/qy-legacy-selection-dialog/index.cjs +1 -1
  41. package/dist/qy-legacy-selection-dialog/index.mjs +1 -1
  42. package/dist/qy-menu-actions/index.cjs +1 -1
  43. package/dist/qy-menu-actions/index.mjs +1 -1
  44. package/dist/qy-money-input/index.cjs +1 -1
  45. package/dist/qy-money-input/index.mjs +1 -1
  46. package/dist/qy-popconfirm/index.cjs +2 -0
  47. package/dist/qy-popconfirm/index.mjs +8 -0
  48. package/dist/qy-radio/index.cjs +1 -1
  49. package/dist/qy-radio/index.mjs +1 -1
  50. package/dist/qy-radio-group/index.cjs +1 -1
  51. package/dist/qy-radio-group/index.mjs +1 -1
  52. package/dist/qy-record-quote-search/index.cjs +1 -1
  53. package/dist/qy-record-quote-search/index.mjs +1 -1
  54. package/dist/qy-remark-image/index.cjs +1 -1
  55. package/dist/qy-remark-image/index.mjs +1 -1
  56. package/dist/qy-remote-select/index.cjs +1 -1
  57. package/dist/qy-remote-select/index.mjs +1 -1
  58. package/dist/qy-result/index.cjs +1 -1
  59. package/dist/qy-result/index.mjs +1 -1
  60. package/dist/qy-scrollbar/index.cjs +1 -1
  61. package/dist/qy-scrollbar/index.mjs +1 -1
  62. package/dist/qy-search-input/index.cjs +1 -1
  63. package/dist/qy-search-input/index.mjs +1 -1
  64. package/dist/qy-select/index.cjs +1 -1
  65. package/dist/qy-select/index.mjs +1 -1
  66. package/dist/qy-selection-dialog/index.cjs +1 -1
  67. package/dist/qy-selection-dialog/index.mjs +1 -1
  68. package/dist/qy-switch/index.cjs +1 -1
  69. package/dist/qy-switch/index.mjs +1 -1
  70. package/dist/qy-table-column-settings/index.cjs +1 -1
  71. package/dist/qy-table-column-settings/index.mjs +1 -1
  72. package/dist/qy-tag/index.cjs +1 -1
  73. package/dist/qy-tag/index.mjs +1 -1
  74. package/dist/qy-tree/index.cjs +1 -1
  75. package/dist/qy-tree/index.mjs +1 -1
  76. package/dist/qy-tree-select/index.cjs +1 -1
  77. package/dist/qy-tree-select/index.mjs +1 -1
  78. package/dist/qy-upload/index.cjs +1 -1
  79. package/dist/qy-upload/index.mjs +1 -1
  80. package/dist/qy-watermark/index.cjs +1 -0
  81. package/dist/qy-watermark/index.mjs +7 -0
  82. package/dist/shared/{index-D-YyFaZ6.cjs → index-3qEac4h8.cjs} +1 -1
  83. package/dist/shared/{index-hEy-3mcr.mjs → index-BBZQowyp.mjs} +8 -8
  84. package/dist/shared/{index-B6xIO6kg.cjs → index-Bi9wgcgT.cjs} +1 -1
  85. package/dist/shared/{index-BWDaV6FO.cjs → index-CwY_jv_I.cjs} +1 -1
  86. package/dist/shared/index-D6-K5xSD.cjs +1 -0
  87. package/dist/shared/{index-xuTVtF4x.mjs → index-DY-CA7Vr.mjs} +1 -1
  88. package/dist/shared/index-Dw5upK-A.cjs +1 -0
  89. package/dist/shared/{index-1LT6Q6XJ.mjs → index-Dwf-JfXM.mjs} +1 -1
  90. package/dist/shared/{index-CpvFUems.cjs → index-Dyyp1ix9.cjs} +1 -1
  91. package/dist/shared/{index-kiAR2M_e.mjs → index-IXbvJ9d7.mjs} +1 -1
  92. package/dist/shared/{index-BmJPEXUM.mjs → index-S8HW36Mc.mjs} +2 -2
  93. package/dist/shared/index-ccugL1Ie.mjs +71 -0
  94. package/dist/shared/index-fh9l84rU.mjs +3541 -0
  95. package/dist/shared/{index-CltDZpF9.cjs → index-n04hARNG.cjs} +1 -1
  96. package/dist/shared/{index.vue_vue_type_script_setup_true_lang-C91DUwOD.mjs → index.vue_vue_type_script_setup_true_lang-C6-hVGUO.mjs} +1 -1
  97. package/dist/shared/index.vue_vue_type_script_setup_true_lang-COAUEujY.mjs +48 -0
  98. package/dist/shared/index.vue_vue_type_script_setup_true_lang-Cr9PdvyR.cjs +1 -0
  99. package/dist/shared/{index.vue_vue_type_script_setup_true_lang-CuXBYNXZ.cjs → index.vue_vue_type_script_setup_true_lang-DOuk75uN.cjs} +1 -1
  100. package/dist/shared/{index.vue_vue_type_script_setup_true_lang-DP-jqqo2.mjs → index.vue_vue_type_script_setup_true_lang-S-rQ0p3E.mjs} +1 -1
  101. package/dist/shared/{index.vue_vue_type_script_setup_true_lang-DkDEcB4G.cjs → index.vue_vue_type_script_setup_true_lang-lvZQ_Cu6.cjs} +1 -1
  102. package/dist/shared/{index.vue_vue_type_style_index_0_lang-CL_IFx-Z.cjs → index.vue_vue_type_style_index_0_lang-BcZb1U13.cjs} +1 -1
  103. package/dist/shared/index.vue_vue_type_style_index_0_lang-BoaO6MKl.cjs +1 -0
  104. package/dist/shared/index.vue_vue_type_style_index_0_lang-C4Yk-UdJ.mjs +172 -0
  105. package/dist/shared/{index.vue_vue_type_style_index_0_lang-DXQ9l1XF.mjs → index.vue_vue_type_style_index_0_lang-CIcZet5j.mjs} +3 -3
  106. package/dist/shared/index.vue_vue_type_style_index_0_lang-Ch3QcF8t.cjs +1 -0
  107. package/dist/shared/index.vue_vue_type_style_index_0_lang-b0y8p1p1.mjs +215 -0
  108. package/index.d.ts +108 -63
  109. package/package.json +483 -459
  110. package/qy-alert/index.d.ts +64 -64
  111. package/qy-autocomplete/index.d.ts +5 -5
  112. package/qy-avatar/index.d.ts +67 -67
  113. package/qy-badge/index.d.ts +63 -63
  114. package/qy-card/index.d.ts +64 -64
  115. package/qy-cascader/index.d.ts +198 -198
  116. package/qy-collapse/index.d.ts +59 -59
  117. package/qy-collapse-item/index.d.ts +45 -45
  118. package/qy-color-picker/index.d.ts +36 -0
  119. package/qy-descriptions/index.d.ts +47 -47
  120. package/qy-descriptions-item/index.d.ts +46 -46
  121. package/qy-dialog/index.d.ts +60 -2
  122. package/qy-divider/index.d.ts +53 -53
  123. package/qy-drawer/index.d.ts +55 -55
  124. package/qy-empty/index.d.ts +51 -51
  125. package/qy-iframe/index.d.ts +66 -0
  126. package/qy-image/index.d.ts +28 -28
  127. package/qy-image-preview/index.d.ts +20 -20
  128. package/qy-link/index.d.ts +69 -69
  129. package/qy-loading/index.d.ts +25 -25
  130. package/qy-menu-actions/index.d.ts +29 -29
  131. package/qy-popconfirm/index.d.ts +55 -0
  132. package/qy-progress/index.d.ts +74 -74
  133. package/qy-result/index.d.ts +64 -64
  134. package/qy-scrollbar/index.d.ts +85 -85
  135. package/qy-skeleton/index.d.ts +54 -54
  136. package/qy-skeleton-item/index.d.ts +48 -48
  137. package/qy-step/index.d.ts +55 -55
  138. package/qy-steps/index.d.ts +62 -62
  139. package/qy-tab-pane/index.d.ts +40 -40
  140. package/qy-table-column-settings/index.d.ts +18 -18
  141. package/qy-tabs/index.d.ts +84 -84
  142. package/qy-tree/index.d.ts +132 -132
  143. package/qy-tree-select/index.d.ts +123 -123
  144. package/qy-watermark/index.d.ts +72 -0
  145. package/dist/shared/index-4wZQbpy3.mjs +0 -3457
  146. package/dist/shared/index-BvKFjDgX.cjs +0 -1
  147. /package/dist/shared/{index-AirHUQwm.cjs → index-AMu0L6uU.cjs} +0 -0
  148. /package/dist/shared/{index-D6ybNdgn.mjs → index-B1b3BksF.mjs} +0 -0
  149. /package/dist/shared/{index-BpI0jwYK.cjs → index-BPaVDCe6.cjs} +0 -0
  150. /package/dist/shared/{index-CCZttbsg.cjs → index-BdTlpKtr.cjs} +0 -0
  151. /package/dist/shared/{index-CwzztWPU.cjs → index-BeubtXXl.cjs} +0 -0
  152. /package/dist/shared/{index-Bxz4crCd.cjs → index-BkX9xlbI.cjs} +0 -0
  153. /package/dist/shared/{index-DLLDXfic.cjs → index-Bvot0uXo.cjs} +0 -0
  154. /package/dist/shared/{index-CaNxcPSD.mjs → index-C91mzAI3.mjs} +0 -0
  155. /package/dist/shared/{index-CmRclPWX.mjs → index-C_1KP3l9.mjs} +0 -0
  156. /package/dist/shared/{index-DfR8Z9MN.mjs → index-C_adKysL.mjs} +0 -0
  157. /package/dist/shared/{index-DEZF-Fkt.mjs → index-D5S48q1B.mjs} +0 -0
  158. /package/dist/shared/{index-Co0_4YEV.mjs → index-D8E_xu0N.mjs} +0 -0
  159. /package/dist/shared/{index-Bmw9BNXm.cjs → index-DCzxcvkn.cjs} +0 -0
  160. /package/dist/shared/{index-C31wpivi.mjs → index-DK0hjfWr.mjs} +0 -0
  161. /package/dist/shared/{index-D_rRdrge.mjs → index-DZRFSGxO.mjs} +0 -0
  162. /package/dist/shared/{index-BDdhBEFr.cjs → index-Dc6gLgAz.cjs} +0 -0
  163. /package/dist/shared/{index-C-ZAw_DP.mjs → index-DcohgM8A.mjs} +0 -0
  164. /package/dist/shared/{index-BxvS3vlc.cjs → index-Di4bIOiB.cjs} +0 -0
  165. /package/dist/shared/{index-Bs2OQHXk.mjs → index-JjHutKmT.mjs} +0 -0
  166. /package/dist/shared/{index-seQHtqdh.mjs → index-Od6HC8Un.mjs} +0 -0
  167. /package/dist/shared/{index-rcu9CzSn.cjs → index-nSFTxVz8.cjs} +0 -0
  168. /package/dist/shared/{index-DIs6iPjF.cjs → index-nos4Y-fm.cjs} +0 -0
  169. /package/dist/shared/{index.vue_vue_type_script_setup_true_lang-S6QPMZay.cjs → index.vue_vue_type_script_setup_true_lang-CglCPcj-.cjs} +0 -0
  170. /package/dist/shared/{index.vue_vue_type_script_setup_true_lang-BLF3RNlY.mjs → index.vue_vue_type_script_setup_true_lang-q37rBg6Z.mjs} +0 -0
  171. /package/dist/shared/{index.vue_vue_type_style_index_0_lang-DUgOOzEZ.cjs → index.vue_vue_type_style_index_0_lang-BXTkWo5P.cjs} +0 -0
  172. /package/dist/shared/{index.vue_vue_type_style_index_0_lang-lmRmXLwB.cjs → index.vue_vue_type_style_index_0_lang-BnPRHCwR.cjs} +0 -0
  173. /package/dist/shared/{index.vue_vue_type_style_index_0_lang-DWiolYb3.mjs → index.vue_vue_type_style_index_0_lang-C1n-zAZh.mjs} +0 -0
  174. /package/dist/shared/{index.vue_vue_type_style_index_0_lang-B-FeHatv.mjs → index.vue_vue_type_style_index_0_lang-CVdFZeHK.mjs} +0 -0
  175. /package/dist/shared/{index.vue_vue_type_style_index_0_lang-DzfGx6ce.mjs → index.vue_vue_type_style_index_0_lang-KHk9wRYT.mjs} +0 -0
  176. /package/dist/shared/{index.vue_vue_type_style_index_0_lang-CUqnwExG.mjs → index.vue_vue_type_style_index_0_lang-Tzo8o6M8.mjs} +0 -0
  177. /package/dist/shared/{index.vue_vue_type_style_index_0_lang-DOfJV2oz.cjs → index.vue_vue_type_style_index_0_lang-WGzoSatU.cjs} +0 -0
  178. /package/dist/shared/{index.vue_vue_type_style_index_0_lang-Cn3P9d4L.cjs → index.vue_vue_type_style_index_0_lang-hbNK_h45.cjs} +0 -0
package/README.md CHANGED
@@ -43,16 +43,20 @@ import {
43
43
  QyCascader,
44
44
  QyTooltip,
45
45
  QyPopover,
46
- QySkeleton,
47
- QySkeletonItem,
48
- QyLoading,
46
+ QyPopconfirm,
47
+ QySkeleton,
48
+ QySkeletonItem,
49
+ QyLoading,
49
50
  QyTabs,
50
51
  QyTabPane,
51
52
  QySteps,
52
53
  QyStep,
53
54
  QyIcon,
54
55
  QyIconPicker,
56
+ QyColorPicker,
57
+ QyWatermark,
55
58
  QyLink,
59
+ QyIframe,
56
60
  QyDivider,
57
61
  QyEmpty,
58
62
  QyScrollbar,
@@ -100,6 +104,7 @@ import QyActionBar from '@qynpm/ui/qy-action-bar'
100
104
  import QyButton from '@qynpm/ui/qy-button'
101
105
  import QyDropdown from '@qynpm/ui/qy-dropdown'
102
106
  import QyIconPicker from '@qynpm/ui/qy-icon-picker'
107
+ import QyColorPicker from '@qynpm/ui/qy-color-picker'
103
108
  import QySearchInput from '@qynpm/ui/qy-search-input'
104
109
  import QyRecordQuoteSearch from '@qynpm/ui/qy-record-quote-search'
105
110
  import QyDialog from '@qynpm/ui/qy-dialog'
@@ -112,14 +117,17 @@ import QyCascader from '@qynpm/ui/qy-cascader'
112
117
  import QyTree from '@qynpm/ui/qy-tree'
113
118
  import QyTooltip from '@qynpm/ui/qy-tooltip'
114
119
  import QyPopover from '@qynpm/ui/qy-popover'
115
- import QySkeleton from '@qynpm/ui/qy-skeleton'
116
- import QySkeletonItem from '@qynpm/ui/qy-skeleton-item'
117
- import QyLoading, { openQyLoading } from '@qynpm/ui/qy-loading'
120
+ import QyPopconfirm from '@qynpm/ui/qy-popconfirm'
121
+ import QyWatermark from '@qynpm/ui/qy-watermark'
122
+ import QySkeleton from '@qynpm/ui/qy-skeleton'
123
+ import QySkeletonItem from '@qynpm/ui/qy-skeleton-item'
124
+ import QyLoading, { openQyLoading } from '@qynpm/ui/qy-loading'
118
125
  import QyTabs from '@qynpm/ui/qy-tabs'
119
126
  import QyTabPane from '@qynpm/ui/qy-tab-pane'
120
127
  import QySteps from '@qynpm/ui/qy-steps'
121
128
  import QyStep from '@qynpm/ui/qy-step'
122
129
  import QyLink from '@qynpm/ui/qy-link'
130
+ import QyIframe from '@qynpm/ui/qy-iframe'
123
131
  import QyEmpty from '@qynpm/ui/qy-empty'
124
132
  import QyScrollbar from '@qynpm/ui/qy-scrollbar'
125
133
  import QyProgress from '@qynpm/ui/qy-progress'
@@ -327,7 +335,27 @@ pnpm install --frozen-lockfile --ignore-scripts
327
335
 
328
336
  默认值为 `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`。
329
337
 
330
- ### `QySkeleton` 与 `QySkeletonItem`
338
+ ### `QyPopconfirm`
339
+
340
+ 二次确认浮层,提供 Qy-owned 的确认、取消、加载锁、关闭原因和焦点恢复语义。支持 `reference`、`title`、`icon` 插槽;`open` 可选受控,确认成功后的父级关闭会以 `close('external')` 记录,异步失败保持打开并允许重试。
341
+
342
+ ```vue
343
+ <QyPopconfirm
344
+ title="确认删除?"
345
+ variant="danger"
346
+ confirm-type="danger"
347
+ :confirm-loading="saving"
348
+ :close-on-confirm="false"
349
+ @confirm="save"
350
+ @close="onClose"
351
+ >
352
+ <template #reference><button type="button">删除</button></template>
353
+ </QyPopconfirm>
354
+ ```
355
+
356
+ 事件为 `update:open`、`open-change`、`confirm`、`cancel` 和 `close(reason)`;关闭原因是 `confirm`、`cancel`、`outside`、`escape`、`trigger`、`external` 或 `disabled`。不公开 Element Plus 类型、实例、teleport 或 popper 参数。
357
+
358
+ ### `QySkeleton` 与 `QySkeletonItem`
331
359
 
332
360
  加载骨架组件基于 Element Plus 的 `ElSkeleton` / `ElSkeletonItem` 渲染。`loading` 由业务受控,加载期间使用 `template` 插槽,加载完成后使用默认插槽;支持 `animated`、`count`、`rows` 及数字或对象形式的 `throttle`。
333
361
 
@@ -340,78 +368,96 @@ pnpm install --frozen-lockfile --ignore-scripts
340
368
  </QySkeleton>
341
369
  ```
342
370
 
343
- `QySkeletonItem` 的 `variant` 支持 `p`、`text`、`h1`、`h3`、`caption`、`button`、`image`、`circle`、`rect`,默认值为 `text`。两者均支持 `class`、`style`、`role`、`title`、`data-*` 和 `aria-*`,不公开 Element Plus 实例。
344
-
345
- ### `QyLoading`
346
-
347
- `QyLoading` 安装后注册 `v-qy-loading` 指令,并配置命令式 `openQyLoading` 服务。指令支持布尔值或 `{ active, text, maskColor, lockScroll }` 对象;服务未传 `target` 时覆盖 body,传入 HTMLElement 时只覆盖该容器。同一目标的多个句柄共享一个遮罩,最后一个句柄调用 `close()` 后才移除。
348
-
349
- ```vue
350
- <script setup>
351
- import { ref } from 'vue'
352
- import { openQyLoading } from '@qynpm/ui/qy-loading'
353
-
354
- const loading = ref(false)
355
- const target = ref(null)
356
-
357
- function load() {
358
- const handle = openQyLoading({ target: target.value, text: '加载中' })
359
- // 请求完成后调用一次即可,重复 close 不会影响后续 loading。
360
- handle.close()
361
- }
362
- </script>
363
-
364
- <template>
365
- <div ref="target" v-qy-loading="{ active: loading, lockScroll: true }">
366
- 容器内容
367
- </div>
368
- </template>
369
- ```
370
-
371
- ### `QyDrawer`
372
-
373
- `QyDrawer` 使用 Qy-owned props、事件和插槽封装抽屉容器,支持四方向、数字尺寸、遮罩/Escape 关闭原因、指定 `teleportTo` 容器、焦点恢复和重叠抽屉顶层响应。`header`、默认内容和 `footer` 插槽均接收 Qy-owned `close()`。
374
-
375
- ```vue
376
- <script setup>
377
- import { ref } from 'vue'
378
- import QyDrawer from '@qynpm/ui/qy-drawer'
379
-
380
- const open = ref(false)
381
- </script>
382
-
383
- <template>
384
- <button type="button" @click="open = true">查看订单</button>
385
- <QyDrawer v-model="open" title="订单详情" placement="right" @close="open = false">
386
- <p>抽屉内容</p>
387
- <template #footer="{ close }">
388
- <button type="button" @click="close">关闭</button>
389
- </template>
390
- </QyDrawer>
391
- </template>
392
- ```
393
-
394
- ### `QyResult`
395
-
396
- `QyResult` 统一展示成功、警告、信息、错误和 401/403/404/500 结果。它只负责结果视觉、标题、说明、图片和操作区,不负责路由、返回、刷新、重试、请求或状态管理;业务动作由消费者放入 `actions` 插槽。
397
-
398
- ```vue
399
- <script setup>
400
- import QyResult from '@qynpm/ui/qy-result'
401
- </script>
402
-
403
- <template>
404
- <QyResult status="404" title="页面不存在" description="请检查地址">
405
- <template #actions>
406
- <button type="button" @click="goHome">返回首页</button>
407
- </template>
408
- </QyResult>
409
- </template>
410
- ```
411
-
412
- `visual` 插槽优先于 `image`,`image` 优先于状态内置视觉;`title` 同时作为结果标题和根节点原生 `title`,`description` 与 `actions` 也支持同名插槽覆盖属性内容。根入口与 `@qynpm/ui/qy-result` 均提供 Qy-owned 类型,不公开 Element Plus 类型、实例或事件。
413
-
414
- ### `QyTabs` 与 `QyTabPane`
371
+ `QySkeletonItem` 的 `variant` 支持 `p`、`text`、`h1`、`h3`、`caption`、`button`、`image`、`circle`、`rect`,默认值为 `text`。两者均支持 `class`、`style`、`role`、`title`、`data-*` 和 `aria-*`,不公开 Element Plus 实例。
372
+
373
+ ### `QyLoading`
374
+
375
+ `QyLoading` 安装后注册 `v-qy-loading` 指令,并配置命令式 `openQyLoading` 服务。指令支持布尔值或 `{ active, text, maskColor, lockScroll }` 对象;服务未传 `target` 时覆盖 body,传入 HTMLElement 时只覆盖该容器。同一目标的多个句柄共享一个遮罩,最后一个句柄调用 `close()` 后才移除。
376
+
377
+ ```vue
378
+ <script setup>
379
+ import { ref } from 'vue'
380
+ import { openQyLoading } from '@qynpm/ui/qy-loading'
381
+
382
+ const loading = ref(false)
383
+ const target = ref(null)
384
+
385
+ function load() {
386
+ const handle = openQyLoading({ target: target.value, text: '加载中' })
387
+ // 请求完成后调用一次即可,重复 close 不会影响后续 loading。
388
+ handle.close()
389
+ }
390
+ </script>
391
+
392
+ <template>
393
+ <div ref="target" v-qy-loading="{ active: loading, lockScroll: true }">
394
+ 容器内容
395
+ </div>
396
+ </template>
397
+ ```
398
+
399
+ ### `QyDrawer`
400
+
401
+ `QyDrawer` 使用 Qy-owned props、事件和插槽封装抽屉容器,支持四方向、数字尺寸、遮罩/Escape 关闭原因、指定 `teleportTo` 容器、焦点恢复和重叠抽屉顶层响应。`header`、默认内容和 `footer` 插槽均接收 Qy-owned `close()`。
402
+
403
+ ```vue
404
+ <script setup>
405
+ import { ref } from 'vue'
406
+ import QyDrawer from '@qynpm/ui/qy-drawer'
407
+
408
+ const open = ref(false)
409
+ </script>
410
+
411
+ <template>
412
+ <button type="button" @click="open = true">查看订单</button>
413
+ <QyDrawer v-model="open" title="订单详情" placement="right" @close="open = false">
414
+ <p>抽屉内容</p>
415
+ <template #footer="{ close }">
416
+ <button type="button" @click="close">关闭</button>
417
+ </template>
418
+ </QyDrawer>
419
+ </template>
420
+ ```
421
+
422
+ ### `QyResult`
423
+
424
+ `QyResult` 统一展示成功、警告、信息、错误和 401/403/404/500 结果。它只负责结果视觉、标题、说明、图片和操作区,不负责路由、返回、刷新、重试、请求或状态管理;业务动作由消费者放入 `actions` 插槽。
425
+
426
+ ```vue
427
+ <script setup>
428
+ import QyResult from '@qynpm/ui/qy-result'
429
+ </script>
430
+
431
+ <template>
432
+ <QyResult status="404" title="页面不存在" description="请检查地址">
433
+ <template #actions>
434
+ <button type="button" @click="goHome">返回首页</button>
435
+ </template>
436
+ </QyResult>
437
+ </template>
438
+ ```
439
+
440
+ `visual` 插槽优先于 `image`,`image` 优先于状态内置视觉;`title` 同时作为结果标题和根节点原生 `title`,`description` 与 `actions` 也支持同名插槽覆盖属性内容。根入口与 `@qynpm/ui/qy-result` 均提供 Qy-owned 类型,不公开 Element Plus 类型、实例或事件。
441
+
442
+ ### `QyWatermark`
443
+
444
+ `QyWatermark` 在容器内提供 Qy-owned 的平铺文字或图片水印,图片优先且加载失败回退到 `content`;`content` 支持多行文字,`font`、`rotate`、`width`、`height`、`gap` 和 `offset` 控制水印单元。水印覆盖层不接收指针事件,默认插槽中的按钮、图片和选择操作仍由消费者处理。
445
+
446
+ ```vue
447
+ <script setup>
448
+ import QyWatermark from '@qynpm/ui/qy-watermark'
449
+ </script>
450
+
451
+ <template>
452
+ <QyWatermark :content="['客户名称', '订单编号']" :rotate="-18">
453
+ <div>订单内容</div>
454
+ </QyWatermark>
455
+ </template>
456
+ ```
457
+
458
+ 公开 interface 只包含 `content`、`image`、`zIndex`、`rotate`、`width`、`height`、`gap`、`offset` 和 Qy-owned `font`,以及安全容器属性 `class`、`style`、`id`、`title`、`role`、`data-*`、`aria-*`;不公开 Element Plus props、实例、DOM、事件或 expose。完整演示位于 `src/docs/QyWatermarkDoc.vue`,入口为 `@qynpm/ui/qy-watermark`。
459
+
460
+ ### `QyTabs` 与 `QyTabPane`
415
461
 
416
462
  `QyTabs` 使用 Element Plus 的 `ElTabs` / `ElTabPane` 处理渲染、焦点与键盘行为。`modelValue` 传入时保持受控;`defaultValue` 仅提供初始选择。`tab-change`、`tab-remove`、`tab-add` 与 `edit` 都是意图事件,不会改写业务页签数组、路由或 AdminShell 运行时。
417
463
 
@@ -675,13 +721,28 @@ options 模式物理复用 `QyCheckbox`;不提供 CheckboxButton、全选、in
675
721
 
676
722
  ### `QyDialog`
677
723
 
678
- 弹窗组件,支持:
724
+ QyDialog 是受控弹窗组件,使用 Qy-owned 协议:
725
+
726
+ - `open` / `update:open` / `open-change` 管理显隐
727
+ - `confirm`、`cancel` 和 `close(reason)` 表达关闭意图;`reason` 为 `confirm | cancel | header | escape | overlay | external`
728
+ - `confirm-loading` 在宿主异步业务期间锁定确认动作,业务成功后由宿主关闭
729
+ - 默认 footer 由 `show-footer`、`show-confirm`、`show-cancel`、`confirm-text` 和 `cancel-text` 控制;自定义 `footer` 时不渲染默认按钮
730
+ - 支持全屏切换、最小化、焦点恢复和顶层弹窗 Escape/遮罩仲裁
731
+
732
+ ```vue
733
+ <QyDialog
734
+ :open="open"
735
+ title="订单确认"
736
+ :confirm-loading="saving"
737
+ :close-on-confirm="false"
738
+ @update:open="open = $event"
739
+ @confirm="save"
740
+ >
741
+ 内容区域
742
+ </QyDialog>
743
+ ```
679
744
 
680
- - 默认头部/底部布局
681
- - 全屏切换
682
- - 最小化
683
- - 自定义 footer
684
- - 移动端自动全屏
745
+ 旧 `modelValue`、`layout`、`confirmProps`、`ok` 和 Element Plus attrs 不属于 QyDialog 公共面;过渡场景使用独立的 `@qynpm/qy-dialog-legacy` adapter,禁止新业务采用。
685
746
 
686
747
  ### `QyButton`
687
748
 
@@ -1275,7 +1336,7 @@ function handleSelect(item) {
1275
1336
 
1276
1337
  ```vue
1277
1338
  <template>
1278
- <QyDialog title="标题" @confirm="handleConfirm">
1339
+ <QyDialog :open="open" title="标题" close-on-confirm @update:open="open = $event">
1279
1340
  内容区域
1280
1341
  </QyDialog>
1281
1342
  </template>
@@ -1500,6 +1561,26 @@ function beforeCollapse(name) {
1500
1561
 
1501
1562
  `disabled` 会移除有效 `href` 与 `target` 并抑制 `click`;非禁用点击只转发一次原生 `MouseEvent`。`type` 和 `underline` 未传时可继承 Element Plus ConfigProvider;布尔下划线仅作兼容,`true` 等同 `hover`、`false` 等同 `never`。不自动改写 `target` 或 `rel`,外部新窗口链接请显式提供 `rel="noopener noreferrer"`。无 href、只监听 `click` 的旧用法可以兼容,但新业务动作应使用 `QyButton`,路由导航应使用 RouterLink。
1502
1563
 
1564
+ ### QyIframe
1565
+
1566
+ `QyIframe` 用于在当前页面容器中嵌入受信任的独立页面。`src` 和无障碍 `title` 必填且去除首尾空白后必须非空;任一为空时不渲染 iframe。支持原生 `loading`、`sandbox`、`allow`、`referrerPolicy`、`allowFullscreen`,并发出无参数的 `load` 和 `error` 通知,不暴露原生 DOM Event。
1567
+
1568
+ ```vue
1569
+ <div style="height: 640px">
1570
+ <QyIframe
1571
+ src="/system/monitor"
1572
+ title="系统监控"
1573
+ :reload-key="reloadKey"
1574
+ loading="lazy"
1575
+ sandbox="allow-scripts allow-same-origin"
1576
+ @load="handleLoad"
1577
+ @error="handleError"
1578
+ />
1579
+ </div>
1580
+ ```
1581
+
1582
+ `src` 变化时更新当前 iframe 地址;即使 `src` 相同,改变 `reloadKey`(`string | number`)也会重建 iframe 以触发受控 reload。组件默认填满父容器,不计算应用头部、标签栏或面包屑高度;宿主必须为容器提供明确高度。根节点只安全透传 `class`、`style`、`id`、`role`、`tabindex`、`data-*` 和 `aria-*`,未知属性及未声明监听器不对外透传。组件不模拟加载时长、不覆盖全局 resize 监听,也不负责登录会话、地址白名单或跨域通信。
1583
+
1503
1584
  ### QyDivider
1504
1585
 
1505
1586
  `QyDivider` 基于 Element Plus `ElDivider`,支持水平/垂直方向、左中右标题位置和标准 CSS `border-style` 值。水平模式渲染默认插槽,垂直模式即使传入插槽也保持 Element Plus 行为而不渲染;消费者传入的 `width`、`height`、`margin` 等根样式会与 Element Plus 的边框 CSS 变量合并。
@@ -1700,6 +1781,23 @@ app.use(createQyIconPlugin(registry))
1700
1781
 
1701
1782
  公开事件为 `update:modelValue`、`change`、`clear`、`update:open` 和 `open-change`;实例只暴露 `focus()`、`blur()`、`open()`、`close()`。面板使用 listbox/option 语义,支持 Enter/Space 打开、方向键移动、Enter 选择和 Escape 回焦;触摸窄屏网格为两列且每个选项至少 40px。完整演示位于 `src/docs/QyIconPickerDoc.vue`,入口为 `@qynpm/ui/qy-icon-picker`。
1702
1783
 
1784
+ ### QyColorPicker
1785
+
1786
+ `QyColorPicker` 是受控颜色选择器。`format` 只接受 `hex` 或 `rgb`;未指定时,关闭透明度输出 hex,开启透明度输出 rgb/rgba。拖动和输入只触发 `active-change`,确认或清空才按 `update:modelValue`、`change`、`visible-change(false)` 顺序提交;Escape、点击外部和失焦会回滚到当前父级值且不发提交事件。
1787
+
1788
+ ```vue
1789
+ <QyColorPicker
1790
+ v-model="brandColor"
1791
+ format="rgb"
1792
+ show-alpha
1793
+ :predefine="['#409eff', '#67c23a']"
1794
+ clearable
1795
+ @active-change="previewColor = $event"
1796
+ />
1797
+ ```
1798
+
1799
+ 事件为 `update:modelValue`、`active-change`、`change` 和 `visible-change`,颜色 payload 为 `string | null`;组件不公开 Element Plus 类型、实例或 expose。完整演示位于 `src/docs/QyColorPickerDoc.vue`,入口为 `@qynpm/ui/qy-color-picker`。
1800
+
1703
1801
  ### QyContainer、QyAside 与 QyMain
1704
1802
 
1705
1803
  三个组件是通用布局原语,入口分别为 `@qynpm/ui/qy-container`、`@qynpm/ui/qy-aside` 与 `@qynpm/ui/qy-main`;根入口也导出 `QyContainer`、`QyAside`、`QyMain` 及其 Qy 自有类型。V1 使用内部 Element Plus renderer,公共 wrapper 和声明文件不要求消费者感知 Element Plus。