vue-composable-ui 0.0.1 → 1.0.2

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 (123) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +5 -1
  3. package/dist/combobox.vue_vue_type_script_setup_true_lang-BhVMcx67.js +140 -0
  4. package/dist/comboboxHiddenInput.vue_vue_type_script_setup_true_lang-Ba-UPd-M.js +29 -0
  5. package/dist/comboboxInput.vue_vue_type_script_setup_true_lang-DzRfJ5ke.js +33 -0
  6. package/dist/comboboxOption.vue_vue_type_script_setup_true_lang-OyJxB4Jk.js +42 -0
  7. package/dist/comboboxOptions.vue_vue_type_script_setup_true_lang-Doy6MfEQ.js +20 -0
  8. package/dist/composable-ui.js +49 -0
  9. package/dist/composable-ui10.js +4 -0
  10. package/dist/composable-ui11.js +4 -0
  11. package/dist/composable-ui12.js +4 -0
  12. package/dist/composable-ui13.js +4 -0
  13. package/dist/composable-ui14.js +4 -0
  14. package/dist/composable-ui15.js +4 -0
  15. package/dist/composable-ui16.js +4 -0
  16. package/dist/composable-ui17.js +31 -0
  17. package/dist/composable-ui18.js +4 -0
  18. package/dist/composable-ui19.js +4 -0
  19. package/dist/composable-ui2.js +55 -0
  20. package/dist/composable-ui20.js +4 -0
  21. package/dist/composable-ui21.js +100 -0
  22. package/dist/composable-ui22.js +144 -0
  23. package/dist/composable-ui23.js +7 -0
  24. package/dist/composable-ui24.js +7 -0
  25. package/dist/composable-ui3.js +4 -0
  26. package/dist/composable-ui4.js +4 -0
  27. package/dist/composable-ui5.js +4 -0
  28. package/dist/composable-ui6.js +4 -0
  29. package/dist/composable-ui7.js +4 -0
  30. package/dist/composable-ui8.js +4 -0
  31. package/dist/composable-ui9.js +4 -0
  32. package/dist/listbox.vue_vue_type_script_setup_true_lang-Bj1ZXiBX.js +69 -0
  33. package/dist/listboxOption.vue_vue_type_script_setup_true_lang-B_yRptJm.js +37 -0
  34. package/dist/menu.vue_vue_type_script_setup_true_lang-Ci7q2rOg.js +82 -0
  35. package/dist/menuItem.vue_vue_type_script_setup_true_lang-mXtMa4gO.js +63 -0
  36. package/dist/menuItems.vue_vue_type_script_setup_true_lang-p9vftREy.js +49 -0
  37. package/dist/popover.vue_vue_type_script_setup_true_lang-DhKF7_nY.js +50 -0
  38. package/dist/popoverDialog.vue_vue_type_script_setup_true_lang-CDXUO7wZ.js +33 -0
  39. package/dist/tab.vue_vue_type_script_setup_true_lang-Y5OFGqMB.js +29 -0
  40. package/dist/tabContainer.vue_vue_type_script_setup_true_lang-fPpLno2Z.js +40 -0
  41. package/dist/tabList.vue_vue_type_script_setup_true_lang-CZyqGCuj.js +48 -0
  42. package/dist/tabPanel.vue_vue_type_script_setup_true_lang-CGhP6SHR.js +31 -0
  43. package/dist/tooltip.vue_vue_type_script_setup_true_lang-DVKYJyfL.js +85 -0
  44. package/dist/types/components/combobox/combobox.vue.d.ts +45 -0
  45. package/dist/types/components/combobox/comboboxHiddenInput.vue.d.ts +6 -0
  46. package/dist/types/components/combobox/comboboxInput.vue.d.ts +9 -0
  47. package/dist/types/components/combobox/comboboxOption.vue.d.ts +20 -0
  48. package/dist/types/components/combobox/comboboxOptions.vue.d.ts +12 -0
  49. package/dist/types/components/injectionKeys.d.ts +43 -0
  50. package/dist/types/components/listbox/listbox.vue.d.ts +26 -0
  51. package/dist/types/components/listbox/listboxOption.vue.d.ts +20 -0
  52. package/dist/types/components/menu/menu.vue.d.ts +42 -0
  53. package/dist/types/components/menu/menuItem.vue.d.ts +24 -0
  54. package/dist/types/components/menu/menuItems.vue.d.ts +12 -0
  55. package/dist/types/components/popover/popover.vue.d.ts +40 -0
  56. package/dist/types/components/popover/popoverDialog.vue.d.ts +12 -0
  57. package/dist/types/components/tabs/tab.vue.d.ts +17 -0
  58. package/dist/types/components/tabs/tabContainer.vue.d.ts +19 -0
  59. package/dist/types/components/tabs/tabList.vue.d.ts +17 -0
  60. package/dist/types/components/tabs/tabPanel.vue.d.ts +15 -0
  61. package/dist/types/components/tooltip.vue.d.ts +34 -0
  62. package/dist/types/composables/formControl.d.ts +48 -0
  63. package/dist/types/composables/list.d.ts +107 -0
  64. package/dist/types/composables/listOption.d.ts +34 -0
  65. package/dist/types/composables/popover.d.ts +68 -0
  66. package/dist/types/main.d.ts +22 -0
  67. package/dist/types/utils/element.d.ts +3 -0
  68. package/package.json +28 -12
  69. package/.github/workflows/deploy.yml +0 -21
  70. package/.github/workflows/docs.yml +0 -62
  71. package/.vscode/extensions.json +0 -7
  72. package/docs/.vitepress/config.mts +0 -40
  73. package/docs/.vitepress/theme/index.js +0 -4
  74. package/docs/.vitepress/theme/style.scss +0 -155
  75. package/docs/components/combobox.md +0 -174
  76. package/docs/components/demos/combobox.vue +0 -142
  77. package/docs/components/demos/combobox_autocomplete.vue +0 -75
  78. package/docs/components/demos/combobox_tags.vue +0 -127
  79. package/docs/components/demos/input.vue +0 -35
  80. package/docs/components/demos/listbox.vue +0 -64
  81. package/docs/components/demos/menu.vue +0 -93
  82. package/docs/components/demos/popover.vue +0 -16
  83. package/docs/components/demos/tabs.vue +0 -59
  84. package/docs/components/demos/tooltip.vue +0 -27
  85. package/docs/components/listbox.md +0 -9
  86. package/docs/components/menu.md +0 -121
  87. package/docs/components/popover.md +0 -82
  88. package/docs/components/tabs.md +0 -9
  89. package/docs/components/tooltip.md +0 -78
  90. package/docs/composables/form-control.md +0 -130
  91. package/docs/composables/list-option.md +0 -47
  92. package/docs/composables/list.md +0 -192
  93. package/docs/composables/popover.md +0 -90
  94. package/docs/index.md +0 -24
  95. package/docs/intro.md +0 -0
  96. package/src/components/combobox/combobox.vue +0 -229
  97. package/src/components/combobox/comboboxFormInput.vue +0 -33
  98. package/src/components/combobox/comboboxOption.vue +0 -52
  99. package/src/components/combobox/comboboxOptions.vue +0 -17
  100. package/src/components/injectionKeys.ts +0 -50
  101. package/src/components/listbox/listbox.vue +0 -91
  102. package/src/components/listbox/listboxOption.vue +0 -37
  103. package/src/components/menu/menu.vue +0 -100
  104. package/src/components/menu/menuItem.vue +0 -86
  105. package/src/components/menu/menuItems.vue +0 -51
  106. package/src/components/popover/popover.vue +0 -68
  107. package/src/components/popover/popoverDialog.vue +0 -35
  108. package/src/components/tabs/tab.vue +0 -35
  109. package/src/components/tabs/tabContainer.vue +0 -50
  110. package/src/components/tabs/tabList.vue +0 -52
  111. package/src/components/tabs/tabPanel.vue +0 -36
  112. package/src/components/tooltip.vue +0 -115
  113. package/src/composables/formControl.ts +0 -144
  114. package/src/composables/list.ts +0 -326
  115. package/src/composables/listOption.ts +0 -80
  116. package/src/composables/popover.ts +0 -306
  117. package/src/main.ts +0 -65
  118. package/src/utils/element.ts +0 -19
  119. package/src/utils/id.ts +0 -5
  120. package/src/vite-env.d.ts +0 -1
  121. package/tsconfig.json +0 -27
  122. package/tsconfig.node.json +0 -10
  123. package/vite.config.ts +0 -28
