niuma-ui 1.2.6 → 1.2.8

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 (42) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/components/RsAutoComplete.d.ts +39 -0
  3. package/dist/components/RsAutoComplete.impl.js +306 -0
  4. package/dist/components/RsAutoComplete.js +5 -0
  5. package/dist/components/RsCascader.css +81 -0
  6. package/dist/components/RsCascader.d.ts +34 -0
  7. package/dist/components/RsCascader.impl.js +138 -0
  8. package/dist/components/RsCascader.js +8 -0
  9. package/dist/components/RsMentions-1.css +29 -0
  10. package/dist/components/RsMentions.css +19 -0
  11. package/dist/components/RsMentions.d.ts +32 -0
  12. package/dist/components/RsMentions.impl.js +242 -0
  13. package/dist/components/RsMentions.js +10 -0
  14. package/dist/components/RsSelect.css +51 -36
  15. package/dist/components/RsSelect.d.ts +27 -7
  16. package/dist/components/RsSelect.impl.js +145 -30
  17. package/dist/components/RsSelect.js +1 -1
  18. package/dist/components/RsTabs.d.ts +1 -1
  19. package/dist/components/RsToaster.d.ts +1 -1
  20. package/dist/components/RsTree.d.ts +4 -4
  21. package/dist/components/RsTree.impl.js +1 -1
  22. package/dist/components/RsTreeSelect.css +60 -0
  23. package/dist/components/RsTreeSelect.d.ts +33 -0
  24. package/dist/components/RsTreeSelect.impl.js +145 -0
  25. package/dist/components/RsTreeSelect.js +8 -0
  26. package/dist/components/cascader-utils.d.ts +16 -0
  27. package/dist/components/cascader-utils.js +39 -0
  28. package/dist/components/mentions-utils.d.ts +46 -0
  29. package/dist/components/mentions-utils.js +128 -0
  30. package/dist/components/overlay-utils.d.ts +31 -0
  31. package/dist/components/overlay-utils.js +29 -1
  32. package/dist/components/select-utils.d.ts +15 -0
  33. package/dist/components/select-utils.js +37 -1
  34. package/dist/components/table/RsTableCellEditor.impl.js +7 -1
  35. package/dist/components/use-rs-select.d.ts +5 -2
  36. package/dist/components/use-rs-select.js +31 -19
  37. package/dist/composables/useRsTableShell.js +1 -1
  38. package/dist/index.d.ts +9 -3
  39. package/dist/index.js +6 -0
  40. package/dist/locale/messages.js +6 -0
  41. package/dist/styles.css +160 -0
  42. package/package.json +1 -1
@@ -6,9 +6,9 @@ import { isRsFormItemBoundControl, useRsFormContext, useRsFormField, useRsFormIt
6
6
  import { useResolvedRsComponentSize } from "./resolve-size.js";
7
7
  import { rsRadiusCss, useResolvedRsRadius } from "./resolve-radius.js";
8
8
  import { ComboboxAnchor, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxLabel, ComboboxPortal, ComboboxRoot, ComboboxTrigger, ComboboxViewport, ComboboxVirtualizer } from "./reka.js";
9
- import { isSelectOptionGroup, toComboboxValue } from "./select-utils.js";
9
+ import { isSelectOptionGroup, splitSelectLabelHighlight, toComboboxValue } from "./select-utils.js";
10
10
  import { useRsSelect } from "./use-rs-select.js";
11
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, isRef, mergeModels, mergeProps, normalizeClass, normalizeStyle, openBlock, ref, renderList, renderSlot, toDisplayString, unref, useAttrs, useModel, withCtx, withModifiers } from "vue";
11
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, isRef, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, ref, renderList, renderSlot, toDisplayString, unref, useAttrs, useModel, watch, withCtx, withModifiers } from "vue";
12
12
  //#region src/components/RsSelect.vue?vue&type=script&setup=true&lang.ts
13
13
  var _hoisted_1 = {
14
14
  key: 0,
@@ -53,9 +53,21 @@ var _hoisted_15 = {
53
53
  class: "rs-select__status"
54
54
  };
55
55
  var _hoisted_16 = { class: "rs-select__item-label" };
56
- var _hoisted_17 = { class: "rs-select__item-label" };
56
+ var _hoisted_17 = {
57
+ key: 0,
58
+ class: "rs-select__mark"
59
+ };
57
60
  var _hoisted_18 = { class: "rs-select__item-label" };
58
61
  var _hoisted_19 = { class: "rs-select__item-label" };
62
+ var _hoisted_20 = {
63
+ key: 0,
64
+ class: "rs-select__mark"
65
+ };
66
+ var _hoisted_21 = { class: "rs-select__item-label" };
67
+ var _hoisted_22 = {
68
+ key: 0,
69
+ class: "rs-select__mark"
70
+ };
59
71
  var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
60
72
  inheritAttrs: false,
61
73
  __name: "RsSelect",
@@ -75,7 +87,10 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
75
87
  type: Boolean,
76
88
  default: false
77
89
  },
78
- multiple: {},
90
+ multiple: {
91
+ type: Boolean,
92
+ default: false
93
+ },
79
94
  required: {
80
95
  type: Boolean,
81
96
  default: false
@@ -119,9 +134,20 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
119
134
  },
