@dolanske/vui 1.0.1 → 1.0.3

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 (194) hide show
  1. package/LICENSE +673 -673
  2. package/README.md +42 -42
  3. package/dist/components/Accordion/Accordion.vue.d.ts +2 -3
  4. package/dist/components/Accordion/AccordionGroup.vue.d.ts +2 -5
  5. package/dist/components/Alert/Alert.vue.d.ts +2 -3
  6. package/dist/components/Avatar/Avatar.vue.d.ts +2 -3
  7. package/dist/components/Badge/Badge.vue.d.ts +2 -3
  8. package/dist/components/Breadcrumbs/BreadcrumbItem.vue.d.ts +2 -3
  9. package/dist/components/Breadcrumbs/Breadcrumbs.vue.d.ts +2 -3
  10. package/dist/components/Button/Button.vue.d.ts +2 -3
  11. package/dist/components/ButtonGroup/ButtonGroup.vue.d.ts +2 -3
  12. package/dist/components/Calendar/Calendar.vue.d.ts +6 -6
  13. package/dist/components/Card/Card.vue.d.ts +3 -4
  14. package/dist/components/Checkbox/Checkbox.vue.d.ts +6 -7
  15. package/dist/components/CopyClipboard/CopyClipboard.vue.d.ts +1 -2
  16. package/dist/components/Divider/Divider.vue.d.ts +2 -3
  17. package/dist/components/Drawer/Drawer.vue.d.ts +5 -6
  18. package/dist/components/Dropdown/Dropdown.vue.d.ts +3 -66
  19. package/dist/components/Dropdown/DropdownItem.vue.d.ts +2 -3
  20. package/dist/components/Dropdown/DropdownTitle.vue.d.ts +6 -6
  21. package/dist/components/Flex/Flex.vue.d.ts +2 -3
  22. package/dist/components/Grid/Grid.vue.d.ts +2 -3
  23. package/dist/components/Input/Color.vue.d.ts +5 -5
  24. package/dist/components/Input/Counter.vue.d.ts +5 -5
  25. package/dist/components/Input/Dropzone.vue.d.ts +10 -95
  26. package/dist/components/Input/File.vue.d.ts +3 -4
  27. package/dist/components/Input/Input.vue.d.ts +6 -7
  28. package/dist/components/Input/Password.vue.d.ts +1 -1
  29. package/dist/components/Input/Textarea.vue.d.ts +6 -7
  30. package/dist/components/Kbd/Kbd.vue.d.ts +1 -1
  31. package/dist/components/Kbd/KbdGroup.vue.d.ts +1 -2
  32. package/dist/components/Modal/Confirm.vue.d.ts +5 -6
  33. package/dist/components/Modal/Modal.vue.d.ts +5 -6
  34. package/dist/components/OTP/OTP.vue.d.ts +6 -7
  35. package/dist/components/OTP/OTPItem.vue.d.ts +1 -1
  36. package/dist/components/Pagination/Pagination.vue.d.ts +2 -3
  37. package/dist/components/Popout/Popout.vue.d.ts +2 -3
  38. package/dist/components/Progress/Progress.vue.d.ts +5 -5
  39. package/dist/components/Radio/Radio.vue.d.ts +6 -7
  40. package/dist/components/Radio/RadioGroup.vue.d.ts +6 -7
  41. package/dist/components/Select/Select.vue.d.ts +8 -4
  42. package/dist/components/Sheet/Sheet.vue.d.ts +5 -6
  43. package/dist/components/Sidebar/Sidebar.vue.d.ts +6 -7
  44. package/dist/components/Skeleton/Skeleton.vue.d.ts +1 -1
  45. package/dist/components/Spinner/Spinner.vue.d.ts +1 -1
  46. package/dist/components/Switch/Switch.vue.d.ts +6 -7
  47. package/dist/components/Table/Cell.vue.d.ts +2 -5
  48. package/dist/components/Table/Head.vue.d.ts +2 -3
  49. package/dist/components/Table/Root.vue.d.ts +2 -3
  50. package/dist/components/Table/table.d.ts +2 -2
  51. package/dist/components/Tabs/Tab.vue.d.ts +2 -3
  52. package/dist/components/Tabs/Tabs.vue.d.ts +6 -7
  53. package/dist/components/Toast/toast.d.ts +6 -6
  54. package/dist/components/Tooltip/Tooltip.vue.d.ts +1 -2
  55. package/dist/internal/Backdrop/Backdrop.vue.d.ts +2 -3
  56. package/dist/{vui.css → style.css} +1 -1
  57. package/dist/vui.js +5318 -5449
  58. package/package.json +72 -72
  59. package/src/App.vue +95 -95
  60. package/src/components/Accordion/Accordion.vue +91 -91
  61. package/src/components/Accordion/AccordionGroup.vue +43 -43
  62. package/src/components/Accordion/accordion.scss +82 -82
  63. package/src/components/Alert/Alert.vue +59 -59
  64. package/src/components/Alert/alert.scss +161 -161
  65. package/src/components/Avatar/Avatar.vue +53 -53
  66. package/src/components/Avatar/avatar.scss +52 -52
  67. package/src/components/Badge/Badge.vue +21 -21
  68. package/src/components/Badge/badge.scss +206 -206
  69. package/src/components/Breadcrumbs/BreadcrumbItem.vue +26 -26
  70. package/src/components/Breadcrumbs/Breadcrumbs.vue +30 -32
  71. package/src/components/Breadcrumbs/breadcrumbs.scss +31 -31
  72. package/src/components/Button/Button.vue +85 -85
  73. package/src/components/Button/button.scss +279 -279
  74. package/src/components/ButtonGroup/ButtonGroup.vue +28 -28
  75. package/src/components/ButtonGroup/button-group.scss +51 -51
  76. package/src/components/Calendar/Calendar.vue +66 -66
  77. package/src/components/Calendar/calendar.scss +83 -83
  78. package/src/components/Card/Card.vue +48 -48
  79. package/src/components/Card/card.scss +53 -53
  80. package/src/components/Checkbox/Checkbox.vue +54 -54
  81. package/src/components/Checkbox/checkbox.scss +80 -80
  82. package/src/components/CopyClipboard/CopyClipboard.vue +91 -91
  83. package/src/components/CopyClipboard/copy-clipboard.scss +25 -25
  84. package/src/components/Divider/Divider.vue +44 -44
  85. package/src/components/Divider/divider.scss +35 -35
  86. package/src/components/Drawer/Drawer.vue +97 -97
  87. package/src/components/Drawer/drawer.scss +37 -37
  88. package/src/components/Dropdown/Dropdown.vue +135 -135
  89. package/src/components/Dropdown/DropdownItem.vue +33 -33
  90. package/src/components/Dropdown/DropdownTitle.vue +14 -14
  91. package/src/components/Dropdown/dropdown-item.scss +84 -84
  92. package/src/components/Dropdown/dropdown.scss +53 -53
  93. package/src/components/Flex/Flex.vue +113 -113
  94. package/src/components/Grid/Grid.vue +80 -80
  95. package/src/components/Input/Color.vue +26 -26
  96. package/src/components/Input/Counter.vue +66 -66
  97. package/src/components/Input/Dropzone.vue +65 -65
  98. package/src/components/Input/File.vue +15 -15
  99. package/src/components/Input/Input.vue +123 -123
  100. package/src/components/Input/Password.vue +35 -35
  101. package/src/components/Input/Textarea.vue +78 -78
  102. package/src/components/Input/input.scss +302 -302
  103. package/src/components/Kbd/Kbd.vue +48 -48
  104. package/src/components/Kbd/KbdGroup.vue +27 -27
  105. package/src/components/Kbd/kbd.scss +19 -19
  106. package/src/components/Modal/Confirm.vue +56 -56
  107. package/src/components/Modal/Modal.vue +99 -99
  108. package/src/components/Modal/modal.scss +54 -54
  109. package/src/components/OTP/OTP.vue +133 -133
  110. package/src/components/OTP/OTPItem.vue +37 -37
  111. package/src/components/OTP/otp.scss +84 -84
  112. package/src/components/Pagination/Pagination.vue +77 -77
  113. package/src/components/Pagination/pagination.ts +78 -78
  114. package/src/components/Popout/Popout.vue +52 -52
  115. package/src/components/Popout/popout.scss +15 -15
  116. package/src/components/Progress/Progress.vue +103 -103
  117. package/src/components/Progress/progress.scss +47 -47
  118. package/src/components/Radio/Radio.vue +38 -38
  119. package/src/components/Radio/RadioGroup.vue +40 -40
  120. package/src/components/Radio/radio.scss +78 -78
  121. package/src/components/Select/Select.vue +211 -211
  122. package/src/components/Select/select.scss +77 -77
  123. package/src/components/Sheet/Sheet.vue +98 -98
  124. package/src/components/Sheet/sheet.scss +69 -69
  125. package/src/components/Sidebar/Sidebar.vue +115 -115
  126. package/src/components/Sidebar/sidebar.scss +124 -124
  127. package/src/components/Skeleton/Skeleton.vue +43 -43
  128. package/src/components/Skeleton/skeleton.scss +14 -14
  129. package/src/components/Spinner/Spinner.vue +42 -42
  130. package/src/components/Spinner/spinner.scss +47 -47
  131. package/src/components/Switch/Switch.vue +31 -31
  132. package/src/components/Switch/switch.scss +93 -93
  133. package/src/components/Table/Cell.vue +23 -23
  134. package/src/components/Table/Head.vue +59 -59
  135. package/src/components/Table/Root.vue +66 -66
  136. package/src/components/Table/SelectAll.vue +23 -23
  137. package/src/components/Table/SelectRow.vue +30 -30
  138. package/src/components/Table/index.ts +7 -7
  139. package/src/components/Table/table.scss +154 -154
  140. package/src/components/Table/table.ts +248 -248
  141. package/src/components/Tabs/Tab.vue +25 -25
  142. package/src/components/Tabs/Tabs.vue +89 -89
  143. package/src/components/Tabs/tabs.scss +87 -87
  144. package/src/components/Toast/Toasts.vue +52 -52
  145. package/src/components/Toast/toast.scss +45 -45
  146. package/src/components/Toast/toast.ts +75 -75
  147. package/src/components/Tooltip/Tooltip.vue +86 -86
  148. package/src/components/Tooltip/tooltip.scss +8 -8
  149. package/src/examples/ExampleAccordions.vue +58 -58
  150. package/src/examples/ExampleAlerts.vue +78 -78
  151. package/src/examples/ExampleAvatars.vue +44 -44
  152. package/src/examples/ExampleBadges.vue +48 -48
  153. package/src/examples/ExampleBreadcrumbs.vue +46 -46
  154. package/src/examples/ExampleButtons.vue +140 -140
  155. package/src/examples/ExampleCalendars.vue +40 -40
  156. package/src/examples/ExampleCards.vue +94 -94
  157. package/src/examples/ExampleCheckboxes.vue +123 -123
  158. package/src/examples/ExampleCopyClipboard.vue +47 -47
  159. package/src/examples/ExampleDividers.vue +39 -39
  160. package/src/examples/ExampleDrawers.vue +67 -67
  161. package/src/examples/ExampleDropdowns.vue +114 -114
  162. package/src/examples/ExampleFlexGrid.vue +122 -122
  163. package/src/examples/ExampleInputs.vue +234 -234
  164. package/src/examples/ExampleKBD.vue +65 -65
  165. package/src/examples/ExampleModals.vue +143 -143
  166. package/src/examples/ExamplePalette.vue +159 -159
  167. package/src/examples/ExamplePopouts.vue +41 -41
  168. package/src/examples/ExampleSheets.vue +77 -77
  169. package/src/examples/ExampleSidebars.vue +270 -270
  170. package/src/examples/ExampleSkeletons.vue +26 -26
  171. package/src/examples/ExampleSpinners.vue +78 -78
  172. package/src/examples/ExampleTables.vue +195 -195
  173. package/src/examples/ExampleTabs.vue +119 -119
  174. package/src/examples/ExampleToasts.vue +96 -96
  175. package/src/examples/ExampleTooltips.vue +70 -70
  176. package/src/examples/shared/ExampleColor.vue +28 -28
  177. package/src/index.scss +1 -1
  178. package/src/index.ts +116 -116
  179. package/src/internal/Backdrop/Backdrop.vue +22 -22
  180. package/src/internal/Backdrop/backdrop.scss +34 -34
  181. package/src/main.ts +5 -5
  182. package/src/shared/helpers.ts +117 -117
  183. package/src/shared/theme.ts +22 -22
  184. package/src/shared/types.ts +29 -29
  185. package/src/style/animation.scss +22 -22
  186. package/src/style/core.scss +125 -125
  187. package/src/style/layout.scss +233 -233
  188. package/src/style/media-query.scss +29 -29
  189. package/src/style/reset.scss +135 -135
  190. package/src/style/text.scss +124 -92
  191. package/src/style/theme.scss +195 -195
  192. package/src/style/tooltip.scss +146 -146
  193. package/src/style/typography.scss +415 -415
  194. package/src/style/utils.scss +36 -36
