niuma-ui 2.0.3 → 2.0.4

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 (202) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/components/_shared/src/reka.d.ts +1 -1
  3. package/dist/components/_shared/src/reka.js +2 -2
  4. package/dist/components/anchor/index.d.ts +1 -1
  5. package/dist/components/anchor/src/RsAnchor.css +63 -32
  6. package/dist/components/anchor/src/RsAnchor.d.ts +29 -2
  7. package/dist/components/anchor/src/RsAnchor.impl.js +199 -81
  8. package/dist/components/anchor/src/RsAnchor.js +1 -1
  9. package/dist/components/anchor/src/anchor-utils.d.ts +36 -4
  10. package/dist/components/anchor/src/anchor-utils.js +81 -19
  11. package/dist/components/auto-complete/index.d.ts +2 -0
  12. package/dist/components/auto-complete/src/RsAutoComplete.css +122 -0
  13. package/dist/components/auto-complete/src/RsAutoComplete.d.ts +47 -7
  14. package/dist/components/auto-complete/src/RsAutoComplete.impl.js +180 -72
  15. package/dist/components/auto-complete/src/RsAutoComplete.js +4 -1
  16. package/dist/components/auto-complete/src/auto-complete-utils.d.ts +7 -0
  17. package/dist/components/auto-complete/src/auto-complete-utils.js +17 -0
  18. package/dist/components/avatar/index.d.ts +1 -0
  19. package/dist/components/avatar/src/RsAvatar.css +36 -19
  20. package/dist/components/avatar/src/RsAvatar.d.ts +9 -3
  21. package/dist/components/avatar/src/RsAvatar.impl.js +57 -33
  22. package/dist/components/avatar/src/RsAvatar.js +2 -1
  23. package/dist/components/avatar/src/avatar-utils.d.ts +16 -7
  24. package/dist/components/avatar/src/avatar-utils.js +41 -3
  25. package/dist/components/breadcrumb/index.d.ts +1 -1
  26. package/dist/components/breadcrumb/src/RsBreadcrumb.css +50 -17
  27. package/dist/components/breadcrumb/src/RsBreadcrumb.d.ts +45 -6
  28. package/dist/components/breadcrumb/src/RsBreadcrumb.impl.js +111 -12
  29. package/dist/components/breadcrumb/src/RsBreadcrumb.js +2 -1
  30. package/dist/components/breadcrumb/src/breadcrumb-utils.d.ts +37 -5
  31. package/dist/components/breadcrumb/src/breadcrumb-utils.js +70 -9
  32. package/dist/components/calendar-grid/index.d.ts +2 -0
  33. package/dist/components/calendar-grid/src/RsCalendarGrid.css +105 -45
  34. package/dist/components/calendar-grid/src/RsCalendarGrid.d.ts +62 -2
  35. package/dist/components/calendar-grid/src/RsCalendarGrid.impl.js +265 -94
  36. package/dist/components/calendar-grid/src/RsCalendarGrid.js +1 -1
  37. package/dist/components/calendar-grid/src/calendar-grid-utils.d.ts +72 -0
  38. package/dist/components/calendar-grid/src/calendar-grid-utils.js +122 -0
  39. package/dist/components/card/index.d.ts +1 -1
  40. package/dist/components/card/src/RsCard.css +108 -98
  41. package/dist/components/card/src/RsCard.d.ts +3 -12
  42. package/dist/components/card/src/RsCard.impl.js +29 -25
  43. package/dist/components/card/src/RsCard.js +2 -1
  44. package/dist/components/card/src/card-utils.d.ts +25 -0
  45. package/dist/components/card/src/card-utils.js +10 -0
  46. package/dist/components/cascader/index.d.ts +1 -0
  47. package/dist/components/cascader/src/RsCascader.css +175 -30
  48. package/dist/components/cascader/src/RsCascader.d.ts +15 -3
  49. package/dist/components/cascader/src/RsCascader.impl.js +277 -48
  50. package/dist/components/cascader/src/RsCascader.js +1 -1
  51. package/dist/components/cascader/src/cascader-utils.d.ts +2 -0
  52. package/dist/components/cascader/src/cascader-utils.js +8 -1
  53. package/dist/components/checkbox/index.d.ts +1 -0
  54. package/dist/components/checkbox/src/RsCheckbox.css +46 -23
  55. package/dist/components/checkbox/src/RsCheckbox.d.ts +11 -1
  56. package/dist/components/checkbox/src/RsCheckbox.impl.js +37 -9
  57. package/dist/components/checkbox/src/RsCheckbox.js +2 -1
  58. package/dist/components/checkbox/src/checkbox-utils.d.ts +4 -0
  59. package/dist/components/checkbox/src/checkbox-utils.js +12 -0
  60. package/dist/components/container/index.d.ts +1 -1
  61. package/dist/components/container/src/RsContainer.css +11 -11
  62. package/dist/components/container/src/RsContainer.d.ts +2 -12
  63. package/dist/components/container/src/RsContainer.impl.js +10 -57
  64. package/dist/components/container/src/RsContainer.js +1 -1
  65. package/dist/components/container/src/container-utils.d.ts +23 -0
  66. package/dist/components/container/src/container-utils.js +51 -0
  67. package/dist/components/date-picker/index.d.ts +4 -2
  68. package/dist/components/date-picker/src/RsDatePicker.css +42 -22
  69. package/dist/components/date-picker/src/RsDatePicker.d.ts +44 -20
  70. package/dist/components/date-picker/src/RsDatePicker.impl.js +484 -222
  71. package/dist/components/date-picker/src/RsDatePicker.js +1 -3
  72. package/dist/components/date-picker/src/RsDateTimePicker.d.ts +33 -6
  73. package/dist/components/date-picker/src/RsDateTimePicker.impl.js +47 -6
  74. package/dist/components/date-picker/src/date-picker-utils.d.ts +19 -0
  75. package/dist/components/date-picker/src/date-picker-utils.js +33 -10
  76. package/dist/components/dynamic-tags/index.d.ts +1 -1
  77. package/dist/components/dynamic-tags/src/RsDynamicTags.css +115 -38
  78. package/dist/components/dynamic-tags/src/RsDynamicTags.d.ts +58 -17
  79. package/dist/components/dynamic-tags/src/RsDynamicTags.impl.js +269 -106
  80. package/dist/components/dynamic-tags/src/RsDynamicTags.js +1 -1
  81. package/dist/components/dynamic-tags/src/dynamic-tags-utils.d.ts +19 -0
  82. package/dist/components/dynamic-tags/src/dynamic-tags-utils.js +60 -0
  83. package/dist/components/fieldset/src/RsFieldset.css +71 -41
  84. package/dist/components/fieldset/src/RsFieldset.d.ts +21 -2
  85. package/dist/components/fieldset/src/RsFieldset.impl.js +93 -26
  86. package/dist/components/fieldset/src/RsFieldset.js +1 -1
  87. package/dist/components/fieldset/src/fieldset-utils.d.ts +4 -0
  88. package/dist/components/fieldset/src/fieldset-utils.js +9 -1
  89. package/dist/components/form/index.d.ts +1 -0
  90. package/dist/components/form/src/RsForm.css +15 -12
  91. package/dist/components/form/src/RsForm.d.ts +20 -22
  92. package/dist/components/form/src/RsForm.impl.js +33 -20
  93. package/dist/components/form/src/RsForm.js +1 -1
  94. package/dist/components/form/src/form-utils.d.ts +7 -0
  95. package/dist/components/form/src/form-utils.js +28 -1
  96. package/dist/components/input/index.d.ts +1 -1
  97. package/dist/components/input/src/RsInput.css +78 -260
  98. package/dist/components/input/src/RsInput.d.ts +5 -3
  99. package/dist/components/input/src/RsInput.impl.js +8 -16
  100. package/dist/components/input/src/RsInput.js +1 -1
  101. package/dist/components/input/src/input-utils.d.ts +11 -0
  102. package/dist/components/input/src/input-utils.js +22 -0
  103. package/dist/components/input-number/index.d.ts +1 -0
  104. package/dist/components/input-number/src/RsInputNumber.css +31 -31
  105. package/dist/components/input-number/src/RsInputNumber.d.ts +15 -13
  106. package/dist/components/input-number/src/RsInputNumber.impl.js +17 -4
  107. package/dist/components/input-number/src/RsInputNumber.js +1 -1
  108. package/dist/components/label/src/RsLabel.css +30 -11
  109. package/dist/components/label/src/RsLabel.d.ts +18 -1
  110. package/dist/components/label/src/RsLabel.impl.js +63 -10
  111. package/dist/components/label/src/RsLabel.js +1 -1
  112. package/dist/components/label/src/label-utils.d.ts +6 -0
  113. package/dist/components/label/src/label-utils.js +16 -0
  114. package/dist/components/link/src/RsLink.d.ts +2 -2
  115. package/dist/components/loading/src/RsLoading.d.ts +1 -1
  116. package/dist/components/mentions/index.d.ts +2 -1
  117. package/dist/components/mentions/src/RsMentions.css +119 -3
  118. package/dist/components/mentions/src/RsMentions.d.ts +56 -4
  119. package/dist/components/mentions/src/RsMentions.impl.js +298 -79
  120. package/dist/components/mentions/src/RsMentions.js +1 -3
  121. package/dist/components/mentions/src/mentions-utils.d.ts +5 -1
  122. package/dist/components/mentions/src/mentions-utils.js +28 -9
  123. package/dist/components/popover/src/RsPopover.d.ts +1 -1
  124. package/dist/components/radio/index.d.ts +1 -1
  125. package/dist/components/radio/src/RsRadio.css +7 -6
  126. package/dist/components/radio/src/RsRadio.d.ts +8 -5
  127. package/dist/components/radio/src/RsRadio.impl.js +34 -24
  128. package/dist/components/radio/src/RsRadio.js +2 -1
  129. package/dist/components/radio/src/RsRadioItem.css +61 -44
  130. package/dist/components/radio/src/RsRadioItem.d.ts +2 -2
  131. package/dist/components/radio/src/RsRadioItem.impl.js +53 -20
  132. package/dist/components/radio/src/RsRadioItem.js +2 -1
  133. package/dist/components/radio/src/radio-utils.d.ts +12 -1
  134. package/dist/components/radio/src/radio-utils.js +15 -1
  135. package/dist/components/scrollbar/src/RsScrollbar.css +71 -24
  136. package/dist/components/scrollbar/src/RsScrollbar.d.ts +9 -5
  137. package/dist/components/scrollbar/src/RsScrollbar.impl.js +372 -47
  138. package/dist/components/scrollbar/src/RsScrollbar.js +2 -1
  139. package/dist/components/scrollbar/src/scrollbar-utils.d.ts +34 -2
  140. package/dist/components/scrollbar/src/scrollbar-utils.js +64 -1
  141. package/dist/components/select/index.d.ts +1 -0
  142. package/dist/components/select/src/RsSelect.css +54 -42
  143. package/dist/components/select/src/RsSelect.d.ts +19 -2
  144. package/dist/components/select/src/RsSelect.impl.js +727 -312
  145. package/dist/components/select/src/RsSelect.js +1 -1
  146. package/dist/components/select/src/select-utils.d.ts +4 -2
  147. package/dist/components/select/src/select-utils.js +8 -3
  148. package/dist/components/select/src/use-rs-select.d.ts +1 -0
  149. package/dist/components/select/src/use-rs-select.js +23 -17
  150. package/dist/components/switch/index.d.ts +2 -1
  151. package/dist/components/switch/src/RsSwitch.css +36 -18
  152. package/dist/components/switch/src/RsSwitch.d.ts +18 -5
  153. package/dist/components/switch/src/RsSwitch.impl.js +61 -29
  154. package/dist/components/switch/src/RsSwitch.js +2 -1
  155. package/dist/components/switch/src/switch-utils.d.ts +4 -0
  156. package/dist/components/switch/src/switch-utils.js +9 -0
  157. package/dist/components/textarea/src/RsTextarea.css +23 -23
  158. package/dist/components/textarea/src/RsTextarea.d.ts +6 -12
  159. package/dist/components/textarea/src/RsTextarea.impl.js +37 -46
  160. package/dist/components/textarea/src/RsTextarea.js +1 -1
  161. package/dist/components/textarea/src/textarea-utils.d.ts +27 -0
  162. package/dist/components/textarea/src/textarea-utils.js +61 -0
  163. package/dist/components/time-picker/index.d.ts +3 -2
  164. package/dist/components/time-picker/src/RsTimePicker.css +41 -24
  165. package/dist/components/time-picker/src/RsTimePicker.d.ts +52 -7
  166. package/dist/components/time-picker/src/RsTimePicker.impl.js +520 -156
  167. package/dist/components/time-picker/src/RsTimePicker.js +1 -3
  168. package/dist/components/time-picker/src/RsTimePickerColumns.css +26 -18
  169. package/dist/components/time-picker/src/RsTimePickerColumns.d.ts +3 -1
  170. package/dist/components/time-picker/src/RsTimePickerColumns.impl.js +62 -9
  171. package/dist/components/time-picker/src/RsTimePickerColumns.js +1 -1
  172. package/dist/components/time-picker/src/time-picker-utils.d.ts +38 -0
  173. package/dist/components/time-picker/src/time-picker-utils.js +97 -5
  174. package/dist/components/toaster/src/RsToaster.d.ts +1 -1
  175. package/dist/components/tooltip/src/RsTooltip.d.ts +1 -1
  176. package/dist/components/tree/src/RsTree.d.ts +3 -3
  177. package/dist/components/tree-select/index.d.ts +2 -0
  178. package/dist/components/tree-select/src/RsTreeSelect.css +100 -25
  179. package/dist/components/tree-select/src/RsTreeSelect.d.ts +91 -7
  180. package/dist/components/tree-select/src/RsTreeSelect.impl.js +464 -79
  181. package/dist/components/tree-select/src/RsTreeSelect.js +1 -1
  182. package/dist/components/tree-select/src/tree-select-utils.d.ts +20 -0
  183. package/dist/components/tree-select/src/tree-select-utils.js +60 -0
  184. package/dist/components/upload/index.d.ts +2 -1
  185. package/dist/components/upload/src/RsUpload.css +223 -75
  186. package/dist/components/upload/src/RsUpload.d.ts +77 -1
  187. package/dist/components/upload/src/RsUpload.impl.js +404 -90
  188. package/dist/components/upload/src/RsUpload.js +1 -1
  189. package/dist/components/upload/src/upload-utils.d.ts +21 -2
  190. package/dist/components/upload/src/upload-utils.js +139 -9
  191. package/dist/index.d.ts +21 -11
  192. package/dist/index.js +6 -0
  193. package/dist/locale/messages.js +46 -2
  194. package/dist/styles.css +518 -154
  195. package/dist/theme/brand.example.css +1 -1
  196. package/package.json +1 -1
  197. package/dist/components/breadcrumb/src/RsBreadcrumbItems.d.ts +0 -8
  198. package/dist/components/breadcrumb/src/RsBreadcrumbItems.impl.js +0 -40
  199. package/dist/components/breadcrumb/src/RsBreadcrumbItems.js +0 -5
  200. package/dist/components/date-picker/src/RsDatePicker-1.css +0 -157
  201. package/dist/components/mentions/src/RsMentions-1.css +0 -29
  202. package/dist/components/time-picker/src/RsTimePicker-1.css +0 -98
