@dolanske/vui 0.3.4 → 0.4.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 (110) hide show
  1. package/LICENSE +673 -673
  2. package/README.md +49 -40
  3. package/dist/components/Dropdown/DropdownItem.vue.d.ts +1 -0
  4. package/dist/style.css +1 -1
  5. package/dist/vui.js +864 -859
  6. package/package.json +68 -68
  7. package/src/App.vue +198 -175
  8. package/src/components/Accordion/Accordion.vue +91 -91
  9. package/src/components/Accordion/AccordionGroup.vue +43 -43
  10. package/src/components/Accordion/accordion.scss +80 -80
  11. package/src/components/Alert/Alert.vue +53 -53
  12. package/src/components/Alert/alert.scss +80 -80
  13. package/src/components/Avatar/Avatar.vue +50 -50
  14. package/src/components/Avatar/avatar.scss +52 -52
  15. package/src/components/Badge/Badge.vue +21 -21
  16. package/src/components/Badge/badge.scss +89 -89
  17. package/src/components/Breadcrumbs/BreadcrumbItem.vue +26 -26
  18. package/src/components/Breadcrumbs/Breadcrumbs.vue +33 -33
  19. package/src/components/Breadcrumbs/breadcrumbs.scss +30 -30
  20. package/src/components/Button/Button.vue +90 -90
  21. package/src/components/Button/button.scss +176 -176
  22. package/src/components/ButtonGroup/ButtonGroup.vue +25 -25
  23. package/src/components/ButtonGroup/button-group.scss +51 -51
  24. package/src/components/Calendar/Calendar.vue +60 -60
  25. package/src/components/Calendar/calendar.scss +56 -56
  26. package/src/components/Card/Card.vue +48 -48
  27. package/src/components/Card/card.scss +53 -53
  28. package/src/components/Checkbox/Checkbox.vue +52 -52
  29. package/src/components/Checkbox/checkbox.scss +66 -66
  30. package/src/components/CopyClipboard/CopyClipboard.vue +82 -82
  31. package/src/components/CopyClipboard/copy-clipboard.scss +17 -17
  32. package/src/components/Divider/Divider.vue +44 -44
  33. package/src/components/Divider/divider.scss +35 -35
  34. package/src/components/Drawer/Drawer.vue +97 -97
  35. package/src/components/Drawer/drawer.scss +36 -36
  36. package/src/components/Dropdown/Dropdown.vue +111 -111
  37. package/src/components/Dropdown/DropdownItem.vue +32 -29
  38. package/src/components/Dropdown/DropdownTitle.vue +8 -8
  39. package/src/components/Dropdown/dropdown.scss +118 -117
  40. package/src/components/Flex/Flex.vue +110 -106
  41. package/src/components/Grid/Grid.vue +57 -54
  42. package/src/components/Input/Counter.vue +70 -70
  43. package/src/components/Input/Dropzone.vue +65 -65
  44. package/src/components/Input/File.vue +15 -15
  45. package/src/components/Input/Input.vue +121 -121
  46. package/src/components/Input/Password.vue +47 -47
  47. package/src/components/Input/Textarea.vue +76 -76
  48. package/src/components/Input/input.scss +208 -208
  49. package/src/components/Kbd/Kbd.vue +48 -48
  50. package/src/components/Kbd/KbdGroup.vue +31 -31
  51. package/src/components/Kbd/kbd.scss +18 -18
  52. package/src/components/Modal/Confirm.vue +56 -56
  53. package/src/components/Modal/Modal.vue +91 -91
  54. package/src/components/Modal/modal.scss +49 -49
  55. package/src/components/OTP/OTP.vue +133 -133
  56. package/src/components/OTP/OTPItem.vue +37 -37
  57. package/src/components/OTP/otp.scss +83 -83
  58. package/src/components/Pagination/Pagination.vue +74 -74
  59. package/src/components/Pagination/pagination.ts +78 -78
  60. package/src/components/Popout/Popout.vue +42 -42
  61. package/src/components/Popout/popout.scss +8 -8
  62. package/src/components/Progress/Progress.vue +90 -90
  63. package/src/components/Progress/progress.scss +41 -41
  64. package/src/components/Radio/Radio.vue +36 -36
  65. package/src/components/Radio/RadioGroup.vue +40 -40
  66. package/src/components/Radio/radio.scss +59 -59
  67. package/src/components/Select/Select.vue +180 -180
  68. package/src/components/Select/select.scss +44 -44
  69. package/src/components/Sheet/Sheet.vue +92 -92
  70. package/src/components/Sheet/sheet.scss +60 -60
  71. package/src/components/Sidebar/Sidebar.vue +85 -0
  72. package/src/components/Sidebar/sidebar.scss +123 -0
  73. package/src/components/Skeleton/Skeleton.vue +43 -43
  74. package/src/components/Skeleton/skeleton.scss +14 -14
  75. package/src/components/Spinner/Spinner.vue +42 -42
  76. package/src/components/Spinner/spinner.scss +46 -46
  77. package/src/components/Switch/Switch.vue +30 -30
  78. package/src/components/Switch/switch.scss +52 -52
  79. package/src/components/Table/Cell.vue +23 -23
  80. package/src/components/Table/Header.vue +59 -59
  81. package/src/components/Table/Row.vue +9 -9
  82. package/src/components/Table/SelectAll.vue +23 -23
  83. package/src/components/Table/SelectRow.vue +29 -29
  84. package/src/components/Table/Table.vue +66 -66
  85. package/src/components/Table/table.scss +134 -134
  86. package/src/components/Table/table.ts +244 -244
  87. package/src/components/Tabs/Tab.vue +27 -27
  88. package/src/components/Tabs/Tabs.vue +82 -82
  89. package/src/components/Tabs/tabs.scss +79 -79
  90. package/src/components/Toast/Toasts.vue +47 -47
  91. package/src/components/Toast/toast.scss +41 -41
  92. package/src/components/Toast/toast.ts +68 -68
  93. package/src/components/Tooltip/Tooltip.vue +86 -86
  94. package/src/components/Tooltip/tooltip.scss +4 -4
  95. package/src/index.scss +1 -1
  96. package/src/index.ts +119 -119
  97. package/src/internal/Backdrop/Backdrop.vue +22 -22
  98. package/src/internal/Backdrop/backdrop.scss +28 -28
  99. package/src/main.ts +5 -5
  100. package/src/shared/helpers.ts +74 -74
  101. package/src/shared/types.ts +29 -29
  102. package/src/style/animation.scss +21 -21
  103. package/src/style/core.scss +148 -148
  104. package/src/style/fonts.scss +53 -53
  105. package/src/style/layout.scss +136 -136
  106. package/src/style/media-query.scss +29 -29
  107. package/src/style/reset.scss +135 -135
  108. package/src/style/tooltip.scss +128 -128
  109. package/src/style/typography.scss +338 -338
  110. package/src/style/utils.scss +36 -36
