@soave/ui 0.2.1 → 0.3.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.
Files changed (109) hide show
  1. package/dist/adapters/types.d.ts +1 -1
  2. package/dist/components/Button.vue +36 -0
  3. package/dist/components/Card.vue +23 -0
  4. package/dist/components/Checkbox.vue +44 -0
  5. package/dist/components/Dialog.vue +99 -0
  6. package/dist/components/Input.vue +42 -0
  7. package/dist/components/RadioGroup.vue +35 -0
  8. package/dist/components/RadioItem.vue +55 -0
  9. package/dist/components/Select.vue +95 -0
  10. package/dist/components/SelectContent.vue +40 -0
  11. package/dist/components/SelectItem.vue +44 -0
  12. package/dist/components/SelectTrigger.vue +61 -0
  13. package/dist/components/Switch.vue +43 -0
  14. package/dist/components/Textarea.vue +49 -0
  15. package/dist/components/index.d.ts +13 -0
  16. package/dist/components/index.mjs +13 -0
  17. package/dist/composables/useButton.d.ts +2 -2
  18. package/dist/composables/useButton.mjs +14 -41
  19. package/dist/composables/useCard.d.ts +2 -2
  20. package/dist/composables/useCard.mjs +5 -18
  21. package/dist/composables/useCheckbox.d.ts +2 -1
  22. package/dist/composables/useCheckbox.mjs +11 -44
  23. package/dist/composables/useFileInput.d.ts +2 -0
  24. package/dist/composables/useFileInput.mjs +15 -30
  25. package/dist/composables/useForm.mjs +2 -2
  26. package/dist/composables/useInput.d.ts +2 -2
  27. package/dist/composables/useInput.mjs +12 -33
  28. package/dist/composables/useRadio.d.ts +2 -1
  29. package/dist/composables/useRadio.mjs +10 -42
  30. package/dist/composables/useSelect.d.ts +3 -0
  31. package/dist/composables/useSelect.mjs +20 -49
  32. package/dist/composables/useSwitch.d.ts +2 -1
  33. package/dist/composables/useSwitch.mjs +10 -43
  34. package/dist/composables/useTextarea.d.ts +2 -1
  35. package/dist/composables/useTextarea.mjs +12 -33
  36. package/dist/composables/useToast.mjs +1 -1
  37. package/dist/env.d.ts +11 -0
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.mjs +1 -1
  40. package/dist/types/button.d.ts +19 -5
  41. package/dist/types/card.d.ts +11 -2
  42. package/dist/types/checkbox.d.ts +15 -6
  43. package/dist/types/composables.d.ts +52 -24
  44. package/dist/types/config.d.ts +1 -0
  45. package/dist/types/file-input.d.ts +15 -5
  46. package/dist/types/form.d.ts +5 -5
  47. package/dist/types/input.d.ts +17 -6
  48. package/dist/types/radio.d.ts +14 -6
  49. package/dist/types/select.d.ts +25 -7
  50. package/dist/types/switch.d.ts +14 -5
  51. package/dist/types/textarea.d.ts +20 -7
  52. package/dist/types/toast.d.ts +2 -2
  53. package/dist/types/tooltip.d.ts +3 -0
  54. package/dist/types/tooltip.mjs +1 -0
  55. package/package.json +1 -9
  56. package/dist/components/ui/Alert.vue +0 -41
  57. package/dist/components/ui/AlertDescription.vue +0 -22
  58. package/dist/components/ui/AlertTitle.vue +0 -22
  59. package/dist/components/ui/Button.vue +0 -85
  60. package/dist/components/ui/Card.vue +0 -39
  61. package/dist/components/ui/CardContent.vue +0 -22
  62. package/dist/components/ui/CardDescription.vue +0 -22
  63. package/dist/components/ui/CardFooter.vue +0 -22
  64. package/dist/components/ui/CardHeader.vue +0 -22
  65. package/dist/components/ui/CardTitle.vue +0 -22
  66. package/dist/components/ui/Checkbox.vue +0 -94
  67. package/dist/components/ui/Dialog.vue +0 -110
  68. package/dist/components/ui/DialogDescription.vue +0 -22
  69. package/dist/components/ui/DialogFooter.vue +0 -22
  70. package/dist/components/ui/DialogHeader.vue +0 -22
  71. package/dist/components/ui/DialogTitle.vue +0 -22
  72. package/dist/components/ui/DropdownMenu.vue +0 -32
  73. package/dist/components/ui/DropdownMenuContent.vue +0 -69
  74. package/dist/components/ui/DropdownMenuItem.vue +0 -71
  75. package/dist/components/ui/DropdownMenuLabel.vue +0 -20
  76. package/dist/components/ui/DropdownMenuSeparator.vue +0 -16
  77. package/dist/components/ui/DropdownMenuTrigger.vue +0 -38
  78. package/dist/components/ui/FileInput.vue +0 -153
  79. package/dist/components/ui/FormError.vue +0 -20
  80. package/dist/components/ui/FormField.vue +0 -12
  81. package/dist/components/ui/FormInput.vue +0 -46
  82. package/dist/components/ui/FormLabel.vue +0 -19
  83. package/dist/components/ui/FormTextarea.vue +0 -39
  84. package/dist/components/ui/Input.vue +0 -72
  85. package/dist/components/ui/Popover.vue +0 -35
  86. package/dist/components/ui/PopoverContent.vue +0 -66
  87. package/dist/components/ui/PopoverTrigger.vue +0 -36
  88. package/dist/components/ui/RadioGroup.vue +0 -47
  89. package/dist/components/ui/RadioItem.vue +0 -62
  90. package/dist/components/ui/Select.vue +0 -62
  91. package/dist/components/ui/SelectContent.vue +0 -55
  92. package/dist/components/ui/SelectItem.vue +0 -55
  93. package/dist/components/ui/SelectTrigger.vue +0 -70
  94. package/dist/components/ui/SelectValue.vue +0 -27
  95. package/dist/components/ui/Sheet.vue +0 -148
  96. package/dist/components/ui/SheetDescription.vue +0 -22
  97. package/dist/components/ui/SheetFooter.vue +0 -22
  98. package/dist/components/ui/SheetHeader.vue +0 -22
  99. package/dist/components/ui/SheetTitle.vue +0 -22
  100. package/dist/components/ui/Switch.vue +0 -63
  101. package/dist/components/ui/Textarea.vue +0 -73
  102. package/dist/components/ui/Toast.vue +0 -116
  103. package/dist/components/ui/Toaster.vue +0 -76
  104. package/dist/components/ui/Tooltip.vue +0 -42
  105. package/dist/components/ui/TooltipContent.vue +0 -71
  106. package/dist/components/ui/TooltipTrigger.vue +0 -39
  107. package/dist/components/ui/UIProvider.vue +0 -23
  108. package/dist/components/ui/index.d.ts +0 -52
  109. package/dist/components/ui/index.mjs +0 -52
