@dolanske/vui 1.4.1 → 1.4.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 (140) hide show
  1. package/package.json +1 -2
  2. package/src/App.vue +0 -103
  3. package/src/components/Accordion/Accordion.vue +0 -98
  4. package/src/components/Accordion/AccordionGroup.vue +0 -49
  5. package/src/components/Accordion/accordion.scss +0 -97
  6. package/src/components/Alert/Alert.vue +0 -59
  7. package/src/components/Alert/alert.scss +0 -162
  8. package/src/components/Avatar/Avatar.vue +0 -53
  9. package/src/components/Avatar/avatar.scss +0 -52
  10. package/src/components/Badge/Badge.vue +0 -21
  11. package/src/components/Badge/badge.scss +0 -210
  12. package/src/components/Breadcrumbs/BreadcrumbItem.vue +0 -26
  13. package/src/components/Breadcrumbs/Breadcrumbs.vue +0 -29
  14. package/src/components/Breadcrumbs/breadcrumbs.scss +0 -31
  15. package/src/components/Button/Button.vue +0 -86
  16. package/src/components/Button/button.scss +0 -292
  17. package/src/components/ButtonGroup/ButtonGroup.vue +0 -28
  18. package/src/components/ButtonGroup/button-group.scss +0 -51
  19. package/src/components/Calendar/Calendar.vue +0 -66
  20. package/src/components/Calendar/calendar.scss +0 -88
  21. package/src/components/Card/Card.vue +0 -48
  22. package/src/components/Card/card.scss +0 -55
  23. package/src/components/Checkbox/Checkbox.vue +0 -54
  24. package/src/components/Checkbox/checkbox.scss +0 -80
  25. package/src/components/CopyClipboard/CopyClipboard.vue +0 -98
  26. package/src/components/CopyClipboard/copy-clipboard.scss +0 -25
  27. package/src/components/Divider/Divider.vue +0 -38
  28. package/src/components/Divider/divider.scss +0 -37
  29. package/src/components/Drawer/Drawer.vue +0 -102
  30. package/src/components/Drawer/drawer.scss +0 -37
  31. package/src/components/Dropdown/Dropdown.vue +0 -120
  32. package/src/components/Dropdown/DropdownItem.vue +0 -33
  33. package/src/components/Dropdown/DropdownTitle.vue +0 -14
  34. package/src/components/Dropdown/dropdown-item.scss +0 -84
  35. package/src/components/Dropdown/dropdown.scss +0 -53
  36. package/src/components/Flex/Flex.vue +0 -113
  37. package/src/components/Grid/Grid.vue +0 -87
  38. package/src/components/Input/Color.vue +0 -26
  39. package/src/components/Input/Counter.vue +0 -66
  40. package/src/components/Input/Dropzone.vue +0 -65
  41. package/src/components/Input/File.vue +0 -15
  42. package/src/components/Input/Input.vue +0 -123
  43. package/src/components/Input/Password.vue +0 -35
  44. package/src/components/Input/Textarea.vue +0 -78
  45. package/src/components/Input/input.scss +0 -302
  46. package/src/components/Kbd/Kbd.vue +0 -48
  47. package/src/components/Kbd/KbdGroup.vue +0 -28
  48. package/src/components/Kbd/kbd.scss +0 -19
  49. package/src/components/Modal/Confirm.vue +0 -56
  50. package/src/components/Modal/Modal.vue +0 -103
  51. package/src/components/Modal/modal.scss +0 -54
  52. package/src/components/OTP/OTP.vue +0 -133
  53. package/src/components/OTP/OTPItem.vue +0 -37
  54. package/src/components/OTP/otp.scss +0 -84
  55. package/src/components/Pagination/Pagination.vue +0 -92
  56. package/src/components/Pagination/pagination.ts +0 -78
  57. package/src/components/Popout/Popout.vue +0 -73
  58. package/src/components/Popout/popout.scss +0 -16
  59. package/src/components/Progress/Progress.vue +0 -103
  60. package/src/components/Progress/progress.scss +0 -47
  61. package/src/components/Radio/Radio.vue +0 -38
  62. package/src/components/Radio/RadioGroup.vue +0 -34
  63. package/src/components/Radio/radio.scss +0 -78
  64. package/src/components/Select/Select.vue +0 -212
  65. package/src/components/Select/select.scss +0 -82
  66. package/src/components/Sheet/Sheet.vue +0 -106
  67. package/src/components/Sheet/sheet.scss +0 -71
  68. package/src/components/Sidebar/Sidebar.vue +0 -116
  69. package/src/components/Sidebar/sidebar.scss +0 -124
  70. package/src/components/Skeleton/Skeleton.vue +0 -43
  71. package/src/components/Skeleton/skeleton.scss +0 -14
  72. package/src/components/Spinner/Spinner.vue +0 -42
  73. package/src/components/Spinner/spinner.scss +0 -47
  74. package/src/components/Switch/Switch.vue +0 -31
  75. package/src/components/Switch/switch.scss +0 -93
  76. package/src/components/Table/Cell.vue +0 -23
  77. package/src/components/Table/Head.vue +0 -66
  78. package/src/components/Table/Root.vue +0 -66
  79. package/src/components/Table/SelectAll.vue +0 -23
  80. package/src/components/Table/SelectRow.vue +0 -30
  81. package/src/components/Table/index.ts +0 -7
  82. package/src/components/Table/table.scss +0 -155
  83. package/src/components/Table/table.ts +0 -248
  84. package/src/components/Tabs/Tab.vue +0 -25
  85. package/src/components/Tabs/Tabs.vue +0 -90
  86. package/src/components/Tabs/tabs.scss +0 -87
  87. package/src/components/Toast/Toasts.vue +0 -52
  88. package/src/components/Toast/toast.scss +0 -45
  89. package/src/components/Toast/toast.ts +0 -75
  90. package/src/components/Tooltip/Tooltip.vue +0 -78
  91. package/src/components/Tooltip/tooltip.scss +0 -5
  92. package/src/examples/ExampleAccordions.vue +0 -69
  93. package/src/examples/ExampleAlerts.vue +0 -78
  94. package/src/examples/ExampleAvatars.vue +0 -44
  95. package/src/examples/ExampleBadges.vue +0 -48
  96. package/src/examples/ExampleBreadcrumbs.vue +0 -46
  97. package/src/examples/ExampleButtons.vue +0 -148
  98. package/src/examples/ExampleCalendars.vue +0 -40
  99. package/src/examples/ExampleCards.vue +0 -94
  100. package/src/examples/ExampleCheckboxes.vue +0 -123
  101. package/src/examples/ExampleCopyClipboard.vue +0 -47
  102. package/src/examples/ExampleDividers.vue +0 -39
  103. package/src/examples/ExampleDrawers.vue +0 -67
  104. package/src/examples/ExampleDropdowns.vue +0 -114
  105. package/src/examples/ExampleFlexGrid.vue +0 -124
  106. package/src/examples/ExampleInputs.vue +0 -236
  107. package/src/examples/ExampleKBD.vue +0 -65
  108. package/src/examples/ExampleModals.vue +0 -143
  109. package/src/examples/ExamplePalette.vue +0 -165
  110. package/src/examples/ExamplePopouts.vue +0 -41
  111. package/src/examples/ExampleSheets.vue +0 -77
  112. package/src/examples/ExampleSidebars.vue +0 -276
  113. package/src/examples/ExampleSkeletons.vue +0 -26
  114. package/src/examples/ExampleSpinners.vue +0 -80
  115. package/src/examples/ExampleTables.vue +0 -359
  116. package/src/examples/ExampleTabs.vue +0 -142
  117. package/src/examples/ExampleToasts.vue +0 -96
  118. package/src/examples/ExampleTooltips.vue +0 -70
  119. package/src/examples/shared/ExampleColor.vue +0 -28
  120. package/src/index.ts +0 -116
  121. package/src/internal/Backdrop/Backdrop.vue +0 -22
  122. package/src/internal/Backdrop/backdrop.scss +0 -34
  123. package/src/main.ts +0 -5
  124. package/src/shared/helpers.ts +0 -124
  125. package/src/shared/slots.ts +0 -61
  126. package/src/shared/theme.ts +0 -22
  127. package/src/shared/types.ts +0 -29
  128. package/src/style/animation.scss +0 -50
  129. package/src/style/core.scss +0 -133
  130. package/src/style/fonts.scss +0 -73
  131. package/src/style/layout.scss +0 -179
  132. package/src/style/media-query.scss +0 -29
  133. package/src/style/reset.scss +0 -135
  134. package/src/style/text.scss +0 -137
  135. package/src/style/theme.scss +0 -195
  136. package/src/style/tooltip.scss +0 -146
  137. package/src/style/typography.scss +0 -435
  138. package/src/style/utils.scss +0 -36
  139. package/src/style.scss +0 -1
  140. package/src/vite-env.d.ts +0 -1
