@soave/ui 0.2.2 → 0.3.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.
Files changed (100) hide show
  1. package/dist/components/Button.vue +36 -0
  2. package/dist/components/Card.vue +23 -0
  3. package/dist/components/Checkbox.vue +44 -0
  4. package/dist/components/Dialog.vue +99 -0
  5. package/dist/components/Input.vue +48 -0
  6. package/dist/components/RadioGroup.vue +35 -0
  7. package/dist/components/RadioItem.vue +55 -0
  8. package/dist/components/Select.vue +95 -0
  9. package/dist/components/SelectContent.vue +40 -0
  10. package/dist/components/SelectItem.vue +44 -0
  11. package/dist/components/SelectTrigger.vue +61 -0
  12. package/dist/components/Switch.vue +43 -0
  13. package/dist/components/Textarea.vue +55 -0
  14. package/dist/components/index.d.ts +13 -0
  15. package/dist/components/index.mjs +13 -0
  16. package/dist/composables/useButton.d.ts +2 -2
  17. package/dist/composables/useButton.mjs +14 -41
  18. package/dist/composables/useCard.d.ts +2 -2
  19. package/dist/composables/useCard.mjs +5 -18
  20. package/dist/composables/useCheckbox.d.ts +2 -1
  21. package/dist/composables/useCheckbox.mjs +11 -44
  22. package/dist/composables/useFileInput.d.ts +2 -0
  23. package/dist/composables/useFileInput.mjs +15 -30
  24. package/dist/composables/useInput.d.ts +2 -2
  25. package/dist/composables/useInput.mjs +12 -33
  26. package/dist/composables/useRadio.d.ts +2 -1
  27. package/dist/composables/useRadio.mjs +10 -42
  28. package/dist/composables/useSelect.d.ts +3 -0
  29. package/dist/composables/useSelect.mjs +20 -49
  30. package/dist/composables/useSwitch.d.ts +2 -1
  31. package/dist/composables/useSwitch.mjs +10 -43
  32. package/dist/composables/useTextarea.d.ts +2 -1
  33. package/dist/composables/useTextarea.mjs +12 -33
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.mjs +1 -1
  36. package/dist/types/button.d.ts +19 -5
  37. package/dist/types/card.d.ts +11 -2
  38. package/dist/types/checkbox.d.ts +15 -6
  39. package/dist/types/composables.d.ts +33 -5
  40. package/dist/types/file-input.d.ts +15 -5
  41. package/dist/types/input.d.ts +17 -6
  42. package/dist/types/radio.d.ts +14 -6
  43. package/dist/types/select.d.ts +25 -7
  44. package/dist/types/switch.d.ts +14 -5
  45. package/dist/types/textarea.d.ts +18 -7
  46. package/package.json +1 -9
  47. package/dist/components/ui/Alert.vue +0 -41
  48. package/dist/components/ui/AlertDescription.vue +0 -22
  49. package/dist/components/ui/AlertTitle.vue +0 -22
  50. package/dist/components/ui/Button.vue +0 -85
  51. package/dist/components/ui/Card.vue +0 -39
  52. package/dist/components/ui/CardContent.vue +0 -22
  53. package/dist/components/ui/CardDescription.vue +0 -22
  54. package/dist/components/ui/CardFooter.vue +0 -22
  55. package/dist/components/ui/CardHeader.vue +0 -22
  56. package/dist/components/ui/CardTitle.vue +0 -22
  57. package/dist/components/ui/Checkbox.vue +0 -94
  58. package/dist/components/ui/Dialog.vue +0 -110
  59. package/dist/components/ui/DialogDescription.vue +0 -22
  60. package/dist/components/ui/DialogFooter.vue +0 -22
  61. package/dist/components/ui/DialogHeader.vue +0 -22
  62. package/dist/components/ui/DialogTitle.vue +0 -22
  63. package/dist/components/ui/DropdownMenu.vue +0 -32
  64. package/dist/components/ui/DropdownMenuContent.vue +0 -69
  65. package/dist/components/ui/DropdownMenuItem.vue +0 -71
  66. package/dist/components/ui/DropdownMenuLabel.vue +0 -20
  67. package/dist/components/ui/DropdownMenuSeparator.vue +0 -16
  68. package/dist/components/ui/DropdownMenuTrigger.vue +0 -38
  69. package/dist/components/ui/FileInput.vue +0 -153
  70. package/dist/components/ui/FormError.vue +0 -20
  71. package/dist/components/ui/FormField.vue +0 -12
  72. package/dist/components/ui/FormInput.vue +0 -46
  73. package/dist/components/ui/FormLabel.vue +0 -19
  74. package/dist/components/ui/FormTextarea.vue +0 -39
  75. package/dist/components/ui/Input.vue +0 -72
  76. package/dist/components/ui/Popover.vue +0 -35
  77. package/dist/components/ui/PopoverContent.vue +0 -66
  78. package/dist/components/ui/PopoverTrigger.vue +0 -36
  79. package/dist/components/ui/RadioGroup.vue +0 -47
  80. package/dist/components/ui/RadioItem.vue +0 -62
  81. package/dist/components/ui/Select.vue +0 -62
  82. package/dist/components/ui/SelectContent.vue +0 -55
  83. package/dist/components/ui/SelectItem.vue +0 -55
  84. package/dist/components/ui/SelectTrigger.vue +0 -70
  85. package/dist/components/ui/SelectValue.vue +0 -27
  86. package/dist/components/ui/Sheet.vue +0 -148
  87. package/dist/components/ui/SheetDescription.vue +0 -22
  88. package/dist/components/ui/SheetFooter.vue +0 -22
  89. package/dist/components/ui/SheetHeader.vue +0 -22
  90. package/dist/components/ui/SheetTitle.vue +0 -22
  91. package/dist/components/ui/Switch.vue +0 -63
  92. package/dist/components/ui/Textarea.vue +0 -73
  93. package/dist/components/ui/Toast.vue +0 -116
  94. package/dist/components/ui/Toaster.vue +0 -76
  95. package/dist/components/ui/Tooltip.vue +0 -41
  96. package/dist/components/ui/TooltipContent.vue +0 -71
  97. package/dist/components/ui/TooltipTrigger.vue +0 -39
  98. package/dist/components/ui/UIProvider.vue +0 -23
  99. package/dist/components/ui/index.d.ts +0 -52
  100. package/dist/components/ui/index.mjs +0 -52
