@soave/ui 0.1.0 → 0.2.0
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/dist/adapters/css-variables.d.ts +2 -0
- package/dist/adapters/css-variables.mjs +228 -0
- package/dist/adapters/headless.d.ts +7 -0
- package/dist/adapters/headless.mjs +7 -0
- package/dist/adapters/index.d.ts +5 -0
- package/dist/adapters/index.mjs +11 -0
- package/dist/adapters/tailwind.d.ts +2 -0
- package/dist/adapters/tailwind.mjs +443 -0
- package/dist/adapters/types.d.ts +38 -0
- package/dist/adapters/types.mjs +10 -0
- package/dist/build.config.mjs +1 -1
- package/dist/components/ui/Alert.vue +18 -16
- package/dist/components/ui/AlertDescription.vue +13 -3
- package/dist/components/ui/AlertTitle.vue +13 -3
- package/dist/components/ui/Button.vue +30 -4
- package/dist/components/ui/Card.vue +27 -3
- package/dist/components/ui/CardContent.vue +13 -3
- package/dist/components/ui/CardDescription.vue +13 -3
- package/dist/components/ui/CardFooter.vue +13 -3
- package/dist/components/ui/CardHeader.vue +13 -3
- package/dist/components/ui/CardTitle.vue +13 -3
- package/dist/components/ui/Checkbox.vue +23 -2
- package/dist/components/ui/Dialog.vue +31 -9
- package/dist/components/ui/DialogDescription.vue +13 -3
- package/dist/components/ui/DialogFooter.vue +13 -3
- package/dist/components/ui/DialogHeader.vue +13 -3
- package/dist/components/ui/DialogTitle.vue +13 -3
- package/dist/components/ui/DropdownMenuContent.vue +16 -13
- package/dist/components/ui/DropdownMenuItem.vue +11 -17
- package/dist/components/ui/Input.vue +26 -3
- package/dist/components/ui/PopoverContent.vue +16 -12
- package/dist/components/ui/RadioGroup.vue +12 -7
- package/dist/components/ui/RadioItem.vue +31 -10
- package/dist/components/ui/Select.vue +8 -1
- package/dist/components/ui/SelectContent.vue +31 -5
- package/dist/components/ui/SelectItem.vue +20 -16
- package/dist/components/ui/SelectTrigger.vue +39 -7
- package/dist/components/ui/SelectValue.vue +13 -2
- package/dist/components/ui/Sheet.vue +32 -24
- package/dist/components/ui/SheetDescription.vue +13 -6
- package/dist/components/ui/SheetFooter.vue +13 -6
- package/dist/components/ui/SheetHeader.vue +13 -6
- package/dist/components/ui/SheetTitle.vue +13 -6
- package/dist/components/ui/Switch.vue +23 -3
- package/dist/components/ui/Textarea.vue +26 -3
- package/dist/components/ui/Toast.vue +38 -29
- package/dist/components/ui/Toaster.vue +12 -16
- package/dist/components/ui/TooltipContent.vue +18 -15
- package/dist/components/ui/UIProvider.vue +6 -2
- package/dist/composables/index.d.ts +1 -1
- package/dist/composables/index.mjs +1 -1
- package/dist/composables/useUIConfig.d.ts +16 -5
- package/dist/composables/useUIConfig.mjs +26 -9
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +1 -0
- package/dist/styles/css-variables.css +1 -0
- package/dist/styles/index.d.ts +1 -0
- package/dist/styles/index.mjs +1 -0
- package/dist/types/alert.d.ts +2 -0
- package/dist/types/card.d.ts +5 -0
- package/dist/types/composables.d.ts +122 -0
- package/dist/types/composables.mjs +0 -0
- package/dist/types/config.d.ts +8 -0
- package/dist/types/dialog.d.ts +7 -0
- package/dist/types/dropdown.d.ts +8 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.mjs +1 -0
- package/dist/types/popover.d.ts +6 -0
- package/dist/types/radio.d.ts +4 -0
- package/dist/types/select.d.ts +21 -0
- package/dist/types/sheet.d.ts +19 -0
- package/dist/types/toast.d.ts +2 -0
- package/dist/types/tooltip.d.ts +6 -0
- package/package.json +9 -1
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
role="radiogroup"
|
|
4
|
-
:class="
|
|
5
|
-
'grid gap-2',
|
|
6
|
-
orientation === 'horizontal' && 'grid-flow-col'
|
|
7
|
-
)"
|
|
4
|
+
:class="[computed_classes, props.class]"
|
|
8
5
|
>
|
|
9
6
|
<slot />
|
|
10
7
|
</div>
|
|
11
8
|
</template>
|
|
12
9
|
|
|
13
10
|
<script setup lang="ts">
|
|
14
|
-
import { provide, toRef } from "vue"
|
|
15
|
-
import {
|
|
11
|
+
import { provide, toRef, computed } from "vue"
|
|
12
|
+
import { useStyleAdapter } from "../../composables"
|
|
16
13
|
import type { RadioGroupProps, RadioGroupContext } from "../../types/radio"
|
|
17
14
|
import { RADIO_GROUP_KEY } from "../../types/radio"
|
|
18
15
|
|
|
@@ -23,13 +20,21 @@ interface Props extends RadioGroupProps {
|
|
|
23
20
|
const props = withDefaults(defineProps<Props>(), {
|
|
24
21
|
modelValue: "",
|
|
25
22
|
disabled: false,
|
|
26
|
-
orientation: "vertical"
|
|
23
|
+
orientation: "vertical",
|
|
24
|
+
unstyled: false
|
|
27
25
|
})
|
|
28
26
|
|
|
29
27
|
const emit = defineEmits<{
|
|
30
28
|
"update:modelValue": [value: string]
|
|
31
29
|
}>()
|
|
32
30
|
|
|
31
|
+
const style_adapter = useStyleAdapter()
|
|
32
|
+
|
|
33
|
+
const computed_classes = computed(() => {
|
|
34
|
+
if (props.unstyled) return ""
|
|
35
|
+
return style_adapter.getClasses("radio-group", { orientation: props.orientation })
|
|
36
|
+
})
|
|
37
|
+
|
|
33
38
|
const context: RadioGroupContext = {
|
|
34
39
|
model_value: toRef(() => props.modelValue),
|
|
35
40
|
disabled: toRef(() => props.disabled),
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button
|
|
3
3
|
type="button"
|
|
4
|
-
:class="
|
|
5
|
-
:disabled="
|
|
6
|
-
|
|
4
|
+
:class="[computed_classes, props.class]"
|
|
5
|
+
:disabled="is_disabled"
|
|
6
|
+
role="radio"
|
|
7
|
+
:aria-checked="is_checked"
|
|
8
|
+
:aria-disabled="is_disabled || undefined"
|
|
7
9
|
@click="handleClick"
|
|
8
10
|
>
|
|
9
11
|
<span
|
|
10
|
-
v-if="
|
|
11
|
-
:class="
|
|
12
|
+
v-if="is_checked"
|
|
13
|
+
:class="indicator_classes"
|
|
12
14
|
>
|
|
13
15
|
<svg
|
|
14
16
|
class="fill-current"
|
|
@@ -21,20 +23,39 @@
|
|
|
21
23
|
</template>
|
|
22
24
|
|
|
23
25
|
<script setup lang="ts">
|
|
24
|
-
import { inject,
|
|
25
|
-
import {
|
|
26
|
+
import { inject, computed } from "vue"
|
|
27
|
+
import { useStyleAdapter } from "../../composables"
|
|
26
28
|
import type { RadioItemProps, RadioGroupContext } from "../../types/radio"
|
|
27
29
|
import { RADIO_GROUP_KEY } from "../../types/radio"
|
|
30
|
+
import type { RadioState } from "../../types/composables"
|
|
28
31
|
|
|
29
32
|
const props = withDefaults(defineProps<RadioItemProps>(), {
|
|
30
|
-
disabled: false
|
|
33
|
+
disabled: false,
|
|
34
|
+
unstyled: false
|
|
31
35
|
})
|
|
32
36
|
|
|
33
37
|
const context = inject<RadioGroupContext>(RADIO_GROUP_KEY)
|
|
34
|
-
const
|
|
38
|
+
const style_adapter = useStyleAdapter()
|
|
39
|
+
|
|
40
|
+
const is_checked = computed(() => context?.model_value.value === props.value)
|
|
41
|
+
const is_disabled = computed(() => props.disabled || context?.disabled.value || false)
|
|
42
|
+
|
|
43
|
+
const computed_classes = computed(() => {
|
|
44
|
+
if (props.unstyled) return ""
|
|
45
|
+
const state: RadioState = {
|
|
46
|
+
checked: is_checked.value,
|
|
47
|
+
disabled: is_disabled.value
|
|
48
|
+
}
|
|
49
|
+
return style_adapter.getClasses("radio", state)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const indicator_classes = computed(() => {
|
|
53
|
+
if (props.unstyled) return ""
|
|
54
|
+
return style_adapter.getClasses("radio-indicator", {})
|
|
55
|
+
})
|
|
35
56
|
|
|
36
57
|
const handleClick = () => {
|
|
37
|
-
if (!
|
|
58
|
+
if (!is_disabled.value && context) {
|
|
38
59
|
context.updateValue(props.value)
|
|
39
60
|
}
|
|
40
61
|
}
|
|
@@ -11,13 +11,15 @@ import { SELECT_KEY } from "../../types/select"
|
|
|
11
11
|
|
|
12
12
|
interface Props extends SelectProps {
|
|
13
13
|
modelValue?: string
|
|
14
|
+
class?: string
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
const props = withDefaults(defineProps<Props>(), {
|
|
17
18
|
modelValue: "",
|
|
18
19
|
size: "md" as SelectSize,
|
|
19
20
|
disabled: false,
|
|
20
|
-
placeholder: "Select..."
|
|
21
|
+
placeholder: "Select...",
|
|
22
|
+
unstyled: false
|
|
21
23
|
})
|
|
22
24
|
|
|
23
25
|
const emit = defineEmits<{
|
|
@@ -25,6 +27,7 @@ const emit = defineEmits<{
|
|
|
25
27
|
}>()
|
|
26
28
|
|
|
27
29
|
const is_open = ref(false)
|
|
30
|
+
const trigger_ref = ref<HTMLElement | null>(null)
|
|
28
31
|
|
|
29
32
|
const context: SelectContext = {
|
|
30
33
|
model_value: toRef(() => props.modelValue),
|
|
@@ -32,6 +35,7 @@ const context: SelectContext = {
|
|
|
32
35
|
disabled: toRef(() => props.disabled),
|
|
33
36
|
size: toRef(() => props.size ?? "md"),
|
|
34
37
|
placeholder: toRef(() => props.placeholder ?? "Select..."),
|
|
38
|
+
trigger_ref,
|
|
35
39
|
updateValue: (value: string) => {
|
|
36
40
|
emit("update:modelValue", value)
|
|
37
41
|
is_open.value = false
|
|
@@ -48,6 +52,9 @@ const context: SelectContext = {
|
|
|
48
52
|
if (!props.disabled) {
|
|
49
53
|
is_open.value = !is_open.value
|
|
50
54
|
}
|
|
55
|
+
},
|
|
56
|
+
setTriggerRef: (element: HTMLElement | null) => {
|
|
57
|
+
trigger_ref.value = element
|
|
51
58
|
}
|
|
52
59
|
}
|
|
53
60
|
|
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
/>
|
|
8
8
|
<div
|
|
9
9
|
v-if="context?.is_open.value"
|
|
10
|
-
:class="
|
|
10
|
+
:class="[computed_classes, props.class]"
|
|
11
|
+
:style="content_style"
|
|
11
12
|
:data-state="context?.is_open.value ? 'open' : 'closed'"
|
|
13
|
+
data-side="bottom"
|
|
12
14
|
role="listbox"
|
|
13
15
|
>
|
|
14
16
|
<div class="p-1">
|
|
@@ -19,11 +21,35 @@
|
|
|
19
21
|
</template>
|
|
20
22
|
|
|
21
23
|
<script setup lang="ts">
|
|
22
|
-
import { inject } from "vue"
|
|
23
|
-
import {
|
|
24
|
-
import type { SelectContext } from "../../types/select"
|
|
24
|
+
import { inject, computed } from "vue"
|
|
25
|
+
import { useStyleAdapter } from "../../composables"
|
|
26
|
+
import type { SelectContext, SelectContentProps } from "../../types/select"
|
|
25
27
|
import { SELECT_KEY } from "../../types/select"
|
|
26
28
|
|
|
29
|
+
const props = withDefaults(defineProps<SelectContentProps>(), {
|
|
30
|
+
unstyled: false
|
|
31
|
+
})
|
|
32
|
+
|
|
27
33
|
const context = inject<SelectContext>(SELECT_KEY)
|
|
28
|
-
const
|
|
34
|
+
const style_adapter = useStyleAdapter()
|
|
35
|
+
|
|
36
|
+
const computed_classes = computed(() => {
|
|
37
|
+
if (props.unstyled) return ""
|
|
38
|
+
return style_adapter.getClasses("select-content", {})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const content_style = computed(() => {
|
|
42
|
+
const trigger_element = context?.trigger_ref.value
|
|
43
|
+
if (!trigger_element) {
|
|
44
|
+
return {}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const rect = trigger_element.getBoundingClientRect()
|
|
48
|
+
return {
|
|
49
|
+
position: "fixed" as const,
|
|
50
|
+
top: `${rect.bottom + 4}px`,
|
|
51
|
+
left: `${rect.left}px`,
|
|
52
|
+
width: `${rect.width}px`
|
|
53
|
+
}
|
|
54
|
+
})
|
|
29
55
|
</script>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
|
-
:class="
|
|
4
|
-
:data-disabled="
|
|
3
|
+
:class="[computed_classes, props.class]"
|
|
4
|
+
:data-disabled="is_disabled ? '' : undefined"
|
|
5
5
|
role="option"
|
|
6
|
-
:aria-selected="
|
|
6
|
+
:aria-selected="is_selected"
|
|
7
7
|
@click="handleClick"
|
|
8
8
|
>
|
|
9
9
|
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
10
10
|
<svg
|
|
11
|
-
v-if="
|
|
11
|
+
v-if="is_selected"
|
|
12
12
|
class="h-4 w-4"
|
|
13
13
|
xmlns="http://www.w3.org/2000/svg"
|
|
14
14
|
viewBox="0 0 24 24"
|
|
@@ -26,25 +26,29 @@
|
|
|
26
26
|
</template>
|
|
27
27
|
|
|
28
28
|
<script setup lang="ts">
|
|
29
|
-
import { inject,
|
|
30
|
-
import {
|
|
31
|
-
import type { SelectContext } from "../../types/select"
|
|
29
|
+
import { inject, computed } from "vue"
|
|
30
|
+
import { useStyleAdapter } from "../../composables"
|
|
31
|
+
import type { SelectContext, SelectItemProps } from "../../types/select"
|
|
32
32
|
import { SELECT_KEY } from "../../types/select"
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
40
|
-
disabled: false
|
|
34
|
+
const props = withDefaults(defineProps<SelectItemProps>(), {
|
|
35
|
+
disabled: false,
|
|
36
|
+
unstyled: false
|
|
41
37
|
})
|
|
42
38
|
|
|
43
39
|
const context = inject<SelectContext>(SELECT_KEY)
|
|
44
|
-
const
|
|
40
|
+
const style_adapter = useStyleAdapter()
|
|
41
|
+
|
|
42
|
+
const is_selected = computed(() => context?.model_value.value === props.value)
|
|
43
|
+
const is_disabled = computed(() => props.disabled)
|
|
44
|
+
|
|
45
|
+
const computed_classes = computed(() => {
|
|
46
|
+
if (props.unstyled) return ""
|
|
47
|
+
return style_adapter.getClasses("select-item", {})
|
|
48
|
+
})
|
|
45
49
|
|
|
46
50
|
const handleClick = () => {
|
|
47
|
-
if (!
|
|
51
|
+
if (!is_disabled.value && context) {
|
|
48
52
|
context.updateValue(props.value)
|
|
49
53
|
}
|
|
50
54
|
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button
|
|
3
|
+
ref="button_ref"
|
|
3
4
|
type="button"
|
|
4
|
-
:class="
|
|
5
|
-
:disabled="
|
|
5
|
+
:class="[computed_classes, props.class]"
|
|
6
|
+
:disabled="is_disabled"
|
|
6
7
|
:aria-expanded="context?.is_open.value"
|
|
7
8
|
aria-haspopup="listbox"
|
|
8
9
|
@click="handleClick"
|
|
9
10
|
>
|
|
10
11
|
<slot />
|
|
11
12
|
<svg
|
|
12
|
-
class="
|
|
13
|
+
:class="icon_classes"
|
|
13
14
|
xmlns="http://www.w3.org/2000/svg"
|
|
14
15
|
viewBox="0 0 24 24"
|
|
15
16
|
fill="none"
|
|
@@ -24,13 +25,44 @@
|
|
|
24
25
|
</template>
|
|
25
26
|
|
|
26
27
|
<script setup lang="ts">
|
|
27
|
-
import { inject } from "vue"
|
|
28
|
-
import {
|
|
29
|
-
import type { SelectContext } from "../../types/select"
|
|
28
|
+
import { inject, ref, computed, onMounted, onUnmounted } from "vue"
|
|
29
|
+
import { useStyleAdapter } from "../../composables"
|
|
30
|
+
import type { SelectContext, SelectTriggerProps } from "../../types/select"
|
|
30
31
|
import { SELECT_KEY } from "../../types/select"
|
|
32
|
+
import type { SelectState } from "../../types/composables"
|
|
33
|
+
|
|
34
|
+
const props = withDefaults(defineProps<SelectTriggerProps>(), {
|
|
35
|
+
unstyled: false
|
|
36
|
+
})
|
|
31
37
|
|
|
32
38
|
const context = inject<SelectContext>(SELECT_KEY)
|
|
33
|
-
const
|
|
39
|
+
const style_adapter = useStyleAdapter()
|
|
40
|
+
const button_ref = ref<HTMLButtonElement | null>(null)
|
|
41
|
+
|
|
42
|
+
const is_disabled = computed(() => context?.disabled.value ?? false)
|
|
43
|
+
|
|
44
|
+
const computed_classes = computed(() => {
|
|
45
|
+
if (props.unstyled) return ""
|
|
46
|
+
const state: SelectState = {
|
|
47
|
+
size: context?.size.value ?? "md",
|
|
48
|
+
disabled: is_disabled.value,
|
|
49
|
+
is_open: context?.is_open.value ?? false
|
|
50
|
+
}
|
|
51
|
+
return style_adapter.getClasses("select", state)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const icon_classes = computed(() => {
|
|
55
|
+
if (props.unstyled) return ""
|
|
56
|
+
return style_adapter.getClasses("select-trigger-icon", {})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
onMounted(() => {
|
|
60
|
+
context?.setTriggerRef(button_ref.value)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
onUnmounted(() => {
|
|
64
|
+
context?.setTriggerRef(null)
|
|
65
|
+
})
|
|
34
66
|
|
|
35
67
|
const handleClick = () => {
|
|
36
68
|
context?.toggle()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<span :class="
|
|
2
|
+
<span :class="[computed_classes, props.class]">
|
|
3
3
|
<slot v-if="hasValue" />
|
|
4
4
|
<template v-else>{{ context?.placeholder.value }}</template>
|
|
5
5
|
</span>
|
|
@@ -7,10 +7,21 @@
|
|
|
7
7
|
|
|
8
8
|
<script setup lang="ts">
|
|
9
9
|
import { computed, inject } from "vue"
|
|
10
|
-
import
|
|
10
|
+
import { useStyleAdapter } from "../../composables"
|
|
11
|
+
import type { SelectContext, SelectValueProps } from "../../types/select"
|
|
11
12
|
import { SELECT_KEY } from "../../types/select"
|
|
12
13
|
|
|
14
|
+
const props = withDefaults(defineProps<SelectValueProps>(), {
|
|
15
|
+
unstyled: false
|
|
16
|
+
})
|
|
17
|
+
|
|
13
18
|
const context = inject<SelectContext>(SELECT_KEY)
|
|
19
|
+
const style_adapter = useStyleAdapter()
|
|
14
20
|
|
|
15
21
|
const hasValue = computed(() => !!context?.model_value.value)
|
|
22
|
+
|
|
23
|
+
const computed_classes = computed(() => {
|
|
24
|
+
if (props.unstyled) return ""
|
|
25
|
+
return style_adapter.getClasses("select-value", { hasValue: hasValue.value })
|
|
26
|
+
})
|
|
16
27
|
</script>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<Transition name="sheet-overlay">
|
|
4
4
|
<div
|
|
5
5
|
v-if="is_open"
|
|
6
|
-
class="
|
|
6
|
+
:class="overlay_classes"
|
|
7
7
|
@click="handleOverlayClick"
|
|
8
8
|
/>
|
|
9
9
|
</Transition>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
ref="sheet_element"
|
|
15
15
|
role="dialog"
|
|
16
16
|
aria-modal="true"
|
|
17
|
-
:class="
|
|
17
|
+
:class="[computed_classes, props.class]"
|
|
18
18
|
tabindex="-1"
|
|
19
19
|
@keydown.escape="close"
|
|
20
20
|
>
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
<button
|
|
24
24
|
v-if="show_close_button"
|
|
25
25
|
type="button"
|
|
26
|
-
class="
|
|
26
|
+
:class="close_button_classes"
|
|
27
27
|
aria-label="Close"
|
|
28
28
|
@click="close"
|
|
29
29
|
>
|
|
@@ -49,20 +49,17 @@
|
|
|
49
49
|
|
|
50
50
|
<script setup lang="ts">
|
|
51
51
|
import { ref, computed, watch, provide, onMounted, onUnmounted, type InjectionKey } from "vue"
|
|
52
|
-
import {
|
|
53
|
-
import type { SheetSide, SheetContext } from "../../types/sheet"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
side?: SheetSide
|
|
58
|
-
show_close_button?: boolean
|
|
59
|
-
class?: string
|
|
60
|
-
}
|
|
52
|
+
import { useStyleAdapter } from "../../composables"
|
|
53
|
+
import type { SheetSide, SheetContext, SheetProps } from "../../types/sheet"
|
|
54
|
+
import type { SheetState } from "../../types/composables"
|
|
55
|
+
|
|
56
|
+
interface Props extends SheetProps {}
|
|
61
57
|
|
|
62
58
|
const props = withDefaults(defineProps<Props>(), {
|
|
63
59
|
open: false,
|
|
64
60
|
side: "right",
|
|
65
|
-
|
|
61
|
+
showCloseButton: true,
|
|
62
|
+
unstyled: false
|
|
66
63
|
})
|
|
67
64
|
|
|
68
65
|
const emit = defineEmits<{
|
|
@@ -71,6 +68,7 @@ const emit = defineEmits<{
|
|
|
71
68
|
|
|
72
69
|
export const SHEET_CONTEXT_KEY: InjectionKey<SheetContext> = Symbol("sheet-context")
|
|
73
70
|
|
|
71
|
+
const style_adapter = useStyleAdapter()
|
|
74
72
|
const is_open = ref(props.open)
|
|
75
73
|
const sheet_element = ref<HTMLElement | null>(null)
|
|
76
74
|
|
|
@@ -114,25 +112,35 @@ watch(is_open, (open) => {
|
|
|
114
112
|
}
|
|
115
113
|
})
|
|
116
114
|
|
|
117
|
-
const side = computed(() => props.side)
|
|
118
|
-
|
|
115
|
+
const side = computed(() => props.side ?? "right")
|
|
116
|
+
const show_close_button = computed(() => props.showCloseButton)
|
|
119
117
|
const transition_name = computed(() => `sheet-${side.value}`)
|
|
120
118
|
|
|
119
|
+
const computed_classes = computed(() => {
|
|
120
|
+
if (props.unstyled) return ""
|
|
121
|
+
const state: SheetState = {
|
|
122
|
+
is_open: is_open.value,
|
|
123
|
+
side: side.value
|
|
124
|
+
}
|
|
125
|
+
return style_adapter.getClasses("sheet", state)
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
const overlay_classes = computed(() => {
|
|
129
|
+
if (props.unstyled) return ""
|
|
130
|
+
return style_adapter.getClasses("sheet-overlay", {})
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
const close_button_classes = computed(() => {
|
|
134
|
+
if (props.unstyled) return ""
|
|
135
|
+
return style_adapter.getClasses("sheet-close", {})
|
|
136
|
+
})
|
|
137
|
+
|
|
121
138
|
provide(SHEET_CONTEXT_KEY, {
|
|
122
139
|
is_open: is_open.value,
|
|
123
140
|
side: side.value,
|
|
124
141
|
open,
|
|
125
142
|
close
|
|
126
143
|
})
|
|
127
|
-
|
|
128
|
-
const base_classes = "fixed z-50 gap-4 bg-background p-6 shadow-lg"
|
|
129
|
-
|
|
130
|
-
const side_classes: Record<SheetSide, string> = {
|
|
131
|
-
top: "inset-x-0 top-0 border-b",
|
|
132
|
-
bottom: "inset-x-0 bottom-0 border-t",
|
|
133
|
-
left: "inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
|
|
134
|
-
right: "inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm"
|
|
135
|
-
}
|
|
136
144
|
</script>
|
|
137
145
|
|
|
138
146
|
<style scoped>
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<p :class="
|
|
2
|
+
<p :class="[computed_classes, props.class]">
|
|
3
3
|
<slot />
|
|
4
4
|
</p>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
|
-
import {
|
|
8
|
+
import { computed } from "vue"
|
|
9
|
+
import { useStyleAdapter } from "../../composables"
|
|
10
|
+
import type { SheetDescriptionProps } from "../../types/sheet"
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
12
|
+
const props = withDefaults(defineProps<SheetDescriptionProps>(), {
|
|
13
|
+
unstyled: false
|
|
14
|
+
})
|
|
13
15
|
|
|
14
|
-
const
|
|
16
|
+
const style_adapter = useStyleAdapter()
|
|
17
|
+
|
|
18
|
+
const computed_classes = computed(() => {
|
|
19
|
+
if (props.unstyled) return ""
|
|
20
|
+
return style_adapter.getClasses("sheet-description", {})
|
|
21
|
+
})
|
|
15
22
|
</script>
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="
|
|
2
|
+
<div :class="[computed_classes, props.class]">
|
|
3
3
|
<slot />
|
|
4
4
|
</div>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
|
-
import {
|
|
8
|
+
import { computed } from "vue"
|
|
9
|
+
import { useStyleAdapter } from "../../composables"
|
|
10
|
+
import type { SheetFooterProps } from "../../types/sheet"
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
12
|
+
const props = withDefaults(defineProps<SheetFooterProps>(), {
|
|
13
|
+
unstyled: false
|
|
14
|
+
})
|
|
13
15
|
|
|
14
|
-
const
|
|
16
|
+
const style_adapter = useStyleAdapter()
|
|
17
|
+
|
|
18
|
+
const computed_classes = computed(() => {
|
|
19
|
+
if (props.unstyled) return ""
|
|
20
|
+
return style_adapter.getClasses("sheet-footer", {})
|
|
21
|
+
})
|
|
15
22
|
</script>
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="
|
|
2
|
+
<div :class="[computed_classes, props.class]">
|
|
3
3
|
<slot />
|
|
4
4
|
</div>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
|
-
import {
|
|
8
|
+
import { computed } from "vue"
|
|
9
|
+
import { useStyleAdapter } from "../../composables"
|
|
10
|
+
import type { SheetHeaderProps } from "../../types/sheet"
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
12
|
+
const props = withDefaults(defineProps<SheetHeaderProps>(), {
|
|
13
|
+
unstyled: false
|
|
14
|
+
})
|
|
13
15
|
|
|
14
|
-
const
|
|
16
|
+
const style_adapter = useStyleAdapter()
|
|
17
|
+
|
|
18
|
+
const computed_classes = computed(() => {
|
|
19
|
+
if (props.unstyled) return ""
|
|
20
|
+
return style_adapter.getClasses("sheet-header", {})
|
|
21
|
+
})
|
|
15
22
|
</script>
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<h2 :class="
|
|
2
|
+
<h2 :class="[computed_classes, props.class]">
|
|
3
3
|
<slot />
|
|
4
4
|
</h2>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
|
-
import {
|
|
8
|
+
import { computed } from "vue"
|
|
9
|
+
import { useStyleAdapter } from "../../composables"
|
|
10
|
+
import type { SheetTitleProps } from "../../types/sheet"
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
12
|
+
const props = withDefaults(defineProps<SheetTitleProps>(), {
|
|
13
|
+
unstyled: false
|
|
14
|
+
})
|
|
13
15
|
|
|
14
|
-
const
|
|
16
|
+
const style_adapter = useStyleAdapter()
|
|
17
|
+
|
|
18
|
+
const computed_classes = computed(() => {
|
|
19
|
+
if (props.unstyled) return ""
|
|
20
|
+
return style_adapter.getClasses("sheet-title", {})
|
|
21
|
+
})
|
|
15
22
|
</script>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button
|
|
3
3
|
type="button"
|
|
4
|
-
:class="
|
|
4
|
+
:class="[computed_classes, props.class]"
|
|
5
5
|
:disabled="composable.is_disabled.value"
|
|
6
6
|
:data-state="modelValue ? 'checked' : 'unchecked'"
|
|
7
7
|
v-bind="composable.aria_attributes.value"
|
|
@@ -15,26 +15,46 @@
|
|
|
15
15
|
</template>
|
|
16
16
|
|
|
17
17
|
<script setup lang="ts">
|
|
18
|
-
import { toRef } from "vue"
|
|
18
|
+
import { toRef, computed } from "vue"
|
|
19
19
|
import { useSwitch } from "../../composables/useSwitch"
|
|
20
|
+
import { useStyleAdapter } from "../../composables/useUIConfig"
|
|
20
21
|
import type { SwitchProps } from "../../types/switch"
|
|
22
|
+
import type { SwitchState } from "../../types/composables"
|
|
21
23
|
|
|
22
24
|
interface Props extends SwitchProps {
|
|
23
25
|
modelValue?: boolean
|
|
26
|
+
class?: string
|
|
27
|
+
unstyled?: boolean
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
const props = withDefaults(defineProps<Props>(), {
|
|
27
31
|
modelValue: false,
|
|
28
|
-
disabled: false
|
|
32
|
+
disabled: false,
|
|
33
|
+
unstyled: false
|
|
29
34
|
})
|
|
30
35
|
|
|
31
36
|
const emit = defineEmits<{
|
|
32
37
|
"update:modelValue": [value: boolean]
|
|
33
38
|
}>()
|
|
34
39
|
|
|
40
|
+
const style_adapter = useStyleAdapter()
|
|
35
41
|
const checked = toRef(() => props.modelValue)
|
|
36
42
|
const composable = useSwitch(toRef(() => props), checked)
|
|
37
43
|
|
|
44
|
+
// StyleAdapterからクラスを取得
|
|
45
|
+
const computed_classes = computed(() => {
|
|
46
|
+
if (props.unstyled) {
|
|
47
|
+
return ""
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const state: SwitchState = {
|
|
51
|
+
checked: props.modelValue,
|
|
52
|
+
disabled: composable.is_disabled.value
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return style_adapter.getClasses("switch", state)
|
|
56
|
+
})
|
|
57
|
+
|
|
38
58
|
const handleClick = () => {
|
|
39
59
|
if (!composable.is_disabled.value) {
|
|
40
60
|
emit("update:modelValue", !props.modelValue)
|