@@ -1,25 +1,38 @@
1
- import type { ComputedRef, Ref } from "vue";
1
+ import type { ComputedRef, Ref, DeepReadonly } from "vue";
2
+ export type TextareaSize = "sm" | "md" | "lg";
3
+ export type TextareaResize = "none" | "vertical" | "horizontal" | "both";
2
4
  export interface TextareaProps {
5
+ size?: TextareaSize;
3
6
  placeholder?: string;
4
7
  disabled?: boolean;
5
8
  readonly?: boolean;
6
9
  error?: string;
7
10
  error_id?: string;
8
11
  rows?: number;
9
- resize?: "none" | "vertical" | "horizontal" | "both";
12
+ resize?: TextareaResize;
13
+ }
14
+ /**
15
+ * テキストエリアの状態(StyleAdapterに渡す用)
16
+ */
17
+ export interface TextareaState {
18
+ size: TextareaSize;
19
+ disabled: boolean;
20
+ readonly: boolean;
21
+ has_error: boolean;
22
+ resize: TextareaResize;
10
23
  }
11
24
  export interface TextareaAriaAttributes {
12
25
  "aria-invalid"?: boolean;
13
26
  "aria-describedby"?: string;
14
27
  "aria-readonly"?: boolean;
15
28
  }
29
+ /**
30
+ * useTextarea の戻り値(ヘッドレス - スタイル情報なし)
31
+ */
16
32
  export interface TextareaReturn {
17
- base_classes: ComputedRef<string>;
33
+ state: DeepReadonly<ComputedRef<TextareaState>>;
18
34
  is_focused: Ref<boolean>;
19
- has_error: ComputedRef<boolean>;
20
- is_disabled: ComputedRef<boolean>;
21
- is_readonly: ComputedRef<boolean>;
22
- aria_attributes: ComputedRef<TextareaAriaAttributes>;
35
+ aria_attributes: DeepReadonly<ComputedRef<TextareaAriaAttributes>>;
23
36
  handleFocus: () => void;
24
37
  handleBlur: () => void;
25
38
  }