@@ -1,70 +1,70 @@
1
- <script setup lang='ts'>
2
- import type { InputProps } from './Input.vue'
3
- import { Icon } from '@iconify/vue'
4
- import Button from '../Button/Button.vue'
5
- import Input from './Input.vue'
6
-
7
- type Props = Omit<InputProps, 'type'> & {
8
- incrementBy?: number
9
- incrementEnabled?: boolean
10
- hideIncrement?: boolean
11
- decrementBy?: number
12
- decrementEnabled?: boolean
13
- hideDecrement?: boolean
14
- }
15
-
16
- const {
17
- incrementBy = 1,
18
- incrementEnabled = true,
19
- hideIncrement = false,
20
- decrementBy = 1,
21
- decrementEnabled = true,
22
- hideDecrement = false,
23
- ...inputProps
24
- } = defineProps<Props>()
25
-
26
- const count = defineModel<number>({
27
- default: 0,
28
- })
29
- </script>
30
-
31
- <template>
32
- <Input v-bind="inputProps" v-model.number="count" type="number">
33
- <template v-if="!hideDecrement" #start>
34
- <Button key="decrease" :disabled="!decrementEnabled" size="s" @click="count -= decrementBy">
35
- <Icon icon="ph:minus" /> {{ decrementBy > 1 ? decrementBy : '' }}
36
- </Button>
37
- </template>
38
-
39
- <template v-if="!hideIncrement" #end>
40
- <Button key="increase" :disabled="!incrementEnabled" size="s" @click="count += incrementBy">
41
- <Icon icon="ph:plus" /> {{ incrementBy > 1 ? incrementBy : '' }}
42
- </Button>
43
- </template>
44
- </Input>
45
- </template>
46
-
47
- <style scoped lang="scss">
48
- :deep(.vui-input-style) {
49
- padding-inline: 4px !important;
50
- gap: 8px !important;
51
- }
52
-
53
- :deep(.vui-button) {
54
- padding-inline: 2px !important;
55
- }
56
-
57
- :deep(input) {
58
- text-align: center;
59
-
60
- ::-webkit-outer-spin-button,
61
- ::-webkit-inner-spin-button {
62
- -webkit-appearance: none;
63
- margin: 0;
64
- }
65
-
66
- /* Firefox */
67
- -moz-appearance: textfield;
68
- appearance: textfield;
69
- }
70
- </style>
1
+ <script setup lang='ts'>
2
+ import type { InputProps } from './Input.vue'
3
+ import { Icon } from '@iconify/vue'
4
+ import Button from '../Button/Button.vue'
5
+ import Input from './Input.vue'
6
+
7
+ type Props = Omit<InputProps, 'type'> & {
8
+ incrementBy?: number
9
+ incrementEnabled?: boolean
10
+ hideIncrement?: boolean
11
+ decrementBy?: number
12
+ decrementEnabled?: boolean
13
+ hideDecrement?: boolean
14
+ }
15
+
16
+ const {
17
+ incrementBy = 1,
18
+ incrementEnabled = true,
19
+ hideIncrement = false,
20
+ decrementBy = 1,
21
+ decrementEnabled = true,
22
+ hideDecrement = false,
23
+ ...inputProps
24
+ } = defineProps<Props>()
25
+
26
+ const count = defineModel<number>({
27
+ default: 0,
28
+ })
29
+ </script>
30
+
31
+ <template>
32
+ <Input v-bind="inputProps" v-model.number="count" type="number">
33
+ <template v-if="!hideDecrement" #start>
34
+ <Button key="decrease" :disabled="!decrementEnabled" size="s" @click="count -= decrementBy">
35
+ <Icon icon="ph:minus" /> {{ decrementBy > 1 ? decrementBy : '' }}
36
+ </Button>
37
+ </template>
38
+
39
+ <template v-if="!hideIncrement" #end>
40
+ <Button key="increase" :disabled="!incrementEnabled" size="s" @click="count += incrementBy">
41
+ <Icon icon="ph:plus" /> {{ incrementBy > 1 ? incrementBy : '' }}
42
+ </Button>
43
+ </template>
44
+ </Input>
45
+ </template>
46
+
47
+ <style scoped lang="scss">
48
+ :deep(.vui-input-style) {
49
+ padding-inline: 4px !important;
50
+ gap: 8px !important;
51
+ }
52
+
53
+ :deep(.vui-button) {
54
+ padding-inline: 2px !important;
55
+ }
56
+
57
+ :deep(input) {
58
+ text-align: center;
59
+
60
+ ::-webkit-outer-spin-button,
61
+ ::-webkit-inner-spin-button {
62
+ -webkit-appearance: none;
63
+ margin: 0;
64
+ }
65
+
66
+ /* Firefox */
67
+ -moz-appearance: textfield;
68
+ appearance: textfield;
69
+ }
70
+ </style>
@@ -1,65 +1,65 @@
1
- <script setup lang='ts'>
2
- import type { InputProps } from './Input.vue'
3
- import { Icon } from '@iconify/vue'
4
- import { useEventListener } from '@vueuse/core'
5
- import { onMounted, ref, useTemplateRef } from 'vue'
6
- import Flex from '../Flex/Flex.vue'
7
- import Input from './Input.vue'
8
-
9
- type Props = Omit<InputProps, 'type' | 'modelValue' | 'focus' | 'limit' | 'placeholder'>
10
-
11
- const props = defineProps<Props>()
12
- const emits = defineEmits<{ files: [FileList] }>()
13
-
14
- const dragging = ref(false)
15
-
16
- function onSubmitHandler(e: any, isFromField?: boolean) {
17
- e.preventDefault()
18
- e.stopPropagation()
19
-
20
- const files = isFromField ? e.target.files : e.dataTransfer.files
21
-
22
- if (files.length > 0)
23
- emits('files', files)
24
- }
25
-
26
- const dropzoneRef = useTemplateRef<HTMLDivElement>('dropzone')
27
-
28
- onMounted(() => {
29
- useEventListener(dropzoneRef, 'dragenter', onSubmitHandler, false)
30
- useEventListener(dropzoneRef, 'dragleave', onSubmitHandler, false)
31
- useEventListener(dropzoneRef, 'dragover', onSubmitHandler, false)
32
- useEventListener(dropzoneRef, 'drop', onSubmitHandler, false)
33
- useEventListener(dropzoneRef, 'input', e => onSubmitHandler(e, true), false)
34
- })
35
- </script>
36
-
37
- <template>
38
- <Input
39
- v-bind="props"
40
- ref="dropzone"
41
- type="file"
42
- class="vui-dropzone"
43
- :class="{ dragging }"
44
- @dragenter="dragging = true"
45
- @mouseleave="dragging = false"
46
- >
47
- <template #__internal_replace_input="{ inputId }">
48
- <input :id="inputId" type="file">
49
- <label :for="inputId">
50
- <slot :dragging>
51
- <Flex justify-center gap="s" align-baseline>
52
- <template v-if="dragging">
53
- <Icon icon="ph:target" />
54
- Drop it
55
- </template>
56
- <template v-else>
57
- <Icon icon="ph:file" />
58
- Click or drag files over here
59
- </template>
60
- </Flex>
61
- </slot>
62
- </label>
63
- </template>
64
- </Input>
65
- </template>
1
+ <script setup lang='ts'>
2
+ import type { InputProps } from './Input.vue'
3
+ import { Icon } from '@iconify/vue'
4
+ import { useEventListener } from '@vueuse/core'
5
+ import { onMounted, ref, useTemplateRef } from 'vue'
6
+ import Flex from '../Flex/Flex.vue'
7
+ import Input from './Input.vue'
8
+
9
+ type Props = Omit<InputProps, 'type' | 'modelValue' | 'focus' | 'limit' | 'placeholder'>
10
+
11
+ const props = defineProps<Props>()
12
+ const emits = defineEmits<{ files: [FileList] }>()
13
+
14
+ const dragging = ref(false)
15
+
16
+ function onSubmitHandler(e: any, isFromField?: boolean) {
17
+ e.preventDefault()
18
+ e.stopPropagation()
19
+
20
+ const files = isFromField ? e.target.files : e.dataTransfer.files
21
+
22
+ if (files.length > 0)
23
+ emits('files', files)
24
+ }
25
+
26
+ const dropzoneRef = useTemplateRef<HTMLDivElement>('dropzone')
27
+
28
+ onMounted(() => {
29
+ useEventListener(dropzoneRef, 'dragenter', onSubmitHandler, false)
30
+ useEventListener(dropzoneRef, 'dragleave', onSubmitHandler, false)
31
+ useEventListener(dropzoneRef, 'dragover', onSubmitHandler, false)
32
+ useEventListener(dropzoneRef, 'drop', onSubmitHandler, false)
33
+ useEventListener(dropzoneRef, 'input', e => onSubmitHandler(e, true), false)
34
+ })
35
+ </script>
36
+
37
+ <template>
38
+ <Input
39
+ v-bind="props"
40
+ ref="dropzone"
41
+ type="file"
42
+ class="vui-dropzone"
43
+ :class="{ dragging }"
44
+ @dragenter="dragging = true"
45
+ @mouseleave="dragging = false"
46
+ >
47
+ <template #__internal_replace_input="{ inputId }">
48
+ <input :id="inputId" type="file">
49
+ <label :for="inputId">
50
+ <slot :dragging>
51
+ <Flex justify-center gap="s" align-baseline>
52
+ <template v-if="dragging">
53
+ <Icon icon="ph:target" />
54
+ Drop it
55
+ </template>
56
+ <template v-else>
57
+ <Icon icon="ph:file" />
58
+ Click or drag files over here
59
+ </template>
60
+ </Flex>
61
+ </slot>
62
+ </label>
63
+ </template>
64
+ </Input>
65
+ </template>
@@ -1,15 +1,15 @@
1
- <script setup lang='ts'>
2
- import type { InputProps } from './Input.vue'
3
- import Input from './Input.vue'
4
-
5
- const props = defineProps<Omit<InputProps, 'type'>>()
6
- const emits = defineEmits<{ files: [FileList] }>()
7
- </script>
8
-
9
- <template>
10
- <Input
11
- type="file"
12
- v-bind="{ ...props }"
13
- @input="emits('files', $event.target.files)"
14
- />
15
- </template>
1
+ <script setup lang='ts'>
2
+ import type { InputProps } from './Input.vue'
3
+ import Input from './Input.vue'
4
+
5
+ const props = defineProps<Omit<InputProps, 'type'>>()
6
+ const emits = defineEmits<{ files: [FileList] }>()
7
+ </script>
8
+
9
+ <template>
10
+ <Input
11
+ type="file"
12
+ v-bind="{ ...props }"
13
+ @input="emits('files', $event.target.files)"
14
+ />
15
+ </template>
@@ -1,121 +1,121 @@
1
- <script setup lang="ts">
2
- import { computed, type InputTypeHTMLAttribute, useId, useTemplateRef, watchEffect } from 'vue'
3
- import { getMaybeRefLength } from '../../shared/helpers'
4
- import Flex from '../Flex/Flex.vue'
5
- import '../../style/core.scss'
6
- import './input.scss'
7
-
8
- // FIXME: sometimes spamming inputs when limit is set, it will _just_ let me write one more letter
9
-
10
- export interface InputProps {
11
- type?: InputTypeHTMLAttribute
12
- label?: string
13
- hint?: string
14
- limit?: number | string
15
- expand?: boolean
16
- placeholder?: string
17
- required?: boolean
18
- modelValue?: string | number
19
- readonly?: boolean
20
- focus?: boolean
21
- errors?: string[]
22
- accept?: string
23
- multiple?: boolean
24
- min?: number
25
- max?: number
26
- disabled?: boolean
27
- }
28
-
29
- const {
30
- type = 'text',
31
- limit,
32
- label,
33
- expand = false,
34
- hint,
35
- placeholder,
36
- required,
37
- modelValue = '',
38
- readonly,
39
- focus,
40
- accept,
41
- min,
42
- max,
43
- errors = [] as string[],
44
- disabled,
45
- } = defineProps<InputProps>()
46
-
47
- const model = defineModel<string | number>({
48
- default: '',
49
- set(newValue) {
50
- // Completely ignore inputs
51
- if (readonly)
52
- return modelValue
53
-
54
- if (getMaybeRefLength(newValue) > Number(limit)) {
55
- return modelValue
56
- }
57
- return newValue
58
- },
59
- })
60
- const id = useId()
61
-
62
- const inputRef = useTemplateRef('input')
63
-
64
- watchEffect(() => {
65
- if (focus)
66
- inputRef.value?.focus()
67
- })
68
-
69
- defineExpose({
70
- focus: () => {
71
- inputRef.value?.focus()
72
- },
73
- })
74
-
75
- const renderLimit = computed(() => {
76
- return `${getMaybeRefLength(model.value)}/${limit}`
77
- })
78
- </script>
79
-
80
- <template>
81
- <div class="vui-input-container" :class="{ expand, disabled, required, readonly, 'has-errors': errors.length > 0 }">
82
- <slot name="before" />
83
- <div class="vui-input">
84
- <label v-if="label" for="id">{{ label }}</label>
85
- <p v-if="hint" class="vui-input-hint">
86
- {{ hint }}
87
- </p>
88
- <Flex class="vui-input-style" :gap="3" align-center>
89
- <slot name="start" />
90
- <slot name="__internal_replace_input" :input-id="id" />
91
- <input
92
- v-if="!$slots.__internal_replace_input"
93
- :id
94
- ref="input"
95
- v-model="model"
96
- :readonly
97
- :type
98
- name="id"
99
- :placeholder
100
- :required
101
- :max="max ?? limit"
102
- :accept
103
- :multiple
104
- :min
105
- :disabled
106
- >
107
- <slot name="end" />
108
- </Flex>
109
- </div>
110
- <p v-if="limit" class="vui-input-limit">
111
- {{ renderLimit }}
112
- </p>
113
- <ul v-if="errors.length > 0" class="vui-input-errors">
114
- <li v-for="err in errors" :key="err">
115
- {{ err }}
116
- </li>
117
- </ul>
118
-
119
- <slot name="after" />
120
- </div>
121
- </template>
1
+ <script setup lang="ts">
2
+ import { computed, type InputTypeHTMLAttribute, useId, useTemplateRef, watchEffect } from 'vue'
3
+ import { getMaybeRefLength } from '../../shared/helpers'
4
+ import Flex from '../Flex/Flex.vue'
5
+ import '../../style/core.scss'
6
+ import './input.scss'
7
+
8
+ // FIXME: sometimes spamming inputs when limit is set, it will _just_ let me write one more letter
9
+
10
+ export interface InputProps {
11
+ type?: InputTypeHTMLAttribute
12
+ label?: string
13
+ hint?: string
14
+ limit?: number | string
15
+ expand?: boolean
16
+ placeholder?: string
17
+ required?: boolean
18
+ modelValue?: string | number
19
+ readonly?: boolean
20
+ focus?: boolean
21
+ errors?: string[]
22
+ accept?: string
23
+ multiple?: boolean
24
+ min?: number
25
+ max?: number
26
+ disabled?: boolean
27
+ }
28
+
29
+ const {
30
+ type = 'text',
31
+ limit,
32
+ label,
33
+ expand = false,
34
+ hint,
35
+ placeholder,
36
+ required,
37
+ modelValue = '',
38
+ readonly,
39
+ focus,
40
+ accept,
41
+ min,
42
+ max,
43
+ errors = [] as string[],
44
+ disabled,
45
+ } = defineProps<InputProps>()
46
+
47
+ const model = defineModel<string | number>({
48
+ default: '',
49
+ set(newValue) {
50
+ // Completely ignore inputs
51
+ if (readonly)
52
+ return modelValue
53
+
54
+ if (getMaybeRefLength(newValue) > Number(limit)) {
55
+ return modelValue
56
+ }
57
+ return newValue
58
+ },
59
+ })
60
+ const id = useId()
61
+
62
+ const inputRef = useTemplateRef('input')
63
+
64
+ watchEffect(() => {
65
+ if (focus)
66
+ inputRef.value?.focus()
67
+ })
68
+
69
+ defineExpose({
70
+ focus: () => {
71
+ inputRef.value?.focus()
72
+ },
73
+ })
74
+
75
+ const renderLimit = computed(() => {
76
+ return `${getMaybeRefLength(model.value)}/${limit}`
77
+ })
78
+ </script>
79
+
80
+ <template>
81
+ <div class="vui-input-container" :class="{ expand, disabled, required, readonly, 'has-errors': errors.length > 0 }">
82
+ <slot name="before" />
83
+ <div class="vui-input">
84
+ <label v-if="label" for="id">{{ label }}</label>
85
+ <p v-if="hint" class="vui-input-hint">
86
+ {{ hint }}
87
+ </p>
88
+ <Flex class="vui-input-style" :gap="3" align-center>
89
+ <slot name="start" />
90
+ <slot name="__internal_replace_input" :input-id="id" />
91
+ <input
92
+ v-if="!$slots.__internal_replace_input"
93
+ :id
94
+ ref="input"
95
+ v-model="model"
96
+ :readonly
97
+ :type
98
+ name="id"
99
+ :placeholder
100
+ :required
101
+ :max="max ?? limit"
102
+ :accept
103
+ :multiple
104
+ :min
105
+ :disabled
106
+ >
107
+ <slot name="end" />
108
+ </Flex>
109
+ </div>
110
+ <p v-if="limit" class="vui-input-limit">
111
+ {{ renderLimit }}
112
+ </p>
113
+ <ul v-if="errors.length > 0" class="vui-input-errors">
114
+ <li v-for="err in errors" :key="err">
115
+ {{ err }}
116
+ </li>
117
+ </ul>
118
+
119
+ <slot name="after" />
120
+ </div>
121
+ </template>
@@ -1,47 +1,47 @@
1
- <script setup lang='ts'>
2
- import type { InputProps } from './Input.vue'
3
- import { Icon } from '@iconify/vue'
4
- import { ref } from 'vue'
5
- import Button from '../Button/Button.vue'
6
- import Input from './Input.vue'
7
-
8
- type Props = Omit<InputProps, 'type'> & {
9
- showPassword?: boolean
10
- }
11
-
12
- const {
13
- showPassword = false,
14
- // @ts-expect-error Don't want to actually provide type as we handle that in
15
- // this component manually
16
- type,
17
- ...inputProps
18
- } = defineProps<Props>()
19
-
20
- const show = ref(showPassword)
21
- </script>
22
-
23
- <template>
24
- <Input v-bind="inputProps" :type="show ? 'text' : 'password'" autocomplete="off">
25
- <template #end>
26
- <Button
27
- square
28
- size="s"
29
- :data-title-top="show ? 'Hide password' : 'Show password'"
30
- @click="show = !show"
31
- >
32
- <Icon :width="18" :height="18" :icon="show ? 'ph:eye-slash' : 'ph:eye'" />
33
- </Button>
34
- </template>
35
- </Input>
36
- </template>
37
-
38
- <style scoped lang="scss">
39
- :deep(.vui-input-style) {
40
- padding-right: 4px !important;
41
- gap: 8px !important;
42
- }
43
-
44
- [data-title-top]:before {
45
- min-width: 104px;
46
- }
47
- </style>
1
+ <script setup lang='ts'>
2
+ import type { InputProps } from './Input.vue'
3
+ import { Icon } from '@iconify/vue'
4
+ import { ref } from 'vue'
5
+ import Button from '../Button/Button.vue'
6
+ import Input from './Input.vue'
7
+
8
+ type Props = Omit<InputProps, 'type'> & {
9
+ showPassword?: boolean
10
+ }
11
+
12
+ const {
13
+ showPassword = false,
14
+ // @ts-expect-error Don't want to actually provide type as we handle that in
15
+ // this component manually
16
+ type,
17
+ ...inputProps
18
+ } = defineProps<Props>()
19
+
20
+ const show = ref(showPassword)
21
+ </script>
22
+
23
+ <template>
24
+ <Input v-bind="inputProps" :type="show ? 'text' : 'password'" autocomplete="off">
25
+ <template #end>
26
+ <Button
27
+ square
28
+ size="s"
29
+ :data-title-top="show ? 'Hide password' : 'Show password'"
30
+ @click="show = !show"
31
+ >
32
+ <Icon :width="18" :height="18" :icon="show ? 'ph:eye-slash' : 'ph:eye'" />
33
+ </Button>
34
+ </template>
35
+ </Input>
36
+ </template>
37
+
38
+ <style scoped lang="scss">
39
+ :deep(.vui-input-style) {
40
+ padding-right: 4px !important;
41
+ gap: 8px !important;
42
+ }
43
+
44
+ [data-title-top]:before {
45
+ min-width: 104px;
46
+ }
47
+ </style>