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,91 +0,0 @@
1
- <template>
2
- <div
3
- @keydown="onKeyDown"
4
- :aria-activedescendant="activeItemId"
5
- :aria-orientation="orientation"
6
- :aria-multiselectable="multiselectable"
7
- role="listbox"
8
- tabindex="0"
9
- >
10
- <slot />
11
- </div>
12
- </template>
13
-
14
- <script setup lang="ts">
15
- import { computed } from "vue";
16
- import { useList } from "../../composables/list";
17
-
18
- const props = withDefaults(
19
- defineProps<{
20
- orientation?: "horizontal" | "vertical";
21
- multiselectable?: boolean;
22
- loop?: boolean;
23
- }>(),
24
- {
25
- orientation: "vertical",
26
- multiselectable: false,
27
- loop: false,
28
- }
29
- );
30
-
31
- const model = defineModel();
32
-
33
- const {
34
- isMultiselectable,
35
- activeItem,
36
- selectActiveItem,
37
- activateFirstItem,
38
- activateLastItem,
39
- activateNextItem,
40
- activatePrevItem,
41
- } = useList(model);
42
-
43
- const activeItemId = computed(() => activeItem.value?.element.value?.id);
44
-
45
- function onKeyDown(evt: KeyboardEvent) {
46
- switch (evt.code) {
47
- case "Space":
48
- selectActiveItem();
49
- break;
50
- case "ArrowUp":
51
- if (props.orientation === "horizontal") return;
52
- activatePrevItem({ focus: false, loop: props.loop });
53
- if (!isMultiselectable.value) {
54
- selectActiveItem();
55
- }
56
- break;
57
- case "ArrowDown":
58
- if (props.orientation === "horizontal") return;
59
- activateNextItem({ focus: false, loop: props.loop });
60
- if (!isMultiselectable.value) {
61
- selectActiveItem();
62
- }
63
- break;
64
- case "ArrowLeft":
65
- if (props.orientation === "vertical") return;
66
- activatePrevItem({ focus: false, loop: props.loop });
67
- if (!isMultiselectable.value) {
68
- selectActiveItem();
69
- }
70
- break;
71
- case "ArrowRight":
72
- if (props.orientation === "vertical") return;
73
- activateNextItem({ focus: false, loop: props.loop });
74
- if (!isMultiselectable.value) {
75
- selectActiveItem();
76
- }
77
- break;
78
- case "Home":
79
- activateFirstItem({ focus: false });
80
- break;
81
- case "End":
82
- activateLastItem({ focus: false });
83
- break;
84
- default:
85
- return;
86
- }
87
- evt.preventDefault();
88
- }
89
- </script>
90
-
91
- <style scoped></style>
@@ -1,37 +0,0 @@
1
- <template>
2
- <div
3
- ref="itemEl"
4
- :id="itemId"
5
- @click="select"
6
- :aria-disabled="disabled"
7
- :aria-selected="isSelected"
8
- :data-active="isActive"
9
- role="option"
10
- tabindex="-1"
11
- >
12
- <slot :isSelected="isSelected" :isActive="isActive" />
13
- </div>
14
- </template>
15
-
16
- <script setup lang="ts">
17
- import { ref } from "vue";
18
- import { useSequentialId } from "../../utils/id";
19
- import { useListOption } from "../../composables/listOption";
20
-
21
- const props = defineProps<{
22
- id?: string;
23
- value?: any;
24
- disabled?: boolean;
25
- }>();
26
-
27
- const itemId = props.id ?? useSequentialId("list-option");
28
-
29
- const itemEl = ref<HTMLElement>();
30
- const { isSelected, isActive, select } = useListOption(
31
- itemEl,
32
- props.value,
33
- props.disabled
34
- );
35
- </script>
36
-
37
- <style scoped></style>
@@ -1,100 +0,0 @@
1
- <template>
2
- <slot :attrs="activatorAttrs"></slot>
3
- </template>
4
-
5
- <script setup lang="ts">
6
- import { computed, provide, nextTick } from "vue";
7
- import { useSequentialId } from "../../utils/id";
8
- import { usePopover } from "../../composables/popover";
9
- import { useList } from "../../composables/list";
10
- import { injectMenu } from "../injectionKeys";
11
-
12
- const props = withDefaults(
13
- defineProps<{
14
- id?: string;
15
- activatorId?: string;
16
- direction?: "up" | "down" | "left" | "right";
17
- align?: "top" | "bottom" | "left" | "right" | "center" | "stretch";
18
- position?: "fixed" | "absolute";
19
- }>(),
20
- {
21
- direction: "down",
22
- align: "left",
23
- position: "fixed",
24
- }
25
- );
26
-
27
- const menuId = props.id ?? useSequentialId("menu");
28
- const activatorId = props.activatorId ?? useSequentialId("menu-activator");
29
-
30
- const model = defineModel();
31
-
32
- const {
33
- isMultiselectable,
34
- activeItem,
35
- activateFirstItem,
36
- activateLastItem,
37
- activateNextItem,
38
- activatePrevItem,
39
- } = useList(model);
40
-
41
- const { isOpen, toggle, open, close } = usePopover(
42
- `#${activatorId}`,
43
- `#${menuId}`,
44
- {
45
- direction: props.direction,
46
- align: props.align,
47
- position: props.position,
48
- closeOnOutsideClick: true,
49
- closeOnInsideClick: false,
50
- }
51
- );
52
-
53
- function onActivatorKeyDown(evt: KeyboardEvent) {
54
- switch (evt.code) {
55
- case "Space":
56
- case "Enter":
57
- toggle();
58
- if (isOpen.value) {
59
- nextTick(activateFirstItem);
60
- }
61
- break;
62
- case "ArrowUp":
63
- open();
64
- nextTick(activateLastItem);
65
- break;
66
- case "ArrowDown":
67
- open();
68
- nextTick(activateFirstItem);
69
- break;
70
- default:
71
- return;
72
- }
73
- evt.preventDefault();
74
- }
75
-
76
- const activatorAttrs = computed(() => ({
77
- id: activatorId,
78
- "aria-controls": isOpen.value ? menuId : undefined,
79
- "aria-haspopup": "menu" as "menu",
80
- "aria-expanded": isOpen.value,
81
- onclick: toggle,
82
- onkeydown: onActivatorKeyDown,
83
- tabindex: 0,
84
- }));
85
-
86
- provide(injectMenu, {
87
- menuId: menuId,
88
- activatorId: activatorId,
89
- isOpen,
90
- close,
91
- isMultiselectable,
92
- activeItemId: computed(() => activeItem.value?.element.value?.id),
93
- activateFirstItem,
94
- activateLastItem,
95
- activateNextItem,
96
- activatePrevItem,
97
- });
98
- </script>
99
-
100
- <style scoped></style>
@@ -1,86 +0,0 @@
1
- <template>
2
- <div
3
- ref="itemEl"
4
- :id="itemId"
5
- @click="onClick"
6
- @keydown="onKeyDown"
7
- @mouseenter="activate({ focus: false })"
8
- :data-active="isActive"
9
- :role="role"
10
- :aria-checked="value !== undefined ? isSelected : undefined"
11
- :aria-disabled="disabled || undefined"
12
- tabindex="-1"
13
- >
14
- <slot :isSelected="isSelected" :isActive="isActive" />
15
- </div>
16
- </template>
17
-
18
- <script setup lang="ts">
19
- import { ref, inject, computed } from "vue";
20
- import { useSequentialId } from "../../utils/id";
21
- import { useListOption } from "../../composables/listOption";
22
- import { injectMenu } from "../injectionKeys";
23
-
24
- const props = defineProps<{
25
- id?: string;
26
- value?: any;
27
- disabled?: boolean;
28
- }>();
29
-
30
- const emit = defineEmits<{
31
- select: [value: any];
32
- }>();
33
-
34
- const itemId = props.id ?? useSequentialId("menu-item");
35
-
36
- const itemEl = ref<HTMLElement>();
37
- const { isSelected, isActive, select, activate } = useListOption(
38
- itemEl,
39
- props.value,
40
- props.disabled
41
- );
42
-
43
- const menu = inject(injectMenu);
44
- if (!menu) {
45
- throw new Error("Menu injectable context is not provided");
46
- }
47
-
48
- const role = computed(() => {
49
- if (props.value !== undefined) {
50
- return menu.isMultiselectable.value ? "menuitemcheckbox" : "menuitemradio";
51
- }
52
- return "menuitem";
53
- });
54
-
55
- function selectAndEmit() {
56
- select();
57
- emit("select", props.value);
58
- }
59
-
60
- function onClick() {
61
- selectAndEmit();
62
- if (props.value === undefined || !menu?.isMultiselectable.value) {
63
- menu!.close();
64
- }
65
- }
66
-
67
- function onKeyDown(evt: KeyboardEvent) {
68
- switch (evt.code) {
69
- case "Space":
70
- selectAndEmit();
71
- if (props.value === undefined) {
72
- menu!.close();
73
- }
74
- break;
75
- case "Enter":
76
- selectAndEmit();
77
- menu!.close();
78
- break;
79
- default:
80
- return;
81
- }
82
- evt.preventDefault();
83
- }
84
- </script>
85
-
86
- <style scoped></style>
@@ -1,51 +0,0 @@
1
- <template>
2
- <div
3
- v-if="menu!.isOpen.value"
4
- @keydown="onKeyDown"
5
- :id="menu!.menuId"
6
- :aria-activedescendant="menu!.activeItemId.value"
7
- :aria-labelledby="menu!.activatorId"
8
- role="menu"
9
- tabindex="-1"
10
- >
11
- <slot />
12
- </div>
13
- </template>
14
-
15
- <script setup lang="ts">
16
- import { inject } from "vue";
17
- import { injectMenu } from "../injectionKeys";
18
-
19
- const menu = inject(injectMenu);
20
- if (!menu) {
21
- throw new Error("Menu injectable context is not provided");
22
- }
23
-
24
- function onKeyDown(evt: KeyboardEvent) {
25
- switch (evt.code) {
26
- case "ArrowUp":
27
- menu!.activatePrevItem({ focus: true, loop: false });
28
- break;
29
- case "ArrowDown":
30
- menu!.activateNextItem({ focus: true, loop: false });
31
- break;
32
- case "Home":
33
- menu!.activateFirstItem({ focus: true });
34
- break;
35
- case "End":
36
- menu!.activateLastItem({ focus: true });
37
- break;
38
- case "Escape":
39
- menu!.close();
40
- break;
41
- case "Tab":
42
- menu!.isOpen.value = false;
43
- return;
44
- default:
45
- return;
46
- }
47
- evt.preventDefault();
48
- }
49
- </script>
50
-
51
- <style scoped></style>
@@ -1,68 +0,0 @@
1
- <template>
2
- <slot
3
- :attrs="activatorAttrs"
4
- :isOpen="isOpen"
5
- :toggle="toggle"
6
- :open="open"
7
- :close="close"
8
- ></slot>
9
- </template>
10
-
11
- <script setup lang="ts">
12
- import { provide, computed } from "vue";
13
- import { useSequentialId } from "../../utils/id";
14
- import { usePopover } from "../../composables/popover";
15
- import { injectPopover } from "../injectionKeys";
16
-
17
- const props = withDefaults(
18
- defineProps<{
19
- id?: string;
20
- activatorId?: string;
21
- direction?: "up" | "down" | "left" | "right";
22
- align?: "top" | "bottom" | "left" | "right" | "center" | "stretch";
23
- position?: "fixed" | "absolute";
24
- closeOnOutsideClick?: boolean;
25
- closeOnInsideClick?: boolean;
26
- role?: "dialog" | "listbox" | "menu" | "tree" | "grid";
27
- }>(),
28
- {
29
- id: useSequentialId("popover"),
30
- activatorId: useSequentialId("popover-activator"),
31
- direction: "down",
32
- align: "left",
33
- position: "fixed",
34
- closeOnOutsideClick: true,
35
- closeOnInsideClick: false,
36
- role: "dialog",
37
- }
38
- );
39
-
40
- const { isOpen, toggle, open, close } = usePopover(
41
- `#${props.activatorId}`,
42
- `#${props.id}`,
43
- {
44
- direction: props.direction,
45
- align: props.align,
46
- position: props.position,
47
- closeOnOutsideClick: props.closeOnOutsideClick,
48
- closeOnInsideClick: props.closeOnInsideClick,
49
- }
50
- );
51
-
52
- const activatorAttrs = computed(() => ({
53
- id: props.activatorId,
54
- "aria-controls": isOpen.value ? props.id : undefined,
55
- "aria-haspopup": props.role,
56
- "aria-expanded": isOpen.value,
57
- }));
58
-
59
- provide(injectPopover, {
60
- popoverId: props.id,
61
- activatorId: props.activatorId,
62
- role: props.role,
63
- isOpen,
64
- close,
65
- });
66
- </script>
67
-
68
- <style scoped></style>
@@ -1,35 +0,0 @@
1
- <template>
2
- <div
3
- v-if="popover!.isOpen.value"
4
- @keydown="onKeyDown"
5
- :id="popover!.popoverId"
6
- :role="popover!.role"
7
- :aria-labelledby="popover!.activatorId"
8
- tabindex="-1"
9
- >
10
- <slot />
11
- </div>
12
- </template>
13
-
14
- <script setup lang="ts">
15
- import { inject } from "vue";
16
- import { injectPopover } from "../injectionKeys";
17
-
18
- const popover = inject(injectPopover);
19
- if (!popover) {
20
- throw new Error("Popover injectable context is not provided");
21
- }
22
-
23
- function onKeyDown(evt: KeyboardEvent) {
24
- switch (evt.code) {
25
- case "Escape":
26
- popover!.close();
27
- break;
28
- default:
29
- return;
30
- }
31
- evt.preventDefault();
32
- }
33
- </script>
34
-
35
- <style scoped></style>
@@ -1,35 +0,0 @@
1
- <template>
2
- <button
3
- ref="tab"
4
- @click="select"
5
- :v="value"
6
- :id="tabId"
7
- :aria-selected="isSelected"
8
- :aria-controls="tabPanelId"
9
- :tabindex="isSelected ? 0 : -1"
10
- role="tab"
11
- >
12
- <slot />
13
- </button>
14
- </template>
15
-
16
- <script setup lang="ts">
17
- import { ref } from "vue";
18
- import { useSequentialId } from "../../utils/id";
19
- import { useListOption } from "../../composables/listOption";
20
-
21
- const props = defineProps<{
22
- id?: string;
23
- ariaControls?: string;
24
- value: any;
25
- }>();
26
-
27
- const tab = ref<HTMLButtonElement>();
28
-
29
- const { isSelected, select } = useListOption(tab, props.value);
30
-
31
- const tabId = props.id ?? useSequentialId("tab");
32
- const tabPanelId = props.ariaControls ?? useSequentialId("tab-panel");
33
- </script>
34
-
35
- <style scoped></style>
@@ -1,50 +0,0 @@
1
- <template>
2
- <div>
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { provide, computed } from "vue";
9
- import { useList } from "../../composables/list";
10
- import { injectTabs } from "../injectionKeys";
11
-
12
- const props = withDefaults(
13
- defineProps<{
14
- orientation?: "horizontal" | "vertical";
15
- }>(),
16
- {
17
- orientation: "horizontal",
18
- }
19
- );
20
-
21
- const model = defineModel();
22
-
23
- const {
24
- items,
25
- selectActiveItem,
26
- activateFirstItem,
27
- activateLastItem,
28
- activateNextItem,
29
- activatePrevItem,
30
- } = useList(model);
31
-
32
- provide(injectTabs, {
33
- getIds: (value: any) =>
34
- computed(() => {
35
- const item = items.value.find((item) => item.value === value);
36
- return {
37
- tabId: item?.element.value?.getAttribute("id") || undefined,
38
- panelId: item?.element.value?.getAttribute("aria-controls") || undefined,
39
- };
40
- }),
41
- selectActiveItem,
42
- activateFirstItem,
43
- activateLastItem,
44
- activateNextItem,
45
- activatePrevItem,
46
- orientation: props.orientation,
47
- });
48
- </script>
49
-
50
- <style scoped></style>
@@ -1,52 +0,0 @@
1
- <template>
2
- <div @keydown="onKeyDown" :aria-orientation="tabs!.orientation" role="tablist">
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { inject } from "vue";
9
- import { injectTabs } from "../injectionKeys";
10
-
11
- const tabs = inject(injectTabs);
12
- if (!tabs) {
13
- throw new Error("Tabs injectable context is not provided");
14
- }
15
-
16
- function onKeyDown(evt: KeyboardEvent) {
17
- switch (evt.code) {
18
- case "ArrowUp":
19
- if (tabs!.orientation === "vertical") {
20
- tabs!.activatePrevItem();
21
- }
22
- break;
23
- case "ArrowDown":
24
- if (tabs!.orientation === "vertical") {
25
- tabs!.activateNextItem();
26
- }
27
- break;
28
- case "ArrowLeft":
29
- if (tabs!.orientation === "horizontal") {
30
- tabs!.activatePrevItem();
31
- }
32
- break;
33
- case "ArrowRight":
34
- if (tabs!.orientation === "horizontal") {
35
- tabs!.activateNextItem();
36
- }
37
- break;
38
- case "Home":
39
- tabs!.activateFirstItem();
40
- break;
41
- case "End":
42
- tabs!.activateLastItem();
43
- break;
44
- default:
45
- return;
46
- }
47
- tabs!.selectActiveItem();
48
- evt.preventDefault();
49
- }
50
- </script>
51
-
52
- <style scoped></style>
@@ -1,36 +0,0 @@
1
- <template>
2
- <div
3
- v-if="isSelected"
4
- :id="ids.panelId"
5
- :aria-labelledby="ids.tabId"
6
- tabindex="0"
7
- role="tabpanel"
8
- >
9
- <slot />
10
- </div>
11
- </template>
12
-
13
- <script setup lang="ts">
14
- import { inject, computed } from "vue";
15
- import { injectList } from "../../composables/list";
16
- import { injectTabs } from "../injectionKeys";
17
-
18
- const props = defineProps<{
19
- value: string | number;
20
- }>();
21
-
22
- const list = inject(injectList);
23
- if (!list) {
24
- throw new Error("List injectable context is not provided");
25
- }
26
-
27
- const tabs = inject(injectTabs);
28
- if (!tabs) {
29
- throw new Error("Tabs injectable context is not provided");
30
- }
31
-
32
- const isSelected = computed(() => props.value === list.value.value);
33
- const ids = tabs.getIds(props.value);
34
- </script>
35
-
36
- <style scoped></style>