@sdata/web-vue 5.1.1 → 5.2.1

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.
@@ -3,7 +3,7 @@ import type { SpinProps } from '../spin';
3
3
  import { VirtualListProps } from '../_components/virtual-list/interface';
4
4
  import { Size } from '../_utils/constant';
5
5
  import { SdLang } from '../locale/interface';
6
- import { ConfigProviderColorPicker, ConfigProviderDatePicker, ConfigProviderDrawer, type JsonFormProviderConfig, ConfigProviderModal, ConfigProviderPagination } from './context';
6
+ import { ConfigProviderColorPicker, ConfigProviderDatePicker, ConfigProviderDrawer, type JsonFormProviderConfig, ConfigProviderModal, ConfigProviderPagination, ConfigProviderTable } from './context';
7
7
  import { SdThemeConfig, SdThemeMode } from './theme';
8
8
  declare var __VLS_8: {};
9
9
  type __VLS_Slots = {} & {
@@ -70,6 +70,9 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
70
70
  colorPicker: {
71
71
  type: PropType<ConfigProviderColorPicker>;
72
72
  };
73
+ table: {
74
+ type: PropType<ConfigProviderTable>;
75
+ };
73
76
  spinProps: {
74
77
  type: PropType<SpinProps>;
75
78
  };
@@ -173,6 +176,9 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
173
176
  colorPicker: {
174
177
  type: PropType<ConfigProviderColorPicker>;
175
178
  };
179
+ table: {
180
+ type: PropType<ConfigProviderTable>;
181
+ };
176
182
  spinProps: {
177
183
  type: PropType<SpinProps>;
178
184
  };
@@ -125,6 +125,11 @@ var config_provider_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
125
125
  */
126
126
  colorPicker: { type: Object },
127
127
  /**
128
+ * @zh Table 组件默认配置
129
+ * @en Default config for Table
130
+ */
131
+ table: { type: Object },
132
+ /**
128
133
  * @zh Spin 组件默认属性
129
134
  * @en Default props for Spin
130
135
  */
@@ -211,7 +216,7 @@ var config_provider_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
211
216
  * @version 2.28.0
212
217
  */
213
218
  const slots = useSlots();
214
- const { prefixCls, locale, size, allowClear, autoInsertSpaceInButton, allowSearch, virtualListProps, updateAtScroll, scrollToClose, exchangeTime, rtl, datePicker, modal, drawer, pagination, colorPicker, spinProps, basicCrudTableSpinProps, cardSpinProps, cascaderSpinProps, listSpinProps, qrCodeSpinProps, selectSpinProps, tableSpinProps, timelineSpinProps, toolbarSpinProps, treeSelectSpinProps, jsonForm } = toRefs(props);
219
+ const { prefixCls, locale, size, allowClear, autoInsertSpaceInButton, allowSearch, virtualListProps, updateAtScroll, scrollToClose, exchangeTime, rtl, datePicker, modal, drawer, pagination, colorPicker, table, spinProps, basicCrudTableSpinProps, cardSpinProps, cascaderSpinProps, listSpinProps, qrCodeSpinProps, selectSpinProps, tableSpinProps, timelineSpinProps, toolbarSpinProps, treeSelectSpinProps, jsonForm } = toRefs(props);
215
220
  const config = reactive({
216
221
  slots,
217
222
  prefixCls,
@@ -230,6 +235,7 @@ var config_provider_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
230
235
  drawer,
231
236
  pagination,
232
237
  colorPicker,
238
+ table,
233
239
  spinProps,
234
240
  basicCrudTableSpinProps,
235
241
  cardSpinProps,
@@ -7,8 +7,11 @@ import type { ShortcutType, WeekStart } from '../date-picker/interface';
7
7
  import type { EllipsisTooltipProps } from '../ellipsis';
8
8
  import type { JsonFormProviderConfig } from '../json-form/types';
9
9
  import type { SdLang } from '../locale/interface';
10
+ import type { PaginationProps } from '../pagination';
10
11
  import type { PaginationSelectProps } from '../pagination/interface';
12
+ import type { ScrollbarProps } from '../scrollbar';
11
13
  import type { SpinProps } from '../spin';
14
+ import type { TableBorder, TablePagePosition } from '../table/interface';
12
15
  import type { SDThemeNormalized, SdThemeMode } from './theme';
13
16
  export interface ConfigProviderModal {
14
17
  mask?: boolean;
@@ -70,6 +73,23 @@ export interface ConfigProviderPagination {
70
73
  export interface ConfigProviderColorPicker {
71
74
  swatchColors?: string[];
72
75
  }
76
+ export interface ConfigProviderTable {
77
+ bordered?: boolean | TableBorder;
78
+ hoverable?: boolean;
79
+ stripe?: boolean;
80
+ tableLayoutFixed?: boolean;
81
+ pagination?: boolean | PaginationProps;
82
+ pagePosition?: TablePagePosition;
83
+ indentSize?: number;
84
+ showHeader?: boolean;
85
+ filterIconAlignLeft?: boolean;
86
+ hideExpandButtonOnEmpty?: boolean;
87
+ columnResizable?: boolean;
88
+ summaryText?: string;
89
+ stickyHeader?: boolean | number;
90
+ scrollbar?: boolean | ScrollbarProps;
91
+ showEmptyTree?: boolean;
92
+ }
73
93
  export interface ConfigProvider {
74
94
  slots: Slots;
75
95
  prefixCls?: string;
@@ -88,6 +108,7 @@ export interface ConfigProvider {
88
108
  drawer?: ConfigProviderDrawer;
89
109
  pagination?: ConfigProviderPagination;
90
110
  colorPicker?: ConfigProviderColorPicker;
111
+ table?: ConfigProviderTable;
91
112
  spinProps?: SpinProps;
92
113
  basicCrudTableSpinProps?: SpinProps;
93
114
  cardSpinProps?: SpinProps;
@@ -63,6 +63,9 @@ declare const ConfigProvider: {
63
63
  colorPicker: {
64
64
  type: import("vue").PropType<import("./context").ConfigProviderColorPicker>;
65
65
  };
66
+ table: {
67
+ type: import("vue").PropType<import("./context").ConfigProviderTable>;
68
+ };
66
69
  spinProps: {
67
70
  type: import("vue").PropType<import("..").SpinProps>;
68
71
  };
@@ -183,6 +186,9 @@ declare const ConfigProvider: {
183
186
  colorPicker: {
184
187
  type: import("vue").PropType<import("./context").ConfigProviderColorPicker>;
185
188
  };
189
+ table: {
190
+ type: import("vue").PropType<import("./context").ConfigProviderTable>;
191
+ };
186
192
  spinProps: {
187
193
  type: import("vue").PropType<import("..").SpinProps>;
188
194
  };
@@ -300,6 +306,9 @@ declare const ConfigProvider: {
300
306
  colorPicker: {
301
307
  type: import("vue").PropType<import("./context").ConfigProviderColorPicker>;
302
308
  };
309
+ table: {
310
+ type: import("vue").PropType<import("./context").ConfigProviderTable>;
311
+ };
303
312
  spinProps: {
304
313
  type: import("vue").PropType<import("..").SpinProps>;
305
314
  };
@@ -362,5 +371,5 @@ declare const ConfigProvider: {
362
371
  export type ConfigProviderInstance = InstanceType<typeof _ConfigProvider>;
363
372
  export type { SdThemeConfig, SdThemeMeta, SdThemeMode, ThemeTokenMap, ThemeTokenValue, } from './theme';
364
373
  export type { JsonFormProviderConfig as ConfigProviderJsonFormConfig } from '../json-form';
365
- export type { ConfigProviderColorPicker } from './context';
374
+ export type { ConfigProviderColorPicker, ConfigProviderTable } from './context';
366
375
  export default ConfigProvider;
package/es/index.css CHANGED
@@ -6602,6 +6602,9 @@ body.sd-tour-active .sd-tour-popover * {
6602
6602
  .sd-table-checkbox .sd-checkbox, .sd-table-radio .sd-radio {
6603
6603
  padding-left: 0;
6604
6604
  }
6605
+ .sd-table-th.sd-table-checkbox .sd-checkbox-label:empty {
6606
+ display: none;
6607
+ }
6605
6608
  .sd-table-selection-checkbox-col, .sd-table-selection-radio-col {
6606
6609
  width: var(--component-table-table-size-selection-col-width, var(--component-table-size-selection-col-width, 40px));
6607
6610
  min-width: var(--component-table-table-size-selection-col-width, var(--component-table-size-selection-col-width, 40px));
@@ -11064,15 +11067,52 @@ body.sd-tour-active .sd-tour-popover * {
11064
11067
  margin-top: 6px;
11065
11068
  }
11066
11069
  .sd-model-selector-group-heading {
11070
+ display: flex;
11071
+ gap: 8px;
11072
+ align-items: center;
11073
+ box-sizing: border-box;
11074
+ width: 100%;
11067
11075
  padding: 6px 12px;
11068
11076
  color: var(--sd-color-text-3);
11069
11077
  font-weight: 500;
11070
11078
  font-size: 12px;
11079
+ text-align: left;
11080
+ background: none;
11081
+ border: 0;
11082
+ cursor: pointer;
11083
+ }
11084
+ .sd-model-selector-group-heading-text {
11085
+ flex: 1;
11086
+ min-width: 0;
11087
+ }
11088
+ .sd-model-selector-group-chevron {
11089
+ flex: none;
11090
+ transition: transform 180ms ease;
11091
+ }
11092
+ .sd-model-selector-group-chevron--expanded {
11093
+ transform: rotate(90deg);
11071
11094
  }
11072
11095
  .sd-model-selector-group-content {
11096
+ display: grid;
11097
+ grid-template-rows: 1fr;
11098
+ opacity: 1;
11099
+ transition: grid-template-rows 180ms ease, opacity 180ms ease;
11100
+ }
11101
+ .sd-model-selector-group-content--collapsed {
11102
+ grid-template-rows: 0fr;
11103
+ opacity: 0;
11104
+ }
11105
+ .sd-model-selector-group-content-inner {
11073
11106
  display: flex;
11074
11107
  flex-direction: column;
11075
11108
  gap: 2px;
11109
+ min-height: 0;
11110
+ overflow: hidden;
11111
+ }
11112
+ @media (prefers-reduced-motion: reduce) {
11113
+ .sd-model-selector-group-chevron, .sd-model-selector-group-content {
11114
+ transition: none;
11115
+ }
11076
11116
  }
11077
11117
  .sd-model-selector-item {
11078
11118
  display: flex;
package/es/index.d.ts CHANGED
@@ -47,7 +47,7 @@ export type { CommentInstance } from './comment';
47
47
  export { default as ColorPicker } from './color-picker';
48
48
  export type { ColorPickerInstance } from './color-picker';
49
49
  export { default as ConfigProvider } from './config-provider';
50
- export type { ConfigProviderInstance, SdThemeConfig, SdThemeMeta, SdThemeMode, ThemeTokenMap, ThemeTokenValue, } from './config-provider';
50
+ export type { ConfigProviderInstance, ConfigProviderTable, SdThemeConfig, SdThemeMeta, SdThemeMode, ThemeTokenMap, ThemeTokenValue, } from './config-provider';
51
51
  export { default as ThemeProvider } from './theme-provider';
52
52
  export { normalizeTheme, getThemeCSSVariables, normalizeTokenKey } from './config-provider/theme';
53
53
  export type { SdThemeSeed } from './config-provider/algorithms';
@@ -3,17 +3,20 @@ import type { ModelSelectorItemData } from './types';
3
3
  export interface ModelSelectorContext {
4
4
  activeDescendant: ComputedRef<string | undefined>;
5
5
  activeId: Ref<symbol | undefined>;
6
+ defaultExpanded: boolean;
6
7
  getVisibleItems: (groupId?: symbol) => ModelSelectorItemData[];
7
8
  itemsVersion: Ref<number>;
8
9
  listId: string;
9
10
  moveActive: (offset: number) => void;
10
11
  query: Ref<string>;
12
+ registerGroup: (id: symbol, expanded: Ref<boolean>) => void;
11
13
  registerItem: (item: ModelSelectorItemData) => void;
12
14
  selectActive: (event: Event) => void;
13
15
  selectItem: (item: ModelSelectorItemData, event: Event) => void;
14
16
  setActive: (id?: symbol) => void;
15
17
  setVisible: (visible: boolean) => void;
16
18
  unregisterItem: (id: symbol) => void;
19
+ unregisterGroup: (id: symbol) => void;
17
20
  updateItem: (item: ModelSelectorItemData) => void;
18
21
  visible: ComputedRef<boolean>;
19
22
  visibleItemCount: ComputedRef<number>;
@@ -17,6 +17,7 @@ import _ModelSelector from './model-selector.vue';
17
17
  declare const ModelSelector: {
18
18
  new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<Readonly<{
19
19
  defaultVisible?: boolean;
20
+ defaultExpanded?: boolean;
20
21
  closeOnSelect?: boolean;
21
22
  resetQueryOnClose?: boolean;
22
23
  } & {
@@ -38,6 +39,7 @@ declare const ModelSelector: {
38
39
  Defaults: {};
39
40
  }, Readonly<{
40
41
  defaultVisible?: boolean;
42
+ defaultExpanded?: boolean;
41
43
  closeOnSelect?: boolean;
42
44
  resetQueryOnClose?: boolean;
43
45
  } & {
@@ -52,6 +54,7 @@ declare const ModelSelector: {
52
54
  __isSuspense?: never;
53
55
  } & import("vue").ComponentOptionsBase<Readonly<{
54
56
  defaultVisible?: boolean;
57
+ defaultExpanded?: boolean;
55
58
  closeOnSelect?: boolean;
56
59
  resetQueryOnClose?: boolean;
57
60
  } & {
@@ -142,6 +145,7 @@ declare const ModelSelector: {
142
145
  Dialog: {
143
146
  new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<Readonly<{
144
147
  defaultVisible?: boolean;
148
+ defaultExpanded?: boolean;
145
149
  closeOnSelect?: boolean;
146
150
  resetQueryOnClose?: boolean;
147
151
  title?: string;
@@ -169,6 +173,7 @@ declare const ModelSelector: {
169
173
  Defaults: {};
170
174
  }, Readonly<{
171
175
  defaultVisible?: boolean;
176
+ defaultExpanded?: boolean;
172
177
  closeOnSelect?: boolean;
173
178
  resetQueryOnClose?: boolean;
174
179
  title?: string;
@@ -189,6 +194,7 @@ declare const ModelSelector: {
189
194
  __isSuspense?: never;
190
195
  } & import("vue").ComponentOptionsBase<Readonly<{
191
196
  defaultVisible?: boolean;
197
+ defaultExpanded?: boolean;
192
198
  closeOnSelect?: boolean;
193
199
  resetQueryOnClose?: boolean;
194
200
  title?: string;
@@ -1,5 +1,6 @@
1
1
  type __VLS_Props = {
2
2
  defaultVisible?: boolean;
3
+ defaultExpanded?: boolean;
3
4
  closeOnSelect?: boolean;
4
5
  resetQueryOnClose?: boolean;
5
6
  title?: string;
@@ -10,6 +10,10 @@ var model_selector_dialog_vue_vue_type_script_setup_true_lang_default = /*@__PUR
10
10
  type: Boolean,
11
11
  default: false
12
12
  },
13
+ defaultExpanded: {
14
+ type: Boolean,
15
+ default: true
16
+ },
13
17
  closeOnSelect: {
14
18
  type: Boolean,
15
19
  default: true
@@ -60,6 +64,7 @@ var model_selector_dialog_vue_vue_type_script_setup_true_lang_default = /*@__PUR
60
64
  return openBlock(), createBlock(model_selector_default, {
61
65
  visible: mergedVisible.value,
62
66
  "default-visible": __props.defaultVisible,
67
+ "default-expanded": __props.defaultExpanded,
63
68
  "close-on-select": __props.closeOnSelect,
64
69
  "reset-query-on-close": __props.resetQueryOnClose,
65
70
  "onUpdate:visible": handleVisibleUpdate,
@@ -88,6 +93,7 @@ var model_selector_dialog_vue_vue_type_script_setup_true_lang_default = /*@__PUR
88
93
  }, 8, [
89
94
  "visible",
90
95
  "default-visible",
96
+ "default-expanded",
91
97
  "close-on-select",
92
98
  "reset-query-on-close"
93
99
  ]);
@@ -1,11 +1,11 @@
1
1
  type __VLS_Props = {
2
2
  heading?: string;
3
3
  };
4
- declare var __VLS_1: {}, __VLS_3: {};
4
+ declare var __VLS_1: {}, __VLS_8: {};
5
5
  type __VLS_Slots = {} & {
6
6
  heading?: (props: typeof __VLS_1) => any;
7
7
  } & {
8
- default?: (props: typeof __VLS_3) => any;
8
+ default?: (props: typeof __VLS_8) => any;
9
9
  };
10
10
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
11
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -1,9 +1,12 @@
1
1
  import _objectSpread2 from "../_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/objectSpread2.js";
2
2
  import { getPrefixCls } from "../_utils/global-config.js";
3
+ import IconRight from "../icon/icon-right/index.js";
3
4
  import { modelSelectorGroupInjectionKey } from "./context.js";
4
5
  import { useModelSelectorContext } from "./use-model-selector-context.js";
5
- import { computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, getCurrentInstance, normalizeClass, openBlock, provide, renderSlot, toDisplayString, unref, vShow, withDirectives } from "vue";
6
+ import { computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, getCurrentInstance, normalizeClass, onBeforeUnmount, openBlock, provide, renderSlot, shallowRef, toDisplayString, unref, useSlots, vShow, watch, withDirectives } from "vue";
6
7
  //#region components/model-selector/model-selector-group.vue?vue&type=script&setup=true&lang.ts
8
+ var _hoisted_1 = ["aria-expanded"];
9
+ var _hoisted_2 = ["aria-hidden", "inert"];
7
10
  var model_selector_group_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent(_objectSpread2(_objectSpread2({}, { name: "ModelSelectorGroup" }), {}, {
8
11
  __name: "model-selector-group",
9
12
  props: { heading: {} },
@@ -11,20 +14,50 @@ var model_selector_group_vue_vue_type_script_setup_true_lang_default = /*@__PURE
11
14
  const context = useModelSelectorContext("ModelSelectorGroup");
12
15
  const prefixCls = getPrefixCls("model-selector-group");
13
16
  const uid = getCurrentInstance().uid;
17
+ const slots = useSlots();
14
18
  const id = Symbol(`model-selector-group-${uid}`);
15
19
  const headingId = `${context.listId}-group-${uid}`;
20
+ const contentId = `${headingId}-content`;
21
+ const expanded = shallowRef(__props.heading || slots.heading ? context.defaultExpanded : true);
22
+ const searchExpanded = shallowRef();
23
+ const isSearching = computed(() => context.query.value.trim().length > 0);
24
+ const isExpanded = computed(() => {
25
+ var _searchExpanded$value;
26
+ return isSearching.value ? (_searchExpanded$value = searchExpanded.value) !== null && _searchExpanded$value !== void 0 ? _searchExpanded$value : true : expanded.value;
27
+ });
16
28
  const hasVisibleItems = computed(() => context.getVisibleItems(id).length > 0);
29
+ function toggleExpanded() {
30
+ if (isSearching.value) searchExpanded.value = !isExpanded.value;
31
+ else expanded.value = !expanded.value;
32
+ }
33
+ watch(() => context.query.value.trim(), () => {
34
+ searchExpanded.value = void 0;
35
+ }, { flush: "sync" });
36
+ context.registerGroup(id, isExpanded);
37
+ onBeforeUnmount(() => context.unregisterGroup(id));
17
38
  provide(modelSelectorGroupInjectionKey, { id });
18
39
  return (_ctx, _cache) => {
19
40
  return withDirectives((openBlock(), createElementBlock("section", {
20
41
  class: normalizeClass(unref(prefixCls)),
21
42
  role: "group",
22
43
  "aria-labelledby": headingId
23
- }, [__props.heading || _ctx.$slots.heading ? (openBlock(), createElementBlock("div", {
44
+ }, [__props.heading || _ctx.$slots.heading ? (openBlock(), createElementBlock("button", {
24
45
  key: 0,
25
46
  id: headingId,
26
- class: normalizeClass(`${unref(prefixCls)}-heading`)
27
- }, [renderSlot(_ctx.$slots, "heading", {}, () => [createTextVNode(toDisplayString(__props.heading), 1)])], 2)) : createCommentVNode("", true), createElementVNode("div", { class: normalizeClass(`${unref(prefixCls)}-content`) }, [renderSlot(_ctx.$slots, "default")], 2)], 2)), [[vShow, hasVisibleItems.value]]);
47
+ type: "button",
48
+ class: normalizeClass(`${unref(prefixCls)}-heading`),
49
+ "aria-controls": contentId,
50
+ "aria-expanded": isExpanded.value,
51
+ onClick: toggleExpanded
52
+ }, [createElementVNode("span", { class: normalizeClass(`${unref(prefixCls)}-heading-text`) }, [renderSlot(_ctx.$slots, "heading", {}, () => [createTextVNode(toDisplayString(__props.heading), 1)])], 2), createVNode(unref(IconRight), {
53
+ class: normalizeClass([`${unref(prefixCls)}-chevron`, { [`${unref(prefixCls)}-chevron--expanded`]: isExpanded.value }]),
54
+ "aria-hidden": "true"
55
+ }, null, 8, ["class"])], 10, _hoisted_1)) : createCommentVNode("", true), createElementVNode("div", {
56
+ id: contentId,
57
+ class: normalizeClass([`${unref(prefixCls)}-content`, { [`${unref(prefixCls)}-content--collapsed`]: !isExpanded.value }]),
58
+ "aria-hidden": !isExpanded.value,
59
+ inert: !isExpanded.value
60
+ }, [createElementVNode("div", { class: normalizeClass(`${unref(prefixCls)}-content-inner`) }, [renderSlot(_ctx.$slots, "default")], 2)], 10, _hoisted_2)], 2)), [[vShow, hasVisibleItems.value]]);
28
61
  };
29
62
  }
30
63
  }));
@@ -1,5 +1,6 @@
1
1
  type __VLS_Props = {
2
2
  defaultVisible?: boolean;
3
+ defaultExpanded?: boolean;
3
4
  closeOnSelect?: boolean;
4
5
  resetQueryOnClose?: boolean;
5
6
  };
@@ -10,6 +10,10 @@ var model_selector_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
10
10
  type: Boolean,
11
11
  default: false
12
12
  },
13
+ defaultExpanded: {
14
+ type: Boolean,
15
+ default: true
16
+ },
13
17
  closeOnSelect: {
14
18
  type: Boolean,
15
19
  default: true
@@ -74,6 +78,7 @@ var model_selector_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
74
78
  const activeId = shallowRef();
75
79
  const itemsVersion = shallowRef(0);
76
80
  const items = /* @__PURE__ */ new Map();
81
+ const groups = /* @__PURE__ */ new Map();
77
82
  const listId = `sd-model-selector-list-${instance.uid}`;
78
83
  const normalizedQuery = computed(() => query.value.trim().toLocaleLowerCase());
79
84
  function isItemVisible(item) {
@@ -90,6 +95,10 @@ var model_selector_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
90
95
  return [...items.values()].filter((item) => (groupId === void 0 || item.groupId === groupId) && isItemVisible(item));
91
96
  }
92
97
  const visibleItems = computed(() => getVisibleItems());
98
+ const navigableItems = computed(() => visibleItems.value.filter((item) => {
99
+ var _groups$get;
100
+ return !item.groupId || ((_groups$get = groups.get(item.groupId)) === null || _groups$get === void 0 ? void 0 : _groups$get.value) !== false;
101
+ }));
93
102
  const visibleItemCount = computed(() => visibleItems.value.length);
94
103
  const activeDescendant = computed(() => {
95
104
  var _items$get;
@@ -99,7 +108,7 @@ var model_selector_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
99
108
  passive: false,
100
109
  onEventFired(event) {
101
110
  if (event.type !== "keydown" || event.repeat || !mergedVisible.value) return;
102
- const item = visibleItems.value.find(({ disabled, shortcut }) => !disabled && shortcut && isShortcutPressed(shortcut, event, magicKeys.current));
111
+ const item = navigableItems.value.find(({ disabled, shortcut }) => !disabled && shortcut && isShortcutPressed(shortcut, event, magicKeys.current));
103
112
  if (!item) return;
104
113
  event.preventDefault();
105
114
  event.stopPropagation();
@@ -116,6 +125,12 @@ var model_selector_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
116
125
  items.set(item.id, item);
117
126
  itemsVersion.value += 1;
118
127
  }
128
+ function registerGroup(id, expanded) {
129
+ groups.set(id, expanded);
130
+ }
131
+ function unregisterGroup(id) {
132
+ groups.delete(id);
133
+ }
119
134
  function updateItem(item) {
120
135
  items.set(item.id, item);
121
136
  itemsVersion.value += 1;
@@ -130,7 +145,7 @@ var model_selector_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
130
145
  }
131
146
  function moveActive(offset) {
132
147
  var _nextItem$element;
133
- const enabledItems = visibleItems.value.filter((item) => !item.disabled);
148
+ const enabledItems = navigableItems.value.filter((item) => !item.disabled);
134
149
  if (!enabledItems.length) {
135
150
  activeId.value = void 0;
136
151
  return;
@@ -147,12 +162,18 @@ var model_selector_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
147
162
  }
148
163
  function selectActive(event) {
149
164
  if (!activeId.value) return;
150
- const item = items.get(activeId.value);
165
+ const item = navigableItems.value.find((item) => item.id === activeId.value);
151
166
  if (item) selectItem(item, event);
152
167
  }
153
168
  watch(query, () => {
154
- var _visibleItems$value$f;
155
- activeId.value = (_visibleItems$value$f = visibleItems.value.find((item) => !item.disabled)) === null || _visibleItems$value$f === void 0 ? void 0 : _visibleItems$value$f.id;
169
+ var _navigableItems$value;
170
+ activeId.value = (_navigableItems$value = navigableItems.value.find((item) => !item.disabled)) === null || _navigableItems$value === void 0 ? void 0 : _navigableItems$value.id;
171
+ });
172
+ watch(navigableItems, (availableItems) => {
173
+ if (activeId.value && !availableItems.some((item) => item.id === activeId.value)) {
174
+ var _availableItems$find;
175
+ activeId.value = (_availableItems$find = availableItems.find((item) => !item.disabled)) === null || _availableItems$find === void 0 ? void 0 : _availableItems$find.id;
176
+ }
156
177
  });
157
178
  watch(mergedVisible, (visible) => {
158
179
  if (!visible && __props.resetQueryOnClose) {
@@ -163,17 +184,20 @@ var model_selector_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
163
184
  provide(modelSelectorInjectionKey, {
164
185
  activeDescendant,
165
186
  activeId,
187
+ defaultExpanded: __props.defaultExpanded,
166
188
  getVisibleItems,
167
189
  itemsVersion,
168
190
  listId,
169
191
  moveActive,
170
192
  query,
193
+ registerGroup,
171
194
  registerItem,
172
195
  selectActive,
173
196
  selectItem,
174
197
  setActive,
175
198
  setVisible,
176
199
  unregisterItem,
200
+ unregisterGroup,
177
201
  updateItem,
178
202
  visible: mergedVisible,
179
203
  visibleItemCount
@@ -67,15 +67,52 @@
67
67
  margin-top: 6px;
68
68
  }
69
69
  .sd-model-selector-group-heading {
70
+ display: flex;
71
+ gap: 8px;
72
+ align-items: center;
73
+ box-sizing: border-box;
74
+ width: 100%;
70
75
  padding: 6px 12px;
71
76
  color: var(--sd-color-text-3);
72
77
  font-weight: 500;
73
78
  font-size: 12px;
79
+ text-align: left;
80
+ background: none;
81
+ border: 0;
82
+ cursor: pointer;
83
+ }
84
+ .sd-model-selector-group-heading-text {
85
+ flex: 1;
86
+ min-width: 0;
87
+ }
88
+ .sd-model-selector-group-chevron {
89
+ flex: none;
90
+ transition: transform 180ms ease;
91
+ }
92
+ .sd-model-selector-group-chevron--expanded {
93
+ transform: rotate(90deg);
74
94
  }
75
95
  .sd-model-selector-group-content {
96
+ display: grid;
97
+ grid-template-rows: 1fr;
98
+ opacity: 1;
99
+ transition: grid-template-rows 180ms ease, opacity 180ms ease;
100
+ }
101
+ .sd-model-selector-group-content--collapsed {
102
+ grid-template-rows: 0fr;
103
+ opacity: 0;
104
+ }
105
+ .sd-model-selector-group-content-inner {
76
106
  display: flex;
77
107
  flex-direction: column;
78
108
  gap: 2px;
109
+ min-height: 0;
110
+ overflow: hidden;
111
+ }
112
+ @media (prefers-reduced-motion: reduce) {
113
+ .sd-model-selector-group-chevron, .sd-model-selector-group-content {
114
+ transition: none;
115
+ }
79
116
  }
80
117
  .sd-model-selector-item {
81
118
  display: flex;
@@ -66,16 +66,62 @@ $model-selector-prefix-cls: string.unquote('#{theme.$prefix}-model-selector');
66
66
  }
67
67
 
68
68
  &-heading {
69
+ display: flex;
70
+ gap: $model-selector-gap;
71
+ align-items: center;
72
+ box-sizing: border-box;
73
+ width: 100%;
69
74
  padding: $model-selector-padding $model-selector-padding-horizontal;
70
75
  color: $model-selector-color-text-secondary;
71
76
  font-weight: theme.$font-weight-500;
72
77
  font-size: $model-selector-font-size-secondary;
78
+ text-align: left;
79
+ background: none;
80
+ border: 0;
81
+ cursor: pointer;
82
+
83
+ &-text {
84
+ flex: 1;
85
+ min-width: 0;
86
+ }
87
+ }
88
+
89
+ &-chevron {
90
+ flex: none;
91
+ transition: transform 180ms ease;
92
+
93
+ &--expanded {
94
+ transform: rotate(90deg);
95
+ }
73
96
  }
74
97
 
75
98
  &-content {
76
- display: flex;
77
- flex-direction: column;
78
- gap: theme.$spacing-1;
99
+ display: grid;
100
+ grid-template-rows: 1fr;
101
+ opacity: 1;
102
+ transition:
103
+ grid-template-rows 180ms ease,
104
+ opacity 180ms ease;
105
+
106
+ &--collapsed {
107
+ grid-template-rows: 0fr;
108
+ opacity: 0;
109
+ }
110
+
111
+ &-inner {
112
+ display: flex;
113
+ flex-direction: column;
114
+ gap: theme.$spacing-1;
115
+ min-height: 0;
116
+ overflow: hidden;
117
+ }
118
+ }
119
+
120
+ @media (prefers-reduced-motion: reduce) {
121
+ &-chevron,
122
+ &-content {
123
+ transition: none;
124
+ }
79
125
  }
80
126
  }
81
127