@guoyg578/k-ui 0.1.4 → 0.1.6

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 (102) hide show
  1. package/dist/components/KAutoComplete.vue.d.ts +2 -0
  2. package/dist/components/KAutoComplete.vue.js +1 -1
  3. package/dist/components/KAutoComplete.vue_vue_type_script_setup_true_lang.js +89 -29
  4. package/dist/components/KCalendar.vue.js +1 -1
  5. package/dist/components/KCalendar.vue_vue_type_script_setup_true_lang.js +132 -39
  6. package/dist/components/KCascader.vue.d.ts +2 -0
  7. package/dist/components/KCascader.vue.js +1 -1
  8. package/dist/components/KCascader.vue_vue_type_script_setup_true_lang.js +45 -43
  9. package/dist/components/KCheckbox.vue.d.ts +6 -2
  10. package/dist/components/KCheckbox.vue.js +1 -1
  11. package/dist/components/KCheckbox.vue_vue_type_script_setup_true_lang.js +38 -18
  12. package/dist/components/KCheckboxGroup.vue.d.ts +2 -0
  13. package/dist/components/KCheckboxGroup.vue.js +1 -1
  14. package/dist/components/KCheckboxGroup.vue_vue_type_script_setup_true_lang.js +23 -15
  15. package/dist/components/KCollapse.vue.d.ts +3 -1
  16. package/dist/components/KCollapse.vue.js +1 -1
  17. package/dist/components/KCollapse.vue_vue_type_script_setup_true_lang.js +27 -16
  18. package/dist/components/KCombobox.vue.js +1 -1
  19. package/dist/components/KCombobox.vue_vue_type_script_setup_true_lang.js +48 -47
  20. package/dist/components/KDataTable.vue.d.ts +48 -1
  21. package/dist/components/KDataTable.vue.js +1 -1
  22. package/dist/components/KDataTable.vue_vue_type_script_setup_true_lang.js +305 -74
  23. package/dist/components/KDatePicker.vue.d.ts +8 -0
  24. package/dist/components/KDatePicker.vue_vue_type_script_setup_true_lang.js +32 -22
  25. package/dist/components/KDialog.vue.d.ts +4 -4
  26. package/dist/components/KDialog.vue.js +1 -1
  27. package/dist/components/KDialog.vue_vue_type_script_setup_true_lang.js +83 -73
  28. package/dist/components/KDrawer.vue.js +1 -1
  29. package/dist/components/KDrawer.vue_vue_type_script_setup_true_lang.js +36 -35
  30. package/dist/components/KDropdown.vue.d.ts +4 -3
  31. package/dist/components/KDropdown.vue_vue_type_script_setup_true_lang.js +48 -30
  32. package/dist/components/KDynamicInput.vue.d.ts +2 -0
  33. package/dist/components/KDynamicInput.vue.js +1 -1
  34. package/dist/components/KDynamicInput.vue_vue_type_script_setup_true_lang.js +17 -6
  35. package/dist/components/KDynamicTags.vue.d.ts +2 -0
  36. package/dist/components/KDynamicTags.vue.js +1 -1
  37. package/dist/components/KDynamicTags.vue_vue_type_script_setup_true_lang.js +11 -10
  38. package/dist/components/KForm.vue.d.ts +12 -0
  39. package/dist/components/KForm.vue.js +1 -1
  40. package/dist/components/KForm.vue_vue_type_script_setup_true_lang.js +26 -4
  41. package/dist/components/KFormField.vue.d.ts +3 -1
  42. package/dist/components/KFormField.vue.js +1 -1
  43. package/dist/components/KFormField.vue_vue_type_script_setup_true_lang.js +124 -61
  44. package/dist/components/KInputNumber.vue.js +1 -1
  45. package/dist/components/KInputNumber.vue_vue_type_script_setup_true_lang.js +35 -29
  46. package/dist/components/KMention.vue.d.ts +2 -0
  47. package/dist/components/KMention.vue.js +1 -1
  48. package/dist/components/KMention.vue_vue_type_script_setup_true_lang.js +34 -33
  49. package/dist/components/KMenu.vue.js +1 -1
  50. package/dist/components/KMenu.vue_vue_type_script_setup_true_lang.js +132 -51
  51. package/dist/components/KMenuItem.vue.js +1 -1
  52. package/dist/components/KMenuItem.vue_vue_type_script_setup_true_lang.js +21 -6
  53. package/dist/components/KMessage.d.ts +5 -0
  54. package/dist/components/KMessage.js +36 -23
  55. package/dist/components/KNotification.d.ts +8 -0
  56. package/dist/components/KNotification.js +45 -29
  57. package/dist/components/KNotificationProvider.vue.js +3 -8
  58. package/dist/components/KNotificationProvider.vue_vue_type_script_setup_true_lang.js +11 -0
  59. package/dist/components/KPagination.vue.d.ts +4 -1
  60. package/dist/components/KPagination.vue.js +1 -1
  61. package/dist/components/KPagination.vue_vue_type_script_setup_true_lang.js +36 -33
  62. package/dist/components/KPopover.vue_vue_type_script_setup_true_lang.js +15 -14
  63. package/dist/components/KRadio.vue.d.ts +1 -0
  64. package/dist/components/KRadio.vue.js +1 -1
  65. package/dist/components/KRadio.vue_vue_type_script_setup_true_lang.js +22 -14
  66. package/dist/components/KRadioGroup.vue.d.ts +4 -2
  67. package/dist/components/KRadioGroup.vue.js +1 -1
  68. package/dist/components/KRadioGroup.vue_vue_type_script_setup_true_lang.js +16 -4
  69. package/dist/components/KRate.vue.d.ts +5 -0
  70. package/dist/components/KRate.vue.js +1 -1
  71. package/dist/components/KRate.vue_vue_type_script_setup_true_lang.js +72 -24
  72. package/dist/components/KSelect.vue.d.ts +2 -2
  73. package/dist/components/KSelect.vue.js +1 -1
  74. package/dist/components/KSelect.vue_vue_type_script_setup_true_lang.js +60 -59
  75. package/dist/components/KSlider.vue.d.ts +2 -0
  76. package/dist/components/KSlider.vue.js +1 -1
  77. package/dist/components/KSlider.vue_vue_type_script_setup_true_lang.js +17 -16
  78. package/dist/components/KTextarea.vue.d.ts +2 -0
  79. package/dist/components/KTextarea.vue.js +1 -1
  80. package/dist/components/KTextarea.vue_vue_type_script_setup_true_lang.js +10 -9
  81. package/dist/components/KTimePicker.vue.d.ts +2 -0
  82. package/dist/components/KTimePicker.vue.js +1 -1
  83. package/dist/components/KTimePicker.vue_vue_type_script_setup_true_lang.js +63 -49
  84. package/dist/components/KTooltip.vue_vue_type_script_setup_true_lang.js +13 -12
  85. package/dist/components/KTransfer.vue.d.ts +2 -0
  86. package/dist/components/KTransfer.vue.js +1 -1
  87. package/dist/components/KTransfer.vue_vue_type_script_setup_true_lang.js +35 -34
  88. package/dist/components/KTreeSelect.vue.d.ts +2 -0
  89. package/dist/components/KTreeSelect.vue.js +1 -1
  90. package/dist/components/KTreeSelect.vue_vue_type_script_setup_true_lang.js +20 -18
  91. package/dist/components/KUpload.vue.d.ts +14 -0
  92. package/dist/components/KUpload.vue.js +1 -1
  93. package/dist/components/KUpload.vue_vue_type_script_setup_true_lang.js +159 -117
  94. package/dist/components/checkbox-context.d.ts +10 -0
  95. package/dist/components/checkbox-context.js +4 -0
  96. package/dist/components/form-context.d.ts +19 -2
  97. package/dist/components/form-context.js +31 -1
  98. package/dist/components/menu-context.d.ts +4 -0
  99. package/dist/components/radio-context.d.ts +6 -1
  100. package/dist/k-ui.css +1 -1
  101. package/dist/styles/tokens.css +40 -1
  102. package/package.json +1 -1