120
135
  optionFilterProp: { default: "label" },
121
136
  maxTagCount: {},
137
+ debounce: { default: 0 },
138
+ variant: { default: "outlined" },
139
+ autoFocus: {
140
+ type: Boolean,
141
+ default: false
142
+ },
143
+ dropdownStyle: {},
144
+ classNames: {},
122
145
  maxTagPlaceholder: {},
123
146
  multipleLimit: {},
124
- labelInValue: {},
147
+ labelInValue: {
148
+ type: Boolean,
149
+ default: false
150
+ },
125
151
  filterSort: {},
126
152
  maxTagTextLength: {},
127
153
  maxTagTooltip: {
@@ -163,13 +189,21 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
163
189
  "search",
164
190
  "select",
165
191
  "deselect",
166
- "clear"
192
+ "clear",
193
+ "focus",
194
+ "blur",
195
+ "dropdownVisibleChange",
196
+ "popupScroll"
167
197
  ], [
168
198
  "update:modelValue",
169
199
  "update:open",
170
200
  "update:searchValue"
171
201
  ]),
172
202
  setup(__props, { expose: __expose, emit: __emit }) {
203
+ /**
204
+ * multiple / labelInValue 是运行时 boolean,不能从 prop 推断字面量。
205
+ * v-model 收完整联合,模板传入 string / number / 数组 / labeled 即可。
206
+ */
173
207
  const model = useModel(__props, "modelValue");
174
208
  const open = useModel(__props, "open");
175
209
  const searchQuery = useModel(__props, "searchValue");
@@ -184,7 +218,7 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
184
218
  name: props.name
185
219
  }));
186
220
  const anchorRef = ref(null);
187
- const { resolvedPlaceholder, resolvedSearchPlaceholder, resolvedEmptyText, resolvedLoadingText, isSearchable, labelMap, useVirtual, useManualFilter, displayOptions, createValue, canCreate, createOptionLabel, virtualValues, selectedValues, hasValue, visibleTagTokens, omittedTagCount, omittedTagLabel, omittedTagTitle, singleDisplayLabel, comboboxModel, tokenLabel, truncateTagLabel, optionFromToken, optionOrCreate, isOptionLimited, isTokenDisabled, restoreTokenValue, onSearchKeydown, onClear, removeTag, setValue, resetSearch } = useRsSelect(props, model, open, searchQuery, emit, t);
221
+ const { resolvedPlaceholder, resolvedSearchPlaceholder, resolvedEmptyText, resolvedLoadingText, isMultiple, isSearchable, labelMap, useVirtual, useManualFilter, displayOptions, createValue, canCreate, createOptionLabel, virtualValues, selectedValues, hasValue, visibleTagTokens, omittedTagCount, omittedTagLabel, omittedTagTitle, singleDisplayLabel, comboboxModel, tokenLabel, truncateTagLabel, optionFromToken, optionOrCreate, isOptionLimited, isTokenDisabled, restoreTokenValue, onSearchKeydown, onClear, removeTag, setValue, resetSearch } = useRsSelect(props, model, open, searchQuery, emit, t);
188
222
  const resolvedDisabled = computed(() => props.disabled || formContext?.disabled.value || false);
189
223
  const resolvedSize = useResolvedRsComponentSize(() => props.size);
190
224
  const resolvedRadius = useResolvedRsRadius(() => props.radius, "sm");
@@ -242,21 +276,84 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
242
276
  clearValidation,
243
277
  validate: runValidate
244
278
  });