@@ -1,25 +1,46 @@
1
+ import { RS_COMPONENT_SIZE_ICON_PX } from "../../../theme/types.js";
1
2
  import { useRsI18n } from "../../../composables/useRsI18n.js";
3
+ import RsIcon_default from "../../icon/src/RsIcon.js";
4
+ import { useRsFormContext, useRsFormField } from "../../form/src/form-utils.js";
2
5
  import { useResolvedRsComponentSize } from "../../_shared/src/resolve-size.js";
3
- import { applyMention, createTextareaCaretMeter, filterMentionOptions, findActiveMention, placeMentionPopup, resolveMentionPrefixes, stepMentionIndex } from "./mentions-utils.js";
4
- import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, mergeModels, nextTick, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, ref, renderList, toDisplayString, unref, useId, useModel, vModelText, watch, withDirectives, withModifiers } from "vue";
6
+ import { applyMention, createTextareaCaretMeter, filterMentionOptions, findActiveMention, normalizeRsMentionOptions, placeMentionPopup, resolveMentionPrefixes, stepMentionIndex } from "./mentions-utils.js";
7
+ import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, onUnmounted, openBlock, ref, renderList, renderSlot, toDisplayString, unref, useAttrs, useId, useModel, vModelText, watch, withDirectives, withModifiers } from "vue";
5
8
  //#region src/components/mentions/src/RsMentions.vue?vue&type=script&setup=true&lang.ts