@@ -1,192 +0,0 @@
1
- # useList
2
-
3
- The composable implements single/multi-selection and navigation functionality for a list of HTML elements. It can be used to power a wide range of components: tabs, button groups, radio groups, comboboxes and all kinds of components where user has to select one or more values from a list.
4
-
5
- `useList` is meant to be used in conjunction with the [`useListOption`](/composables/list-option) composable.
6
-
7
- ## Basic Usage
8
-
9
- ::: code-group
10
-
11
- ```vue [example.vue]
12
- <script setup>
13
- import { ref } from 'vue'
14
-
15
- const value = ref()
16
- </script>
17
-
18
- <template>
19
- Selected value: {{value}}
20
- <List v-model="value">
21
- <Item value="1">Item 1</Item>
22
- <Item value="2">Item 2</Item>
23
- <Item value="3" :disabled="true">Item 3</Item>
24
- <List>
25
- </template>
26
- ```
27
-
28
- ```vue [list.vue]
29
- <script setup>
30
- import { useList } from "vue-composable-ui";
31
-
32
- const model = defineModel();
33
- const list = useList(model);
34
- </script>
35
-
36
- <template>
37
- <div>
38
- <slot />
39
- </div>
40
- </template>
41
- ```
42
-
43
- ```vue [item.vue]
44
- <script setup>
45
- import { useListOption } from "vue-composable-ui";
46
- import { ref } from "vue";
47
-
48
- const props = defineProps<{
49
- value: any;
50
- disabled?: boolean;
51
- }>()
52
-
53
- const itemEl = ref<HTMLElement>()
54
- const option = useListOption(itemEl, props.value, props.disabled);
55
-
56
- const onClick = () => option.select();
57
- </script>
58
-
59
- <template>
60
- <div ref="itemEl" @click="onClick">
61
- <slot />
62
- </div>
63
- </template>
64
- ```
65
-
66
- :::
67
-
68
- ## Type Declarations
69
-
70
- ### Composable
71
-
72
- ```ts
73
- /**
74
- * Creates a reactive list of HTML elements with assigned values.
75
- *
76
- * @param value A ref to store the list value. Set to an array to enable multiselection.
77
- */
78
- export declare function useList(value: Ref<unknown>): UseListReturn;
79
- ```
80
-
81
- ### Return Type
82
-
83
- ```ts
84
- export type ItemValue = unknown;
85
- export interface Item {
86
- id: number;
87
- element: Ref<HTMLElement | undefined>;
88
- value: ItemValue;
89
- disabled: MaybeRef<boolean>;
90
- }
91
-
92
- interface ActivationOptions {
93
- /**
94
- * Focus the corresponding HTML element
95
- *
96
- * @defaultValue false
97
- */
98
- focus?: boolean;
99
- }
100
-
101
- interface NavigationOptions {
102
- /**
103
- * Infinitely cycle throught the items
104
- *
105
- * @defaultValue false
106
- */
107
- loop?: boolean;
108
- }
109
-
110
- export interface UseListReturn {
111
- /**
112
- * Array of items
113
- */
114
- items: Readonly<ShallowRef<Item[]>>;
115
- /**
116
- * Multiselection flag
117
- */
118
- isMultiselectable: Readonly<Ref<boolean>>;
119
- /**
120
- * Currently active item
121
- */
122
- activeItem: ComputedRef<Item | undefined>;
123
- /**
124
- * Select the currently active item
125
- */
126
- selectActiveItem: () => void;
127
- /**
128
- * Activate the currently selected item
129
- */
130
- activateSelectedItem: (options?: ActivationOptions) => void;
131
- /**
132
- * Activate the first item
133
- */
134
- activateFirstItem: (options?: ActivationOptions) => void;
135
- /**
136
- * Activate the last item
137
- */
138
- activateLastItem: (options?: ActivationOptions) => void;
139
- /**
140
- * Activate next item
141
- */
142
- activateNextItem: (options?: ActivationOptions & NavigationOptions) => void;
143
- /**
144
- * Activate previous item
145
- */
146
- activatePrevItem: (options?: ActivationOptions & NavigationOptions) => void;
147
- }
148
- ```
149
-
150
- ### Injection Key
151
-
152
- > [!NOTE]
153
- > List items get unique ids that are not equal to their indexes in the `items` array returned by the composable. You need to access `item.id` to get its id value.
154
-
155
- ```ts
156
- interface UseListInjectionKey {
157
- /**
158
- * The list value
159
- */
160
- value: Readonly<Ref<unknown>>;
161
- /**
162
- * Select an item by ID
163
- */
164
- selectItem: (itemId: number) => void;
165
- /**
166
- * Activate an item by ID
167
- */
168
- activateItem: (itemId: number, options?: ActivationOptions) => void;
169
- /**
170
- * Check if an item is selected
171
- */
172
- isSelected: (itemId: number) => boolean;
173
- /**
174
- * Check if an item is active
175
- */
176
- isActive: (itemId: number) => boolean;
177
- /**
178
- * Add an item to the list
179
- *
180
- * @returns New item ID
181
- */
182
- addItem: (
183
- itemEl: HTMLElementType,
184
- itemVal: ItemValue,
185
- disabled?: MaybeRef<boolean>
186
- ) => number;
187
- /**
188
- * Remove an item from the list by ID
189
- */
190
- removeItem: (itemId: number) => void;
191
- }
192
- ```
@@ -1,90 +0,0 @@
1
- # usePopover
2
-
3
- Popover is a floating container that appears next to its activator element above the main document flow. It can be used as a basic component for dropdown menus, comboboxes, tooltips, and more.
4
-
5
- The composable abstracts the logic of positioning a popover relative to its activating element and captures clicks to automatically close the popover.
6
-
7
- No event listeners are attached to the activating element to give the user full control over the way the popover is triggered.
8
-
9
- ## Type Declarations
10
-
11
- ### Composable
12
-
13
- ```ts
14
- interface UsePopoverOptions {
15
- /**
16
- * The direction of the popover dialog
17
- *
18
- * @defaultValue `"down"`
19
- */
20
- direction?: "up" | "down" | "left" | "right";
21
- /**
22
- * The alignment of the popover dialog
23
- *
24
- * @defaultValue `"left"`
25
- */
26
- align?: "top" | "bottom" | "left" | "right" | "center" | "stretch";
27
- /**
28
- * The CSS position of the popover dialog
29
- *
30
- * @defaultValue `"fixed"`
31
- */
32
- position?: "fixed" | "absolute";
33
- /**
34
- * Close the popover on a click outside of the dialog
35
- *
36
- * @defaultValue `true`
37
- */
38
- closeOnOutsideClick?: boolean;
39
- /**
40
- * Close the popover on a click inside of the dialog
41
- *
42
- * @defaultValue `false`
43
- */
44
- closeOnInsideClick?: boolean;
45
- }
46
-
47
- /**
48
- *
49
- * @param activatorEl A template ref or a CSS selector
50
- * @param popupEl A template ref or a CSS selector
51
- * @param options Popover options
52
- */
53
- export declare function usePopover(
54
- activatorEl: TemplateRefOrSelector,
55
- popupEl: TemplateRefOrSelector,
56
- options?: UsePopoverOptions
57
- ): UsePopoverReturn;
58
- ```
59
-
60
- ### Return Type
61
-
62
- ```ts
63
- interface FocusOptions {
64
- /**
65
- * Focus the popover/activator
66
- *
67
- * @defaultValue `true`
68
- */
69
- focus?: boolean;
70
- }
71
-
72
- export interface UsePopoverReturn {
73
- /**
74
- * The popover state
75
- */
76
- isOpen: Ref<boolean>;
77
- /**
78
- * Open the popover
79
- */
80
- open: (options?: FocusOptions) => void;
81
- /**
82
- * Close the popover
83
- */
84
- close: (options?: FocusOptions) => void;
85
- /**
86
- * Toggle the popover
87
- */
88
- toggle: (options?: FocusOptions) => void;
89
- }
90
- ```
package/docs/index.md DELETED
@@ -1,24 +0,0 @@
1
- ---
2
- # https://vitepress.dev/reference/default-theme-home-page
3
- layout: home
4
-
5
- hero:
6
- name: "Vue Composable UI"
7
- text: "A truly headless UI framework"
8
- tagline: My great project tagline
9
- actions:
10
- - theme: brand
11
- text: Introduction
12
- link: /intro
13
- - theme: alt
14
- text: API Examples
15
- link: /api-examples
16
-
17
- features:
18
- - title: Feature A
19
- details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
20
- - title: Feature B
21
- details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
22
- - title: Feature C
23
- details: Lorem ipsum dolor sit amet, consectetur adipiscing elit
24
- ---
package/docs/intro.md DELETED
File without changes
@@ -1,229 +0,0 @@
1
- <template>
2
- <template v-if="name">
3
- <ComboboxFormInput
4
- v-if="isMultiselectable"
5
- v-for="(value, id) in formInputs"
6
- :name="`${name}[${id}]`"
7
- :value="value"
8
- />
9
- <ComboboxFormInput v-else :name="name" :value="formInputs" />
10
- </template>
11
-
12
- <slot
13
- name="input"
14
- :popoverId="popoverId"
15
- :attrs="inputAttrs"
16
- :isOpen="isOpen"
17
- :toggle="toggle"
18
- >
19
- <input v-bind="{ ...$attrs, ...inputAttrs }" autocomplete="off" />
20
- </slot>
21
-
22
- <slot />
23
- </template>
24
-
25
- <script setup lang="ts">
26
- import { ref, computed, provide, watch, nextTick } from "vue";
27
- import { useSequentialId } from "../../utils/id";
28
- import { usePopover } from "../../composables/popover";
29
- import { useList } from "../../composables/list";
30
- import { useFormControl, FormValidator } from "../../composables/formControl";
31
- import ComboboxFormInput from "./comboboxFormInput.vue";
32
- import { injectCombobox } from "../injectionKeys";
33
-
34
- defineOptions({ inheritAttrs: false });
35
-
36
- const props = withDefaults(
37
- defineProps<{
38
- displayValue?: (value: any) => string;
39
-
40
- id?: string;
41
- activatorId?: string;
42
-
43
- name?: string;
44
- formValue?: (item: any) => Record<string, string> | string;
45
-
46
- validators?: FormValidator[];
47
- showValidationError?: boolean;
48
- }>(),
49
- {
50
- displayValue: (value: any) =>
51
- Array.isArray(value)
52
- ? value.map((i) => i.toString()).join(", ")
53
- : value.toString(),
54
- formValue: (item: any) => item,
55
- showValidationError: true,
56
- }
57
- );
58
-
59
- const formInputs = computed(() => {
60
- if (isMultiselectable.value) {
61
- return (model.value as any[]).map((i) => props.formValue(i));
62
- } else {
63
- return props.formValue(model.value);
64
- }
65
- });
66
-
67
- const model = defineModel();
68
- const modelIsValid = defineModel("isValid");
69
- const modelValidationMessage = defineModel("validationMessage");
70
-
71
- const comboboxId = props.id ?? useSequentialId("combobox");
72
- const activatorId = props.activatorId ?? comboboxId;
73
- const popoverId = `${comboboxId}-popover`;
74
-
75
- // Popover
76
- const { isOpen, toggle, open, close } = usePopover(
77
- `#${activatorId}`,
78
- `#${popoverId}`,
79
- {
80
- direction: "down",
81
- align: "stretch",
82
- position: "fixed",
83
- closeOnOutsideClick: true,
84
- closeOnInsideClick: false,
85
- }
86
- );
87
-
88
- // List
89
- const {
90
- items,
91
- activeItem,
92
- isMultiselectable,
93
- selectActiveItem,
94
- activateSelectedItem,
95
- activateFirstItem,
96
- activateLastItem,
97
- activateNextItem,
98
- activatePrevItem,
99
- } = useList(model);
100
-
101
- // Form Control
102
- const { focus, isValid, validationMessage } = useFormControl(
103
- `#${comboboxId}`,
104
- props.validators,
105
- props.showValidationError
106
- );
107
-
108
- watch(isValid, () => (modelIsValid.value = isValid.value));
109
- watch(
110
- validationMessage,
111
- () => (modelValidationMessage.value = validationMessage.value)
112
- );
113
-
114
- watch(items, () => {
115
- if (!activeItem.value && items.value.length) {
116
- if (
117
- (isMultiselectable.value && (model.value as any[]).length) ||
118
- (!isMultiselectable.value && model.value)
119
- ) {
120
- activateSelectedItem({ focus: false });
121
- } else {
122
- activateFirstItem({ focus: false });
123
- }
124
- }
125
- });
126
-
127
- const inputValue = ref("");
128
-
129
- function updateInputValue() {
130
- inputValue.value = props.displayValue(model.value);
131
- }
132
-
133
- watch(model, updateInputValue, { deep: true, immediate: true });
134
-
135
- function onChange() {
136
- updateInputValue();
137
- }
138
-
139
- function onInput(evt: KeyboardEvent) {
140
- inputValue.value = (evt.target as HTMLInputElement).value;
141
- open({ focus: false });
142
- }
143
-
144
- function onKeyDown(evt: KeyboardEvent) {
145
- if (!isOpen.value) {
146
- switch (evt.code) {
147
- case "Space":
148
- case "Enter":
149
- open({ focus: false });
150
- break;
151
-
152
- case "End":
153
- case "ArrowUp":
154
- open({ focus: false });
155
- nextTick(() => activateLastItem({ focus: false }));
156
- break;
157
-
158
- case "Home":
159
- case "ArrowDown":
160
- open({ focus: false });
161
- nextTick(() => activateFirstItem({ focus: false }));
162
- break;
163
-
164
- default:
165
- return;
166
- }
167
- } else {
168
- switch (evt.code) {
169
- case "Space":
170
- selectActiveItem();
171
- if (!isMultiselectable.value) {
172
- close();
173
- }
174
- break;
175
- case "Enter":
176
- selectActiveItem();
177
- close();
178
- break;
179
- case "Tab":
180
- selectActiveItem();
181
- close();
182
- return;
183
- case "ArrowUp":
184
- activatePrevItem({ focus: false, loop: false });
185
- break;
186
- case "ArrowDown":
187
- activateNextItem({ focus: false, loop: false });
188
- break;
189
- case "Home":
190
- activateFirstItem({ focus: false });
191
- break;
192
- case "End":
193
- activateLastItem({ focus: false });
194
- break;
195
- case "Escape":
196
- close();
197
- break;
198
- default:
199
- return;
200
- }
201
- }
202
-
203
- evt.preventDefault();
204
- }
205
-
206
- const inputAttrs = computed(() => ({
207
- value: inputValue.value,
208
- oninput: onInput,
209
- onchange: onChange,
210
- onkeydown: onKeyDown,
211
- onclick: () => open({ focus: false }),
212
- id: comboboxId,
213
- "aria-controls": isOpen.value ? popoverId : undefined,
214
- "aria-expanded": isOpen.value,
215
- "aria-activedescendant": activeItem.value?.element.value?.id,
216
- "aria-haspopup": "listbox" as "listbox",
217
- role: "combobox",
218
- }));
219
-
220
- provide(injectCombobox, {
221
- popoverId,
222
- isOpen,
223
- isMultiselectable,
224
- close,
225
- focus,
226
- });
227
- </script>
228
-
229
- <style scoped></style>
@@ -1,33 +0,0 @@
1
- <template>
2
- <input
3
- v-for="(value, name) in inputs"
4
- :name="name"
5
- :value="value"
6
- type="hidden"
7
- />
8
- </template>
9
-
10
- <script setup lang="ts">
11
- import { computed } from "vue";
12
-
13
- const props = defineProps<{
14
- name: string;
15
- value: any;
16
- }>();
17
-
18
- const inputs = computed(() => {
19
- if (typeof props.value === "object") {
20
- const fields: Record<string, any> = {};
21
- for (const [key, value] of Object.entries(props.value)) {
22
- fields[`${props.name}[${key}]`] = value;
23
- }
24
- return fields;
25
- } else {
26
- return {
27
- [props.name]: props.value,
28
- };
29
- }
30
- });
31
- </script>
32
-
33
- <style scoped></style>
@@ -1,52 +0,0 @@
1
- <template>
2
- <div
3
- ref="itemEl"
4
- :id="itemId"
5
- @click="onClick"
6
- @mouseenter="activate({ focus: false })"
7
- :data-active="isActive"
8
- :aria-selected="isSelected"
9
- :aria-disabled="disabled || undefined"
10
- role="option"
11
- >
12
- <slot :isSelected="isSelected" :isActive="isActive" />
13
- </div>
14
- </template>
15
-
16
- <script setup lang="ts">
17
- import { ref, inject } from "vue";
18
- import { useSequentialId } from "../../utils/id";
19
- import { useListOption } from "../../composables/listOption";
20
- import { injectCombobox } from "../injectionKeys";
21
-
22
- const props = defineProps<{
23
- id?: string;
24
- value: any;
25
- disabled?: boolean;
26
- }>();
27
-
28
- const itemId = props.id ?? useSequentialId("combobox-option");
29
-
30
- const itemEl = ref<HTMLElement>();
31
-
32
- const { isSelected, isActive, activate, select } = useListOption(
33
- itemEl,
34
- props.value,
35
- props.disabled
36
- );
37
-
38
- const combobox = inject(injectCombobox);
39
- if (!combobox) {
40
- throw new Error("Combobox injectable context is not provided");
41
- }
42
-
43
- function onClick() {
44
- select();
45
- if (!combobox!.isMultiselectable.value) {
46
- combobox!.close({ focus: false });
47
- }
48
- combobox!.focus();
49
- }
50
- </script>
51
-
52
- <style scoped></style>
@@ -1,17 +0,0 @@
1
- <template>
2
- <div v-if="combobox!.isOpen.value" :id="combobox!.popoverId" role="listbox">
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { inject } from "vue";
9
- import { injectCombobox } from "../injectionKeys";
10
-
11
- const combobox = inject(injectCombobox);
12
- if (!combobox) {
13
- throw new Error("Combobox injectable context is not provided");
14
- }
15
- </script>
16
-
17
- <style scoped></style>
@@ -1,50 +0,0 @@
1
- import type { ComputedRef, InjectionKey } from "vue";
2
-
3
- import type { UseListReturn } from "../composables/list";
4
- import type { UsePopoverReturn } from "../composables/popover";
5
- import type { useFormControlReturn } from "../composables/formControl";
6
-
7
- export const injectTabs: InjectionKey<{
8
- getIds: (value: any) => ComputedRef<{
9
- tabId: string | undefined;
10
- panelId: string | undefined;
11
- }>;
12
- selectActiveItem: UseListReturn["selectActiveItem"];
13
- activateFirstItem: UseListReturn["activateFirstItem"];
14
- activateLastItem: UseListReturn["activateLastItem"];
15
- activateNextItem: UseListReturn["activateNextItem"];
16
- activatePrevItem: UseListReturn["activatePrevItem"];
17
- orientation: "horizontal" | "vertical";
18
- }> = Symbol();
19
-
20
- export const injectPopover: InjectionKey<{
21
- popoverId: string;
22
- activatorId: string;
23
- role: "dialog" | "listbox" | "menu" | "tree" | "grid";
24
- isOpen: UsePopoverReturn["isOpen"];
25
- close: UsePopoverReturn["close"];
26
- }> = Symbol();
27
-
28
- export const injectMenu: InjectionKey<{
29
- menuId: string;
30
- activatorId: string;
31
- isOpen: UsePopoverReturn["isOpen"];
32
- close: UsePopoverReturn["close"];
33
-
34
- activeItemId: ComputedRef<string | undefined>;
35
- isMultiselectable: UseListReturn["isMultiselectable"];
36
- activateFirstItem: UseListReturn["activateFirstItem"];
37
- activateLastItem: UseListReturn["activateLastItem"];
38
- activateNextItem: UseListReturn["activateNextItem"];
39
- activatePrevItem: UseListReturn["activatePrevItem"];
40
- }> = Symbol();
41
-
42
- export const injectCombobox: InjectionKey<{
43
- popoverId: string;
44
- isOpen: UsePopoverReturn["isOpen"];
45
- close: UsePopoverReturn["close"];
46
-
47
- isMultiselectable: UseListReturn["isMultiselectable"];
48
-
49
- focus: useFormControlReturn["focus"];
50
- }> = Symbol();