279
+ watch(open, (isOpen) => {
280
+ emit("dropdownVisibleChange", isOpen);
281
+ });
282
+ onMounted(() => {
283
+ if (!props.autoFocus) return;
284
+ const el = anchorRef.value;
285
+ const node = el instanceof HTMLElement ? el : el?.$el;
286
+ ((node instanceof HTMLElement ? node : void 0)?.querySelector?.(".rs-select__trigger"))?.focus();
287
+ });
288
+ const responsiveTagCap = ref(null);
289
+ let tagResize;
290
+ function measureResponsiveTags() {
291
+ if (props.maxTagCount !== "responsive" || !isMultiple.value) {
292
+ responsiveTagCap.value = null;
293
+ return;
294
+ }
295
+ const el = anchorRef.value;
296
+ const node = el instanceof HTMLElement ? el : el?.$el;
297
+ const trigger = (node instanceof HTMLElement ? node : void 0)?.querySelector?.(".rs-select__value--multiple");
298
+ if (!trigger) return;
299
+ const budget = trigger.clientWidth - 48;
300
+ if (budget <= 0) return;
301
+ const tags = Array.from(trigger.querySelectorAll(".rs-select__tag"));
302
+ if (!tags.length) {
303
+ responsiveTagCap.value = selectedValues.value.length;
304
+ return;
305
+ }
306
+ let used = 0;
307
+ let fit = 0;
308
+ for (const tag of tags) {
309
+ if (tag.classList.contains("rs-select__tag--rest")) continue;
310
+ const next = used + tag.offsetWidth + 4;
311
+ if (next > budget && fit > 0) break;
312
+ used = next;
313
+ fit += 1;
314
+ }
315
+ responsiveTagCap.value = Math.max(1, fit);
316
+ }
317
+ onMounted(() => {
318
+ if (typeof ResizeObserver === "undefined") return;
319
+ tagResize = new ResizeObserver(() => measureResponsiveTags());
320
+ nextTick(() => {
321
+ const el = anchorRef.value;
322
+ const node = el instanceof HTMLElement ? el : el?.$el;
323
+ if (node instanceof HTMLElement) tagResize?.observe(node);
324
+ measureResponsiveTags();
325
+ });
326
+ });
327
+ onUnmounted(() => tagResize?.disconnect());
328
+ watch(() => [
329
+ selectedValues.value.join("\0"),
330
+ props.maxTagCount,
331
+ isMultiple.value
332
+ ], () => void nextTick(measureResponsiveTags));
333
+ const shownTagTokens = computed(() => {
334
+ if (props.maxTagCount !== "responsive" || responsiveTagCap.value == null) return visibleTagTokens.value;
335
+ return selectedValues.value.slice(0, responsiveTagCap.value);
336
+ });
337
+ const shownOmittedCount = computed(() => props.maxTagCount === "responsive" ? Math.max(0, selectedValues.value.length - shownTagTokens.value.length) : omittedTagCount.value);
338
+ function highlightParts(label) {
339
+ return splitSelectLabelHighlight(label, isSearchable.value ? searchQuery.value : "");
340
+ }
245
341
  return (_ctx, _cache) => {
246
342
  return openBlock(), createBlock(unref(ComboboxRoot), {
247
343
  modelValue: unref(comboboxModel),
248
- "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => isRef(comboboxModel) ? comboboxModel.value = $event : null),
344
+ "onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => isRef(comboboxModel) ? comboboxModel.value = $event : null),
249
345
  open: open.value,
250
- "onUpdate:open": _cache[7] || (_cache[7] = ($event) => open.value = $event),
346
+ "onUpdate:open": _cache[10] || (_cache[10] = ($event) => open.value = $event),
251
347
  class: normalizeClass(["rs-select", {
252
- "rs-select--multiple": __props.multiple,
348
+ "rs-select--multiple": unref(isMultiple),
253
349
  "rs-select--searchable": unref(isSearchable),
254
350
  "rs-select--creatable": __props.creatable,
255
351
  "rs-select--block": __props.block,
256
- [`rs-select--${unref(resolvedSize)}`]: true
352
+ [`rs-select--${unref(resolvedSize)}`]: true,
353
+ [`rs-select--${__props.variant}`]: true
257
354
  }]),
258
355
  style: normalizeStyle(rootStyle.value),
259
- multiple: __props.multiple,
356
+ multiple: unref(isMultiple),
260
357
  disabled: resolvedDisabled.value,
261
358
  "ignore-filter": unref(useManualFilter),
262
359
  "reset-search-term-on-select": __props.autoClearSearchValue,
@@ -269,15 +366,17 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
269
366
  }, {
270
367
  default: withCtx(() => [createVNode(unref(ComboboxTrigger), mergeProps(unref(attrs), {
271
368
  id: __props.id,
272
- class: ["rs-select__trigger", {
369
+ class: ["rs-select__trigger", [__props.classNames?.trigger, {
273
370
  "rs-select__trigger--invalid": isInvalid.value,
274
371
  "rs-select__trigger--warning": isWarning.value
275
- }],
276
- "aria-invalid": isInvalid.value || void 0
372
+ }]],
373
+ "aria-invalid": isInvalid.value || void 0,
374
+ onFocus: _cache[3] || (_cache[3] = ($event) => emit("focus", $event)),
375
+ onBlur: _cache[4] || (_cache[4] = ($event) => emit("blur", $event))
277
376
  }), {
278
377
  default: withCtx(() => [
279
378
  _ctx.$slots.prefix ? (openBlock(), createElementBlock("span", _hoisted_1, [renderSlot(_ctx.$slots, "prefix", {}, void 0, true)])) : createCommentVNode("", true),
280
- __props.multiple ? (openBlock(), createElementBlock("span", _hoisted_2, [unref(hasValue) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(visibleTagTokens), (value) => {
379
+ unref(isMultiple) ? (openBlock(), createElementBlock("span", _hoisted_2, [unref(hasValue) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [(openBlock(true), createElementBlock(Fragment, null, renderList(shownTagTokens.value, (value) => {
281
380
  return openBlock(), createElementBlock("span", {
282
381
  key: value,
283
382
  class: "rs-select__tag"
@@ -295,11 +394,11 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
295
394
  name: "x",
296
395
  size: 12
297
396
  })], 40, _hoisted_4)], true)]);
298
- }), 128)), unref(omittedTagCount) > 0 ? (openBlock(), createElementBlock("span", {
397
+ }), 128)), shownOmittedCount.value > 0 ? (openBlock(), createElementBlock("span", {
299
398
  key: 0,
300
399
  class: "rs-select__tag rs-select__tag--rest",
301
400
  title: unref(omittedTagTitle)
302
- }, [renderSlot(_ctx.$slots, "maxTagPlaceholder", { omitted: unref(omittedTagCount) }, () => [createTextVNode(toDisplayString(unref(omittedTagLabel)), 1)], true)], 8, _hoisted_5)) : createCommentVNode("", true)], 64)) : (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(unref(resolvedPlaceholder)), 1))])) : (openBlock(), createElementBlock("span", _hoisted_7, [unref(hasValue) ? (openBlock(), createElementBlock("span", _hoisted_8, toDisplayString(unref(singleDisplayLabel)), 1)) : (openBlock(), createElementBlock("span", _hoisted_9, toDisplayString(unref(resolvedPlaceholder)), 1))])),
401
+ }, [renderSlot(_ctx.$slots, "maxTagPlaceholder", { omitted: shownOmittedCount.value }, () => [createTextVNode(toDisplayString(typeof __props.maxTagPlaceholder === "function" ? __props.maxTagPlaceholder(shownOmittedCount.value) : unref(omittedTagLabel)), 1)], true)], 8, _hoisted_5)) : createCommentVNode("", true)], 64)) : (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(unref(resolvedPlaceholder)), 1))])) : (openBlock(), createElementBlock("span", _hoisted_7, [unref(hasValue) ? (openBlock(), createElementBlock("span", _hoisted_8, toDisplayString(unref(singleDisplayLabel)), 1)) : (openBlock(), createElementBlock("span", _hoisted_9, toDisplayString(unref(resolvedPlaceholder)), 1))])),
303
402
  createElementVNode("span", _hoisted_10, [__props.clearable && unref(hasValue) && !resolvedDisabled.value ? (openBlock(), createElementBlock("button", {
304
403
  key: 0,
305
404
  type: "button",
@@ -325,8 +424,15 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
325
424
  _: 3
326
425
  }, 512), createVNode(unref(ComboboxPortal), { to: portalTo.value }, {
327
426
  default: withCtx(() => [createVNode(unref(ComboboxContent), {
328
- class: normalizeClass(["rs-select__content", [__props.popupClassName, { "rs-select__content--match-trigger": __props.matchTriggerWidth }]]),
329
- style: normalizeStyle({ "--rs-select-list-height": `${__props.listHeight}px` }),
427
+ class: normalizeClass(["rs-select__content", [
428
+ __props.popupClassName,
429
+ __props.classNames?.popup,
430
+ { "rs-select__content--match-trigger": __props.matchTriggerWidth }
431
+ ]]),
432
+ style: normalizeStyle({
433
+ "--rs-select-list-height": `${__props.listHeight}px`,
434
+ ...__props.dropdownStyle
435
+ }),
330
436
  align: "start",
331
437
  side: __props.placement,
332
438
  "side-offset": 4,
@@ -336,7 +442,7 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
336
442
  _ctx.$slots.header ? (openBlock(), createElementBlock("div", {
337
443
  key: 0,
338
444
  class: "rs-select__panel-header",
339
- onMousedown: _cache[3] || (_cache[3] = withModifiers(() => {}, ["prevent"]))
445
+ onMousedown: _cache[5] || (_cache[5] = withModifiers(() => {}, ["prevent"]))
340
446
  }, [renderSlot(_ctx.$slots, "header", {}, void 0, true)], 32)) : createCommentVNode("", true),
341
447
  unref(isSearchable) ? (openBlock(), createElementBlock("div", _hoisted_13, [createElementVNode("div", _hoisted_14, [createVNode(RsIcon_default, {
342
448
  name: "search",
@@ -345,7 +451,7 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
345
451
  "aria-hidden": "true"
346
452
  }), createVNode(unref(ComboboxInput), {
347
453
  modelValue: searchQuery.value,
348
- "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => searchQuery.value = $event),
454
+ "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => searchQuery.value = $event),
349
455
  class: "rs-select__search",
350
456
  placeholder: unref(resolvedSearchPlaceholder),
351
457
  "auto-focus": "",
@@ -363,7 +469,10 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
363
469
  default: withCtx(() => [renderSlot(_ctx.$slots, "empty", {}, () => [createTextVNode(toDisplayString(unref(resolvedEmptyText)), 1)], true)]),
364
470
  _: 3
365
471
  })) : createCommentVNode("", true),
366
- createVNode(unref(ComboboxViewport), { class: "rs-select__viewport" }, {
472
+ createVNode(unref(ComboboxViewport), {
473
+ class: "rs-select__viewport",
474
+ onScroll: _cache[7] || (_cache[7] = ($event) => emit("popupScroll", $event))
475
+ }, {
367
476
  default: withCtx(() => [unref(useVirtual) ? (openBlock(), createBlock(unref(ComboboxVirtualizer), {
368
477
  key: 0,
369
478
  options: unref(virtualValues),
@@ -380,7 +489,9 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
380
489
  default: withCtx(() => [createElementVNode("span", _hoisted_16, [renderSlot(_ctx.$slots, "option", {
381
490
  option: unref(optionOrCreate)(String(option)),
382
491
  selected: unref(selectedValues).includes(String(option))
383
- }, () => [createTextVNode(toDisplayString(unref(canCreate) && String(option) === unref(createValue) ? unref(createOptionLabel) : unref(labelMap).get(String(option)) ?? String(option)), 1)], true)]), createVNode(unref(ComboboxItemIndicator), { class: "rs-select__item-check" }, {
492
+ }, () => [(openBlock(true), createElementBlock(Fragment, null, renderList(highlightParts(unref(canCreate) && String(option) === unref(createValue) ? unref(createOptionLabel) : unref(labelMap).get(String(option)) ?? String(option)), (part, i) => {
493
+ return openBlock(), createElementBlock(Fragment, { key: i }, [part.highlight ? (openBlock(), createElementBlock("mark", _hoisted_17, toDisplayString(part.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(part.text), 1)], 64))], 64);
494
+ }), 128))], true)]), createVNode(unref(ComboboxItemIndicator), { class: "rs-select__item-check" }, {
384
495
  default: withCtx(() => [createVNode(RsIcon_default, {
385
496
  name: "check",
386
497
  size: 14
@@ -402,7 +513,7 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
402
513
  "text-value": unref(createValue),
403
514
  class: "rs-select__item rs-select__item--create"
404
515
  }, {
405
- default: withCtx(() => [createElementVNode("span", _hoisted_17, toDisplayString(unref(createOptionLabel)), 1), createVNode(unref(ComboboxItemIndicator), { class: "rs-select__item-check" }, {
516
+ default: withCtx(() => [createElementVNode("span", _hoisted_18, toDisplayString(unref(createOptionLabel)), 1), createVNode(unref(ComboboxItemIndicator), { class: "rs-select__item-check" }, {
406
517
  default: withCtx(() => [createVNode(RsIcon_default, {
407
518
  name: "check",
408
519
  size: 14
@@ -427,10 +538,12 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
427
538
  class: "rs-select__item",
428
539
  title: opt.title
429
540
  }, {
430
- default: withCtx(() => [createElementVNode("span", _hoisted_18, [renderSlot(_ctx.$slots, "option", {
541
+ default: withCtx(() => [createElementVNode("span", _hoisted_19, [renderSlot(_ctx.$slots, "option", {
431
542
  option: opt,
432
543
  selected: unref(selectedValues).includes(unref(toComboboxValue)(opt.value))
433
- }, () => [createTextVNode(toDisplayString(opt.label), 1)], true)]), createVNode(unref(ComboboxItemIndicator), { class: "rs-select__item-check" }, {
544
+ }, () => [(openBlock(true), createElementBlock(Fragment, null, renderList(highlightParts(opt.label), (part, i) => {
545
+ return openBlock(), createElementBlock(Fragment, { key: i }, [part.highlight ? (openBlock(), createElementBlock("mark", _hoisted_20, toDisplayString(part.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(part.text), 1)], 64))], 64);
546
+ }), 128))], true)]), createVNode(unref(ComboboxItemIndicator), { class: "rs-select__item-check" }, {
434
547
  default: withCtx(() => [createVNode(RsIcon_default, {
435
548
  name: "check",
436
549
  size: 14
@@ -454,10 +567,12 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
454
567
  class: "rs-select__item",
455
568
  title: entry.title
456
569
  }, {
457
- default: withCtx(() => [createElementVNode("span", _hoisted_19, [renderSlot(_ctx.$slots, "option", {
570
+ default: withCtx(() => [createElementVNode("span", _hoisted_21, [renderSlot(_ctx.$slots, "option", {
458
571
  option: entry,
459
572
  selected: unref(selectedValues).includes(unref(toComboboxValue)(entry.value))
460
- }, () => [createTextVNode(toDisplayString(entry.label), 1)], true)]), createVNode(unref(ComboboxItemIndicator), { class: "rs-select__item-check" }, {
573
+ }, () => [(openBlock(true), createElementBlock(Fragment, null, renderList(highlightParts(entry.label), (part, i) => {
574
+ return openBlock(), createElementBlock(Fragment, { key: i }, [part.highlight ? (openBlock(), createElementBlock("mark", _hoisted_22, toDisplayString(part.text), 1)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(part.text), 1)], 64))], 64);
575
+ }), 128))], true)]), createVNode(unref(ComboboxItemIndicator), { class: "rs-select__item-check" }, {
461
576
  default: withCtx(() => [createVNode(RsIcon_default, {
462
577
  name: "check",
463
578
  size: 14
@@ -477,7 +592,7 @@ var RsSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
477
592
  _ctx.$slots.footer ? (openBlock(), createElementBlock("div", {
478
593
  key: 4,
479
594
  class: "rs-select__panel-footer",
480
- onMousedown: _cache[5] || (_cache[5] = withModifiers(() => {}, ["prevent"]))
595
+ onMousedown: _cache[8] || (_cache[8] = withModifiers(() => {}, ["prevent"]))
481
596
  }, [renderSlot(_ctx.$slots, "footer", {}, void 0, true)], 32)) : createCommentVNode("", true)
482
597
  ], true)]),
483
598
  _: 3
@@ -3,6 +3,6 @@ import _plugin_vue_export_helper_default from "../_virtual/_plugin-vue_export-he
3
3
  import RsSelect_vue_vue_type_script_setup_true_lang_default from "./RsSelect.impl.js";
4
4
 
5
5
  //#region src/components/RsSelect.vue
6
- var RsSelect_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RsSelect_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-48ee70c4"]]);
6
+ var RsSelect_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RsSelect_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-956c54dc"]]);
7
7
  //#endregion
8
8
  export { RsSelect_default as default };
@@ -74,12 +74,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
74
74
  overflow: RsTabsOverflow | false;
75
75
  closable: boolean;
76
76
  borderless: boolean;
77
+ draggable: boolean;
77
78
  panelless: boolean;
78
79
  contentGap: RsTabsContentGap;
79
80
  justify: RsTabsJustify;
80
81
  addable: boolean;
81
82
  renamable: boolean;
82
- draggable: boolean;
83
83
  contextMenu: boolean;
84
84
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
85
85
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -9,9 +9,9 @@ type __VLS_Props = {
9
9
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
10
  gap: number;
11
11
  position: RsToastPosition;
12
+ expand: boolean;
12
13
  closeButton: boolean;
13
14
  richColors: boolean;
14
- expand: boolean;
15
15
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
16
  declare const _default: typeof __VLS_export;
17
17
  export default _default;
@@ -77,10 +77,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
77
77
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
78
78
  check: (keys: string[], halfCheckedKeys: string[], node: RsTreeNode, key: string) => any;
79
79
  "update:modelValue": (value: string | string[]) => any;
80
- expand: (key: string, expanded: boolean) => any;
81
80
  "node-click": (node: RsTreeNode, key: string) => any;
82
81
  "node-dblclick": (node: RsTreeNode, key: string) => any;
83
82
  "node-contextmenu": (node: RsTreeNode, key: string, event: MouseEvent) => any;
83
+ expand: (key: string, expanded: boolean) => any;
84
84
  "node-drop": (dragKey: string, dropKey: string, position: RsTreeDropPosition) => any;
85
85
  "update:expandedKeys": (value: string[] | undefined) => any;
86
86
  "update:checkedKeys": (value: string[] | undefined) => any;
@@ -88,10 +88,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
88
88
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
89
89
  onCheck?: ((keys: string[], halfCheckedKeys: string[], node: RsTreeNode, key: string) => any) | undefined;
90
90
  "onUpdate:modelValue"?: ((value: string | string[]) => any) | undefined;
91
- onExpand?: ((key: string, expanded: boolean) => any) | undefined;
92
91
  "onNode-click"?: ((node: RsTreeNode, key: string) => any) | undefined;
93
92
  "onNode-dblclick"?: ((node: RsTreeNode, key: string) => any) | undefined;
94
93
  "onNode-contextmenu"?: ((node: RsTreeNode, key: string, event: MouseEvent) => any) | undefined;
94
+ onExpand?: ((key: string, expanded: boolean) => any) | undefined;
95
95
  "onNode-drop"?: ((dragKey: string, dropKey: string, position: RsTreeDropPosition) => any) | undefined;
96
96
  "onUpdate:expandedKeys"?: ((value: string[] | undefined) => any) | undefined;
97
97
  "onUpdate:checkedKeys"?: ((value: string[] | undefined) => any) | undefined;
@@ -105,8 +105,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
105
105
  virtualThreshold: number;
106
106
  highlight: boolean;
107
107
  overscan: number;
108
- draggable: boolean;
109
- lazy: boolean;
110
108
  checkable: boolean;
111
109
  checkStrictly: boolean;
112
110
  onlyCheckLeaf: boolean;
@@ -119,6 +117,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
119
117
  showLine: boolean;
120
118
  accordion: boolean;
121
119
  autoExpandParent: boolean;
120
+ lazy: boolean;
121
+ draggable: boolean;
122
122
  dragTrigger: RsTreeDragTrigger;
123
123
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
124
124
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -1,8 +1,8 @@
1
1
  import { useRsI18n } from "../composables/useRsI18n.js";
2
2
  import RsIcon_default from "./RsIcon.js";
3
3
  import RsEmpty_default from "./RsEmpty.js";
4
- import { isVirtualListFillHeight, parseVirtualListHeightPx, resolveVirtualListHeight } from "./virtual-list-utils.js";
5
4
  import { buildTreeNodeIndex, collectExpandableKeys, collectHalfCheckedKeys, filterTreeNodes, flattenVisibleTreeNodes, getTreeChildren, getTreeKey, getTreeLabel, hasTreeChildren, isTreeAncestorKey, isTreeCheckboxDisabled, isTreeNodeDisabled, isTreeNodeLoading, resolveAccordionExpandedKeys, resolveTreeCheckState, resolveTreeFieldNames, resolveTreeFocusKey, resolveTreeIndent, resolveTreeRowHeight, resolveTreeVirtualEnabled, shouldShowTreeCheckbox, sliceVirtualTreeNodes, splitTreeLabelHighlight, toggleTreeCheck } from "./tree-utils.js";
5
+ import { isVirtualListFillHeight, parseVirtualListHeightPx, resolveVirtualListHeight } from "./virtual-list-utils.js";
6
6
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeModels, nextTick, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, ref, renderList, renderSlot, toDisplayString, unref, useModel, vShow, watch, withDirectives, withModifiers } from "vue";
7
7
  //#region src/components/RsTree.vue?vue&type=script&setup=true&lang.ts
8
8
  var _hoisted_1 = ["aria-label", "aria-multiselectable"];
@@ -0,0 +1,60 @@
1
+
2
+ .rs-tree-select[data-v-a057dd37] {
3
+ display: inline-flex;
4
+ align-items: center;
5
+ gap: var(--rs-space-sm);
6
+ box-sizing: border-box;
7
+ width: 100%;
8
+ min-width: 12rem;
9
+ height: var(--rs-control-height-md);
10
+ padding: 0 var(--rs-space-md);
11
+ border: 1px solid var(--rs-input-border, var(--rs-border));
12
+ border-radius: var(--rs-radius-sm);
13
+ background: var(--rs-input-bg);
14
+ color: var(--rs-text);
15
+ font-size: var(--rs-font-size-sm);
16
+ cursor: pointer;
17
+ }
18
+ .rs-tree-select--sm[data-v-a057dd37] {
19
+ height: var(--rs-control-height-sm);
20
+ }
21
+ .rs-tree-select--lg[data-v-a057dd37] {
22
+ height: var(--rs-control-height-lg);
23
+ }
24
+ .rs-tree-select--disabled[data-v-a057dd37] {
25
+ opacity: 0.38;
26
+ cursor: not-allowed;
27
+ }
28
+ .rs-tree-select__placeholder[data-v-a057dd37] {
29
+ flex: 1;
30
+ color: var(--rs-muted);
31
+ text-align: left;
32
+ }
33
+ .rs-tree-select__value[data-v-a057dd37] {
34
+ flex: 1;
35
+ overflow: hidden;
36
+ text-align: left;
37
+ text-overflow: ellipsis;
38
+ white-space: nowrap;
39
+ }
40
+ .rs-tree-select__clear[data-v-a057dd37] {
41
+ border: 0;
42
+ background: transparent;
43
+ color: var(--rs-muted);
44
+ cursor: pointer;
45
+ }
46
+ .rs-tree-select__panel[data-v-a057dd37] {
47
+ max-height: 18rem;
48
+ padding: var(--rs-space-xs);
49
+ overflow: auto;
50
+ }
51
+ .rs-tree-select__search[data-v-a057dd37] {
52
+ box-sizing: border-box;
53
+ width: 100%;
54
+ margin-bottom: var(--rs-space-xs);
55
+ padding: var(--rs-space-xs) var(--rs-space-sm);
56
+ border: 1px solid var(--rs-input-border, var(--rs-border));
57
+ border-radius: var(--rs-radius-xs);
58
+ background: var(--rs-input-bg);
59
+ color: var(--rs-text);
60
+ }
@@ -0,0 +1,33 @@
1
+ import type { RsComponentSize } from '../theme/types';
2
+ import { type RsTreeFieldNames, type RsTreeNode } from './tree-utils';
3
+ type __VLS_Props = {
4
+ treeData: RsTreeNode[];
5
+ fieldNames?: RsTreeFieldNames;
6
+ placeholder?: string;
7
+ disabled?: boolean;
8
+ allowClear?: boolean;
9
+ multiple?: boolean;
10
+ checkable?: boolean;
11
+ searchable?: boolean;
12
+ size?: RsComponentSize;
13
+ };
14
+ type __VLS_ModelProps = {
15
+ modelValue?: string | string[];
16
+ 'open'?: boolean;
17
+ };
18
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
19
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
20
+ "update:modelValue": (value: string | string[]) => any;
21
+ "update:open": (value: boolean) => any;
22
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
23
+ "onUpdate:modelValue"?: ((value: string | string[]) => any) | undefined;
24
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
25
+ }>, {
26
+ disabled: boolean;
27
+ multiple: boolean;
28
+ searchable: boolean;
29
+ allowClear: boolean;
30
+ checkable: boolean;
31
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
32
+ declare const _default: typeof __VLS_export;
33
+ export default _default;
@@ -0,0 +1,145 @@
1
+ import { useRsI18n } from "../composables/useRsI18n.js";
2
+ import RsIcon_default from "./RsIcon.js";
3
+ import { useResolvedRsComponentSize } from "./resolve-size.js";
4
+ import RsPopover_default from "./RsPopover.js";
5
+ import { buildTreeNodeIndex, getTreeLabel, resolveTreeFieldNames } from "./tree-utils.js";
6
+ import RsTree_default from "./RsTree.js";
7
+ import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, mergeModels, normalizeClass, openBlock, ref, toDisplayString, unref, useModel, vModelText, withCtx, withDirectives, withModifiers } from "vue";
8
+ //#region src/components/RsTreeSelect.vue?vue&type=script&setup=true&lang.ts
9
+ var _hoisted_1 = ["disabled"];
10
+ var _hoisted_2 = {
11
+ key: 0,
12
+ class: "rs-tree-select__value"
13
+ };
14
+ var _hoisted_3 = {
15
+ key: 1,
16
+ class: "rs-tree-select__placeholder"
17
+ };
18
+ var _hoisted_4 = ["aria-label"];
19
+ var _hoisted_5 = ["placeholder"];
20
+ var RsTreeSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
21
+ name: "RsTreeSelect",
22
+ __name: "RsTreeSelect",
23
+ props: /*@__PURE__*/ mergeModels({
24
+ treeData: {},
25
+ fieldNames: {},
26
+ placeholder: {},
27
+ disabled: {
28
+ type: Boolean,
29
+ default: false
30
+ },
31
+ allowClear: {
32
+ type: Boolean,
33
+ default: false
34
+ },
35
+ multiple: {
36
+ type: Boolean,
37
+ default: false
38
+ },
39
+ checkable: {
40
+ type: Boolean,
41
+ default: false
42
+ },
43
+ searchable: {
44
+ type: Boolean,
45
+ default: false
46
+ },
47
+ size: {}
48
+ }, {
49
+ "modelValue": { default: "" },
50
+ "modelModifiers": {},
51
+ "open": {
52
+ type: Boolean,
53
+ default: false
54
+ },
55
+ "openModifiers": {}
56
+ }),
57
+ emits: ["update:modelValue", "update:open"],
58
+ setup(__props) {
59
+ const model = useModel(__props, "modelValue");
60
+ const open = useModel(__props, "open");
61
+ const props = __props;
62
+ const { t } = useRsI18n();
63
+ const resolvedSize = useResolvedRsComponentSize(() => props.size);
64
+ const filter = ref("");
65
+ const names = computed(() => resolveTreeFieldNames(props.fieldNames));
66
+ const index = computed(() => buildTreeNodeIndex(props.treeData, names.value));
67
+ const selectedKeys = computed(() => {
68
+ if (Array.isArray(model.value)) return model.value.map(String);
69
+ return model.value === "" || model.value == null ? [] : [String(model.value)];
70
+ });
71
+ const display = computed(() => {
72
+ return selectedKeys.value.map((key) => {
73
+ const entry = index.value.get(key);
74
+ return entry ? getTreeLabel(entry.node, names.value) : key;
75
+ }).join(", ");
76
+ });
77
+ function onTreeUpdate(value) {
78
+ model.value = props.multiple || props.checkable ? value : value;
79
+ if (!props.multiple && !props.checkable) open.value = false;
80
+ }
81
+ function onClear() {
82
+ model.value = props.multiple || props.checkable ? [] : "";
83
+ }
84
+ return (_ctx, _cache) => {
85
+ return openBlock(), createBlock(RsPopover_default, {
86
+ open: open.value,
87
+ "onUpdate:open": _cache[2] || (_cache[2] = ($event) => open.value = $event),
88
+ side: "bottom",
89
+ align: "start",
90
+ width: "md"
91
+ }, {
92
+ content: withCtx(() => [createElementVNode("div", {
93
+ class: "rs-tree-select__panel",
94
+ onMousedown: _cache[1] || (_cache[1] = withModifiers(() => {}, ["prevent"]))
95
+ }, [__props.searchable ? withDirectives((openBlock(), createElementBlock("input", {
96
+ key: 0,
97
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => filter.value = $event),
98
+ class: "rs-tree-select__search",
99
+ placeholder: unref(t)("select.searchPlaceholder")
100
+ }, null, 8, _hoisted_5)), [[vModelText, filter.value]]) : createCommentVNode("", true), createVNode(RsTree_default, {
101
+ "model-value": __props.multiple || __props.checkable ? selectedKeys.value : selectedKeys.value[0] ?? "",
102
+ nodes: __props.treeData,
103
+ "field-names": __props.fieldNames,
104
+ multiple: __props.multiple,
105
+ checkable: __props.checkable,
106
+ filter: filter.value,
107
+ highlight: "",
108
+ "default-expand-all": "",
109
+ "onUpdate:modelValue": onTreeUpdate
110
+ }, null, 8, [
111
+ "model-value",
112
+ "nodes",
113
+ "field-names",
114
+ "multiple",
115
+ "checkable",
116
+ "filter"
117
+ ])], 32)]),
118
+ default: withCtx(() => [createElementVNode("button", {
119
+ type: "button",
120
+ class: normalizeClass(["rs-tree-select", [`rs-tree-select--${unref(resolvedSize)}`, { "rs-tree-select--disabled": __props.disabled }]]),
121
+ disabled: __props.disabled
122
+ }, [
123
+ display.value ? (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(display.value), 1)) : (openBlock(), createElementBlock("span", _hoisted_3, toDisplayString(__props.placeholder ?? unref(t)("select.placeholder")), 1)),
124
+ __props.allowClear && display.value && !__props.disabled ? (openBlock(), createElementBlock("button", {
125
+ key: 2,
126
+ type: "button",
127
+ class: "rs-tree-select__clear",
128
+ "aria-label": unref(t)("select.clear"),
129
+ onClick: withModifiers(onClear, ["stop"])
130
+ }, [createVNode(RsIcon_default, {
131
+ name: "x",
132
+ size: 12
133
+ })], 8, _hoisted_4)) : createCommentVNode("", true),
134
+ createVNode(RsIcon_default, {
135
+ name: "chevron-down",
136
+ size: 14
137
+ })
138
+ ], 10, _hoisted_1)]),
139
+ _: 1
140
+ }, 8, ["open"]);
141
+ };
142
+ }
143
+ });
144
+ //#endregion
145
+ export { RsTreeSelect_vue_vue_type_script_setup_true_lang_default as default };