6
9
  var _hoisted_1 = [
10
+ "id",
11
+ "name",
7
12
  "rows",
8
13
  "placeholder",
9
14
  "disabled",
15
+ "readonly",
16
+ "aria-label",
10
17
  "aria-expanded",
11
18
  "aria-controls",
12
19
  "aria-activedescendant"
13
20
  ];
14
- var _hoisted_2 = ["id", "aria-label"];
21
+ var _hoisted_2 = ["aria-label"];
15
22
  var _hoisted_3 = [
23
+ "id",
24
+ "aria-label",
25
+ "aria-busy",
26
+ "data-rs-theme",
27
+ "data-placement"
28
+ ];
29
+ var _hoisted_4 = {
30
+ key: 0,
31
+ class: "rs-mentions__item rs-mentions__item--empty",
32
+ role: "presentation"
33
+ };
34
+ var _hoisted_5 = [
16
35
  "id",
17
36
  "aria-selected",
18
37
  "aria-disabled",
38
+ "title",
19
39
  "onMousedown"
20
40
  ];
21
41
  var RsMentions_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
22
42
  name: "RsMentions",
43
+ inheritAttrs: false,
23
44
  __name: "RsMentions",
24
45
  props: /*@__PURE__*/ mergeModels({
25
46
  options: { default: () => [] },
@@ -31,19 +52,51 @@ var RsMentions_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
31
52
  type: Boolean,
32
53
  default: false
33
54
  },
34
- size: {}
55
+ readonly: {
56
+ type: Boolean,
57
+ default: false
58
+ },
59
+ size: {},
60
+ allowClear: {
61
+ type: Boolean,
62
+ default: false
63
+ },
64
+ filterOption: {
65
+ type: [Boolean, Function],
66
+ default: true
67
+ },
68
+ debounce: { default: 0 },
69
+ emptyText: { default: "" },
70
+ loading: {
71
+ type: Boolean,
72
+ default: false
73
+ },
74
+ loadingText: {},
75
+ id: {},
76
+ name: {},
77
+ ariaLabel: {}
35
78
  }, {
36
79
  "modelValue": { default: "" },
37
80
  "modelModifiers": {}
38
81
  }),