@@ -1,48 +0,0 @@
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,28 +0,0 @@
1
- <script setup lang='ts'>
2
- import { useMagicKeys, whenever } from '@vueuse/core'
3
- import { enforceSlotType, useFlattenedSlot } from '../../shared/slots'
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
- const keys = useMagicKeys()
16
-
17
- const flattened = useFlattenedSlot(slots.default)
18
- enforceSlotType(flattened, 'Kbd')
19
-
20
- whenever(
21
- keys[flattened.value.map(vnode => vnode.props.keys).join('+')],
22
- () => emits('trigger'),
23
- )
24
- </script>
25
-
26
- <template>
27
- <slot />
28
- </template>
@@ -1,19 +0,0 @@
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 +0,0 @@
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
- open: false,
25
- })
26
-
27
- const emit = defineEmits<{
28
- cancel: []
29
- confirm: []
30
- close: []
31
- }>()
32
- </script>
33
-
34
- <template>
35
- <Modal
36
- v-bind="props"
37
- :open="props.open"
38
- @close="emit('close')"
39
- >
40
- <template #default>
41
- <div class="typeset">
42
- <slot />
43
- </div>
44
- </template>
45
- <template #footer>
46
- <Flex x-end>
47
- <Button v-if="props.showCancel" plain @click="emit('cancel'), emit('close')">
48
- {{ props.cancelText }}
49
- </Button>
50
- <Button :variant="props.confirmVariant" @click="emit('confirm'), emit('close')">
51
- {{ props.confirmText }}
52
- </Button>
53
- </Flex>
54
- </template>
55
- </Modal>
56
- </template>
@@ -1,103 +0,0 @@
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
- /**
12
- * Controls the visibility of the modal
13
- */
14
- open?: boolean
15
- /**
16
- * Controls the width of the modal
17
- */
18
- size?: Sizes | 'full' | 'screen'
19
- /**
20
- * Modal wraps a floating card. You can optinally pass in any props you'd pass
21
- * into the <Card /> component.
22
- */
23
- card?: CardProps
24
- /**
25
- * Modal will not overflow the screen, but its card's content will be scrollable instead.
26
- */
27
- scrollable?: boolean
28
- /**
29
- * Modal appears in the center of the screen
30
- */
31
- centered?: boolean
32
- /**
33
- * Wether modal can be closed by clicking the X button
34
- */
35
- canDismiss?: boolean
36
- }
37
-
38
- const {
39
- size = 'm',
40
- card = {},
41
- scrollable,
42
- centered,
43
- canDismiss = true,
44
- open = false,
45
- } = defineProps<ModalProps>()
46
-
47
- const emit = defineEmits<{ close: [] }>()
48
-
49
- const attrs = useAttrs()
50
-
51
- function tryClose() {
52
- if (canDismiss) {
53
- emit('close')
54
- }
55
- }
56
- </script>
57
-
58
- <template>
59
- <Teleport to="body">
60
- <Transition appear name="modal">
61
- <Backdrop v-if="open" :class="{ 'p-0': size === 'screen' }" @close="tryClose">
62
- <div class="vui-modal" :class="[`vui-modal-size-${size}`, { scrollable: scrollable || size === 'screen', centered }]" v-bind="attrs" @click.self="tryClose">
63
- <Card v-bind="card">
64
- <template v-if="$slots.header" #header>
65
- <slot name="header" :close="() => emit('close')" />
66
- </template>
67
- <template #header-end>
68
- <Button
69
- v-if="canDismiss"
70
- class="vui-modal-close"
71
- plain
72
- square
73
- icon="ph:x"
74
- @click="emit('close')"
75
- />
76
- </template>
77
- <template v-if="$slots.default" #default>
78
- <div>
79
- <slot name="default" :close="() => emit('close')" />
80
- </div>
81
- </template>
82
- <template v-if="$slots.footer" #footer>
83
- <slot name="footer" :close="() => emit('close')" />
84
- </template>
85
- </Card>
86
- </div>
87
- </Backdrop>
88
- </Transition>
89
- </Teleport>
90
- </template>
91
-
92
- <style scoped>
93
- .modal-enter-active,
94
- .modal-leave-active {
95
- transition: var(--transition);
96
- }
97
-
98
- .modal-enter-from,
99
- .modal-leave-to {
100
- opacity: 0;
101
- transform: scale(1.025);
102
- }
103
- </style>
@@ -1,54 +0,0 @@
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,133 +0,0 @@
1
- <script setup lang='ts'>
2
- import type { ModelRef, Ref } from 'vue'
3
- import { computed, provide, ref, toRef, useTemplateRef, watch } from 'vue'
4
- import { setCharAt } from '../../shared/helpers'
5
- import './otp.scss'
6
-
7
- export interface OtpContext {
8
- otpValue: ModelRef<string>
9
- cursorIndex: Ref<number>
10
- redacted: Ref<boolean>
11
- register: () => void
12
- }
13
-
14
- interface Props {
15
- mode?: 'num' | 'char' | 'both'
16
- redacted?: boolean
17
- }
18
-
19
- const {
20
- mode = 'both',
21
- redacted = false,
22
- } = defineProps<Props>()
23
-
24
- const emits = defineEmits<{
25
- change: [value?: string]
26
- complete: [value: string]
27
- }>()
28
-
29
- const otpValue = defineModel<string>({
30
- default: '',
31
- })
32
-
33
- const cursorIndex = ref<number>(-1)
34
- const regexNumbers = '^\\d+$'
35
- const regexChars = '^[a-z]+$'
36
- const regexBoth = '^[a-z0-9]+$'
37
-
38
- const pattern = computed(() => {
39
- if (mode === 'num')
40
- return new RegExp(regexNumbers)
41
- else if (mode === 'char')
42
- return new RegExp(regexChars, 'i')
43
- else return new RegExp(regexBoth, 'i')
44
- })
45
-
46
- const maxLen = ref(0)
47
-
48
- const input = useTemplateRef('inputRef')
49
-
50
- provide('otp-context', {
51
- otpValue,
52
- cursorIndex,
53
- redacted: toRef(() => redacted),
54
- // Called by all OTPItem child components to properly set max length of the input.
55
- register: () => maxLen.value++,
56
- })
57
-
58
- watch(otpValue, value => emits('change', value))
59
-
60
- function setOtpValue(value: string) {
61
- otpValue.value = value
62
- if (input.value) {
63
- input.value.value = value
64
- }
65
- }
66
-
67
- function updateValue(e: KeyboardEvent) {
68
- const key = e.key
69
-
70
- // Capping at length 0 prevents all non-character keyboard inputs
71
- if (pattern.value.test(key) && key.length === 1) {
72
- const newValue = setCharAt(otpValue.value, key, cursorIndex.value)
73
-
74
- if (newValue.length <= maxLen.value) {
75
- setOtpValue(newValue)
76
-
77
- if (cursorIndex.value < maxLen.value - 1)
78
- cursorIndex.value++
79
- }
80
- }
81
- else if (key === 'ArrowLeft' && cursorIndex.value > 0) {
82
- cursorIndex.value--
83
- }
84
- else if (key === 'ArrowRight' && cursorIndex.value < otpValue.value.length) {
85
- cursorIndex.value++
86
- }
87
- else if (key === 'Backspace') {
88
- // If we press backspace multiple times make sure to traverse back by 1
89
- if (otpValue.value.charAt(cursorIndex.value) === '' && cursorIndex.value > 0) {
90
- cursorIndex.value--
91
- }
92
-
93
- const newValue = setCharAt(otpValue.value, '', cursorIndex.value)
94
- setOtpValue(newValue)
95
- }
96
- }
97
-
98
- function handlePaste(e: any) {
99
- const clipboard = e.clipboardData?.getData('text/plain')
100
- if (clipboard) {
101
- const clipboardTrim = clipboard.trim().slice(0, maxLen.value - cursorIndex.value)
102
-
103
- if (!pattern.value.test(clipboardTrim)) {
104
- return
105
- }
106
-
107
- const currentTrimStart = otpValue.value.slice(0, cursorIndex.value)
108
- const currentTrimEnd = otpValue.value.slice(cursorIndex.value + clipboardTrim.length)
109
- const newValue = (currentTrimStart + clipboardTrim + currentTrimEnd).trim()
110
- setOtpValue(newValue)
111
- cursorIndex.value = Math.min(newValue.length, maxLen.value - 1)
112
- }
113
- }
114
- </script>
115
-
116
- <template>
117
- <div class="vui-otp">
118
- <input
119
- ref="inputRef"
120
- type="text"
121
- class="vui-otp-input"
122
- contenteditable="true"
123
- @keydown="updateValue"
124
- @blur="cursorIndex = -1"
125
- @focus="cursorIndex = Math.min(otpValue.length, maxLen - 1)"
126
- @paste="handlePaste"
127
- >
128
-
129
- <div class="vui-otp-items">
130
- <slot />
131
- </div>
132
- </div>
133
- </template>
@@ -1,37 +0,0 @@
1
- <script setup lang='ts'>
2
- import type { OtpContext } from './OTP.vue'
3
- import { Icon } from '@iconify/vue'
4
- import { inject } from 'vue'
5
-
6
- interface Props {
7
- i: number
8
- }
9
-
10
- const props = defineProps<Props>()
11
-
12
- const {
13
- otpValue,
14
- cursorIndex,
15
- redacted,
16
- register,
17
- } = inject('otp-context') as OtpContext
18
-
19
- register()
20
- </script>
21
-
22
- <template>
23
- <div
24
- class="vui-otp-item" :class="{
25
- 'active': props.i === cursorIndex,
26
- 'has-value': otpValue.trim().at(props.i),
27
- }"
28
- >
29
- <div class="blinker" />
30
- <template v-if="otpValue.trim().at(props.i)">
31
- <Icon v-if="redacted" icon="ph:asterisk" />
32
- <template v-else>
33
- {{ otpValue.at(props.i) }}
34
- </template>
35
- </template>
36
- </div>
37
- </template>
@@ -1,84 +0,0 @@
1
- .vui-otp {
2
- display: inline-block;
3
- position: relative;
4
-
5
- .vui-otp-items {
6
- display: inline-flex;
7
- gap: 0;
8
-
9
- .vui-otp-item {
10
- display: flex;
11
- align-items: center;
12
- justify-content: center;
13
- width: var(--interactive-el-height);
14
- height: var(--interactive-el-height);
15
- border: 1px solid var(--color-border-strong);
16
- color: var(--color-text);
17
- z-index: var(--z-default);
18
- font-size: var(--font-size-m);
19
- outline: 0 solid var(--color-text-light);
20
- transition: var(--transition-fast);
21
-
22
- .blinker {
23
- display: block;
24
- height: 16px;
25
- width: 1px;
26
- background-color: var(--color-text);
27
- animation: blink 1s ease-out infinite;
28
- visibility: hidden;
29
- }
30
-
31
- @keyframes blink {
32
- 0%,
33
- 70%,
34
- 100% {
35
- opacity: 1;
36
- }
37
- 20%,
38
- 50% {
39
- opacity: 0;
40
- }
41
- }
42
-
43
- &.has-value {
44
- background-color: var(--color-bg-medium);
45
-
46
- .blinker {
47
- display: none !important;
48
- }
49
- }
50
-
51
- &.active {
52
- z-index: var(--z-active);
53
- outline-width: 2px;
54
-
55
- .blinker {
56
- visibility: visible;
57
- }
58
- }
59
-
60
- &:not(:first-child) {
61
- margin-left: -1px;
62
- }
63
-
64
- &:first-child {
65
- border-top-left-radius: var(--border-radius-m);
66
- border-bottom-left-radius: var(--border-radius-m);
67
- }
68
-
69
- &:last-child {
70
- border-top-right-radius: var(--border-radius-m);
71
- border-bottom-right-radius: var(--border-radius-m);
72
- }
73
- }
74
- }
75
-
76
- .vui-otp-input {
77
- position: absolute;
78
- inset: 0;
79
- outline-width: 0px;
80
- opacity: 0;
81
- background: transparent;
82
- z-index: var(--z-mask);
83
- }
84
- }
@@ -1,92 +0,0 @@
1
- <script setup lang='ts'>
2
- import type { Variants } from '../Button/Button.vue'
3
- import type { Pagination } from './pagination'
4
- import { computed } from 'vue'
5
- import Button from '../Button/Button.vue'
6
- import Flex from '../Flex/Flex.vue'
7
- import Tooltip from '../Tooltip/Tooltip.vue'
8
-
9
- interface Props {
10
- numbers?: boolean
11
- pagination: Pagination
12
- prevNext?: boolean
13
- firstLast?: boolean
14
- variant?: Variants
15
- }
16
-
17
- const props = withDefaults(defineProps<Props>(), {
18
- numbers: true,
19
- prevNext: true,
20
- firstLast: true,
21
- variant: 'gray',
22
- })
23
-
24
- const emit = defineEmits<{
25
- change: [page: number]
26
- }>()
27
-
28
- const canNextPage = computed(() => props.pagination.currentPage < props.pagination.endPage)
29
- const canPrevPage = computed(() => props.pagination.currentPage > props.pagination.startPage)
30
-
31
- function setNext() {
32
- emit('change', props.pagination.currentPage + 1)
33
- }
34
-
35
- function setPrev() {
36
- emit('change', props.pagination.currentPage - 1)
37
- }
38
- </script>
39
-
40
- <template>
41
- <Flex inline class="vui-pagination" gap="xxs">
42
- <slot name="start">
43
- <Tooltip v-if="props.firstLast">
44
- <Button plain :disabled="props.pagination.startPage === props.pagination.currentPage" square icon="ph:caret-double-left" @click="emit('change', props.pagination.startPage)" />
45
- <template #tooltip>
46
- <p>First page</p>
47
- </template>
48
- </Tooltip>
49
- </slot>
50
-
51
- <slot name="prev" :disabled="canPrevPage" :set-page="setPrev">
52
- <Tooltip v-if="props.prevNext">
53
- <Button plain :disabled="!canPrevPage" square icon="ph:caret-left" @click="setPrev" />
54
- <template #tooltip>
55
- <p>Previous page</p>
56
- </template>
57
- </Tooltip>
58
- </slot>
59
-
60
- <template v-if="props.numbers">
61
- <Flex gap="xxs">
62
- <Button
63
- v-for="page in props.pagination.pages"
64
- :key="page"
65
- square
66
- :plain="props.pagination.currentPage !== page"
67
- variant="gray"
68
- @click="emit('change', page)"
69
- >
70
- {{ page }}
71
- </Button>
72
- </Flex>
73
- </template>
74
- <slot name="next" :disabled="canNextPage" :set-page="setNext">
75
- <Tooltip v-if="props.prevNext">
76
- <Button plain :disabled="!canNextPage" square icon="ph:caret-right" @click="setNext" />
77
- <template #tooltip>
78
- <p>Next page</p>
79
- </template>
80
- </Tooltip>
81
- </slot>
82
-
83
- <slot name="end">
84
- <Tooltip v-if="props.firstLast">
85
- <Button plain :disabled="props.pagination.endPage === props.pagination.currentPage" square icon="ph:caret-double-right" @click="emit('change', props.pagination.endPage)" />
86
- <template #tooltip>
87
- <p>Last page</p>
88
- </template>
89
- </Tooltip>
90
- </slot>
91
- </Flex>
92
- </template>