vueless 1.4.12-beta.17 → 1.4.12-beta.18

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.
package/README.md CHANGED
@@ -14,7 +14,7 @@ A UI library with Open Architecture for Vue.js 3 and Nuxt.js 3 / 4, powered by [
14
14
 
15
15
  ### Key features
16
16
 
17
- - 🧩 65+ crafted UI components (including range date picker, multi-select, and nested table)
17
+ - 🧩 74 crafted UI components (including range date picker, multi-select, and nested table)
18
18
  - ✨ Open Architecture lets you customize, copy, extend, and create your own components
19
19
  - 📕 Built-in Storybook support
20
20
  - 🪩 Theme Builder for runtime theme customization
package/index.d.ts CHANGED
@@ -108,6 +108,108 @@ export type {
108
108
  LocaleInstance,
109
109
  LocaleMessages,
110
110
  } from "./types";
111
+ /* component props */
112
+ export type { Props as UAccordionProps } from "./ui.container-accordion/types";
113
+ export type { Props as UAccordionItemProps } from "./ui.container-accordion-item/types";
114
+ export type { Props as UAlertProps } from "./ui.text-alert/types";
115
+ export type { Props as UAvatarProps } from "./ui.image-avatar/types";
116
+ export type { Props as UAvatarGroupProps } from "./ui.image-avatar-group/types";
117
+ export type { Props as UBadgeProps } from "./ui.text-badge/types";
118
+ export type { Props as UBoilerplateProps } from "./ui.boilerplate/types";
119
+ export type { Props as UBreadcrumbsProps } from "./ui.navigation-breadcrumbs/types";
120
+ export type { Props as UButtonProps } from "./ui.button/types";
121
+ export type { Props as UCalendarProps } from "./ui.form-calendar/types";
122
+ export type { Props as UCardProps } from "./ui.container-card/types";
123
+ export type { Props as UCheckboxProps } from "./ui.form-checkbox/types";
124
+ export type { Props as UCheckboxGroupProps } from "./ui.form-checkbox-group/types";
125
+ export type { Props as UCheckboxMultiStateProps } from "./ui.form-checkbox-multi-state/types";
126
+ export type { Props as UChipProps } from "./ui.other-chip/types";
127
+ export type { Props as UColProps } from "./ui.container-col/types";
128
+ export type { Props as UCollapsibleProps } from "./ui.container-collapsible/types";
129
+ export type { Props as UColorToggleProps } from "./ui.form-color-toggle/types";
130
+ export type { Props as UDataListProps } from "./ui.data-list/types";
131
+ export type { Props as UDatePickerProps } from "./ui.form-date-picker/types";
132
+ export type { Props as UDatePickerRangeProps } from "./ui.form-date-picker-range/types";
133
+ export type { Props as UDividerProps } from "./ui.container-divider/types";
134
+ export type { Props as UDotProps } from "./ui.other-dot/types";
135
+ export type { Props as UDrawerProps } from "./ui.container-drawer/types";
136
+ export type { Props as UDropdownProps } from "./ui.dropdown/types";
137
+ export type { Props as UDropdownBadgeProps } from "./ui.dropdown-badge/types";
138
+ export type { Props as UDropdownButtonProps } from "./ui.dropdown-button/types";
139
+ export type { Props as UDropdownLinkProps } from "./ui.dropdown-link/types";
140
+ export type { Props as UEmptyProps } from "./ui.container-empty/types";
141
+ export type { Props as UFileProps } from "./ui.text-file/types";
142
+ export type { Props as UFilesProps } from "./ui.text-files/types";
143
+ export type { Props as UGridProps } from "./ui.container-grid/types";
144
+ export type { Props as UGroupProps } from "./ui.container-group/types";
145
+ export type { Props as UGroupsProps } from "./ui.container-groups/types";
146
+ export type { Props as UHeaderProps } from "./ui.text-header/types";
147
+ export type { Props as UIconProps } from "./ui.image-icon/types";
148
+ export type { Props as UInputProps } from "./ui.form-input/types";
149
+ export type { Props as UInputCounterProps } from "./ui.form-input-counter/types";
150
+ export type { Props as UInputFileProps } from "./ui.form-input-file/types";
151
+ export type { Props as UInputNumberProps } from "./ui.form-input-number/types";
152
+ export type { Props as UInputPasswordProps } from "./ui.form-input-password/types";
153
+ export type { Props as UInputRatingProps } from "./ui.form-input-rating/types";
154
+ export type { Props as UInputSearchProps } from "./ui.form-input-search/types";
155
+ export type { Props as UKeyProps } from "./ui.text-key/types";
156
+ export type { Props as ULabelProps } from "./ui.form-label/types";
157
+ export type { Props as ULinkProps } from "./ui.button-link/types";
158
+ export type { Props as UListboxProps } from "./ui.form-listbox/types";
159
+ export type { Props as ULoaderProps } from "./ui.loader/types";
160
+ export type { Props as ULoaderOverlayProps } from "./ui.loader-overlay/types";
161
+ export type { Props as ULoaderProgressProps } from "./ui.loader-progress/types";
162
+ export type { Props as UModalProps } from "./ui.container-modal/types";
163
+ export type { Props as UModalConfirmProps } from "./ui.container-modal-confirm/types";
164
+ export type { Props as UNotifyProps } from "./ui.text-notify/types";
165
+ export type { Props as UNumberProps } from "./ui.text-number/types";
166
+ export type { Props as UPageProps } from "./ui.container-page/types";
167
+ export type { Props as UPaginationProps } from "./ui.navigation-pagination/types";
168
+ export type { Props as UPlaceholderProps } from "./ui.container-placeholder/types";
169
+ export type { Props as UProgressProps } from "./ui.navigation-progress/types";
170
+ export type { Props as URadioProps } from "./ui.form-radio/types";
171
+ export type { Props as URadioGroupProps } from "./ui.form-radio-group/types";
172
+ export type { Props as URowProps } from "./ui.container-row/types";
173
+ export type { Props as USelectProps } from "./ui.form-select/types";
174
+ export type { Props as USkeletonProps } from "./ui.skeleton/types";
175
+ export type { Props as USkeletonChoiceProps } from "./ui.skeleton-choice/types";
176
+ export type { Props as USkeletonInputProps } from "./ui.skeleton-input/types";
177
+ export type { Props as USkeletonTextProps } from "./ui.skeleton-text/types";
178
+ export type { Props as USplitterProps } from "./ui.container-splitter/types";
179
+ export type { Props as USwitchProps } from "./ui.form-switch/types";
180
+ export type { Props as UTabProps } from "./ui.navigation-tab/types";
181
+ export type { Props as UTableProps } from "./ui.data-table/types";
182
+ export type { Props as UTabsProps } from "./ui.navigation-tabs/types";
183
+ export type { Props as UTextProps } from "./ui.text-block/types";
184
+ export type { Props as UTextareaProps } from "./ui.form-textarea/types";
185
+ export type { Props as UThemeColorToggleProps } from "./ui.other-theme-color-toggle/types";
186
+ export type { Props as UToggleProps } from "./ui.button-toggle/types";
187
+ /* component data types */
188
+ export type {
189
+ Row,
190
+ BaseRow,
191
+ TableRow,
192
+ FlatRow,
193
+ RowId,
194
+ RowData,
195
+ Cell,
196
+ CellObject,
197
+ Column,
198
+ ColumnObject,
199
+ TableColumn,
200
+ DateDivider,
201
+ BaseDateDivider,
202
+ } from "./ui.data-table/types";
203
+ export type { Option, BaseOption, ListboxOption, SelectedValue } from "./ui.form-listbox/types";
204
+ export type { SelectOption } from "./ui.form-select/types";
205
+ export type { UTabsOption, BaseTabOption } from "./ui.navigation-tabs/types";
206
+ export type { UBreadcrumb, BaseBreadcrumb } from "./ui.navigation-breadcrumbs/types";
207
+ export type { UToggleOption, BaseToggleOption } from "./ui.button-toggle/types";
208
+ export type { UAccordionOption, BaseAccordionOption } from "./ui.container-accordion/types";
209
+ export type { DataListItem, BaseDataListItem } from "./ui.data-list/types";
210
+ export type { UCheckboxOption, BaseCheckboxOption } from "./ui.form-checkbox/types";
211
+ export type { ChipItem, BaseChipItem } from "./ui.image-avatar/types";
212
+ export type { AvatarItem, BaseAvatarItem } from "./ui.image-avatar-group/types";
111
213
  /* Export enums directly (not as types) */
112
214
  export { ColorMode } from "./types";
113
215
 
package/index.ts CHANGED
@@ -114,6 +114,108 @@ export type {
114
114
  LocaleInstance,
115
115
  LocaleMessages,
116
116
  } from "./types";
117
+ /* component props */
118
+ export type { Props as UAccordionProps } from "./ui.container-accordion/types";
119
+ export type { Props as UAccordionItemProps } from "./ui.container-accordion-item/types";
120
+ export type { Props as UAlertProps } from "./ui.text-alert/types";
121
+ export type { Props as UAvatarProps } from "./ui.image-avatar/types";
122
+ export type { Props as UAvatarGroupProps } from "./ui.image-avatar-group/types";
123
+ export type { Props as UBadgeProps } from "./ui.text-badge/types";
124
+ export type { Props as UBoilerplateProps } from "./ui.boilerplate/types";
125
+ export type { Props as UBreadcrumbsProps } from "./ui.navigation-breadcrumbs/types";
126
+ export type { Props as UButtonProps } from "./ui.button/types";
127
+ export type { Props as UCalendarProps } from "./ui.form-calendar/types";
128
+ export type { Props as UCardProps } from "./ui.container-card/types";
129
+ export type { Props as UCheckboxProps } from "./ui.form-checkbox/types";
130
+ export type { Props as UCheckboxGroupProps } from "./ui.form-checkbox-group/types";
131
+ export type { Props as UCheckboxMultiStateProps } from "./ui.form-checkbox-multi-state/types";
132
+ export type { Props as UChipProps } from "./ui.other-chip/types";
133
+ export type { Props as UColProps } from "./ui.container-col/types";
134
+ export type { Props as UCollapsibleProps } from "./ui.container-collapsible/types";
135
+ export type { Props as UColorToggleProps } from "./ui.form-color-toggle/types";
136
+ export type { Props as UDataListProps } from "./ui.data-list/types";
137
+ export type { Props as UDatePickerProps } from "./ui.form-date-picker/types";
138
+ export type { Props as UDatePickerRangeProps } from "./ui.form-date-picker-range/types";
139
+ export type { Props as UDividerProps } from "./ui.container-divider/types";
140
+ export type { Props as UDotProps } from "./ui.other-dot/types";
141
+ export type { Props as UDrawerProps } from "./ui.container-drawer/types";
142
+ export type { Props as UDropdownProps } from "./ui.dropdown/types";
143
+ export type { Props as UDropdownBadgeProps } from "./ui.dropdown-badge/types";
144
+ export type { Props as UDropdownButtonProps } from "./ui.dropdown-button/types";
145
+ export type { Props as UDropdownLinkProps } from "./ui.dropdown-link/types";
146
+ export type { Props as UEmptyProps } from "./ui.container-empty/types";
147
+ export type { Props as UFileProps } from "./ui.text-file/types";
148
+ export type { Props as UFilesProps } from "./ui.text-files/types";
149
+ export type { Props as UGridProps } from "./ui.container-grid/types";
150
+ export type { Props as UGroupProps } from "./ui.container-group/types";
151
+ export type { Props as UGroupsProps } from "./ui.container-groups/types";
152
+ export type { Props as UHeaderProps } from "./ui.text-header/types";
153
+ export type { Props as UIconProps } from "./ui.image-icon/types";
154
+ export type { Props as UInputProps } from "./ui.form-input/types";
155
+ export type { Props as UInputCounterProps } from "./ui.form-input-counter/types";
156
+ export type { Props as UInputFileProps } from "./ui.form-input-file/types";
157
+ export type { Props as UInputNumberProps } from "./ui.form-input-number/types";
158
+ export type { Props as UInputPasswordProps } from "./ui.form-input-password/types";
159
+ export type { Props as UInputRatingProps } from "./ui.form-input-rating/types";
160
+ export type { Props as UInputSearchProps } from "./ui.form-input-search/types";
161
+ export type { Props as UKeyProps } from "./ui.text-key/types";
162
+ export type { Props as ULabelProps } from "./ui.form-label/types";
163
+ export type { Props as ULinkProps } from "./ui.button-link/types";
164
+ export type { Props as UListboxProps } from "./ui.form-listbox/types";
165
+ export type { Props as ULoaderProps } from "./ui.loader/types";
166
+ export type { Props as ULoaderOverlayProps } from "./ui.loader-overlay/types";
167
+ export type { Props as ULoaderProgressProps } from "./ui.loader-progress/types";
168
+ export type { Props as UModalProps } from "./ui.container-modal/types";
169
+ export type { Props as UModalConfirmProps } from "./ui.container-modal-confirm/types";
170
+ export type { Props as UNotifyProps } from "./ui.text-notify/types";
171
+ export type { Props as UNumberProps } from "./ui.text-number/types";
172
+ export type { Props as UPageProps } from "./ui.container-page/types";
173
+ export type { Props as UPaginationProps } from "./ui.navigation-pagination/types";
174
+ export type { Props as UPlaceholderProps } from "./ui.container-placeholder/types";
175
+ export type { Props as UProgressProps } from "./ui.navigation-progress/types";
176
+ export type { Props as URadioProps } from "./ui.form-radio/types";
177
+ export type { Props as URadioGroupProps } from "./ui.form-radio-group/types";
178
+ export type { Props as URowProps } from "./ui.container-row/types";
179
+ export type { Props as USelectProps } from "./ui.form-select/types";
180
+ export type { Props as USkeletonProps } from "./ui.skeleton/types";
181
+ export type { Props as USkeletonChoiceProps } from "./ui.skeleton-choice/types";
182
+ export type { Props as USkeletonInputProps } from "./ui.skeleton-input/types";
183
+ export type { Props as USkeletonTextProps } from "./ui.skeleton-text/types";
184
+ export type { Props as USplitterProps } from "./ui.container-splitter/types";
185
+ export type { Props as USwitchProps } from "./ui.form-switch/types";
186
+ export type { Props as UTabProps } from "./ui.navigation-tab/types";
187
+ export type { Props as UTableProps } from "./ui.data-table/types";
188
+ export type { Props as UTabsProps } from "./ui.navigation-tabs/types";
189
+ export type { Props as UTextProps } from "./ui.text-block/types";
190
+ export type { Props as UTextareaProps } from "./ui.form-textarea/types";
191
+ export type { Props as UThemeColorToggleProps } from "./ui.other-theme-color-toggle/types";
192
+ export type { Props as UToggleProps } from "./ui.button-toggle/types";
193
+ /* component data types */
194
+ export type {
195
+ Row,
196
+ BaseRow,
197
+ TableRow,
198
+ FlatRow,
199
+ RowId,
200
+ RowData,
201
+ Cell,
202
+ CellObject,
203
+ Column,
204
+ ColumnObject,
205
+ TableColumn,
206
+ DateDivider,
207
+ BaseDateDivider,
208
+ } from "./ui.data-table/types";
209
+ export type { Option, BaseOption, ListboxOption, SelectedValue } from "./ui.form-listbox/types";
210
+ export type { SelectOption } from "./ui.form-select/types";
211
+ export type { UTabsOption, BaseTabOption } from "./ui.navigation-tabs/types";
212
+ export type { UBreadcrumb, BaseBreadcrumb } from "./ui.navigation-breadcrumbs/types";
213
+ export type { UToggleOption, BaseToggleOption } from "./ui.button-toggle/types";
214
+ export type { UAccordionOption, BaseAccordionOption } from "./ui.container-accordion/types";
215
+ export type { DataListItem, BaseDataListItem } from "./ui.data-list/types";
216
+ export type { UCheckboxOption, BaseCheckboxOption } from "./ui.form-checkbox/types";
217
+ export type { ChipItem, BaseChipItem } from "./ui.image-avatar/types";
218
+ export type { AvatarItem, BaseAvatarItem } from "./ui.image-avatar-group/types";
117
219
  /* Export enums directly (not as types) */
118
220
  export { ColorMode } from "./types";
119
221
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "1.4.12-beta.17",
3
+ "version": "1.4.12-beta.18",
4
4
  "description": "Vue Styleless UI Component Library, powered by Tailwind CSS.",
5
5
  "author": "Johnny Grid <hello@vueless.com> (https://vueless.com)",
6
6
  "homepage": "https://vueless.com",
@@ -1,20 +1,22 @@
1
1
  import defaultConfig from "./config";
2
2
 
3
- import type { ComponentConfig } from "../types";
3
+ import type { ComponentConfig, UnknownObject } from "../types";
4
4
 
5
5
  export type Config = typeof defaultConfig;
6
6
 
7
- export interface UToggleOption {
7
+ export interface BaseToggleOption {
8
8
  value: string | number | boolean;
9
9
  label?: string;
10
10
  disabled?: boolean;
11
11
  icon?: string;
12
12
  leftIcon?: string;
13
13
  rightIcon?: string;
14
- onClick?: (option: Omit<UToggleOption, "onClick">) => void;
15
- [key: string]: unknown;
14
+ onClick?: (option: Omit<BaseToggleOption, "onClick">) => void;
16
15
  }
17
16
 
17
+ /* Any object shape is a valid option, only reserved option keys are type checked. */
18
+ export type UToggleOption = BaseToggleOption & (object | UnknownObject);
19
+
18
20
  export interface Props {
19
21
  /**
20
22
  * Selected value.
@@ -1,15 +1,18 @@
1
1
  import defaultConfig from "./config";
2
- import type { ComponentConfig } from "../types";
2
+ import type { ComponentConfig, UnknownObject } from "../types";
3
3
 
4
4
  export type Config = typeof defaultConfig;
5
5
 
6
- export interface UAccordionOption {
6
+ export interface BaseAccordionOption {
7
7
  value: string;
8
8
  title: string;
9
9
  description?: string;
10
10
  opened?: boolean;
11
11
  }
12
12
 
13
+ /* Any object shape is a valid option, only reserved option keys are type checked. */
14
+ export type UAccordionOption = BaseAccordionOption & (object | UnknownObject);
15
+
13
16
  export type SetAccordionSelectedItem = (value: string, opened: boolean) => void;
14
17
 
15
18
  export interface Props {
@@ -13,6 +13,7 @@ import { COMPONENT_NAME } from "./constants";
13
13
  import defaultConfig from "./config";
14
14
  import { useComponentLocaleMessages } from "../composables/useComponentLocaleMassages";
15
15
 
16
+ import type { UnknownObject } from "../types";
16
17
  import type { Props, DataListItem, Config } from "./types";
17
18
 
18
19
  defineOptions({ inheritAttrs: false });
@@ -43,7 +44,9 @@ function isCrossed(element: DataListItem) {
43
44
  }
44
45
 
45
46
  function hasNestedList(element: DataListItem) {
46
- return Boolean(element.children?.length || (props.nestedKey && element[props.nestedKey]));
47
+ return Boolean(
48
+ element.children?.length || (props.nestedKey && (element as UnknownObject)[props.nestedKey]),
49
+ );
47
50
  }
48
51
 
49
52
  function onDragEnd() {
@@ -61,7 +64,7 @@ function prepareSortData(list: DataListItem[] = [], parentValue: string | number
61
64
  if (hasItemChildren) {
62
65
  const childrenItem = prepareSortData(
63
66
  item.children,
64
- item[props.valueKey] as string | number | null,
67
+ (item as UnknownObject)[props.valueKey] as string | number | null,
65
68
  );
66
69
 
67
70
  childrenItem.forEach((item) => sortData.push(item));
@@ -9,7 +9,7 @@ import draggable from "vuedraggable";
9
9
  import type { Props, DataListItem } from "../types";
10
10
 
11
11
  describe("UDataList.vue", () => {
12
- const defaultList: DataListItem[] = [
12
+ const defaultList = [
13
13
  { value: 1, label: "Item 1" },
14
14
  { value: 2, label: "Item 2", crossed: true },
15
15
  { value: 3, label: "Item 3", actions: false },
@@ -280,7 +280,7 @@ describe("UDataList.vue", () => {
280
280
  });
281
281
 
282
282
  it("Nesting – emits dragged item with parentValue of the leaf after drop into empty drop-zone", async () => {
283
- const leaf: DataListItem = { value: 1, label: "Leaf", canNest: true, children: [] };
283
+ const leaf = { value: 1, label: "Leaf", canNest: true, children: [] as DataListItem[] };
284
284
  const list: DataListItem[] = [leaf, { value: 2, label: "Dragged", canNest: true }];
285
285
 
286
286
  const component = mount(UDataList, {
@@ -293,7 +293,10 @@ describe("UDataList.vue", () => {
293
293
 
294
294
  await component.findComponent(draggable).vm.$emit("end");
295
295
 
296
- const sortData = component.emitted("dragSort")?.[0]?.[0] as DataListItem[];
296
+ const sortData = component.emitted("dragSort")?.[0]?.[0] as {
297
+ value: number;
298
+ parentValue: unknown;
299
+ }[];
297
300
  const dragged = sortData.find((item) => item.value === 2);
298
301
 
299
302
  expect(dragged?.parentValue).toBe(leaf.value);
@@ -2,7 +2,7 @@ import defaultConfig from "./config";
2
2
 
3
3
  import DraggableContext from "vuedraggable";
4
4
 
5
- import type { ComponentConfig, UnknownType } from "../types";
5
+ import type { ComponentConfig, UnknownObject } from "../types";
6
6
 
7
7
  export type Config = typeof defaultConfig;
8
8
 
@@ -11,13 +11,15 @@ export interface DragMoveEvent extends DragEvent {
11
11
  relatedContext: typeof DraggableContext | null;
12
12
  }
13
13
 
14
- export interface DataListItem {
14
+ export interface BaseDataListItem {
15
15
  crossed?: boolean;
16
16
  actions?: boolean;
17
17
  children?: DataListItem[];
18
- [key: string]: UnknownType | DataListItem[];
19
18
  }
20
19
 
20
+ /* Any object shape is a valid item, only reserved item keys are type checked. */
21
+ export type DataListItem = BaseDataListItem & (object | UnknownObject);
22
+
21
23
  export interface Props {
22
24
  /**
23
25
  * Data item options.
@@ -212,7 +212,7 @@ const tableRowWidthStyle = computed(() => ({
212
212
  width: `${tableWidth.value / PX_IN_REM}rem`,
213
213
  }));
214
214
 
215
- const flatTableRows = computed(() => getFlatRows(props.rows));
215
+ const flatTableRows = computed(() => getFlatRows(props.rows as Row[]));
216
216
 
217
217
  const visibleFlatRows = computed(() => {
218
218
  const expanded = expandedRowsSet.value;
@@ -532,7 +532,7 @@ onBeforeUnmount(() => {
532
532
 
533
533
  function onChangeSelectedRows() {
534
534
  if (!isEqual(props.selectedRows, localSelectedRows.value)) {
535
- localSelectedRows.value = props.selectedRows;
535
+ localSelectedRows.value = props.selectedRows as Row[];
536
536
  }
537
537
  }
538
538
 
@@ -25,20 +25,30 @@ export interface RowData {
25
25
  [key: string]: Cell;
26
26
  }
27
27
 
28
- export interface DateDivider {
28
+ export interface BaseDateDivider {
29
29
  date: Date | string;
30
30
  label?: string;
31
31
  config?: ComponentConfig<UDividerConfig>;
32
32
  }
33
33
 
34
- export interface Row {
34
+ /* Any object shape is a valid divider, only reserved divider keys are type checked. */
35
+ export type DateDivider = BaseDateDivider & (object | UnknownObject);
36
+
37
+ export interface BaseRow {
35
38
  id: RowId;
36
39
  rowDate?: string | Date;
37
- row?: Row | Row[];
40
+ row?: TableRow | TableRow[];
38
41
  class?: string | ((row: Row) => string);
42
+ }
43
+
44
+ export interface Row extends BaseRow {
45
+ row?: Row | Row[];
39
46
  [key: string]: unknown;
40
47
  }
41
48
 
49
+ /* Any object shape is a valid row, only reserved row keys are type checked. */
50
+ export type TableRow = BaseRow & (object | UnknownObject);
51
+
42
52
  export interface FlatRow extends Row {
43
53
  parentRowId?: RowId;
44
54
  nestedLevel: number;
@@ -58,7 +68,10 @@ export interface ColumnObject {
58
68
  thClass?: string;
59
69
  }
60
70
 
61
- export type Column = ColumnObject | string;
71
+ /* Any object shape is a valid column, only reserved column keys are type checked. */
72
+ export type TableColumn = ColumnObject & (object | UnknownObject);
73
+
74
+ export type Column = TableColumn | string;
62
75
 
63
76
  export interface Props {
64
77
  /**
@@ -69,12 +82,12 @@ export interface Props {
69
82
  /**
70
83
  * Table rows data.
71
84
  */
72
- rows: Row[];
85
+ rows: TableRow[];
73
86
 
74
87
  /**
75
88
  * Selected rows.
76
89
  */
77
- selectedRows?: Row[];
90
+ selectedRows?: TableRow[];
78
91
 
79
92
  /**
80
93
  * Selected rows id.
@@ -83,9 +83,12 @@ const dropdownSearch = computed({
83
83
  set: (value: string) => emit("update:search", value),
84
84
  });
85
85
 
86
+ /* Indexable view of the options, `labelKey` / `valueKey` lookups need an index signature. */
87
+ const localOptions = computed(() => props.options as Option[]);
88
+
86
89
  const selectedOptions = computed(() => {
87
90
  if (props.multiple) {
88
- return props.options.filter((option) => {
91
+ return localOptions.value.filter((option) => {
89
92
  return (
90
93
  option[props.valueKey] &&
91
94
  (dropdownValue.value as SelectedValue[]).find((selected) =>
@@ -96,7 +99,7 @@ const selectedOptions = computed(() => {
96
99
  }
97
100
 
98
101
  return [
99
- props.options.find(
102
+ localOptions.value.find(
100
103
  (option) => option[props.valueKey] && isEqual(option[props.valueKey], dropdownValue.value),
101
104
  ),
102
105
  ].filter((option) => !!option);
@@ -1,6 +1,6 @@
1
1
  import defaultConfig from "./config";
2
2
 
3
- import type { Option } from "../ui.form-listbox/types";
3
+ import type { ListboxOption } from "../ui.form-listbox/types";
4
4
  import type { ComponentConfig, UnknownObject } from "../types";
5
5
 
6
6
  export type Config = typeof defaultConfig;
@@ -24,7 +24,7 @@ export interface Props {
24
24
  /**
25
25
  * Options list.
26
26
  */
27
- options?: Option[];
27
+ options?: ListboxOption[];
28
28
 
29
29
  /**
30
30
  * Label key in the item object of options.
@@ -1,6 +1,6 @@
1
1
  import defaultConfig from "./config";
2
2
 
3
- import type { Option } from "../ui.form-listbox/types";
3
+ import type { ListboxOption } from "../ui.form-listbox/types";
4
4
  import type { ComponentConfig, UnknownObject } from "../types";
5
5
 
6
6
  export type Config = typeof defaultConfig;
@@ -24,7 +24,7 @@ export interface Props {
24
24
  /**
25
25
  * Options list.
26
26
  */
27
- options?: Option[];
27
+ options?: ListboxOption[];
28
28
 
29
29
  /**
30
30
  * Label key in the item object of options.
@@ -1,6 +1,6 @@
1
1
  import defaultConfig from "./config";
2
2
 
3
- import type { Option } from "../ui.form-listbox/types";
3
+ import type { ListboxOption } from "../ui.form-listbox/types";
4
4
  import type { ComponentConfig, UnknownObject } from "../types";
5
5
 
6
6
  export type Config = typeof defaultConfig;
@@ -24,7 +24,7 @@ export interface Props {
24
24
  /**
25
25
  * Options list.
26
26
  */
27
- options?: Option[];
27
+ options?: ListboxOption[];
28
28
 
29
29
  /**
30
30
  * Label key in the item object of options.
@@ -1,6 +1,6 @@
1
1
  import defaultConfig from "./config";
2
2
 
3
- import type { Option } from "../ui.form-listbox/types";
3
+ import type { ListboxOption } from "../ui.form-listbox/types";
4
4
  import type { ComponentConfig, UnknownObject } from "../types";
5
5
 
6
6
  export type Config = typeof defaultConfig;
@@ -24,7 +24,7 @@ export interface Props {
24
24
  /**
25
25
  * Options list.
26
26
  */
27
- options?: Option[];
27
+ options?: ListboxOption[];
28
28
 
29
29
  /**
30
30
  * Label key in the item object of options.
@@ -33,7 +33,7 @@ describe("UCheckbox.vue", () => {
33
33
  it("Value – returns correct value type when checkbox is checked", async () => {
34
34
  const testValues = ["string-value", 42, true, { id: 1, name: "test" }, [1, 2, 3]];
35
35
 
36
- testValues.forEach(async (testValue) => {
36
+ for (const testValue of testValues) {
37
37
  const component = mount(UCheckbox, {
38
38
  props: {
39
39
  value: testValue,
@@ -48,7 +48,7 @@ describe("UCheckbox.vue", () => {
48
48
  const emittedValues = component.emitted("update:modelValue");
49
49
 
50
50
  expect(emittedValues![0][0]).toEqual([testValue]);
51
- });
51
+ }
52
52
  });
53
53
 
54
54
  it("TrueValue and FalseValue – returns correct values when checkbox is checked and unchecked", async () => {
@@ -59,7 +59,7 @@ describe("UCheckbox.vue", () => {
59
59
  { trueValue: true, falseValue: false },
60
60
  ];
61
61
 
62
- testValuePairs.forEach(async ({ trueValue, falseValue }) => {
62
+ for (const { trueValue, falseValue } of testValuePairs) {
63
63
  const component = mount(UCheckbox, {
64
64
  props: {
65
65
  trueValue,
@@ -81,7 +81,7 @@ describe("UCheckbox.vue", () => {
81
81
  emittedValues = component.emitted("update:modelValue");
82
82
 
83
83
  expect(emittedValues![1][0]).toEqual(falseValue);
84
- });
84
+ }
85
85
  });
86
86
 
87
87
  it("Partial – displays correct icon when checkbox is partially checked", () => {
@@ -4,16 +4,18 @@ import type { ComponentConfig, UnknownObject, UnknownArray } from "../types";
4
4
 
5
5
  export type Config = typeof defaultConfig;
6
6
 
7
- export interface UCheckboxOption {
7
+ export interface BaseCheckboxOption {
8
8
  value?: string | number | boolean | UnknownObject | UnknownArray;
9
9
  falseValue?: string | number | boolean | UnknownObject | UnknownArray;
10
10
  trueValue?: string | number | boolean | UnknownObject | UnknownArray;
11
11
  label?: string;
12
12
  icon?: string;
13
13
  description?: string;
14
- [key: string]: string | number | boolean | UnknownObject | UnknownArray | undefined;
15
14
  }
16
15
 
16
+ /* Any object shape is a valid option, only reserved option keys are type checked. */
17
+ export type UCheckboxOption = BaseCheckboxOption & (object | UnknownObject);
18
+
17
19
  export interface Props {
18
20
  /**
19
21
  * Checkbox value.
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { provide, ref, watch, useTemplateRef } from "vue";
2
+ import { computed, provide, ref, watch, useTemplateRef } from "vue";
3
3
  import { isEqual } from "lodash-es";
4
4
 
5
5
  import { useUI } from "../composables/useUI";
@@ -12,6 +12,7 @@ import { COMPONENT_NAME } from "./constants";
12
12
  import defaultConfig from "./config";
13
13
 
14
14
  import type { UnknownObject } from "../types";
15
+ import type { BaseCheckboxOption } from "../ui.form-checkbox/types";
15
16
  import type { Props, Config } from "./types";
16
17
 
17
18
  defineOptions({ inheritAttrs: false });
@@ -35,6 +36,11 @@ const listRef = useTemplateRef<HTMLDivElement>("list");
35
36
 
36
37
  const checkedItems = ref([] as UnknownObject[]);
37
38
 
39
+ /* Indexable view of the options for `labelKey` / `valueKey` lookups. */
40
+ const keyedOptions = computed(
41
+ () => props.options as (BaseCheckboxOption & Record<string, BaseCheckboxOption["value"]>)[],
42
+ );
43
+
38
44
  provide<(value: UnknownObject[]) => void>(
39
45
  "setCheckboxGroupCheckedItems",
40
46
  (value: UnknownObject[]) => {
@@ -116,7 +122,7 @@ const { getDataTest, groupLabelAttrs, groupCheckboxAttrs, listAttrs } =
116
122
  <!-- @slot Use it to add UCheckbox directly. -->
117
123
  <slot>
118
124
  <UCheckbox
119
- v-for="(option, index) in options"
125
+ v-for="(option, index) in keyedOptions"
120
126
  :key="index"
121
127
  :model-value="modelValue"
122
128
  :value="option[valueKey]"
@@ -75,8 +75,11 @@ const wrapperMaxHeight = ref("");
75
75
 
76
76
  const localSearch = ref(props.search ?? "");
77
77
 
78
+ /* Indexable view of the options, `labelKey` / `valueKey` lookups need an index signature. */
79
+ const localOptions = computed(() => props.options as Option[]);
80
+
78
81
  const { pointer, pointerDirty, pointerSet, pointerBackward, pointerForward, pointerReset } =
79
- usePointer(props.options, optionsRef, wrapperRef);
82
+ usePointer(localOptions.value, optionsRef, wrapperRef);
80
83
 
81
84
  const elementId = props.id || useId();
82
85
 
@@ -126,7 +129,7 @@ const getOptionAriaSelected = (option: Option) => {
126
129
  const filteredOptions = computed(() => {
127
130
  const normalizedSearch = searchModel.value.toLowerCase().trim();
128
131
 
129
- let options = [...props.options];
132
+ let options = [...localOptions.value];
130
133
 
131
134
  options = props.groupValueKey
132
135
  ? filterGroups(
@@ -324,9 +327,9 @@ function optionHighlight(index: number, option: Option) {
324
327
  }
325
328
 
326
329
  function addPointerElement(keyCode?: string) {
327
- if (props.options.length > 0) {
328
- select(props.options[pointer.value], keyCode);
329
- onClickOption(props.options[pointer.value]);
330
+ if (localOptions.value.length > 0) {
331
+ select(localOptions.value[pointer.value], keyCode);
332
+ onClickOption(localOptions.value[pointer.value]);
330
333
  }
331
334
 
332
335
  pointerReset();
@@ -16,6 +16,9 @@ export interface Option extends BaseOption {
16
16
  [key: string]: string | number | boolean | UnknownObject | Option[] | OnClickOption | undefined;
17
17
  }
18
18
 
19
+ /* Any object shape is a valid option, only reserved option keys are type checked. */
20
+ export type ListboxOption = BaseOption & (object | UnknownObject);
21
+
19
22
  export type SelectedValue = string | number | UnknownObject;
20
23
 
21
24
  export interface Props {
@@ -32,7 +35,7 @@ export interface Props {
32
35
  /**
33
36
  * List options.
34
37
  */
35
- options?: Option[];
38
+ options?: ListboxOption[];
36
39
 
37
40
  /**
38
41
  * Shows input to search value in a list.
@@ -10,7 +10,7 @@ import URadio from "../ui.form-radio/URadio.vue";
10
10
  import defaultConfig from "./config";
11
11
  import { COMPONENT_NAME } from "./constants";
12
12
 
13
- import type { Props, SetRadioGroupSelectedItem, Config } from "./types";
13
+ import type { Props, BaseOption, SetRadioGroupSelectedItem, Config } from "./types";
14
14
 
15
15
  defineOptions({ inheritAttrs: false });
16
16
 
@@ -31,6 +31,11 @@ const emit = defineEmits([
31
31
 
32
32
  const listRef = useTemplateRef<HTMLDivElement>("list");
33
33
 
34
+ /* Indexable view of the options for `labelKey` / `valueKey` lookups. */
35
+ const keyedOptions = computed(
36
+ () => props.options as (BaseOption & Record<string, BaseOption["value"]>)[],
37
+ );
38
+
34
39
  const selectedItem = computed({
35
40
  get: () => props.modelValue,
36
41
  set: (value) => emit("update:modelValue", value),
@@ -106,7 +111,7 @@ const { getDataTest, groupLabelAttrs, listAttrs, groupRadioAttrs } = useUI<Confi
106
111
  <!-- @slot Use it to add URadio directly. -->
107
112
  <slot>
108
113
  <URadio
109
- v-for="(option, index) in options"
114
+ v-for="(option, index) in keyedOptions"
110
115
  :key="index"
111
116
  :model-value="selectedItem"
112
117
  :value="option[valueKey]"
@@ -10,9 +10,8 @@ export interface BaseOption {
10
10
  description?: string;
11
11
  }
12
12
 
13
- export interface Option extends BaseOption {
14
- [key: string]: string | number | boolean | UnknownArray | UnknownObject | undefined;
15
- }
13
+ /* Any object shape is a valid option, only reserved option keys are type checked. */
14
+ export type Option = BaseOption & (object | UnknownObject);
16
15
 
17
16
  export type SetRadioGroupSelectedItem =
18
17
  | ((value: string | number | boolean | UnknownArray | UnknownObject) => void)
@@ -151,16 +151,20 @@ const isMultipleBadgeVariant = computed(
151
151
  () => props.multiple && props.multipleVariant === MULTIPLE_VARIANTS.badge,
152
152
  );
153
153
 
154
+ const listboxOptions = computed(() => props.options as Option[]);
155
+
154
156
  const localValue = computed<Option | Option[]>(() => {
155
157
  if (!props.multiple) {
156
158
  const [singleValue] = Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue];
157
159
 
158
- return getCurrentOption(props.options, singleValue, props.valueKey, props.groupValueKey);
160
+ return getCurrentOption(listboxOptions.value, singleValue, props.valueKey, props.groupValueKey);
159
161
  }
160
162
 
161
163
  return props.modelValue && Array.isArray(props.modelValue)
162
164
  ? (props.modelValue
163
- .map((value) => getCurrentOption(props.options, value, props.valueKey, props.groupValueKey))
165
+ .map((value) =>
166
+ getCurrentOption(listboxOptions.value, value, props.valueKey, props.groupValueKey),
167
+ )
164
168
  .filter(Boolean) as Option[])
165
169
  : [];
166
170
  });
@@ -858,7 +862,7 @@ const {
858
862
  :searchable="searchable"
859
863
  :options-limit="optionsLimit"
860
864
  :multiple="multiple"
861
- :options="options"
865
+ :options="listboxOptions"
862
866
  :disabled="disabled"
863
867
  :size="size"
864
868
  :debounce="debounce"
@@ -1,10 +1,13 @@
1
1
  import defaultConfig from "./config";
2
2
 
3
- import type { Option } from "../ui.form-listbox/types";
4
- import type { ComponentConfig } from "../types";
3
+ import type { BaseOption } from "../ui.form-listbox/types";
4
+ import type { ComponentConfig, UnknownObject } from "../types";
5
5
 
6
6
  export type Config = typeof defaultConfig;
7
7
 
8
+ /* Any object shape is a valid option, only reserved option keys are type checked. */
9
+ export type SelectOption = BaseOption & (object | UnknownObject);
10
+
8
11
  export interface Props {
9
12
  /**
10
13
  * Select value.
@@ -14,7 +17,7 @@ export interface Props {
14
17
  /**
15
18
  * Select options.
16
19
  */
17
- options?: Option[];
20
+ options?: SelectOption[];
18
21
 
19
22
  /**
20
23
  * Select label.
@@ -1,10 +1,10 @@
1
1
  import defaultConfig from "./config";
2
2
 
3
- import type { ComponentConfig } from "../types";
3
+ import type { ComponentConfig, UnknownObject } from "../types";
4
4
 
5
5
  export type Config = typeof defaultConfig;
6
6
 
7
- export interface ChipItem {
7
+ export interface BaseChipItem {
8
8
  icon?: string;
9
9
  color?: Props["color"];
10
10
  xPosition?: "left" | "right";
@@ -12,6 +12,9 @@ export interface ChipItem {
12
12
  inset?: boolean;
13
13
  }
14
14
 
15
+ /* Any object shape is a valid chip, only reserved chip keys are type checked. */
16
+ export type ChipItem = BaseChipItem & (object | UnknownObject);
17
+
15
18
  export interface Props {
16
19
  /**
17
20
  * Avatar label (username, nickname, etc.).
@@ -1,11 +1,11 @@
1
1
  import defaultConfig from "./config";
2
2
 
3
- import type { ComponentConfig } from "../types";
3
+ import type { ComponentConfig, UnknownObject } from "../types";
4
4
  import type { ChipItem } from "../ui.image-avatar/types";
5
5
 
6
6
  export type Config = typeof defaultConfig;
7
7
 
8
- export interface AvatarItem {
8
+ export interface BaseAvatarItem {
9
9
  src?: string;
10
10
  label?: string;
11
11
  color?: string;
@@ -13,6 +13,9 @@ export interface AvatarItem {
13
13
  chip?: ChipItem;
14
14
  }
15
15
 
16
+ /* Any object shape is a valid avatar, only reserved avatar keys are type checked. */
17
+ export type AvatarItem = BaseAvatarItem & (object | UnknownObject);
18
+
16
19
  export interface Props {
17
20
  /**
18
21
  * Avatar items.
@@ -11,13 +11,14 @@ import defaultConfig from "./config";
11
11
 
12
12
  import USkeleton from "../ui.skeleton/USkeleton.vue";
13
13
 
14
- import type { AsyncComponentLoader, ComponentPublicInstance } from "vue";
14
+ import type { AsyncComponentLoader, ComponentOptions, ComponentPublicInstance } from "vue";
15
15
  import type { Props, Config } from "./types";
16
16
 
17
17
  defineOptions({ inheritAttrs: false });
18
18
 
19
19
  const props = withDefaults(defineProps<Props>(), {
20
20
  ...getDefaults<Props, Config>(defaultConfig, COMPONENT_NAME),
21
+ src: undefined,
21
22
  });
22
23
 
23
24
  const emit = defineEmits([
@@ -53,7 +54,7 @@ const dynamicComponent = computed(() => {
53
54
  }
54
55
 
55
56
  const name = props.name;
56
- const src = props.src;
57
+ const src = props.src as ComponentOptions | undefined;
57
58
 
58
59
  /* Edge case */
59
60
  if (!src && !name) return "";
@@ -1,6 +1,6 @@
1
1
  import defaultConfig from "./config";
2
2
 
3
- import type { DefineComponent, SVGAttributes } from "vue";
3
+ import type { Component, SVGAttributes } from "vue";
4
4
 
5
5
  import type { ComponentConfig } from "../types";
6
6
 
@@ -17,7 +17,7 @@ export interface Props {
17
17
  /**
18
18
  * Icon source (svg as a vue component).
19
19
  */
20
- src?: DefineComponent<SVGAttributes>;
20
+ src?: Component<SVGAttributes>;
21
21
 
22
22
  /**
23
23
  * Icon color.
@@ -1,13 +1,16 @@
1
1
  import defaultConfig from "./config";
2
- import type { ComponentConfig } from "../types";
2
+ import type { ComponentConfig, UnknownObject } from "../types";
3
3
  import type { Props as ULinkProps } from "../ui.button-link/types";
4
4
 
5
5
  export type Config = typeof defaultConfig;
6
6
 
7
- export interface UBreadcrumb extends ULinkProps {
7
+ export interface BaseBreadcrumb extends ULinkProps {
8
8
  icon?: string;
9
9
  }
10
10
 
11
+ /* Any object shape is a valid breadcrumb, only reserved breadcrumb keys are type checked. */
12
+ export type UBreadcrumb = BaseBreadcrumb & (object | UnknownObject);
13
+
11
14
  export interface Props {
12
15
  /**
13
16
  * Array of links.
@@ -8,12 +8,15 @@ export type SetUTabsSelectedItem = (
8
8
  value: string | number | boolean | UnknownArray | UnknownObject,
9
9
  ) => void;
10
10
 
11
- export interface UTabsOption {
11
+ export interface BaseTabOption {
12
12
  value: string | number;
13
13
  label: string;
14
14
  disabled?: boolean;
15
15
  }
16
16
 
17
+ /* Any object shape is a valid option, only reserved option keys are type checked. */
18
+ export type UTabsOption = BaseTabOption & (object | UnknownObject);
19
+
17
20
  export interface Props {
18
21
  /**
19
22
  * Selected tab value.
@@ -2,4 +2,4 @@
2
2
  This const is needed to prevent the issue in script setup:
3
3
  `defineProps` is referencing locally declared variables. (vue/valid-define-props)
4
4
  */
5
- export const COMPONENT_NAME = "USkeletonInput";
5
+ export const COMPONENT_NAME = "USkeletonText";