39
- emits: /*@__PURE__*/ mergeModels(["select", "search"], ["update:modelValue"]),
40
- setup(__props, { emit: __emit }) {
82
+ emits: /*@__PURE__*/ mergeModels([
83
+ "select",
84
+ "search",
85
+ "clear",
86
+ "focus",
87
+ "blur"
88
+ ], ["update:modelValue"]),
89
+ setup(__props, { expose: __expose, emit: __emit }) {
41
90
  const model = useModel(__props, "modelValue");
42
91
  const props = __props;
43
92
  const emit = __emit;
44
93
  const { t } = useRsI18n();
94
+ const attrs = useAttrs();
95
+ const formContext = useRsFormContext();
45
96
  const resolvedSize = useResolvedRsComponentSize(() => props.size);
46
97
  const listId = useId();
98
+ const autoId = useId();
99
+ const inputId = computed(() => props.id || autoId);
47
100
  const areaRef = ref(null);
48
101
  const listRef = ref(null);
49
102
  const cursor = ref(0);
@@ -55,13 +108,45 @@ var RsMentions_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
55
108
  const highlight = ref(0);
56
109
  const dismissed = ref(false);
57
110
  const lastSearch = ref(null);
111
+ const composing = ref(false);
112
+ const searchTimer = ref();
58
113
  const prefixes = computed(() => resolveMentionPrefixes(props.prefix));
59
114
  const meter = createTextareaCaretMeter();
60
- const active = computed(() => dismissed.value ? null : findActiveMention(model.value, cursor.value, prefixes.value, props.split));
61
- const suggestions = computed(() => active.value ? filterMentionOptions(props.options, active.value.query) : []);
62
- const open = computed(() => Boolean(active.value && suggestions.value.length));
63
- const activeOption = computed(() => suggestions.value[highlight.value]);
64
- const activeOptionId = computed(() => open.value && activeOption.value ? `${listId}-${activeOption.value.value}` : void 0);
115
+ /** 面板挂到 body 后仍跟输入框最近的 data-rs-theme(深色岛 / 混主题页)。 */
116
+ const panelTheme = ref();
117
+ function syncPanelTheme() {
118
+ const el = areaRef.value;
119
+ if (!el) {
120
+ panelTheme.value = void 0;
121
+ return;
122
+ }
123
+ const themed = el.closest("[data-rs-theme]");
124
+ panelTheme.value = themed instanceof HTMLElement ? themed.dataset.rsTheme : void 0;
125
+ }
126
+ const resolvedDisabled = computed(() => props.disabled || Boolean(formContext?.disabled.value));
127
+ const iconPx = computed(() => RS_COMPONENT_SIZE_ICON_PX[resolvedSize.value]);
128
+ const normalized = computed(() => normalizeRsMentionOptions(props.options));
129
+ const active = computed(() => dismissed.value || resolvedDisabled.value || props.readonly ? null : findActiveMention(model.value, cursor.value, prefixes.value, props.split));
130
+ const suggestions = computed(() => active.value ? filterMentionOptions(normalized.value, active.value.query, props.filterOption) : []);
131
+ const suggestionViews = computed(() => suggestions.value.map((option, index) => ({
132
+ option,
133
+ index,
134
+ optionId: `${listId}-${index}-${String(option.value)}`
135
+ })));
136
+ const open = computed(() => Boolean(active.value));
137
+ const activeOption = computed(() => {
138
+ const option = suggestions.value[highlight.value];
139
+ return option && !option.disabled ? option : void 0;
140
+ });
141
+ const activeOptionId = computed(() => {
142
+ if (!open.value || !activeOption.value) return void 0;
143
+ return suggestionViews.value[highlight.value]?.optionId;
144
+ });
145
+ const showClear = computed(() => Boolean(props.allowClear && model.value && !resolvedDisabled.value && !props.readonly));
146
+ const listStatusText = computed(() => {
147
+ if (props.loading && !suggestions.value.length) return props.loadingText || t("select.loading");
148
+ return props.emptyText || t("select.empty");
149
+ });
65
150
  function viewportCaret() {
66
151
  const el = areaRef.value;
67
152
  const mention = active.value;
@@ -80,7 +165,7 @@ var RsMentions_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
80
165
  const list = listRef.value?.getBoundingClientRect();
81
166
  popup.value = placeMentionPopup(caret, {
82
167
  width: list?.width || 160,
83
- height: list?.height || Math.min(192, suggestions.value.length * 32)
168
+ height: list?.height || Math.min(192, Math.max(1, suggestions.value.length) * 32)
84
169
  }, {
85
170
  width: window.innerWidth,
86
171
  height: window.innerHeight
@@ -88,13 +173,23 @@ var RsMentions_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
88
173
  }
89
174
  let frame = 0;
90
175
  function requestPlace() {
176
+ if (typeof window === "undefined") return;
91
177
  if (frame) return;
92
178
  frame = window.requestAnimationFrame(() => {
93
179
  frame = 0;
94
180
  placePopup();
95
181
  });
96
182
  }
97
- function syncCursor(emitSearch, keepDismissed = false) {
183
+ function emitSearch(query) {
184
+ if (searchTimer.value) clearTimeout(searchTimer.value);
185
+ const wait = props.debounce ?? 0;
186
+ if (wait <= 0) {
187
+ emit("search", query);
188
+ return;
189
+ }
190
+ searchTimer.value = setTimeout(() => emit("search", query), wait);
191
+ }
192
+ function syncCursor(emitSearchEvent, keepDismissed = false) {
98
193
  const el = areaRef.value;
99
194
  cursor.value = el?.selectionStart ?? model.value.length;
100
195
  if (!keepDismissed) dismissed.value = false;
@@ -103,14 +198,14 @@ var RsMentions_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
103
198
  lastSearch.value = null;
104
199
  return;
105
200
  }
106
- if (emitSearch && mention.query !== lastSearch.value) {
201
+ if (emitSearchEvent && mention.query !== lastSearch.value) {
107
202
  lastSearch.value = mention.query;
108
- emit("search", mention.query);
203
+ emitSearch(mention.query);
109
204
  }
110
- requestPlace();
205
+ if (!keepDismissed) requestPlace();
111
206
  }
112
207
  function pick(option) {
113
- if (!active.value || option.disabled) return;
208
+ if (!active.value || option.disabled || resolvedDisabled.value || props.readonly) return;
114
209
  const next = applyMention(model.value, active.value, option.value, props.split);
115
210
  model.value = next.text;
116
211
  emit("select", option.value);
@@ -124,6 +219,7 @@ var RsMentions_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
124
219
  });
125
220
  }
126
221
  function onKeydown(event) {
222
+ if (event.isComposing || composing.value || resolvedDisabled.value || props.readonly) return;
127
223
  if (!open.value) return;
128
224
  if (event.key === "ArrowDown") {
129
225
  event.preventDefault();
@@ -136,8 +232,9 @@ var RsMentions_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
136
232
  return;
137
233
  }
138
234
  if (event.key === "Enter") {
235
+ if (!activeOption.value) return;
139
236
  event.preventDefault();
140
- if (activeOption.value) pick(activeOption.value);
237
+ pick(activeOption.value);
141
238
  return;
142
239
  }
143
240
  if (event.key === "Escape") {
@@ -160,81 +257,203 @@ var RsMentions_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
160
257
  pick(activeOption.value);
161
258
  }
162
259
  }
260
+ function onCompositionStart() {
261
+ composing.value = true;
262
+ }
263
+ function onCompositionEnd() {
264
+ composing.value = false;
265
+ syncCursor(true);
266
+ }
267
+ function onClear() {
268
+ model.value = "";
269
+ emit("clear");
270
+ dismissed.value = true;
271
+ nextTick(() => areaRef.value?.focus());
272
+ }
273
+ function onFocus(event) {
274
+ emit("focus", event);
275
+ syncCursor(true);
276
+ }
277
+ let blurTimer = 0;
278
+ function onBlur(event) {
279
+ emit("blur", event);
280
+ if (typeof window === "undefined") return;
281
+ if (blurTimer) window.clearTimeout(blurTimer);
282
+ blurTimer = window.setTimeout(() => {
283
+ blurTimer = 0;
284
+ if (document.activeElement === areaRef.value) return;
285
+ dismissed.value = true;
286
+ }, 0);
287
+ }
288
+ function onDocPointerDown(event) {
289
+ const target = event.target;
290
+ if (!target) return;
291
+ if (areaRef.value?.contains(target)) return;
292
+ if (listRef.value?.contains(target)) return;
293
+ dismissed.value = true;
294
+ }
295
+ function scrollActiveIntoView() {
296
+ if (!open.value || !activeOptionId.value) return;
297
+ document.getElementById(activeOptionId.value)?.scrollIntoView({ block: "nearest" });
298
+ }
163
299
  watch(suggestions, (list) => {
164
300
  highlight.value = list.findIndex((item) => !item.disabled);
165
301
  if (highlight.value < 0) highlight.value = 0;
166
- requestPlace();
302
+ if (open.value) requestPlace();
167
303
  });
304
+ watch(highlight, () => {
305
+ nextTick(scrollActiveIntoView);
306
+ });
307
+ let overlayBound = false;
308
+ function attachOverlay() {
309
+ if (overlayBound || typeof window === "undefined" || typeof document === "undefined") return;
310
+ overlayBound = true;
311
+ document.addEventListener("pointerdown", onDocPointerDown);
312
+ window.addEventListener("resize", onWindowChange);
313
+ window.addEventListener("scroll", onWindowChange, true);
314
+ }
315
+ function detachOverlay() {
316
+ if (frame && typeof window !== "undefined") {
317
+ window.cancelAnimationFrame(frame);
318
+ frame = 0;
319
+ }
320
+ if (!overlayBound) return;
321
+ overlayBound = false;
322
+ if (typeof document !== "undefined") document.removeEventListener("pointerdown", onDocPointerDown);
323
+ if (typeof window !== "undefined") {
324
+ window.removeEventListener("resize", onWindowChange);
325
+ window.removeEventListener("scroll", onWindowChange, true);
326
+ }
327
+ }
168
328
  watch(open, (isOpen) => {
169
- if (isOpen) nextTick(() => requestPlace());
329
+ if (isOpen) {
330
+ attachOverlay();
331
+ nextTick(() => {
332
+ syncPanelTheme();
333
+ requestPlace();
334
+ });
335
+ return;
336
+ }
337
+ detachOverlay();
170
338
  });
171
339
  function onWindowChange() {
172
340
  if (open.value) requestPlace();
173
341
  }
174
- onMounted(() => {
175
- window.addEventListener("resize", onWindowChange);
176
- window.addEventListener("scroll", onWindowChange, true);
342
+ function setFieldValue(value) {
343
+ model.value = value == null ? "" : String(value);
344
+ }
345
+ useRsFormField(() => ({
346
+ get name() {
347
+ return props.name;
348
+ },
349
+ getValue: () => model.value,
350
+ setValue: setFieldValue
351
+ }));
352
+ function focus() {
353
+ areaRef.value?.focus();
354
+ }
355
+ function blur() {
356
+ areaRef.value?.blur();
357
+ }
358
+ __expose({
359
+ focus,
360
+ blur
177
361
  });
178
362
  onUnmounted(() => {
179
- if (frame) window.cancelAnimationFrame(frame);
363
+ detachOverlay();
364
+ if (searchTimer.value) clearTimeout(searchTimer.value);
365
+ if (blurTimer && typeof window !== "undefined") window.clearTimeout(blurTimer);
180
366
  meter.dispose();
181
- window.removeEventListener("resize", onWindowChange);
182
- window.removeEventListener("scroll", onWindowChange, true);
183
367
  });
184
368
  return (_ctx, _cache) => {
185
- return openBlock(), createElementBlock("div", { class: normalizeClass(["rs-mentions", `rs-mentions--${unref(resolvedSize)}`]) }, [withDirectives(createElementVNode("textarea", {
186
- ref_key: "areaRef",
187
- ref: areaRef,
188
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
189
- class: "rs-mentions__input",
190
- rows: __props.rows,
191
- placeholder: __props.placeholder ?? unref(t)("mentions.placeholder"),
192
- disabled: __props.disabled,
193
- role: "combobox",
194
- "aria-autocomplete": "list",
195
- "aria-haspopup": "listbox",
196
- "aria-expanded": open.value ? "true" : "false",
197
- "aria-controls": open.value ? unref(listId) : void 0,
198
- "aria-activedescendant": activeOptionId.value,
199
- onKeydown,
200
- onKeyup: _cache[1] || (_cache[1] = ($event) => syncCursor(true, [
201
- "Escape",
202
- "Enter",
203
- "Tab",
204
- "ArrowUp",
205
- "ArrowDown",
206
- "Home",
207
- "End"
208
- ].includes($event.key))),
209
- onClick: _cache[2] || (_cache[2] = ($event) => syncCursor(true)),
210
- onInput: _cache[3] || (_cache[3] = ($event) => syncCursor(true)),
211
- onScroll: _cache[4] || (_cache[4] = ($event) => syncCursor(false, true))
212
- }, null, 40, _hoisted_1), [[vModelText, model.value]]), (openBlock(), createBlock(Teleport, { to: "body" }, [open.value ? (openBlock(), createElementBlock("ul", {
213
- key: 0,
214
- id: unref(listId),
215
- ref_key: "listRef",
216
- ref: listRef,
217
- class: "rs-mentions__list",
218
- role: "listbox",
219
- "aria-label": unref(t)("mentions.suggestions"),
220
- style: normalizeStyle({
221
- top: `${popup.value.top}px`,
222
- left: `${popup.value.left}px`
223
- })
224
- }, [(openBlock(true), createElementBlock(Fragment, null, renderList(suggestions.value, (opt, index) => {
225
- return openBlock(), createElementBlock("li", {
226
- id: `${unref(listId)}-${opt.value}`,
227
- key: opt.value,
228
- role: "option",
229
- class: normalizeClass(["rs-mentions__item", {
230
- "rs-mentions__item--disabled": opt.disabled,
231
- "rs-mentions__item--active": index === highlight.value
232
- }]),
233
- "aria-selected": index === highlight.value,
234
- "aria-disabled": opt.disabled ? "true" : void 0,
235
- onMousedown: withModifiers(($event) => pick(opt), ["prevent"])
236
- }, toDisplayString(opt.label), 43, _hoisted_3);
237
- }), 128))], 12, _hoisted_2)) : createCommentVNode("", true)]))], 2);
369
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["rs-mentions", [`rs-mentions--${unref(resolvedSize)}`, {
370
+ "rs-mentions--clearable": showClear.value,
371
+ "rs-mentions--disabled": resolvedDisabled.value,
372
+ "rs-mentions--readonly": __props.readonly
373
+ }]]) }, [
374
+ withDirectives(createElementVNode("textarea", mergeProps({
375
+ id: inputId.value,
376
+ ref_key: "areaRef",
377
+ ref: areaRef
378
+ }, unref(attrs), {
379
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
380
+ class: "rs-mentions__input",
381
+ name: __props.name,
382
+ rows: __props.rows,
383
+ placeholder: __props.placeholder ?? unref(t)("mentions.placeholder"),
384
+ disabled: resolvedDisabled.value,
385
+ readonly: __props.readonly,
386
+ "aria-label": __props.ariaLabel,
387
+ autocomplete: "off",
388
+ role: "combobox",
389
+ "aria-autocomplete": "list",
390
+ "aria-haspopup": "listbox",
391
+ "aria-expanded": open.value ? "true" : "false",
392
+ "aria-controls": open.value ? unref(listId) : void 0,
393
+ "aria-activedescendant": activeOptionId.value,
394
+ onKeydown,
395
+ onKeyup: _cache[1] || (_cache[1] = ($event) => syncCursor(true, [
396
+ "Escape",
397
+ "Enter",
398
+ "Tab",
399
+ "ArrowUp",
400
+ "ArrowDown",
401
+ "Home",
402
+ "End"
403
+ ].includes($event.key))),
404
+ onClick: _cache[2] || (_cache[2] = ($event) => syncCursor(true)),
405
+ onInput: _cache[3] || (_cache[3] = ($event) => syncCursor(true)),
406
+ onScroll: _cache[4] || (_cache[4] = ($event) => syncCursor(false, true)),
407
+ onFocus,
408
+ onBlur,
409
+ onCompositionstart: onCompositionStart,
410
+ onCompositionend: onCompositionEnd
411
+ }), null, 16, _hoisted_1), [[vModelText, model.value]]),
412
+ showClear.value ? (openBlock(), createElementBlock("button", {
413
+ key: 0,
414
+ type: "button",
415
+ class: "rs-mentions__clear",
416
+ "aria-label": unref(t)("select.clear"),
417
+ onPointerdown: _cache[5] || (_cache[5] = withModifiers(() => {}, ["prevent"])),
418
+ onClick: onClear
419
+ }, [createVNode(RsIcon_default, {
420
+ name: "x",
421
+ size: iconPx.value
422
+ }, null, 8, ["size"])], 40, _hoisted_2)) : createCommentVNode("", true),
423
+ (openBlock(), createBlock(Teleport, { to: "body" }, [open.value ? (openBlock(), createElementBlock("ul", {
424
+ key: 0,
425
+ id: unref(listId),
426
+ ref_key: "listRef",
427
+ ref: listRef,
428
+ class: "rs-mentions__list",
429
+ role: "listbox",
430
+ "aria-label": unref(t)("mentions.suggestions"),
431
+ "aria-busy": __props.loading ? "true" : void 0,
432
+ "data-rs-theme": panelTheme.value,
433
+ "data-placement": popup.value.placement,
434
+ style: normalizeStyle({
435
+ top: `${popup.value.top}px`,
436
+ left: `${popup.value.left}px`
437
+ })
438
+ }, [!suggestions.value.length ? (openBlock(), createElementBlock("li", _hoisted_4, [renderSlot(_ctx.$slots, "empty", {}, () => [createTextVNode(toDisplayString(listStatusText.value), 1)], true)])) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(suggestionViews.value, (row) => {
439
+ return openBlock(), createElementBlock("li", {
440
+ id: row.optionId,
441
+ key: row.optionId,
442
+ role: "option",
443
+ class: normalizeClass(["rs-mentions__item", {
444
+ "rs-mentions__item--disabled": row.option.disabled,
445
+ "rs-mentions__item--active": row.index === highlight.value
446
+ }]),
447
+ "aria-selected": row.index === highlight.value,
448
+ "aria-disabled": row.option.disabled ? "true" : void 0,
449
+ title: row.option.title,
450
+ onMousedown: withModifiers(($event) => pick(row.option), ["prevent"])
451
+ }, [renderSlot(_ctx.$slots, "option", {
452
+ option: row.option,
453
+ active: row.index === highlight.value
454
+ }, () => [createTextVNode(toDisplayString(row.option.label), 1)], true)], 42, _hoisted_5);
455
+ }), 128))], 12, _hoisted_3)) : createCommentVNode("", true)]))
456
+ ], 2);
238
457
  };