@@ -5,16 +5,16 @@ import { AlertCircle as y, CheckCircle2 as b, FileText as x, Loader2 as S, Uploa
5
5
  var T = { class: "k-upload__hint" }, E = {
6
6
  key: 0,
7
7
  class: "k-upload__meta"
8
- }, D = { key: 0 }, O = { key: 1 }, k = { key: 2 }, A = ["disabled"], j = ["multiple", "accept"], M = {
8
+ }, D = { key: 0 }, O = { key: 1 }, k = { key: 2 }, ee = ["disabled"], te = ["multiple", "accept"], A = {
9
9
  key: 2,
10
10
  class: "k-upload__list"
11
- }, N = { class: "k-upload__file-info" }, P = { class: "k-upload__file-name" }, F = { class: "k-upload__file-meta" }, I = {
11
+ }, j = { class: "k-upload__file-info" }, M = { class: "k-upload__file-name" }, N = { class: "k-upload__file-meta" }, P = {
12
12
  key: 0,
13
13
  class: "k-upload__error-text"
14
- }, L = {
14
+ }, F = {
15
15
  key: 0,
16
16
  class: "k-upload__progress"
17
- }, R = { class: "k-upload__file-status" }, z = ["onClick"], B = /* @__PURE__ */ c({
17
+ }, I = { class: "k-upload__file-status" }, L = ["onClick"], R = /* @__PURE__ */ c({
18
18
  __name: "KUpload",
19
19
  props: {
20
20
  multiple: {
@@ -23,6 +23,11 @@ var T = { class: "k-upload__hint" }, E = {
23
23
  },
24
24
  accept: {},
25
25
  maxSize: {},
26
+ action: {},
27
+ headers: {},
28
+ withCredentials: { type: Boolean },
29
+ name: {},
30
+ data: {},
26
31
  uploader: {},
27
32
  customRequest: {},
28
33
  beforeUpload: {},
@@ -59,17 +64,17 @@ var T = { class: "k-upload__hint" }, E = {
59
64
  "success",
60
65
  "error"
61
66
  ],
62
- setup(c, { expose: B, emit: V }) {
63
- let H = c, U = V, W = p([]), G = p(!1), K = p(null);
67
+ setup(c, { expose: R, emit: z }) {
68
+ let B = c, V = z, H = p([]), U = p(!1), W = p(null);
64
69
  f(e, {
65
- open: Z,
66
- isDragOver: G
70
+ open: Q,
71
+ isDragOver: U
67
72
  });
68
- function q(e) {
73
+ function G(e) {
69
74
  return e < 1024 ? e + " B" : e < 1024 * 1024 ? (e / 1024).toFixed(1) + " KB" : (e / 1024 / 1024).toFixed(2) + " MB";
70
75
  }
71
- let J = 0;
72
- function Y(e, t) {
76
+ let K = 0;
77
+ function q(e, t) {
73
78
  return {
74
79
  id: e.id,
75
80
  name: e.name,
@@ -79,40 +84,49 @@ var T = { class: "k-upload__hint" }, E = {
79
84
  url: e.url
80
85
  };
81
86
  }
82
- async function X(e) {
83
- if (H.disabled) return;
87
+ function J(e) {
88
+ let t = B.accept?.trim();
89
+ if (!t) return !0;
90
+ let n = e.name.toLowerCase(), r = e.type.toLowerCase();
91
+ return t.split(",").map((e) => e.trim().toLowerCase()).filter(Boolean).some((e) => e.startsWith(".") ? n.endsWith(e) : e.endsWith("/*") ? r.startsWith(e.slice(0, -1)) : r === e);
92
+ }
93
+ function Y(e) {
94
+ return {
95
+ id: "",
96
+ name: e.name,
97
+ status: "pending",
98
+ percentage: 0,
99
+ file: e
100
+ };
101
+ }
102
+ function X(e, t) {
103
+ H.value.push({
104
+ id: String(++K),
105
+ name: e.name,
106
+ size: e.size,
107
+ status: "error",
108
+ progress: 0,
109
+ error: t
110
+ });
111
+ }
112
+ async function Z(e) {
113
+ if (B.disabled) return;
84
114
  let t = Array.from(e);
85
- !H.multiple && t.length > 1 && (t = t.slice(0, 1));
86
- let n = [];
87
- for (let e of t) {
88
- let t = {
89
- id: String(++J),
90
- name: e.name,
91
- size: e.size,
92
- status: "pending",
93
- progress: 0,
94
- raw: e,
95
- file: e
96
- }, r = !0;
97
- H.beforeUpload && (r = await H.beforeUpload({ file: Y(t, e) })), r !== !1 && H.onBeforeUpload && (r = await H.onBeforeUpload({ file: Y(t, e) })), r !== !1 && n.push(e);
98
- }
99
- if (t = n, t.length === 0) return;
100
- U("select", t);
101
- let r = [];
115
+ !B.multiple && t.length > 1 && (t = t.slice(0, 1));
116
+ let n = [], r = [];
102
117
  for (let e of t) {
103
- if (H.maxSize && e.size > H.maxSize) {
104
- W.value.push({
105
- id: String(++J),
106
- name: e.name,
107
- size: e.size,
108
- status: "error",
109
- progress: 0,
110
- error: `超过最大 ${q(H.maxSize)}`
111
- });
118
+ let t = !0;
119
+ if (B.beforeUpload && (t = await B.beforeUpload({ file: Y(e) })), t !== !1 && B.onBeforeUpload && (t = await B.onBeforeUpload({ file: Y(e) })), t === !1) continue;
120
+ if (!J(e)) {
121
+ X(e, "文件类型不允许");
122
+ continue;
123
+ }
124
+ if (B.maxSize && e.size > B.maxSize) {
125
+ X(e, `超过最大 ${G(B.maxSize)}`);
112
126
  continue;
113
127
  }
114
- let t = {
115
- id: String(++J),
128
+ let i = {
129
+ id: String(++K),
116
130
  name: e.name,
117
131
  size: e.size,
118
132
  status: "pending",
@@ -120,84 +134,112 @@ var T = { class: "k-upload__hint" }, E = {
120
134
  raw: e,
121
135
  file: e
122
136
  };
123
- W.value.push(t), r.push({
124
- uf: t,
137
+ H.value.push(i), n.push(e), r.push({
138
+ uf: i,
125
139
  raw: e
126
140
  });
127
141
  }
128
- if (U("change", W.value), !(!H.autoUpload || !H.defaultUpload)) {
129
- if (H.customRequest) {
130
- await Promise.all(r.map(async ({ uf: e, raw: t }) => {
131
- e.status = "uploading", await new Promise((n) => {
132
- H.customRequest?.({
133
- file: Y(e, t),
134
- onProgress: ({ percent: t }) => {
135
- e.progress = Math.max(0, Math.min(100, t));
136
- },
137
- onFinish: () => {
138
- if (!W.value.includes(e)) return n();
139
- e.status = "success", e.progress = 100, U("success", e), U("change", W.value), n();
140
- },
141
- onError: (t) => {
142
- if (!W.value.includes(e)) return n();
143
- e.status = "error", e.error = t?.message || "上传失败", U("error", e, t), U("change", W.value), n();
144
- }
145
- });
146
- });
147
- }));
148
- return;
149
- }
150
- if (H.uploader) {
151
- let e = H.uploader;
152
- await Promise.all(r.map(async ({ uf: t, raw: n }) => {
153
- t.status = "uploading";
154
- try {
155
- let r = await e(n, (e) => t.progress = e);
156
- if (!W.value.includes(t)) return;
157
- t.status = "success", t.progress = 100, t.url = r?.url, U("success", t);
158
- } catch (e) {
159
- if (!W.value.includes(t)) return;
160
- t.status = "error", t.error = e?.message || "上传失败", U("error", t, e);
142
+ V("change", H.value), n.length !== 0 && (V("select", n), !(!B.autoUpload || !B.defaultUpload) && await ne(r));
143
+ }
144
+ async function ne(e) {
145
+ if (B.customRequest) {
146
+ await Promise.all(e.map(({ uf: e, raw: t }) => (e.status = "uploading", new Promise((n) => {
147
+ B.customRequest?.({
148
+ file: q(e, t),
149
+ onProgress: ({ percent: t }) => {
150
+ e.progress = Math.max(0, Math.min(100, t));
151
+ },
152
+ onFinish: () => {
153
+ H.value.includes(e) && (e.status = "success", e.progress = 100, V("success", e), V("change", H.value)), n();
154
+ },
155
+ onError: (t) => {
156
+ H.value.includes(e) && (e.status = "error", e.error = t?.message || "上传失败", V("error", e, t), V("change", H.value)), n();
161
157
  }
162
- }));
163
- } else r.forEach(({ uf: e }) => {
164
- e.status = "success", e.progress = 100;
165
- });
166
- U("change", W.value);
158
+ });
159
+ }))));
160
+ return;
161
+ }
162
+ if (B.uploader) {
163
+ let t = B.uploader;
164
+ await Promise.all(e.map(async ({ uf: e, raw: n }) => {
165
+ e.status = "uploading";
166
+ try {
167
+ let r = await t(n, (t) => {
168
+ e.progress = Math.max(0, Math.min(100, t));
169
+ });
170
+ if (!H.value.includes(e)) return;
171
+ e.status = "success", e.progress = 100, e.url = r?.url, V("success", e);
172
+ } catch (t) {
173
+ if (!H.value.includes(e)) return;
174
+ e.status = "error", e.error = t?.message || "上传失败", V("error", e, t);
175
+ }
176
+ })), V("change", H.value);
177
+ return;
167
178
  }
179
+ if (B.action) {
180
+ await Promise.all(e.map(({ uf: e, raw: t }) => re(e, t)));
181
+ return;
182
+ }
183
+ }
184
+ function re(e, t) {
185
+ return new Promise((n) => {
186
+ e.status = "uploading";
187
+ let r = new XMLHttpRequest();
188
+ e.abort = () => r.abort();
189
+ let i = new FormData();
190
+ if (i.append(B.name ?? "file", t, t.name), B.data) for (let [e, t] of Object.entries(B.data)) i.append(e, t);
191
+ if (r.open("POST", B.action), B.withCredentials && (r.withCredentials = !0), B.headers) for (let [e, t] of Object.entries(B.headers)) r.setRequestHeader(e, t);
192
+ r.upload.onprogress = (t) => {
193
+ t.lengthComputable && H.value.includes(e) && (e.progress = Math.round(t.loaded / t.total * 100));
194
+ }, r.onload = () => {
195
+ if (!H.value.includes(e)) return n();
196
+ if (r.status >= 200 && r.status < 300) {
197
+ e.status = "success", e.progress = 100;
198
+ try {
199
+ e.url = JSON.parse(r.responseText)?.url;
200
+ } catch {}
201
+ V("success", e);
202
+ } else e.status = "error", e.error = `上传失败 (${r.status})`, V("error", e, Error(e.error));
203
+ V("change", H.value), n();
204
+ }, r.onerror = () => {
205
+ if (!H.value.includes(e)) return n();
206
+ e.status = "error", e.error = "网络错误", V("error", e, /* @__PURE__ */ Error("network error")), V("change", H.value), n();
207
+ }, r.onabort = () => n(), r.send(i);
208
+ });
168
209
  }
169
- function Z() {
170
- H.disabled || K.value?.click();
210
+ function Q() {
211
+ B.disabled || W.value?.click();
171
212
  }
172
- function Q(e) {
213
+ function ie(e) {
173
214
  let t = e.target;
174
- t.files && X(t.files), t.value = "";
215
+ t.files && Z(t.files), t.value = "";
175
216
  }
176
- function ee(e) {
177
- G.value = !1, !H.disabled && e.dataTransfer?.files && X(e.dataTransfer.files);
217
+ function ae(e) {
218
+ U.value = !1, !B.disabled && e.dataTransfer?.files && Z(e.dataTransfer.files);
178
219
  }
179
220
  function $(e) {
180
- W.value = W.value.filter((t) => t.id !== e), U("change", W.value);
221
+ let t = H.value.find((t) => t.id === e);
222
+ t?.status === "uploading" && t.abort?.(), H.value = H.value.filter((t) => t.id !== e), V("change", H.value);
181
223
  }
182
- return B({
183
- files: W,
224
+ return R({
225
+ files: H,
184
226
  remove: $,
185
- addFiles: X,
186
- open: Z
227
+ addFiles: Z,
228
+ open: Q
187
229
  }), (e, f) => (d(), i("div", { class: l(["k-upload", { "k-upload--disabled": c.disabled }]) }, [
188
230
  c.drag ? (d(), i("div", {
189
231
  key: 0,
190
- class: l(["k-upload__zone", { "k-upload__zone--over": G.value }]),
191
- onClick: Z,
192
- onDragover: f[0] ||= v((e) => G.value = !0, ["prevent"]),
193
- onDragleave: f[1] ||= v((e) => G.value = !1, ["prevent"]),
194
- onDrop: v(ee, ["prevent"])
232
+ class: l(["k-upload__zone", { "k-upload__zone--over": U.value }]),
233
+ onClick: Q,
234
+ onDragover: f[0] ||= v((e) => U.value = !0, ["prevent"]),
235
+ onDragleave: f[1] ||= v((e) => U.value = !1, ["prevent"]),
236
+ onDrop: v(ae, ["prevent"])
195
237
  }, [h(e.$slots, "trigger", {
196
- isDragOver: G.value,
197
- open: Z
238
+ isDragOver: U.value,
239
+ open: Q
198
240
  }, () => [h(e.$slots, "default", {
199
- isDragOver: G.value,
200
- open: Z
241
+ isDragOver: U.value,
242
+ open: Q
201
243
  }, () => [s(_(C), {
202
244
  size: 28,
203
245
  class: "k-upload__icon"
@@ -209,31 +251,31 @@ var T = { class: "k-upload__hint" }, E = {
209
251
  c.accept || c.maxSize ? (d(), i("div", E, [
210
252
  c.accept ? (d(), i("span", D, "支持: " + g(c.accept), 1)) : r("", !0),
211
253
  c.accept && c.maxSize ? (d(), i("span", O, " · ")) : r("", !0),
212
- c.maxSize ? (d(), i("span", k, "最大: " + g(q(c.maxSize)), 1)) : r("", !0)
254
+ c.maxSize ? (d(), i("span", k, "最大: " + g(G(c.maxSize)), 1)) : r("", !0)
213
255
  ])) : r("", !0)
214
256
  ])], !0)], !0)], 34)) : (d(), i("button", {
215
257
  key: 1,
216
258
  type: "button",
217
259
  class: "k-upload__btn",
218
260
  disabled: c.disabled,
219
- onClick: Z
261
+ onClick: Q
220
262
  }, [h(e.$slots, "trigger", {
221
263
  isDragOver: !1,
222
- open: Z
264
+ open: Q
223
265
  }, () => [h(e.$slots, "default", {
224
266
  isDragOver: !1,
225
- open: Z
226
- }, () => [s(_(C), { size: 14 }), o(" " + g(c.buttonText), 1)], !0)], !0)], 8, A)),
267
+ open: Q
268
+ }, () => [s(_(C), { size: 14 }), o(" " + g(c.buttonText), 1)], !0)], !0)], 8, ee)),
227
269
  a("input", {
228
270
  ref_key: "fileInputRef",
229
- ref: K,
271
+ ref: W,
230
272
  type: "file",
231
273
  multiple: c.multiple,
232
274
  accept: c.accept,
233
275
  class: "k-upload__input",
234
- onChange: Q
235
- }, null, 40, j),
236
- c.showList && c.showFileList && W.value.length > 0 ? (d(), i("ul", M, [(d(!0), i(t, null, m(W.value, (e) => (d(), i("li", {
276
+ onChange: ie
277
+ }, null, 40, te),
278
+ c.showList && c.showFileList && H.value.length > 0 ? (d(), i("ul", A, [(d(!0), i(t, null, m(H.value, (e) => (d(), i("li", {
237
279
  key: e.id,
238
280
  class: l(["k-upload__item", `k-upload__item--${e.status}`])
239
281
  }, [
@@ -241,15 +283,15 @@ var T = { class: "k-upload__hint" }, E = {
241
283
  size: 14,
242
284
  class: "k-upload__file-icon"
243
285
  }),
244
- a("div", N, [
245
- a("div", P, g(e.name), 1),
246
- a("div", F, [o(g(q(e.size)) + " ", 1), e.error ? (d(), i("span", I, "· " + g(e.error), 1)) : r("", !0)]),
247
- e.status === "uploading" ? (d(), i("div", L, [a("div", {
286
+ a("div", j, [
287
+ a("div", M, g(e.name), 1),
288
+ a("div", N, [o(g(G(e.size)) + " ", 1), e.error ? (d(), i("span", P, "· " + g(e.error), 1)) : r("", !0)]),
289
+ e.status === "uploading" ? (d(), i("div", F, [a("div", {
248
290
  class: "k-upload__progress-bar",
249
291
  style: u({ width: e.progress + "%" })
250
292
  }, null, 4)])) : r("", !0)
251
293
  ]),
252
- a("div", R, [e.status === "uploading" ? (d(), n(_(S), {
294
+ a("div", I, [e.status === "uploading" ? (d(), n(_(S), {
253
295
  key: 0,
254
296
  size: 14,
255
297
  class: "k-upload__spin"
@@ -267,10 +309,10 @@ var T = { class: "k-upload__hint" }, E = {
267
309
  class: "k-upload__remove",
268
310
  "aria-label": "移除",
269
311
  onClick: (t) => $(e.id)
270
- }, [s(_(w), { size: 12 })], 8, z)
312
+ }, [s(_(w), { size: 12 })], 8, L)
271
313
  ], 2))), 128))])) : r("", !0)
272
314
  ], 2));
273
315
  }
274
316
  });
275
317
  //#endregion
276
- export { B as default };
318
+ export { R as default };
@@ -0,0 +1,10 @@
1
+ import type { InjectionKey, Ref } from 'vue';
2
+ export type CheckboxSize = 'small' | 'sm' | 'medium' | 'md' | 'large' | 'lg';
3
+ /** KCheckboxGroup 下发给 KCheckbox 的上下文:组级尺寸(子项未显式设置 size 时回退到此) */
4
+ export interface CheckboxGroupContext {
5
+ size: Ref<CheckboxSize | undefined>;
6
+ /** 子项登记原始 value (reka 内部会字符串化, 这里记下 String(value)→原始值, emit 时还原类型) */
7
+ register: (raw: string | number) => void;
8
+ unregister: (raw: string | number) => void;
9
+ }
10
+ export declare const CHECKBOX_GROUP_KEY: InjectionKey<CheckboxGroupContext>;
@@ -0,0 +1,4 @@
1
+ //#region components/checkbox-context.ts
2
+ var e = Symbol("k-checkbox-group");
3
+ //#endregion
4
+ export { e as CHECKBOX_GROUP_KEY };
@@ -1,20 +1,29 @@
1
1
  import type { InjectionKey } from 'vue';
2
2
  export interface FormRule {
3
3
  required?: boolean;
4
- type?: 'string' | 'number' | 'array' | string;
4
+ /** 'string'(默认) | 'number' | 'integer' | 'array' | 'email' | 'url' | 'boolean' */
5
+ type?: 'string' | 'number' | 'integer' | 'array' | 'email' | 'url' | 'boolean' | string;
6
+ /** type=number/integer 时为数值下限; string/array 时为长度下限 */
5
7
  min?: number;
8
+ /** type=number/integer 时为数值上限; string/array 时为长度上限 */
6
9
  max?: number;
7
10
  len?: number;
8
11
  pattern?: RegExp;
9
12
  validator?: ((rule: FormRule, value: any) => boolean | string | Error | void | Promise<boolean | string | Error | void>) | ((value: any) => boolean | string | Error | void | Promise<boolean | string | Error | void>);
10
13
  message?: string;
14
+ /** 触发校验的时机: 'blur' | 'change'(或数组); 不填则两者皆触发 */
11
15
  trigger?: string | string[];
12
16
  }
13
17
  export type FormRules = Record<string, FormRule | FormRule[]>;
14
18
  export interface FormFieldRef {
15
- validate: () => Promise<boolean>;
19
+ name: string;
20
+ /** trigger 省略 = 全量校验(所有规则); 传 'blur'/'change' = 只跑匹配该时机的规则 */
21
+ validate: (trigger?: string) => Promise<boolean>;
22
+ /** 还原到初始值并清除校验态 */
16
23
  reset: () => void;
17
24
  clearValidate: () => void;
25
+ hasError: () => boolean;
26
+ scrollIntoView: () => void;
18
27
  }
19
28
  export interface FormContext {
20
29
  model: Record<string, any>;
@@ -23,7 +32,15 @@ export interface FormContext {
23
32
  labelPosition: 'top' | 'left';
24
33
  size: 'sm' | 'md' | 'lg';
25
34
  disabled: boolean;
35
+ /** rules 变化时自动重新校验已校验过的字段 */
36
+ validateOnRuleChange: boolean;
26
37
  registerField: (name: string, field: FormFieldRef) => void;
27
38
  unregisterField: (name: string) => void;
28
39
  }
29
40
  export declare const formContextKey: InjectionKey<FormContext>;
41
+ /** 解析嵌套字段路径 a.b.c / a.b[0].c → 取值 (扁平 model[name] 解析不了带点的 key) */
42
+ export declare function getByPath(obj: Record<string, any>, path: string): any;
43
+ /** 解析嵌套路径写值 (resetFields 还原初始值用) */
44
+ export declare function setByPath(obj: Record<string, any>, path: string, value: any): void;
45
+ /** 深拷贝初始值快照 (普通表单数据) */
46
+ export declare function cloneValue<T>(v: T): T;
@@ -1,4 +1,34 @@
1
1
  //#region components/form-context.ts
2
2
  var e = Symbol("formContext");
3
+ function t(e, t) {
4
+ if (!t) return;
5
+ let n = t.replace(/\[(\w+)\]/g, ".$1").split(".").filter(Boolean), r = e;
6
+ for (let e of n) {
7
+ if (r == null) return;
8
+ r = r[e];
9
+ }
10
+ return r;
11
+ }
12
+ function n(e, t, n) {
13
+ if (!t) return;
14
+ let r = t.replace(/\[(\w+)\]/g, ".$1").split(".").filter(Boolean), i = e;
15
+ for (let e = 0; e < r.length - 1; e++) {
16
+ let t = r[e];
17
+ (i[t] == null || typeof i[t] != "object") && (i[t] = {}), i = i[t];
18
+ }
19
+ i[r[r.length - 1]] = n;
20
+ }
21
+ function r(e) {
22
+ if (typeof e != "object" || !e) return e;
23
+ try {
24
+ return structuredClone(e);
25
+ } catch {
26
+ try {
27
+ return JSON.parse(JSON.stringify(e));
28
+ } catch {
29
+ return e;
30
+ }
31
+ }
32
+ }
3
33
  //#endregion
4
- export { e as formContextKey };
34
+ export { r as cloneValue, e as formContextKey, t as getByPath, n as setByPath };
@@ -20,6 +20,10 @@ export interface MenuContext {
20
20
  isExpanded: (key: string) => boolean;
21
21
  toggle: (key: string) => void;
22
22
  select: (option: MenuOption) => void;
23
+ /** roving tabindex: 当前可聚焦项 */
24
+ isFocused: (key: string) => boolean;
25
+ /** 子项获得焦点时回写 roving 游标 */
26
+ setFocus: (key: string) => void;
23
27
  indent: number;
24
28
  rootIndent: number;
25
29
  }
@@ -1,6 +1,11 @@
1
1
  import type { InjectionKey, Ref } from 'vue';
2
- /** KRadioGroup 下发给 KRadio 的上下文,目前仅传递“分段按钮态”视觉标记 */
2
+ export type RadioSize = 'small' | 'sm' | 'medium' | 'md' | 'large' | 'lg';
3
+ /** KRadioGroup 下发给 KRadio 的上下文:分段按钮态 + 组级尺寸(子项未显式设置 size 时回退到此) */
3
4
  export interface RadioGroupContext {
4
5
  button: Ref<boolean>;
6
+ size: Ref<RadioSize | undefined>;
7
+ /** 子项登记原始 value (reka 内部会字符串化, 这里记下 String(value)→原始值, emit 时还原类型) */
8
+ register: (raw: string | number) => void;
9
+ unregister: (raw: string | number) => void;
5
10
  }
6
11
  export declare const RADIO_GROUP_KEY: InjectionKey<RadioGroupContext>;