@@ -1,48 +1,48 @@
1
- <script setup lang='ts'>
2
- import { useMagicKeys, whenever } from '@vueuse/core'
3
- import { computed } from 'vue'
4
- import './kbd.scss'
5
-
6
- interface Props {
7
- /**
8
- * Specify the key or the combination of keys connected with "+". Make sure
9
- * there are no white spaces between letters.
10
- *
11
- * keys="Escape" keys="Ctrl+A"
12
- */
13
- keys: string
14
- /**
15
- * Display custom label instead of the automatically formatted keys.
16
- */
17
- label?: string
18
- /**
19
- * Show active state when this combination of keys is pressed.
20
- */
21
- highlight?: boolean
22
- }
23
-
24
- const props = defineProps<Props>()
25
- const emits = defineEmits<{
26
- trigger: []
27
- }>()
28
- const keyHandler = useMagicKeys()
29
-
30
- whenever(keyHandler[props.keys], () => {
31
- emits('trigger')
32
- })
33
-
34
- const isActive = computed(() => {
35
- if (!props.highlight)
36
- return false
37
-
38
- return props.keys.split('+').every((key) => {
39
- return keyHandler.current.has(key.toLowerCase())
40
- })
41
- })
42
- </script>
43
-
44
- <template>
45
- <kbd class="vui-kbd" :class="{ active: isActive }">
46
- {{ props.label ?? props.keys.replaceAll("+", " + ") }}
47
- </kbd>
48
- </template>
1
+ <script setup lang='ts'>
2
+ import { useMagicKeys, whenever } from '@vueuse/core'
3
+ import { computed } from 'vue'
4
+ import './kbd.scss'
5
+
6
+ interface Props {
7
+ /**
8
+ * Specify the key or the combination of keys connected with "+". Make sure
9
+ * there are no white spaces between letters.
10
+ *
11
+ * keys="Escape" keys="Ctrl+A"
12
+ */
13
+ keys: string
14
+ /**
15
+ * Display custom label instead of the automatically formatted keys.
16
+ */
17
+ label?: string
18
+ /**
19
+ * Show active state when this combination of keys is pressed.
20
+ */
21
+ highlight?: boolean
22
+ }
23
+
24
+ const props = defineProps<Props>()
25
+ const emits = defineEmits<{
26
+ trigger: []
27
+ }>()
28
+ const keyHandler = useMagicKeys()
29
+
30
+ whenever(keyHandler[props.keys], () => {
31
+ emits('trigger')
32
+ })
33
+
34
+ const isActive = computed(() => {
35
+ if (!props.highlight)
36
+ return false
37
+
38
+ return props.keys.split('+').every((key) => {
39
+ return keyHandler.current.has(key.toLowerCase())
40
+ })
41
+ })
42
+ </script>
43
+
44
+ <template>
45
+ <kbd class="vui-kbd" :class="{ active: isActive }">
46
+ {{ props.label ?? props.keys.replaceAll("+", " + ") }}
47
+ </kbd>
48
+ </template>
@@ -1,27 +1,27 @@
1
- <script setup lang='ts'>
2
- import type Kbd from './Kbd.vue'
3
- import { useMagicKeys, whenever } from '@vueuse/core'
4
-
5
- /**
6
- * Can be used to wrap multiple <Kbd /> elements and triggers the callback when
7
- * all of them are active
8
- */
9
-
10
- const emits = defineEmits<{
11
- trigger: []
12
- }>()
13
-
14
- const slots = defineSlots<{
15
- default: () => Array<typeof Kbd>
16
- }>()
17
- const keys = useMagicKeys()
18
-
19
- whenever(
20
- keys[slots.default().map(vnode => vnode.props.keys).join('+')],
21
- () => emits('trigger'),
22
- )
23
- </script>
24
-
25
- <template>
26
- <slot />
27
- </template>
1
+ <script setup lang='ts'>
2
+ import type Kbd from './Kbd.vue'
3
+ import { useMagicKeys, whenever } from '@vueuse/core'
4
+
5
+ /**
6
+ * Can be used to wrap multiple <Kbd /> elements and triggers the callback when
7
+ * all of them are active
8
+ */
9
+
10
+ const emits = defineEmits<{
11
+ trigger: []
12
+ }>()
13
+
14
+ const slots = defineSlots<{
15
+ default: () => Array<typeof Kbd>
16
+ }>()
17
+ const keys = useMagicKeys()
18
+
19
+ whenever(
20
+ keys[slots.default().map(vnode => vnode.props.keys).join('+')],
21
+ () => emits('trigger'),
22
+ )
23
+ </script>
24
+
25
+ <template>
26
+ <slot />
27
+ </template>
@@ -1,19 +1,19 @@
1
- .vui-kbd {
2
- display: inline-flex;
3
- align-items: center;
4
- justify-content: center;
5
- height: 24px;
6
- border-radius: var(--border-radius-xs);
7
- font-size: var(--font-size-s);
8
- padding: 0 4px;
9
- transition: var(--transition-fast);
10
- font-weight: 600;
11
- background-color: var(--color-button-gray);
12
- color: var(--color-text-accent);
13
-
14
- &.active {
15
- transform: translateY(2px);
16
- color: var(--color-text-invert);
17
- background-color: var(--color-button-fill);
18
- }
19
- }
1
+ .vui-kbd {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ height: 24px;
6
+ border-radius: var(--border-radius-xs);
7
+ font-size: var(--font-size-s);
8
+ padding: 0 4px;
9
+ transition: var(--transition-fast);
10
+ font-weight: 600;
11
+ background-color: var(--color-button-gray);
12
+ color: var(--color-text-accent);
13
+
14
+ &.active {
15
+ transform: translateY(2px);
16
+ color: var(--color-text-invert);
17
+ background-color: var(--color-button-fill);
18
+ }
19
+ }
@@ -1,56 +1,56 @@
1
- <script setup lang='ts'>
2
- import type { Variants } from '../Button/Button.vue'
3
- import type { ModalProps } from './Modal.vue'
4
- import Button from '../Button/Button.vue'
5
- import Flex from '../Flex/Flex.vue'
6
- import Modal from './Modal.vue'
7
-
8
- type Props = {
9
- title?: string
10
- content?: string
11
- confirmText?: string
12
- confirmVariant?: Variants
13
- cancelText?: string
14
- showCancel?: boolean
15
- } & Partial<ModalProps>
16
-
17
- const props = withDefaults(defineProps<Props>(), {
18
- cancelText: 'Cancel',
19
- confirmText: 'Ok',
20
- size: 's',
21
- canDismiss: true,
22
- showCancel: true,
23
- confirmVariant: 'gray',
24
- })
25
-
26
- const emits = defineEmits<{
27
- cancel: []
28
- confirm: []
29
- }>()
30
-
31
- const open = defineModel<boolean>()
32
- </script>
33
-
34
- <template>
35
- <pre>{{ $props }}</pre>
36
- <Modal
37
- v-bind="props"
38
- v-model="open"
39
- >
40
- <template #default>
41
- <div class="typeset">
42
- <slot />
43
- </div>
44
- </template>
45
- <template #footer>
46
- <Flex justify-end>
47
- <Button v-if="props.showCancel" plain @click="emits('cancel'), open = false">
48
- {{ props.cancelText }}
49
- </Button>
50
- <Button :variant="props.confirmVariant" @click="emits('confirm'), open = false">
51
- {{ props.confirmText }}
52
- </Button>
53
- </Flex>
54
- </template>
55
- </Modal>
56
- </template>
1
+ <script setup lang='ts'>
2
+ import type { Variants } from '../Button/Button.vue'
3
+ import type { ModalProps } from './Modal.vue'
4
+ import Button from '../Button/Button.vue'
5
+ import Flex from '../Flex/Flex.vue'
6
+ import Modal from './Modal.vue'
7
+
8
+ type Props = {
9
+ title?: string
10
+ content?: string
11
+ confirmText?: string
12
+ confirmVariant?: Variants
13
+ cancelText?: string
14
+ showCancel?: boolean
15
+ } & Partial<ModalProps>
16
+
17
+ const props = withDefaults(defineProps<Props>(), {
18
+ cancelText: 'Cancel',
19
+ confirmText: 'Ok',
20
+ size: 's',
21
+ canDismiss: true,
22
+ showCancel: true,
23
+ confirmVariant: 'gray',
24
+ })
25
+
26
+ const emits = defineEmits<{
27
+ cancel: []
28
+ confirm: []
29
+ }>()
30
+
31
+ const open = defineModel<boolean>()
32
+ </script>
33
+
34
+ <template>
35
+ <pre>{{ $props }}</pre>
36
+ <Modal
37
+ v-bind="props"
38
+ v-model="open"
39
+ >
40
+ <template #default>
41
+ <div class="typeset">
42
+ <slot />
43
+ </div>
44
+ </template>
45
+ <template #footer>
46
+ <Flex justify-end>
47
+ <Button v-if="props.showCancel" plain @click="emits('cancel'), open = false">
48
+ {{ props.cancelText }}
49
+ </Button>
50
+ <Button :variant="props.confirmVariant" @click="emits('confirm'), open = false">
51
+ {{ props.confirmText }}
52
+ </Button>
53
+ </Flex>
54
+ </template>
55
+ </Modal>
56
+ </template>
@@ -1,99 +1,99 @@
1
- <script setup lang='ts'>
2
- import type { Sizes } from '../../shared/types'
3
- import type { Props as CardProps } from '../Card/Card.vue'
4
- import { useAttrs } from 'vue'
5
- import Backdrop from '../../internal/Backdrop/Backdrop.vue'
6
- import Button from '../Button/Button.vue'
7
- import Card from '../Card/Card.vue'
8
- import './modal.scss'
9
-
10
- export interface ModalProps {
11
- size?: Sizes | 'full' | 'screen'
12
- /**
13
- * Modal wraps a floating card. You can optinally pass in any props you'd pass
14
- * into the <Card /> component.
15
- */
16
- card?: CardProps
17
- /**
18
- * Modal will not overflow the screen, but its card's content will be scrollable instead.
19
- */
20
- scrollable?: boolean
21
- /**
22
- * Modal appears in the center of the screen
23
- */
24
- centered?: boolean
25
- /**
26
- * Wether modal can be closed by clicking the X button
27
- */
28
- canDismiss?: boolean
29
- }
30
-
31
- const {
32
- size = 'm',
33
- card = {},
34
- scrollable,
35
- centered,
36
- canDismiss = true,
37
- } = defineProps<ModalProps>()
38
-
39
- const open = defineModel<boolean>()
40
-
41
- function close() {
42
- open.value = false
43
- }
44
-
45
- const attrs = useAttrs()
46
-
47
- function tryClose() {
48
- if (canDismiss) {
49
- close()
50
- }
51
- }
52
- </script>
53
-
54
- <template>
55
- <Teleport to="body">
56
- <Transition appear name="modal">
57
- <Backdrop v-if="open" :class="{ 'p-0': size === 'screen' }" @close="tryClose">
58
- <div class="vui-modal" :class="[`vui-modal-size-${size}`, { scrollable: scrollable || size === 'screen', centered }]" v-bind="attrs" @click.self="tryClose">
59
- <Card v-bind="card">
60
- <template v-if="$slots.header" #header>
61
- <slot name="header" :close="close" />
62
- </template>
63
- <template #header-end>
64
- <Button
65
- v-if="canDismiss"
66
- class="vui-modal-close"
67
- plain
68
- square
69
- icon="ph:x"
70
- @click="open = false"
71
- />
72
- </template>
73
- <template v-if="$slots.default" #default>
74
- <div>
75
- <slot name="default" :close="close" />
76
- </div>
77
- </template>
78
- <template v-if="$slots.footer" #footer>
79
- <slot name="footer" :close="close" />
80
- </template>
81
- </Card>
82
- </div>
83
- </Backdrop>
84
- </Transition>
85
- </Teleport>
86
- </template>
87
-
88
- <style scoped>
89
- .modal-enter-active,
90
- .modal-leave-active {
91
- transition: var(--transition);
92
- }
93
-
94
- .modal-enter-from,
95
- .modal-leave-to {
96
- opacity: 0;
97
- transform: scale(1.025);
98
- }
99
- </style>
1
+ <script setup lang='ts'>
2
+ import type { Sizes } from '../../shared/types'
3
+ import type { Props as CardProps } from '../Card/Card.vue'
4
+ import { useAttrs } from 'vue'
5
+ import Backdrop from '../../internal/Backdrop/Backdrop.vue'
6
+ import Button from '../Button/Button.vue'
7
+ import Card from '../Card/Card.vue'
8
+ import './modal.scss'
9
+
10
+ export interface ModalProps {
11
+ size?: Sizes | 'full' | 'screen'
12
+ /**
13
+ * Modal wraps a floating card. You can optinally pass in any props you'd pass
14
+ * into the <Card /> component.
15
+ */
16
+ card?: CardProps
17
+ /**
18
+ * Modal will not overflow the screen, but its card's content will be scrollable instead.
19
+ */
20
+ scrollable?: boolean
21
+ /**
22
+ * Modal appears in the center of the screen
23
+ */
24
+ centered?: boolean
25
+ /**
26
+ * Wether modal can be closed by clicking the X button
27
+ */
28
+ canDismiss?: boolean
29
+ }
30
+
31
+ const {
32
+ size = 'm',
33
+ card = {},
34
+ scrollable,
35
+ centered,
36
+ canDismiss = true,
37
+ } = defineProps<ModalProps>()
38
+
39
+ const open = defineModel<boolean>()
40
+
41
+ function close() {
42
+ open.value = false
43
+ }
44
+
45
+ const attrs = useAttrs()
46
+
47
+ function tryClose() {
48
+ if (canDismiss) {
49
+ close()
50
+ }
51
+ }
52
+ </script>
53
+
54
+ <template>
55
+ <Teleport to="body">
56
+ <Transition appear name="modal">
57
+ <Backdrop v-if="open" :class="{ 'p-0': size === 'screen' }" @close="tryClose">
58
+ <div class="vui-modal" :class="[`vui-modal-size-${size}`, { scrollable: scrollable || size === 'screen', centered }]" v-bind="attrs" @click.self="tryClose">
59
+ <Card v-bind="card">
60
+ <template v-if="$slots.header" #header>
61
+ <slot name="header" :close="close" />
62
+ </template>
63
+ <template #header-end>
64
+ <Button
65
+ v-if="canDismiss"
66
+ class="vui-modal-close"
67
+ plain
68
+ square
69
+ icon="ph:x"
70
+ @click="open = false"
71
+ />
72
+ </template>
73
+ <template v-if="$slots.default" #default>
74
+ <div>
75
+ <slot name="default" :close="close" />
76
+ </div>
77
+ </template>
78
+ <template v-if="$slots.footer" #footer>
79
+ <slot name="footer" :close="close" />
80
+ </template>
81
+ </Card>
82
+ </div>
83
+ </Backdrop>
84
+ </Transition>
85
+ </Teleport>
86
+ </template>
87
+
88
+ <style scoped>
89
+ .modal-enter-active,
90
+ .modal-leave-active {
91
+ transition: var(--transition);
92
+ }
93
+
94
+ .modal-enter-from,
95
+ .modal-leave-to {
96
+ opacity: 0;
97
+ transform: scale(1.025);
98
+ }
99
+ </style>
@@ -1,54 +1,54 @@
1
- .vui-modal {
2
- width: 100%;
3
- margin-inline: auto;
4
- height: 100%;
5
- position: relative;
6
-
7
- &.centered {
8
- display: flex;
9
- align-items: center;
10
- }
11
-
12
- &.vui-modal-size-s {
13
- max-width: 440px;
14
- }
15
-
16
- &.vui-modal-size-m {
17
- max-width: 620px;
18
- }
19
-
20
- &.vui-modal-size-l {
21
- max-width: 728px;
22
- }
23
-
24
- &.vui-modal-size-screen {
25
- position: fixed;
26
- inset: 0;
27
-
28
- & > .vui-card {
29
- border-radius: 0;
30
- border: none;
31
- height: 100vh;
32
- }
33
- }
34
-
35
- &.scrollable {
36
- & > .vui-card {
37
- display: flex;
38
- flex-direction: column;
39
- inline-size: 100%;
40
- max-height: 100%;
41
-
42
- .vui-card-content {
43
- flex: 1 1 0%;
44
- overflow-y: auto;
45
- }
46
- }
47
- }
48
-
49
- & > .vui-card {
50
- width: 100%;
51
- margin-bottom: var(--backdrop-offset);
52
- box-shadow: var(--box-shadow-strong);
53
- }
54
- }
1
+ .vui-modal {
2
+ width: 100%;
3
+ margin-inline: auto;
4
+ height: 100%;
5
+ position: relative;
6
+
7
+ &.centered {
8
+ display: flex;
9
+ align-items: center;
10
+ }
11
+
12
+ &.vui-modal-size-s {
13
+ max-width: 440px;
14
+ }
15
+
16
+ &.vui-modal-size-m {
17
+ max-width: 620px;
18
+ }
19
+
20
+ &.vui-modal-size-l {
21
+ max-width: 728px;
22
+ }
23
+
24
+ &.vui-modal-size-screen {
25
+ position: fixed;
26
+ inset: 0;
27
+
28
+ & > .vui-card {
29
+ border-radius: 0;
30
+ border: none;
31
+ height: 100vh;
32
+ }
33
+ }
34
+
35
+ &.scrollable {
36
+ & > .vui-card {
37
+ display: flex;
38
+ flex-direction: column;
39
+ inline-size: 100%;
40
+ max-height: 100%;
41
+
42
+ .vui-card-content {
43
+ flex: 1 1 0%;
44
+ overflow-y: auto;
45
+ }
46
+ }
47
+ }
48
+
49
+ & > .vui-card {
50
+ width: 100%;
51
+ margin-bottom: var(--backdrop-offset);
52
+ box-shadow: var(--box-shadow-strong);
53
+ }
54
+ }