239
458
  }
240
459
  });
@@ -1,10 +1,8 @@
1
1
  import './RsMentions.css'
2
- import './RsMentions-1.css'
3
2
  import _plugin_vue_export_helper_default from "../../../_virtual/_plugin-vue_export-helper.js";
4
3
  import RsMentions_vue_vue_type_script_setup_true_lang_default from "./RsMentions.impl.js";
5
4
 
6
-
7
5
  //#region src/components/mentions/src/RsMentions.vue
8
- var RsMentions_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RsMentions_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-3b6a5d22"]]);
6
+ var RsMentions_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RsMentions_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-c5c1f2dc"]]);
9
7
  //#endregion
10
8
  export { RsMentions_default as default };
@@ -2,7 +2,11 @@ export interface RsMentionOption {
2
2
  label: string;
3
3
  value: string;
4
4
  disabled?: boolean;
5
+ title?: string;
5
6
  }
7
+ export type RsMentionOptionInput = string | RsMentionOption;
8
+ export type RsMentionFilterOption = boolean | ((query: string, option: RsMentionOption) => boolean);
9
+ export declare function normalizeRsMentionOptions(options: ReadonlyArray<RsMentionOptionInput> | undefined): RsMentionOption[];
6
10
  export interface RsMentionActive {
7
11
  prefix: string;
8
12
  query: string;
@@ -43,4 +47,4 @@ export interface RsTextareaCaretMeter {
43
47
  export declare function createTextareaCaretMeter(): RsTextareaCaretMeter;
44
48
  /** 相对 textarea 内容区的光标坐标(已扣滚动)。测试 / 单次调用用;热路径请复用 meter。 */
45
49
  export declare function measureTextareaCaret(textarea: HTMLTextAreaElement, index: number): RsMentionCaretBox;
46
- export declare function filterMentionOptions(options: readonly RsMentionOption[], query: string): RsMentionOption[];
50
+ export declare function filterMentionOptions(options: readonly RsMentionOption[], query: string, filterOption?: RsMentionFilterOption): RsMentionOption[];
@@ -1,5 +1,12 @@
1
1
  import { placeAnchoredPopup, stepEnabledIndex } from "../../_shared/src/overlay-utils.js";
2
2
  //#region src/components/mentions/src/mentions-utils.ts
3
+ function normalizeRsMentionOptions(options) {
4
+ if (!options?.length) return [];
5
+ return options.map((item) => typeof item === "string" ? {
6
+ label: item,
7
+ value: item
8
+ } : { ...item });
9
+ }
3
10
  function resolveMentionPrefixes(prefix) {
4
11
  return (Array.isArray(prefix) ? prefix : [prefix]).map(String).filter(Boolean);
5
12
  }
@@ -67,13 +74,15 @@ var MIRROR_STYLE_KEYS = [
67
74
  "tabSize",
68
75
  "lineHeight",
69
76
  "whiteSpace",
70
- "wordWrap"
77
+ "wordWrap",
78
+ "direction"
71
79
  ];
72
80
  /** 复用隐藏镜像节点,避免每次按键 insert/remove 逼 reflow。 */
73
81
  function createTextareaCaretMeter() {
74
82
  let mirror = null;
75
83
  let marker = null;
76
84
  function ensure() {
85
+ if (typeof document === "undefined") return null;
77
86
  if (mirror && marker) return {
78
87
  mirror,
79
88
  marker
@@ -87,7 +96,7 @@ function createTextareaCaretMeter() {
87
96
  s.whiteSpace = "pre-wrap";
88
97
  s.wordWrap = "break-word";
89
98
  s.top = "0";
90
- s.left = "-9999px";
99
+ s.insetInlineStart = "-9999px";
91
100
  marker = document.createElement("span");
92
101
  marker.textContent = ".";
93
102
  document.body.appendChild(mirror);
@@ -97,16 +106,23 @@ function createTextareaCaretMeter() {
97
106
  };
98
107
  }
99
108
  function measure(textarea, index) {
100
- const { mirror: box, marker: caret } = ensure();
109
+ const nodes = ensure();
110
+ if (!nodes) return {
111
+ top: 0,
112
+ left: 0,
113
+ height: 16
114
+ };
115
+ const { mirror: box, marker: caret } = nodes;
101
116
  const style = window.getComputedStyle(textarea);
102
117
  for (const key of MIRROR_STYLE_KEYS) box.style.setProperty(key.replace(/[A-Z]/g, (ch) => `-${ch.toLowerCase()}`), style[key]);
118
+ box.dir = textarea.dir || document.documentElement.dir || "ltr";
103
119
  const text = textarea.value.slice(0, Math.max(0, index));
104
120
  box.textContent = text.endsWith("\n") ? `${text}\u00a0` : text;
105
121
  box.appendChild(caret);
106
122
  return {
107
123
  top: caret.offsetTop - textarea.scrollTop,
108
124
  left: caret.offsetLeft - textarea.scrollLeft,
109
- height: caret.offsetHeight || parseFloat(style.lineHeight) || 16
125
+ height: caret.offsetHeight || Number.parseFloat(style.lineHeight) || 16
110
126
  };
111
127
  }
112
128
  function dispose() {
@@ -119,10 +135,13 @@ function createTextareaCaretMeter() {
119
135
  dispose
120
136
  };
121
137
  }
122
- function filterMentionOptions(options, query) {
123
- const q = query.trim().toLowerCase();
124
- if (!q) return options.filter((item) => !item.disabled);
125
- return options.filter((item) => !item.disabled && (item.label.toLowerCase().includes(q) || item.value.toLowerCase().includes(q)));
138
+ function filterMentionOptions(options, query, filterOption) {
139
+ if (filterOption === false) return options.slice();
140
+ const q = query.trim();
141
+ if (typeof filterOption === "function") return options.filter((item) => filterOption(q, item));
142
+ if (!q) return options.slice();
143
+ const lower = q.toLowerCase();
144
+ return options.filter((item) => item.label.toLowerCase().includes(lower) || item.value.toLowerCase().includes(lower));
126
145
  }
127
146
  //#endregion
128
- export { applyMention, createTextareaCaretMeter, filterMentionOptions, findActiveMention, placeMentionPopup, resolveMentionPrefixes, stepMentionIndex };
147
+ export { applyMention, createTextareaCaretMeter, filterMentionOptions, findActiveMention, normalizeRsMentionOptions, placeMentionPopup, resolveMentionPrefixes, stepMentionIndex };
@@ -26,10 +26,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
26
26
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
27
27
  }>, {
28
28
  width: RsPopoverWidth;
29
- forceMount: boolean;
30
29
  side: RsPopoverSide;
31
30
  sideOffset: number;
32
31
  align: RsPopoverAlign;
32
+ forceMount: boolean;
33
33
  modal: boolean;
34
34
  lazyMount: boolean;
35
35
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -1,3 +1,3 @@
1
1
  export { default as RsRadio } from './src/RsRadio.js';
2
2
  export { default as RsRadioItem } from './src/RsRadioItem.js';
3
- export type { RsRadioValue } from './src/radio-utils';
3
+ export type { RsRadioOrientation, RsRadioValue } from './src/radio-utils';
@@ -1,19 +1,20 @@
1
1
 
2
- .rs-radio-group {
3
- display: inline-flex;
2
+ .rs-radio-group[data-v-b3347bb9] {
3
+ display: flex;
4
+ width: max-content;
5
+ max-width: 100%;
4
6
  gap: var(--rs-space-md);
5
7
  color: var(--rs-text);
6
8
  }
7
- .rs-radio-group--vertical {
9
+ .rs-radio-group--vertical[data-v-b3347bb9] {
8
10
  flex-direction: column;
9
11
  align-items: flex-start;
10
12
  }
11
- .rs-radio-group--horizontal {
13
+ .rs-radio-group--horizontal[data-v-b3347bb9] {
12
14
  flex-direction: row;
13
15
  flex-wrap: wrap;
14
16
  align-items: center;
15
17
  }
16
- .rs-radio-group--disabled {
17
- opacity: 0.55;
18
+ .rs-radio-group--disabled[data-v-b3347bb9] {
18
19
  cursor: not-allowed;
19
20
  }