@@ -1,71 +0,0 @@
1
- <template>
2
- <div
3
- role="menuitem"
4
- :tabindex="disabled ? -1 : 0"
5
- :class="[computed_classes, props.class]"
6
- :aria-disabled="disabled"
7
- :data-highlighted="is_active ? '' : undefined"
8
- :data-disabled="disabled ? '' : undefined"
9
- @click="handleClick"
10
- @mouseenter="handleMouseEnter"
11
- @keydown.enter="handleClick"
12
- @keydown.space.prevent="handleClick"
13
- >
14
- <slot />
15
- </div>
16
- </template>
17
-
18
- <script setup lang="ts">
19
- import { inject, computed, onMounted } from "vue"
20
- import { useStyleAdapter } from "../../composables"
21
- import type { DropdownItemProps } from "../../types/dropdown"
22
- import { DROPDOWN_CONTEXT_KEY } from "../../types/dropdown"
23
-
24
- const props = withDefaults(defineProps<DropdownItemProps>(), {
25
- disabled: false,
26
- destructive: false,
27
- unstyled: false
28
- })
29
-
30
- const emit = defineEmits<{
31
- select: []
32
- }>()
33
-
34
- const context = inject(DROPDOWN_CONTEXT_KEY)
35
-
36
- if (!context) {
37
- throw new Error("DropdownMenuItem must be used within a DropdownMenu component")
38
- }
39
-
40
- const { active_item_index, close, registerItem, setActiveItem } = context
41
- const style_adapter = useStyleAdapter()
42
-
43
- let item_index = -1
44
-
45
- onMounted(() => {
46
- if (!props.disabled) {
47
- item_index = registerItem()
48
- }
49
- })
50
-
51
- const is_active = computed(() => {
52
- return active_item_index.value === item_index && !props.disabled
53
- })
54
-
55
- const handleClick = (): void => {
56
- if (props.disabled) return
57
- emit("select")
58
- close()
59
- }
60
-
61
- const handleMouseEnter = (): void => {
62
- if (!props.disabled && item_index >= 0) {
63
- setActiveItem(item_index)
64
- }
65
- }
66
-
67
- const computed_classes = computed(() => {
68
- if (props.unstyled) return ""
69
- return style_adapter.getClasses("dropdown-item", {})
70
- })
71
- </script>
@@ -1,20 +0,0 @@
1
- <template>
2
- <div
3
- :class="cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', props.class)"
4
- >
5
- <slot />
6
- </div>
7
- </template>
8
-
9
- <script setup lang="ts">
10
- import { cn } from "../../utils/cn"
11
-
12
- export interface Props {
13
- inset?: boolean
14
- class?: string
15
- }
16
-
17
- const props = withDefaults(defineProps<Props>(), {
18
- inset: false
19
- })
20
- </script>
@@ -1,16 +0,0 @@
1
- <template>
2
- <div
3
- role="separator"
4
- :class="cn('-mx-1 my-1 h-px bg-muted', props.class)"
5
- />
6
- </template>
7
-
8
- <script setup lang="ts">
9
- import { cn } from "../../utils/cn"
10
-
11
- export interface Props {
12
- class?: string
13
- }
14
-
15
- const props = defineProps<Props>()
16
- </script>
@@ -1,38 +0,0 @@
1
- <template>
2
- <button
3
- ref="trigger_element"
4
- type="button"
5
- :aria-expanded="is_open"
6
- :aria-controls="dropdown_id"
7
- :aria-haspopup="true"
8
- @click="handleTriggerClick"
9
- @keydown="handleTriggerKeyDown"
10
- >
11
- <slot />
12
- </button>
13
- </template>
14
-
15
- <script setup lang="ts">
16
- import { inject, ref, watchEffect } from "vue"
17
- import { DROPDOWN_CONTEXT_KEY } from "../../types/dropdown"
18
-
19
- const context = inject(DROPDOWN_CONTEXT_KEY)
20
-
21
- if (!context) {
22
- throw new Error("DropdownMenuTrigger must be used within a DropdownMenu component")
23
- }
24
-
25
- const {
26
- is_open,
27
- trigger_ref,
28
- dropdown_id,
29
- handleTriggerClick,
30
- handleTriggerKeyDown
31
- } = context
32
-
33
- const trigger_element = ref<HTMLElement | null>(null)
34
-
35
- watchEffect(() => {
36
- trigger_ref.value = trigger_element.value
37
- })
38
- </script>
@@ -1,153 +0,0 @@
1
- <template>
2
- <div :class="composable.base_classes.value">
3
- <input
4
- ref="input_ref"
5
- type="file"
6
- :accept="accept"
7
- :multiple="multiple"
8
- :disabled="composable.is_disabled.value"
9
- class="sr-only"
10
- @change="handleChange"
11
- />
12
-
13
- <div
14
- :class="composable.dropzone_classes.value"
15
- v-bind="composable.aria_attributes.value"
16
- @click="composable.openFilePicker"
17
- @dragenter="composable.handleDragEnter"
18
- @dragleave="composable.handleDragLeave"
19
- @dragover.prevent
20
- @drop="composable.handleDrop"
21
- >
22
- <slot name="dropzone">
23
- <svg
24
- class="w-10 h-10 mb-3 text-muted-foreground"
25
- xmlns="http://www.w3.org/2000/svg"
26
- viewBox="0 0 24 24"
27
- fill="none"
28
- stroke="currentColor"
29
- stroke-width="1.5"
30
- stroke-linecap="round"
31
- stroke-linejoin="round"
32
- >
33
- <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
34
- <polyline points="17 8 12 3 7 8" />
35
- <line x1="12" y1="3" x2="12" y2="15" />
36
- </svg>
37
- <p class="text-sm text-muted-foreground">
38
- <span class="font-semibold text-primary">クリック</span>
39
- または ドラッグ&ドロップ
40
- </p>
41
- <p v-if="accept" class="mt-1 text-xs text-muted-foreground">
42
- {{ accept }}
43
- </p>
44
- </slot>
45
- </div>
46
-
47
- <p
48
- v-if="composable.error.value"
49
- class="mt-2 text-sm text-destructive"
50
- >
51
- {{ composable.error.value }}
52
- </p>
53
-
54
- <ul
55
- v-if="composable.files.value.length > 0"
56
- class="mt-4 space-y-2"
57
- >
58
- <li
59
- v-for="(file, index) in composable.files.value"
60
- :key="file.name + index"
61
- class="flex items-center gap-3 p-2 rounded-md border bg-muted/50"
62
- >
63
- <img
64
- v-if="file.preview_url"
65
- :src="file.preview_url"
66
- :alt="file.name"
67
- class="w-10 h-10 object-cover rounded"
68
- />
69
- <svg
70
- v-else
71
- class="w-10 h-10 text-muted-foreground"
72
- xmlns="http://www.w3.org/2000/svg"
73
- viewBox="0 0 24 24"
74
- fill="none"
75
- stroke="currentColor"
76
- stroke-width="1.5"
77
- >
78
- <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
79
- <polyline points="14 2 14 8 20 8" />
80
- </svg>
81
- <div class="flex-1 min-w-0">
82
- <p class="text-sm font-medium truncate">{{ file.name }}</p>
83
- <p class="text-xs text-muted-foreground">
84
- {{ formatSize(file.size) }}
85
- </p>
86
- </div>
87
- <button
88
- type="button"
89
- class="p-1 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive"
90
- @click.stop="composable.removeFile(index)"
91
- >
92
- <svg
93
- class="w-4 h-4"
94
- xmlns="http://www.w3.org/2000/svg"
95
- viewBox="0 0 24 24"
96
- fill="none"
97
- stroke="currentColor"
98
- stroke-width="2"
99
- >
100
- <line x1="18" y1="6" x2="6" y2="18" />
101
- <line x1="6" y1="6" x2="18" y2="18" />
102
- </svg>
103
- </button>
104
- </li>
105
- </ul>
106
- </div>
107
- </template>
108
-
109
- <script setup lang="ts">
110
- import { ref, toRef, watch } from "vue"
111
- import { useFileInput } from "../../composables/useFileInput"
112
- import type { FileInputProps, FileInfo } from "../../types/file-input"
113
-
114
- interface Props extends FileInputProps {
115
- modelValue?: File | File[] | null
116
- }
117
-
118
- const props = withDefaults(defineProps<Props>(), {
119
- multiple: false,
120
- disabled: false
121
- })
122
-
123
- const emit = defineEmits<{
124
- "update:modelValue": [value: File | File[] | null]
125
- }>()
126
-
127
- const input_ref = ref<HTMLInputElement | null>(null)
128
- const composable = useFileInput(toRef(() => props), input_ref)
129
-
130
- const formatSize = (bytes: number): string => {
131
- if (bytes < 1024) return `${bytes}B`
132
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`
133
- return `${(bytes / (1024 * 1024)).toFixed(1)}MB`
134
- }
135
-
136
- const handleChange = (event: Event) => {
137
- const target = event.target as HTMLInputElement
138
- composable.handleFiles(target.files)
139
- target.value = ""
140
- }
141
-
142
- watch(
143
- () => composable.files.value,
144
- (new_files: FileInfo[]) => {
145
- if (props.multiple) {
146
- emit("update:modelValue", new_files.map(f => f.file))
147
- } else {
148
- emit("update:modelValue", new_files[0]?.file ?? null)
149
- }
150
- },
151
- { deep: true }
152
- )
153
- </script>
@@ -1,20 +0,0 @@
1
- <template>
2
- <p
3
- v-if="$slots.default"
4
- :id="id"
5
- :class="cn('text-sm font-medium text-destructive', props.class)"
6
- >
7
- <slot />
8
- </p>
9
- </template>
10
-
11
- <script setup lang="ts">
12
- import { cn } from "../../utils/cn"
13
- import type { FormErrorProps } from "../../types/form"
14
-
15
- interface Props extends FormErrorProps {
16
- id?: string
17
- }
18
-
19
- const props = defineProps<Props>()
20
- </script>
@@ -1,12 +0,0 @@
1
- <template>
2
- <div :class="cn('space-y-2', props.class)">
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { cn } from "../../utils/cn"
9
- import type { FormFieldProps } from "../../types/form"
10
-
11
- const props = defineProps<FormFieldProps>()
12
- </script>
@@ -1,46 +0,0 @@
1
- <template>
2
- <Input
3
- :id="id"
4
- :type="type"
5
- :size="size"
6
- :placeholder="placeholder"
7
- :disabled="disabled"
8
- :readonly="readonly"
9
- :error="error"
10
- :error_id="error_id"
11
- :model-value="modelValue"
12
- :class="props.class"
13
- @update:model-value="emit('update:modelValue', $event)"
14
- @blur="emit('blur', $event)"
15
- />
16
- </template>
17
-
18
- <script setup lang="ts">
19
- import Input from "./Input.vue"
20
- import type { InputType, InputSize } from "../../types/input"
21
-
22
- interface Props {
23
- id?: string
24
- type?: InputType
25
- size?: InputSize
26
- placeholder?: string
27
- disabled?: boolean
28
- readonly?: boolean
29
- error?: string
30
- error_id?: string
31
- modelValue?: string | number
32
- class?: string
33
- }
34
-
35
- const props = withDefaults(defineProps<Props>(), {
36
- type: "text",
37
- size: "md",
38
- disabled: false,
39
- readonly: false
40
- })
41
-
42
- const emit = defineEmits<{
43
- "update:modelValue": [value: string | number]
44
- blur: [event: FocusEvent]
45
- }>()
46
- </script>
@@ -1,19 +0,0 @@
1
- <template>
2
- <label
3
- :for="props.for"
4
- :class="cn(
5
- 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
6
- props.class
7
- )"
8
- >
9
- <slot />
10
- <span v-if="props.required" class="text-destructive ml-1">*</span>
11
- </label>
12
- </template>
13
-
14
- <script setup lang="ts">
15
- import { cn } from "../../utils/cn"
16
- import type { FormLabelProps } from "../../types/form"
17
-
18
- const props = defineProps<FormLabelProps>()
19
- </script>
@@ -1,39 +0,0 @@
1
- <template>
2
- <Textarea
3
- :id="id"
4
- :placeholder="placeholder"
5
- :disabled="disabled"
6
- :readonly="readonly"
7
- :error="error"
8
- :error_id="error_id"
9
- :rows="rows"
10
- :resize="resize"
11
- :model-value="modelValue"
12
- :class="props.class"
13
- @update:model-value="emit('update:modelValue', $event)"
14
- @blur="emit('blur', $event)"
15
- />
16
- </template>
17
-
18
- <script setup lang="ts">
19
- import Textarea from "./Textarea.vue"
20
- import type { TextareaProps } from "../../types/textarea"
21
-
22
- interface Props extends TextareaProps {
23
- id?: string
24
- modelValue?: string
25
- class?: string
26
- }
27
-
28
- const props = withDefaults(defineProps<Props>(), {
29
- rows: 3,
30
- resize: "vertical",
31
- disabled: false,
32
- readonly: false
33
- })
34
-
35
- const emit = defineEmits<{
36
- "update:modelValue": [value: string]
37
- blur: [event: FocusEvent]
38
- }>()
39
- </script>
@@ -1,72 +0,0 @@
1
- <template>
2
- <input
3
- :id="id"
4
- :type="type"
5
- :class="[computed_classes, props.class]"
6
- :disabled="composable.is_disabled.value"
7
- :readonly="composable.is_readonly.value"
8
- :placeholder="placeholder"
9
- :value="modelValue"
10
- v-bind="composable.aria_attributes.value"
11
- @input="handleInput"
12
- @focus="composable.handleFocus"
13
- @blur="handleBlur"
14
- />
15
- </template>
16
-
17
- <script setup lang="ts">
18
- import { toRef, computed } from "vue"
19
- import { useInput } from "../../composables/useInput"
20
- import { useStyleAdapter, useUI } from "../../composables/useUIConfig"
21
- import type { InputProps, InputType } from "../../types/input"
22
- import type { InputState } from "../../types/composables"
23
-
24
- interface Props extends InputProps {
25
- id?: string
26
- modelValue?: string | number
27
- class?: string
28
- unstyled?: boolean
29
- }
30
-
31
- const props = withDefaults(defineProps<Props>(), {
32
- type: "text" as InputType,
33
- disabled: false,
34
- readonly: false,
35
- unstyled: false
36
- })
37
-
38
- const emit = defineEmits<{
39
- "update:modelValue": [value: string | number]
40
- blur: [event: FocusEvent]
41
- }>()
42
-
43
- const ui_config = useUI("input")
44
- const style_adapter = useStyleAdapter()
45
- const composable = useInput(toRef(() => props))
46
-
47
- // StyleAdapterからクラスを取得
48
- const computed_classes = computed(() => {
49
- if (props.unstyled) {
50
- return ""
51
- }
52
-
53
- const state: InputState = {
54
- size: props.size ?? ui_config.default_size,
55
- disabled: composable.is_disabled.value,
56
- readonly: composable.is_readonly.value,
57
- error: props.error
58
- }
59
-
60
- return style_adapter.getClasses("input", state)
61
- })
62
-
63
- const handleInput = (event: Event) => {
64
- const target = event.target as HTMLInputElement
65
- emit("update:modelValue", target.value)
66
- }
67
-
68
- const handleBlur = (event: FocusEvent) => {
69
- composable.handleBlur()
70
- emit("blur", event)
71
- }
72
- </script>
@@ -1,35 +0,0 @@
1
- <template>
2
- <div class="relative inline-block" :class="props.class">
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { provide, ref, type Ref } from "vue"
9
- import { usePopover } from "../../composables/usePopover"
10
- import type { PopoverSide, PopoverAlign } from "../../types/popover"
11
- import { POPOVER_CONTEXT_KEY } from "../../types/popover"
12
-
13
- interface Props {
14
- side?: PopoverSide
15
- align?: PopoverAlign
16
- modal?: boolean
17
- class?: string
18
- }
19
-
20
- const props = withDefaults(defineProps<Props>(), {
21
- side: "bottom",
22
- align: "center",
23
- modal: false
24
- })
25
-
26
- const popover_props = ref({
27
- side: props.side,
28
- align: props.align,
29
- modal: props.modal
30
- })
31
-
32
- const popover = usePopover(popover_props as Ref<typeof popover_props.value>)
33
-
34
- provide(POPOVER_CONTEXT_KEY, popover)
35
- </script>
@@ -1,66 +0,0 @@
1
- <template>
2
- <Transition name="popover">
3
- <div
4
- v-if="is_open"
5
- ref="content_element"
6
- :id="popover_id"
7
- role="dialog"
8
- aria-modal="false"
9
- :style="position_styles"
10
- :class="[computed_classes, props.class]"
11
- tabindex="-1"
12
- >
13
- <slot />
14
- </div>
15
- </Transition>
16
- </template>
17
-
18
- <script setup lang="ts">
19
- import { inject, ref, computed, watchEffect, onMounted } from "vue"
20
- import { useStyleAdapter } from "../../composables"
21
- import type { PopoverContentProps } from "../../types/popover"
22
- import { POPOVER_CONTEXT_KEY } from "../../types/popover"
23
- import type { PopoverState } from "../../types/composables"
24
-
25
- const props = withDefaults(defineProps<PopoverContentProps>(), {
26
- unstyled: false
27
- })
28
-
29
- const context = inject(POPOVER_CONTEXT_KEY)
30
-
31
- if (!context) {
32
- throw new Error("PopoverContent must be used within a Popover component")
33
- }
34
-
35
- const {
36
- is_open,
37
- content_ref,
38
- popover_id,
39
- position_styles
40
- } = context
41
-
42
- const style_adapter = useStyleAdapter()
43
- const content_element = ref<HTMLElement | null>(null)
44
-
45
- watchEffect(() => {
46
- content_ref.value = content_element.value
47
- })
48
-
49
- onMounted(() => {
50
- if (is_open.value && content_element.value) {
51
- content_element.value.focus()
52
- }
53
- })
54
-
55
- const computed_classes = computed(() => {
56
- if (props.unstyled) return ""
57
- const state: PopoverState = {
58
- is_open: is_open.value
59
- }
60
- return style_adapter.getClasses("popover", state)
61
- })
62
- </script>
63
-
64
- <style scoped>
65
- .popover-enter-active,.popover-leave-active{transition:opacity .2s ease,transform .2s ease}.popover-enter-from,.popover-leave-to{opacity:0;transform:scale(.95)}
66
- </style>
@@ -1,36 +0,0 @@
1
- <template>
2
- <button
3
- ref="trigger_element"
4
- type="button"
5
- :aria-expanded="is_open"
6
- :aria-controls="popover_id"
7
- :aria-haspopup="true"
8
- @click="handleTriggerClick"
9
- >
10
- <slot />
11
- </button>
12
- </template>
13
-
14
- <script setup lang="ts">
15
- import { inject, ref, watchEffect } from "vue"
16
- import { POPOVER_CONTEXT_KEY } from "../../types/popover"
17
-
18
- const context = inject(POPOVER_CONTEXT_KEY)
19
-
20
- if (!context) {
21
- throw new Error("PopoverTrigger must be used within a Popover component")
22
- }
23
-
24
- const {
25
- is_open,
26
- trigger_ref,
27
- popover_id,
28
- handleTriggerClick
29
- } = context
30
-
31
- const trigger_element = ref<HTMLElement | null>(null)
32
-
33
- watchEffect(() => {
34
- trigger_ref.value = trigger_element.value
35
- })
36
- </script>