@@ -15,7 +15,7 @@ export interface ToastAction {
15
15
  label: string;
16
16
  onClick: () => void;
17
17
  }
18
- export interface Toast extends Required<Pick<ToastProps, "id" | "variant" | "duration" | "dismissible">> {
18
+ export interface ToastItem extends Required<Pick<ToastProps, "id" | "variant" | "duration" | "dismissible">> {
19
19
  title?: string;
20
20
  description?: string;
21
21
  action?: ToastAction;
@@ -27,7 +27,7 @@ export interface ToasterProps {
27
27
  gap?: number;
28
28
  }
29
29
  export interface ToastReturn {
30
- toasts: Toast[];
30
+ toasts: ToastItem[];
31
31
  add: (props: ToastProps) => string;
32
32
  dismiss: (id: string) => void;
33
33
  dismissAll: () => void;
@@ -1,3 +1,5 @@
1
+ import type { InjectionKey } from "vue";
2
+ import type { UseTooltipReturn } from "../composables/useTooltip";
1
3
  export type TooltipSide = "top" | "right" | "bottom" | "left";
2
4
  export type TooltipAlign = "start" | "center" | "end";
3
5
  export interface TooltipProps {
@@ -29,3 +31,4 @@ export interface TooltipAriaAttributes {
29
31
  export interface TooltipTriggerAriaAttributes {
30
32
  "aria-describedby": string;
31
33
  }
34
+ export declare const TOOLTIP_CONTEXT_KEY: InjectionKey<UseTooltipReturn>;
@@ -0,0 +1 @@
1
+ export const TOOLTIP_CONTEXT_KEY = Symbol("tooltip-context");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soave/ui",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "soave UI - Composable-First UI Framework for Vue 3 / Nuxt 4",
5
5
  "author": "Arata Ouchi (Original SIN Architecture)",
6
6
  "license": "MIT",
@@ -22,17 +22,9 @@
22
22
  "import": "./dist/composables/index.mjs",
23
23
  "types": "./dist/composables/index.d.ts"
24
24
  },
25
- "./components": {
26
- "import": "./dist/components/ui/index.mjs",
27
- "types": "./dist/components/ui/index.d.ts"
28
- },
29
25
  "./adapters": {
30
26
  "import": "./dist/adapters/index.mjs",
31
27
  "types": "./dist/adapters/index.d.ts"
32
- },
33
- "./styles/css-variables.css": {
34
- "import": "./dist/styles/css-variables.css",
35
- "default": "./dist/styles/css-variables.css"
36
28
  }
37
29
  },
38
30
  "files": [
@@ -1,41 +0,0 @@
1
- <template>
2
- <div
3
- role="alert"
4
- :class="[computed_classes, props.class]"
5
- >
6
- <slot />
7
- </div>
8
- </template>
9
-
10
- <script setup lang="ts">
11
- import { computed } from "vue"
12
- import { useUI, useStyleAdapter } from "../../composables/useUIConfig"
13
- import type { AlertVariant } from "../../types/alert"
14
- import type { AlertState } from "../../types/composables"
15
-
16
- interface Props {
17
- variant?: AlertVariant
18
- class?: string
19
- unstyled?: boolean
20
- }
21
-
22
- const props = withDefaults(defineProps<Props>(), {
23
- unstyled: false
24
- })
25
-
26
- const ui_config = useUI("alert")
27
- const style_adapter = useStyleAdapter()
28
-
29
- // StyleAdapterからクラスを取得
30
- const computed_classes = computed(() => {
31
- if (props.unstyled) {
32
- return ""
33
- }
34
-
35
- const state: AlertState = {
36
- variant: props.variant ?? ui_config.default_variant
37
- }
38
-
39
- return style_adapter.getClasses("alert", state)
40
- })
41
- </script>
@@ -1,22 +0,0 @@
1
- <template>
2
- <div :class="[computed_classes, props.class]">
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { computed } from "vue"
9
- import { useStyleAdapter } from "../../composables"
10
- import type { AlertDescriptionProps } from "../../types/alert"
11
-
12
- const props = withDefaults(defineProps<AlertDescriptionProps>(), {
13
- unstyled: false
14
- })
15
-
16
- const style_adapter = useStyleAdapter()
17
-
18
- const computed_classes = computed(() => {
19
- if (props.unstyled) return ""
20
- return style_adapter.getClasses("alert-description", {})
21
- })
22
- </script>
@@ -1,22 +0,0 @@
1
- <template>
2
- <h5 :class="[computed_classes, props.class]">
3
- <slot />
4
- </h5>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { computed } from "vue"
9
- import { useStyleAdapter } from "../../composables"
10
- import type { AlertTitleProps } from "../../types/alert"
11
-
12
- const props = withDefaults(defineProps<AlertTitleProps>(), {
13
- unstyled: false
14
- })
15
-
16
- const style_adapter = useStyleAdapter()
17
-
18
- const computed_classes = computed(() => {
19
- if (props.unstyled) return ""
20
- return style_adapter.getClasses("alert-title", {})
21
- })
22
- </script>
@@ -1,85 +0,0 @@
1
- <template>
2
- <button
3
- :class="[computed_classes, props.class]"
4
- :disabled="composable.is_disabled.value"
5
- v-bind="composable.aria_attributes.value"
6
- @click="handleClick"
7
- >
8
- <slot name="icon-left" />
9
- <span v-if="composable.is_loading.value" class="animate-spin">
10
- <slot name="loading">
11
- <svg
12
- class="h-4 w-4"
13
- xmlns="http://www.w3.org/2000/svg"
14
- fill="none"
15
- viewBox="0 0 24 24"
16
- >
17
- <circle
18
- class="opacity-25"
19
- cx="12"
20
- cy="12"
21
- r="10"
22
- stroke="currentColor"
23
- stroke-width="4"
24
- />
25
- <path
26
- class="opacity-75"
27
- fill="currentColor"
28
- d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
29
- />
30
- </svg>
31
- </slot>
32
- </span>
33
- <slot />
34
- <slot name="icon-right" />
35
- </button>
36
- </template>
37
-
38
- <script setup lang="ts">
39
- import { toRef, computed } from "vue"
40
- import { useButton } from "../../composables/useButton"
41
- import { useStyleAdapter, useUI } from "../../composables/useUIConfig"
42
- import type { ButtonProps } from "../../types/button"
43
- import type { ButtonState } from "../../types/composables"
44
-
45
- interface ButtonComponentProps extends ButtonProps {
46
- class?: string
47
- unstyled?: boolean
48
- }
49
-
50
- const props = withDefaults(defineProps<ButtonComponentProps>(), {
51
- disabled: false,
52
- loading: false,
53
- unstyled: false
54
- })
55
-
56
- const emit = defineEmits<{
57
- click: [event: MouseEvent]
58
- }>()
59
-
60
- const ui_config = useUI("button")
61
- const style_adapter = useStyleAdapter()
62
- const composable = useButton(toRef(() => props))
63
-
64
- // StyleAdapterからクラスを取得
65
- const computed_classes = computed(() => {
66
- if (props.unstyled) {
67
- return ""
68
- }
69
-
70
- const state: ButtonState = {
71
- variant: props.variant ?? ui_config.default_variant,
72
- size: props.size ?? ui_config.default_size,
73
- disabled: composable.is_disabled.value,
74
- loading: composable.is_loading.value
75
- }
76
-
77
- return style_adapter.getClasses("button", state)
78
- })
79
-
80
- const handleClick = (event: MouseEvent) => {
81
- if (!composable.is_disabled.value && !composable.is_loading.value) {
82
- emit("click", event)
83
- }
84
- }
85
- </script>
@@ -1,39 +0,0 @@
1
- <template>
2
- <div :class="[computed_classes, props.class]">
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { toRef, computed } from "vue"
9
- import { useCard } from "../../composables/useCard"
10
- import { useStyleAdapter, useUI } from "../../composables/useUIConfig"
11
- import type { CardProps } from "../../types/card"
12
- import type { CardState } from "../../types/composables"
13
-
14
- interface CardComponentProps extends CardProps {
15
- class?: string
16
- unstyled?: boolean
17
- }
18
-
19
- const props = withDefaults(defineProps<CardComponentProps>(), {
20
- unstyled: false
21
- })
22
-
23
- const ui_config = useUI("card")
24
- const style_adapter = useStyleAdapter()
25
- const composable = useCard(toRef(() => props))
26
-
27
- // StyleAdapterからクラスを取得
28
- const computed_classes = computed(() => {
29
- if (props.unstyled) {
30
- return ""
31
- }
32
-
33
- const state: CardState = {
34
- padding: props.padding ?? ui_config.default_padding
35
- }
36
-
37
- return style_adapter.getClasses("card", state)
38
- })
39
- </script>
@@ -1,22 +0,0 @@
1
- <template>
2
- <div :class="[computed_classes, props.class]">
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { computed } from "vue"
9
- import { useStyleAdapter } from "../../composables"
10
- import type { CardContentProps } from "../../types/card"
11
-
12
- const props = withDefaults(defineProps<CardContentProps>(), {
13
- unstyled: false
14
- })
15
-
16
- const style_adapter = useStyleAdapter()
17
-
18
- const computed_classes = computed(() => {
19
- if (props.unstyled) return ""
20
- return style_adapter.getClasses("card-content", {})
21
- })
22
- </script>
@@ -1,22 +0,0 @@
1
- <template>
2
- <p :class="[computed_classes, props.class]">
3
- <slot />
4
- </p>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { computed } from "vue"
9
- import { useStyleAdapter } from "../../composables"
10
- import type { CardDescriptionProps } from "../../types/card"
11
-
12
- const props = withDefaults(defineProps<CardDescriptionProps>(), {
13
- unstyled: false
14
- })
15
-
16
- const style_adapter = useStyleAdapter()
17
-
18
- const computed_classes = computed(() => {
19
- if (props.unstyled) return ""
20
- return style_adapter.getClasses("card-description", {})
21
- })
22
- </script>
@@ -1,22 +0,0 @@
1
- <template>
2
- <div :class="[computed_classes, props.class]">
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { computed } from "vue"
9
- import { useStyleAdapter } from "../../composables"
10
- import type { CardFooterProps } from "../../types/card"
11
-
12
- const props = withDefaults(defineProps<CardFooterProps>(), {
13
- unstyled: false
14
- })
15
-
16
- const style_adapter = useStyleAdapter()
17
-
18
- const computed_classes = computed(() => {
19
- if (props.unstyled) return ""
20
- return style_adapter.getClasses("card-footer", {})
21
- })
22
- </script>
@@ -1,22 +0,0 @@
1
- <template>
2
- <div :class="[computed_classes, props.class]">
3
- <slot />
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { computed } from "vue"
9
- import { useStyleAdapter } from "../../composables"
10
- import type { CardHeaderProps } from "../../types/card"
11
-
12
- const props = withDefaults(defineProps<CardHeaderProps>(), {
13
- unstyled: false
14
- })
15
-
16
- const style_adapter = useStyleAdapter()
17
-
18
- const computed_classes = computed(() => {
19
- if (props.unstyled) return ""
20
- return style_adapter.getClasses("card-header", {})
21
- })
22
- </script>
@@ -1,22 +0,0 @@
1
- <template>
2
- <h3 :class="[computed_classes, props.class]">
3
- <slot />
4
- </h3>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { computed } from "vue"
9
- import { useStyleAdapter } from "../../composables"
10
- import type { CardTitleProps } from "../../types/card"
11
-
12
- const props = withDefaults(defineProps<CardTitleProps>(), {
13
- unstyled: false
14
- })
15
-
16
- const style_adapter = useStyleAdapter()
17
-
18
- const computed_classes = computed(() => {
19
- if (props.unstyled) return ""
20
- return style_adapter.getClasses("card-title", {})
21
- })
22
- </script>
@@ -1,94 +0,0 @@
1
- <template>
2
- <button
3
- type="button"
4
- :class="[computed_classes, props.class]"
5
- :disabled="composable.is_disabled.value"
6
- :data-state="dataState"
7
- v-bind="composable.aria_attributes.value"
8
- @click="handleClick"
9
- >
10
- <span
11
- v-if="modelValue || composable.is_indeterminate.value"
12
- :class="composable.indicator_classes.value"
13
- >
14
- <svg
15
- v-if="composable.is_indeterminate.value"
16
- xmlns="http://www.w3.org/2000/svg"
17
- viewBox="0 0 24 24"
18
- fill="none"
19
- stroke="currentColor"
20
- stroke-width="3"
21
- stroke-linecap="round"
22
- >
23
- <line x1="5" y1="12" x2="19" y2="12" />
24
- </svg>
25
- <svg
26
- v-else
27
- xmlns="http://www.w3.org/2000/svg"
28
- viewBox="0 0 24 24"
29
- fill="none"
30
- stroke="currentColor"
31
- stroke-width="3"
32
- stroke-linecap="round"
33
- stroke-linejoin="round"
34
- >
35
- <polyline points="20 6 9 17 4 12" />
36
- </svg>
37
- </span>
38
- </button>
39
- </template>
40
-
41
- <script setup lang="ts">
42
- import { computed, toRef } from "vue"
43
- import { useCheckbox } from "../../composables/useCheckbox"
44
- import { useStyleAdapter } from "../../composables/useUIConfig"
45
- import type { CheckboxProps } from "../../types/checkbox"
46
- import type { CheckboxState } from "../../types/composables"
47
-
48
- interface Props extends CheckboxProps {
49
- modelValue?: boolean
50
- class?: string
51
- unstyled?: boolean
52
- }
53
-
54
- const props = withDefaults(defineProps<Props>(), {
55
- modelValue: false,
56
- disabled: false,
57
- indeterminate: false,
58
- unstyled: false
59
- })
60
-
61
- const emit = defineEmits<{
62
- "update:modelValue": [value: boolean]
63
- }>()
64
-
65
- const style_adapter = useStyleAdapter()
66
- const checked = toRef(() => props.modelValue)
67
- const composable = useCheckbox(toRef(() => props), checked)
68
-
69
- // StyleAdapterからクラスを取得
70
- const computed_classes = computed(() => {
71
- if (props.unstyled) {
72
- return ""
73
- }
74
-
75
- const state: CheckboxState = {
76
- checked: props.modelValue,
77
- disabled: composable.is_disabled.value,
78
- indeterminate: composable.is_indeterminate.value
79
- }
80
-
81
- return style_adapter.getClasses("checkbox", state)
82
- })
83
-
84
- const dataState = computed(() => {
85
- if (props.indeterminate) return "indeterminate"
86
- return props.modelValue ? "checked" : "unchecked"
87
- })
88
-
89
- const handleClick = () => {
90
- if (!composable.is_disabled.value) {
91
- emit("update:modelValue", !props.modelValue)
92
- }
93
- }
94
- </script>
@@ -1,110 +0,0 @@
1
- <template>
2
- <Teleport to="body">
3
- <Transition name="dialog">
4
- <div
5
- v-if="is_open"
6
- class="fixed inset-0 z-50 flex items-center justify-center"
7
- >
8
- <div
9
- :class="overlay_classes"
10
- @click="handleOverlayClick"
11
- />
12
- <div
13
- :class="[computed_classes, props.class]"
14
- role="dialog"
15
- aria-modal="true"
16
- >
17
- <slot />
18
- <button
19
- v-if="show_close_button"
20
- :class="close_button_classes"
21
- @click="close"
22
- >
23
- <svg
24
- xmlns="http://www.w3.org/2000/svg"
25
- width="24"
26
- height="24"
27
- viewBox="0 0 24 24"
28
- fill="none"
29
- stroke="currentColor"
30
- stroke-width="2"
31
- stroke-linecap="round"
32
- stroke-linejoin="round"
33
- class="h-4 w-4"
34
- >
35
- <path d="M18 6 6 18" />
36
- <path d="m6 6 12 12" />
37
- </svg>
38
- <span class="sr-only">閉じる</span>
39
- </button>
40
- </div>
41
- </div>
42
- </Transition>
43
- </Teleport>
44
- </template>
45
-
46
- <script setup lang="ts">
47
- import { computed, provide } from "vue"
48
- import { useStyleAdapter } from "../../composables"
49
- import type { DialogProps } from "../../types/dialog"
50
- import { DIALOG_KEY } from "../../types/dialog"
51
- import type { DialogState } from "../../types/composables"
52
-
53
- interface DialogComponentProps extends DialogProps {
54
- class?: string
55
- }
56
-
57
- const props = withDefaults(defineProps<DialogComponentProps>(), {
58
- open: false,
59
- modal: true,
60
- showCloseButton: true,
61
- unstyled: false
62
- })
63
-
64
- const emit = defineEmits<{
65
- "update:open": [value: boolean]
66
- }>()
67
-
68
- const style_adapter = useStyleAdapter()
69
-
70
- const is_open = computed({
71
- get: () => props.open,
72
- set: (value) => emit("update:open", value)
73
- })
74
-
75
- const show_close_button = computed(() => props.showCloseButton)
76
-
77
- const computed_classes = computed(() => {
78
- if (props.unstyled) return ""
79
- const state: DialogState = {
80
- is_open: is_open.value
81
- }
82
- return style_adapter.getClasses("dialog", state)
83
- })
84
-
85
- const overlay_classes = computed(() => {
86
- if (props.unstyled) return ""
87
- return style_adapter.getClasses("dialog-overlay", {})
88
- })
89
-
90
- const close_button_classes = computed(() => {
91
- if (props.unstyled) return ""
92
- return style_adapter.getClasses("dialog-close", {})
93
- })
94
-
95
- const close = () => {
96
- is_open.value = false
97
- }
98
-
99
- const handleOverlayClick = () => {
100
- if (props.modal) {
101
- close()
102
- }
103
- }
104
-
105
- provide(DIALOG_KEY, { close })
106
- </script>
107
-
108
- <style scoped>
109
- .dialog-enter-active,.dialog-leave-active{transition:opacity .2s ease}.dialog-enter-from,.dialog-leave-to{opacity:0}
110
- </style>
@@ -1,22 +0,0 @@
1
- <template>
2
- <p :class="[computed_classes, props.class]">
3
- <slot />
4
- </p>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- import { computed } from "vue"
9
- import { useStyleAdapter } from "../../composables"
10
- import type { DialogDescriptionProps } from "../../types/dialog"
11
-
12
- const props = withDefaults(defineProps<DialogDescriptionProps>(), {
13
- unstyled: false
14
- })
15
-
16
- const style_adapter = useStyleAdapter()
17
-
18
- const computed_classes = computed(() => {
19
- if (props.unstyled) return ""
20
- return style_adapter.getClasses("dialog-description", {})
21
- })
22
- </script>