@dolanske/vui 1.0.4 → 1.1.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 (195) hide show
  1. package/LICENSE +673 -673
  2. package/README.md +42 -42
  3. package/dist/components/Accordion/Accordion.vue.d.ts +3 -2
  4. package/dist/components/Accordion/AccordionGroup.vue.d.ts +5 -2
  5. package/dist/components/Alert/Alert.vue.d.ts +3 -2
  6. package/dist/components/Avatar/Avatar.vue.d.ts +3 -2
  7. package/dist/components/Badge/Badge.vue.d.ts +3 -2
  8. package/dist/components/Breadcrumbs/BreadcrumbItem.vue.d.ts +3 -2
  9. package/dist/components/Breadcrumbs/Breadcrumbs.vue.d.ts +3 -2
  10. package/dist/components/Button/Button.vue.d.ts +3 -2
  11. package/dist/components/ButtonGroup/ButtonGroup.vue.d.ts +3 -2
  12. package/dist/components/Calendar/Calendar.vue.d.ts +6 -6
  13. package/dist/components/Card/Card.vue.d.ts +4 -3
  14. package/dist/components/Checkbox/Checkbox.vue.d.ts +7 -6
  15. package/dist/components/CopyClipboard/CopyClipboard.vue.d.ts +2 -1
  16. package/dist/components/Divider/Divider.vue.d.ts +3 -2
  17. package/dist/components/Drawer/Drawer.vue.d.ts +10 -9
  18. package/dist/components/Dropdown/Dropdown.vue.d.ts +66 -3
  19. package/dist/components/Dropdown/DropdownItem.vue.d.ts +3 -2
  20. package/dist/components/Dropdown/DropdownTitle.vue.d.ts +6 -6
  21. package/dist/components/Flex/Flex.vue.d.ts +13 -12
  22. package/dist/components/Grid/Grid.vue.d.ts +7 -6
  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 +95 -10
  26. package/dist/components/Input/File.vue.d.ts +4 -3
  27. package/dist/components/Input/Input.vue.d.ts +7 -6
  28. package/dist/components/Input/Password.vue.d.ts +1 -1
  29. package/dist/components/Input/Textarea.vue.d.ts +7 -6
  30. package/dist/components/Kbd/Kbd.vue.d.ts +1 -1
  31. package/dist/components/Kbd/KbdGroup.vue.d.ts +2 -1
  32. package/dist/components/Modal/Confirm.vue.d.ts +7 -9
  33. package/dist/components/Modal/Modal.vue.d.ts +16 -13
  34. package/dist/components/OTP/OTP.vue.d.ts +7 -6
  35. package/dist/components/OTP/OTPItem.vue.d.ts +1 -1
  36. package/dist/components/Pagination/Pagination.vue.d.ts +3 -2
  37. package/dist/components/Popout/Popout.vue.d.ts +3 -2
  38. package/dist/components/Progress/Progress.vue.d.ts +5 -5
  39. package/dist/components/Radio/Radio.vue.d.ts +7 -6
  40. package/dist/components/Radio/RadioGroup.vue.d.ts +7 -6
  41. package/dist/components/Select/Select.vue.d.ts +4 -8
  42. package/dist/components/Sheet/Sheet.vue.d.ts +22 -13
  43. package/dist/components/Sidebar/Sidebar.vue.d.ts +7 -6
  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 +7 -6
  47. package/dist/components/Table/Cell.vue.d.ts +5 -2
  48. package/dist/components/Table/Head.vue.d.ts +3 -2
  49. package/dist/components/Table/Root.vue.d.ts +3 -2
  50. package/dist/components/Table/table.d.ts +2 -2
  51. package/dist/components/Tabs/Tab.vue.d.ts +3 -2
  52. package/dist/components/Tabs/Tabs.vue.d.ts +7 -6
  53. package/dist/components/Toast/toast.d.ts +6 -6
  54. package/dist/components/Tooltip/Tooltip.vue.d.ts +2 -1
  55. package/dist/internal/Backdrop/Backdrop.vue.d.ts +3 -2
  56. package/dist/vui.css +1 -0
  57. package/dist/vui.js +8090 -7884
  58. package/package.json +73 -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 +210 -206
  69. package/src/components/Breadcrumbs/BreadcrumbItem.vue +26 -26
  70. package/src/components/Breadcrumbs/Breadcrumbs.vue +30 -30
  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 +102 -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 +79 -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 +103 -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 +108 -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 +90 -90
  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 +124 -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 +80 -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.ts +116 -116
  178. package/src/internal/Backdrop/Backdrop.vue +22 -22
  179. package/src/internal/Backdrop/backdrop.scss +34 -34
  180. package/src/main.ts +5 -5
  181. package/src/shared/helpers.ts +117 -117
  182. package/src/shared/theme.ts +22 -22
  183. package/src/shared/types.ts +29 -29
  184. package/src/style/animation.scss +22 -22
  185. package/src/style/core.scss +119 -125
  186. package/src/style/layout.scss +207 -233
  187. package/src/style/media-query.scss +29 -29
  188. package/src/style/reset.scss +135 -135
  189. package/src/style/text.scss +137 -124
  190. package/src/style/theme.scss +195 -195
  191. package/src/style/tooltip.scss +146 -146
  192. package/src/style/typography.scss +415 -415
  193. package/src/style/utils.scss +36 -36
  194. package/src/style.scss +1 -1
  195. package/dist/style.css +0 -1
@@ -1,133 +1,133 @@
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
+ <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 +1,37 @@
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
+ <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 +1,84 @@
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: 1;
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: 2;
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: 5;
83
- }
84
- }
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: 1;
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: 2;
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: 5;
83
+ }
84
+ }
@@ -1,77 +1,77 @@
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
-
8
- interface Props {
9
- numbers?: boolean
10
- pagination: Pagination
11
- prevNext?: boolean
12
- firstLast?: boolean
13
- variant?: Variants
14
- }
15
-
16
- const props = withDefaults(defineProps<Props>(), {
17
- numbers: true,
18
- prevNext: true,
19
- firstLast: true,
20
- variant: 'gray',
21
- })
22
-
23
- const emit = defineEmits<{
24
- change: [page: number]
25
- }>()
26
-
27
- const canNextPage = computed(() => props.pagination.currentPage < props.pagination.endPage)
28
- const canPrevPage = computed(() => props.pagination.currentPage > props.pagination.startPage)
29
-
30
- function setNext() {
31
- emit('change', props.pagination.currentPage + 1)
32
- }
33
-
34
- function setPrev() {
35
- emit('change', props.pagination.currentPage - 1)
36
- }
37
- </script>
38
-
39
- <template>
40
- <Flex inline class="vui-pagination" gap="xxs">
41
- <slot name="start">
42
- <Button v-if="props.firstLast" data-title-top="First page" plain :disabled="props.pagination.startPage === props.pagination.currentPage" square icon="ph:caret-double-left" @click="emit('change', props.pagination.startPage)" />
43
- </slot>
44
-
45
- <slot name="prev" :disabled="canPrevPage" :set-page="setPrev">
46
- <Button v-if="props.prevNext" data-title-top="Previous page" plain :disabled="!canPrevPage" square icon="ph:caret-left" @click="setPrev" />
47
- </slot>
48
-
49
- <template v-if="props.numbers">
50
- <Flex gap="xxs">
51
- <Button
52
- v-for="page in props.pagination.pages"
53
- :key="page"
54
- square
55
- :plain="props.pagination.currentPage !== page"
56
- variant="gray"
57
- @click="emit('change', page)"
58
- >
59
- {{ page }}
60
- </Button>
61
- </Flex>
62
- </template>
63
- <slot name="next" :disabled="canNextPage" :set-page="setNext">
64
- <Button v-if="props.prevNext" data-title-top="Next page" plain :disabled="!canNextPage" square icon="ph:caret-right" @click="setNext" />
65
- </slot>
66
-
67
- <slot name="end">
68
- <Button v-if="props.firstLast" data-title-top="Last page" plain :disabled="props.pagination.endPage === props.pagination.currentPage" square icon="ph:caret-double-right" @click="emit('change', props.pagination.endPage)" />
69
- </slot>
70
- </Flex>
71
- </template>
72
-
73
- <style scoped>
74
- [data-title-top]:before {
75
- white-space: nowrap;
76
- }
77
- </style>
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
+
8
+ interface Props {
9
+ numbers?: boolean
10
+ pagination: Pagination
11
+ prevNext?: boolean
12
+ firstLast?: boolean
13
+ variant?: Variants
14
+ }
15
+
16
+ const props = withDefaults(defineProps<Props>(), {
17
+ numbers: true,
18
+ prevNext: true,
19
+ firstLast: true,
20
+ variant: 'gray',
21
+ })
22
+
23
+ const emit = defineEmits<{
24
+ change: [page: number]
25
+ }>()
26
+
27
+ const canNextPage = computed(() => props.pagination.currentPage < props.pagination.endPage)
28
+ const canPrevPage = computed(() => props.pagination.currentPage > props.pagination.startPage)
29
+
30
+ function setNext() {
31
+ emit('change', props.pagination.currentPage + 1)
32
+ }
33
+
34
+ function setPrev() {
35
+ emit('change', props.pagination.currentPage - 1)
36
+ }
37
+ </script>
38
+
39
+ <template>
40
+ <Flex inline class="vui-pagination" gap="xxs">
41
+ <slot name="start">
42
+ <Button v-if="props.firstLast" data-title-top="First page" plain :disabled="props.pagination.startPage === props.pagination.currentPage" square icon="ph:caret-double-left" @click="emit('change', props.pagination.startPage)" />
43
+ </slot>
44
+
45
+ <slot name="prev" :disabled="canPrevPage" :set-page="setPrev">
46
+ <Button v-if="props.prevNext" data-title-top="Previous page" plain :disabled="!canPrevPage" square icon="ph:caret-left" @click="setPrev" />
47
+ </slot>
48
+
49
+ <template v-if="props.numbers">
50
+ <Flex gap="xxs">
51
+ <Button
52
+ v-for="page in props.pagination.pages"
53
+ :key="page"
54
+ square
55
+ :plain="props.pagination.currentPage !== page"
56
+ variant="gray"
57
+ @click="emit('change', page)"
58
+ >
59
+ {{ page }}
60
+ </Button>
61
+ </Flex>
62
+ </template>
63
+ <slot name="next" :disabled="canNextPage" :set-page="setNext">
64
+ <Button v-if="props.prevNext" data-title-top="Next page" plain :disabled="!canNextPage" square icon="ph:caret-right" @click="setNext" />
65
+ </slot>
66
+
67
+ <slot name="end">
68
+ <Button v-if="props.firstLast" data-title-top="Last page" plain :disabled="props.pagination.endPage === props.pagination.currentPage" square icon="ph:caret-double-right" @click="emit('change', props.pagination.endPage)" />
69
+ </slot>
70
+ </Flex>
71
+ </template>
72
+
73
+ <style scoped>
74
+ [data-title-top]:before {
75
+ white-space: nowrap;
76
+ }
77
+ </style>