kaze 0.4.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kaze/commands/install_command.rb +25 -13
- data/lib/kaze/commands/installs_hotwire_stack.rb +11 -8
- data/lib/kaze/commands/installs_inertia_stacks.rb +34 -24
- data/lib/kaze/commands/version_command.rb +6 -0
- data/lib/kaze/version.rb +1 -1
- data/lib/kaze.rb +1 -3
- data/stubs/default/app/forms/auth/login_form.rb +2 -8
- data/stubs/default/app/forms/auth/new_password_form.rb +1 -1
- data/stubs/default/app/forms/update_profile_information_form.rb +1 -1
- data/stubs/default/app/mailers/application_mailer.rb +4 -4
- data/stubs/default/app/mailers/user_mailer.rb +1 -1
- data/stubs/default/app/models/auth.rb +57 -0
- data/stubs/default/app/models/current.rb +1 -1
- data/stubs/default/app/validators/current_password_validator.rb +1 -1
- data/stubs/default/app/validators/email_validator.rb +1 -1
- data/stubs/default/app/validators/lowercase_validator.rb +2 -2
- data/stubs/default/app/views/layouts/mailer.html.erb +367 -372
- data/stubs/default/app/views/layouts/mailer.text.erb +1 -4
- data/stubs/default/app/views/user_mailer/reset_password.html.erb +21 -26
- data/stubs/default/config/routes.rb +16 -16
- data/stubs/default/db/migrate/20240101000001_create_delayed_jobs.rb +1 -1
- data/stubs/default/test/factories/users.rb +7 -0
- data/stubs/default/test/integration/auth/authentication_test.rb +43 -0
- data/stubs/default/test/integration/auth/password_reset_test.rb +41 -0
- data/stubs/default/test/integration/auth/registration_test.rb +21 -0
- data/stubs/default/test/integration/password_update_test.rb +28 -0
- data/stubs/default/test/integration/profile_test.rb +51 -0
- data/stubs/default/test/test_helper.rb +38 -0
- data/stubs/hotwire/app/components/danger_button_component.rb +1 -1
- data/stubs/hotwire/app/components/dropdown_component.html.erb +17 -18
- data/stubs/hotwire/app/components/dropdown_component.rb +7 -7
- data/stubs/hotwire/app/components/modal_component.html.erb +55 -59
- data/stubs/hotwire/app/components/modal_component.rb +6 -6
- data/stubs/hotwire/app/components/primary_button_component.rb +1 -1
- data/stubs/hotwire/app/components/secondary_button_component.rb +1 -1
- data/stubs/hotwire/app/controllers/application_controller.rb +1 -0
- data/stubs/hotwire/app/controllers/auth/authenticated_session_controller.rb +12 -9
- data/stubs/hotwire/app/controllers/auth/new_password_controller.rb +7 -5
- data/stubs/hotwire/app/controllers/auth/password_reset_link_controller.rb +7 -5
- data/stubs/hotwire/app/controllers/auth/registered_user_controller.rb +7 -5
- data/stubs/hotwire/app/controllers/concerns/authenticate.rb +5 -20
- data/stubs/hotwire/app/controllers/concerns/redirect_if_authenticated.rb +19 -0
- data/stubs/hotwire/app/controllers/concerns/set_current_auth.rb +9 -0
- data/stubs/hotwire/app/controllers/password_controller.rb +3 -3
- data/stubs/hotwire/app/controllers/profile_controller.rb +11 -9
- data/stubs/hotwire/app/controllers/welcome_controller.rb +1 -1
- data/stubs/hotwire/app/javascript/application.js +3 -3
- data/stubs/hotwire/app/views/auth/forgot_password.html.erb +12 -17
- data/stubs/hotwire/app/views/auth/login.html.erb +0 -9
- data/stubs/hotwire/app/views/auth/register.html.erb +0 -13
- data/stubs/hotwire/app/views/auth/reset_password.html.erb +0 -7
- data/stubs/hotwire/app/views/dashboard/index.html.erb +9 -10
- data/stubs/hotwire/app/views/layouts/_navigation.html.erb +77 -87
- data/stubs/hotwire/app/views/layouts/application.html.erb +0 -9
- data/stubs/hotwire/app/views/layouts/guest.html.erb +0 -6
- data/stubs/hotwire/app/views/profile/edit.html.erb +19 -22
- data/stubs/hotwire/app/views/profile/partials/_delete_user_form.html.erb +32 -42
- data/stubs/hotwire/app/views/profile/partials/_update_password_form.html.erb +42 -55
- data/stubs/hotwire/app/views/profile/partials/_update_profile_information_form.html.erb +36 -46
- data/stubs/hotwire/app/views/welcome/index.html.erb +34 -46
- data/stubs/hotwire/config/importmap.rb +3 -3
- data/stubs/hotwire/config/tailwind.config.js +2 -2
- data/stubs/inertia-common/app/controllers/application_controller.rb +1 -0
- data/stubs/inertia-common/app/controllers/auth/authenticated_session_controller.rb +11 -8
- data/stubs/inertia-common/app/controllers/auth/new_password_controller.rb +5 -3
- data/stubs/inertia-common/app/controllers/auth/password_reset_link_controller.rb +5 -3
- data/stubs/inertia-common/app/controllers/auth/registered_user_controller.rb +5 -3
- data/stubs/inertia-common/app/controllers/concerns/authenticate.rb +5 -20
- data/stubs/inertia-common/app/controllers/concerns/handle_inertia_requests.rb +1 -1
- data/stubs/inertia-common/app/controllers/concerns/redirect_if_authenticated.rb +19 -0
- data/stubs/inertia-common/app/controllers/concerns/set_current_auth.rb +9 -0
- data/stubs/inertia-common/app/controllers/concerns/verify_csrf_token.rb +4 -4
- data/stubs/inertia-common/app/controllers/dashboard_controller.rb +1 -1
- data/stubs/inertia-common/app/controllers/password_controller.rb +1 -1
- data/stubs/inertia-common/app/controllers/profile_controller.rb +7 -5
- data/stubs/inertia-common/app/controllers/welcome_controller.rb +2 -2
- data/stubs/inertia-common/bin/vite +6 -6
- data/stubs/inertia-common/test/integration/password_update_test.rb +28 -0
- data/stubs/inertia-common/test/integration/profile_test.rb +51 -0
- data/stubs/inertia-react-ts/app/javascript/Components/ApplicationLogo.tsx +13 -9
- data/stubs/inertia-react-ts/app/javascript/Components/Checkbox.tsx +15 -12
- data/stubs/inertia-react-ts/app/javascript/Components/DangerButton.tsx +20 -15
- data/stubs/inertia-react-ts/app/javascript/Components/Dropdown.tsx +119 -87
- data/stubs/inertia-react-ts/app/javascript/Components/InputError.tsx +14 -7
- data/stubs/inertia-react-ts/app/javascript/Components/InputLabel.tsx +18 -7
- data/stubs/inertia-react-ts/app/javascript/Components/Modal.tsx +60 -60
- data/stubs/inertia-react-ts/app/javascript/Components/NavLink.tsx +21 -16
- data/stubs/inertia-react-ts/app/javascript/Components/PrimaryButton.tsx +20 -15
- data/stubs/inertia-react-ts/app/javascript/Components/ResponsiveNavLink.tsx +19 -14
- data/stubs/inertia-react-ts/app/javascript/Components/SecondaryButton.tsx +22 -16
- data/stubs/inertia-react-ts/app/javascript/Components/TextInput.tsx +35 -24
- data/stubs/inertia-react-ts/app/javascript/Layouts/AuthenticatedLayout.tsx +157 -117
- data/stubs/inertia-react-ts/app/javascript/Layouts/GuestLayout.tsx +15 -15
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ForgotPassword.tsx +52 -49
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Login.tsx +90 -82
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Register.tsx +118 -115
- data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ResetPassword.tsx +63 -60
- data/stubs/inertia-react-ts/app/javascript/Pages/Dashboard.tsx +23 -17
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Edit.tsx +31 -27
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.tsx +109 -99
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.tsx +121 -113
- data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.tsx +76 -69
- data/stubs/inertia-react-ts/app/javascript/Pages/Welcome.tsx +87 -63
- data/stubs/inertia-react-ts/app/javascript/entrypoints/application.tsx +32 -25
- data/stubs/inertia-react-ts/app/views/layouts/application.html.erb +0 -4
- data/stubs/inertia-react-ts/config/tailwind.config.js +2 -2
- data/stubs/inertia-react-ts/vite.config.ts +2 -5
- data/stubs/inertia-vue-ts/app/javascript/Components/ApplicationLogo.vue +10 -6
- data/stubs/inertia-vue-ts/app/javascript/Components/Checkbox.vue +18 -18
- data/stubs/inertia-vue-ts/app/javascript/Components/DangerButton.vue +5 -5
- data/stubs/inertia-vue-ts/app/javascript/Components/Dropdown.vue +60 -57
- data/stubs/inertia-vue-ts/app/javascript/Components/DropdownLink.vue +9 -9
- data/stubs/inertia-vue-ts/app/javascript/Components/InputError.vue +7 -7
- data/stubs/inertia-vue-ts/app/javascript/Components/InputLabel.vue +6 -6
- data/stubs/inertia-vue-ts/app/javascript/Components/Modal.vue +84 -74
- data/stubs/inertia-vue-ts/app/javascript/Components/NavLink.vue +12 -12
- data/stubs/inertia-vue-ts/app/javascript/Components/PrimaryButton.vue +5 -5
- data/stubs/inertia-vue-ts/app/javascript/Components/ResponsiveNavLink.vue +12 -12
- data/stubs/inertia-vue-ts/app/javascript/Components/SecondaryButton.vue +13 -13
- data/stubs/inertia-vue-ts/app/javascript/Components/TextInput.vue +13 -13
- data/stubs/inertia-vue-ts/app/javascript/Layouts/AuthenticatedLayout.vue +168 -136
- data/stubs/inertia-vue-ts/app/javascript/Layouts/GuestLayout.vue +15 -13
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ForgotPassword.vue +56 -49
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Login.vue +78 -72
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Register.vue +101 -97
- data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ResetPassword.vue +71 -68
- data/stubs/inertia-vue-ts/app/javascript/Pages/Dashboard.vue +22 -14
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Edit.vue +34 -30
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.vue +87 -83
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdatePasswordForm.vue +105 -98
- data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdateProfileInformationForm.vue +69 -59
- data/stubs/inertia-vue-ts/app/javascript/Pages/Welcome.vue +74 -47
- data/stubs/inertia-vue-ts/app/views/layouts/application.html.erb +0 -4
- data/stubs/inertia-vue-ts/config/tailwind.config.js +2 -2
- data/stubs/inertia-vue-ts/vite.config.ts +2 -5
- metadata +19 -6
- data/stubs/hotwire/bin/vite +0 -27
- data/stubs/inertia-common/Procfile.dev +0 -3
- /data/stubs/{hotwire → default}/Procfile.dev +0 -0
- /data/stubs/hotwire/app/javascript/{alpinejs.js → alpinejs.stub} +0 -0
@@ -1,96 +1,106 @@
|
|
1
1
|
<script setup lang="ts">
|
2
|
-
import { computed, onMounted, onUnmounted, watch } from 'vue'
|
2
|
+
import { computed, onMounted, onUnmounted, watch } from 'vue'
|
3
3
|
|
4
4
|
const props = withDefaults(
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
)
|
5
|
+
defineProps<{
|
6
|
+
show?: boolean
|
7
|
+
maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
8
|
+
closeable?: boolean
|
9
|
+
}>(),
|
10
|
+
{
|
11
|
+
show: false,
|
12
|
+
maxWidth: '2xl',
|
13
|
+
closeable: true,
|
14
|
+
},
|
15
|
+
)
|
16
16
|
|
17
|
-
const emit = defineEmits(['close'])
|
17
|
+
const emit = defineEmits(['close'])
|
18
18
|
|
19
19
|
watch(
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
}
|
20
|
+
() => props.show,
|
21
|
+
() => {
|
22
|
+
if (props.show) {
|
23
|
+
document.body.style.overflow = 'hidden'
|
24
|
+
} else {
|
25
|
+
document.body.style.overflow = 'visible'
|
27
26
|
}
|
28
|
-
|
27
|
+
},
|
28
|
+
)
|
29
29
|
|
30
30
|
const close = () => {
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
}
|
31
|
+
if (props.closeable) {
|
32
|
+
emit('close')
|
33
|
+
}
|
34
|
+
}
|
35
35
|
|
36
36
|
const closeOnEscape = (e: KeyboardEvent) => {
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
}
|
37
|
+
if (e.key === 'Escape' && props.show) {
|
38
|
+
close()
|
39
|
+
}
|
40
|
+
}
|
41
41
|
|
42
|
-
onMounted(() => document.addEventListener('keydown', closeOnEscape))
|
42
|
+
onMounted(() => document.addEventListener('keydown', closeOnEscape))
|
43
43
|
|
44
44
|
onUnmounted(() => {
|
45
|
-
|
46
|
-
|
47
|
-
})
|
45
|
+
document.removeEventListener('keydown', closeOnEscape)
|
46
|
+
document.body.style.overflow = 'visible'
|
47
|
+
})
|
48
48
|
|
49
49
|
const maxWidthClass = computed(() => {
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
})
|
50
|
+
return {
|
51
|
+
sm: 'sm:max-w-sm',
|
52
|
+
md: 'sm:max-w-md',
|
53
|
+
lg: 'sm:max-w-lg',
|
54
|
+
xl: 'sm:max-w-xl',
|
55
|
+
'2xl': 'sm:max-w-2xl',
|
56
|
+
}[props.maxWidth]
|
57
|
+
})
|
58
58
|
</script>
|
59
59
|
|
60
60
|
<template>
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
61
|
+
<Teleport to="body">
|
62
|
+
<Transition leave-active-class="duration-200">
|
63
|
+
<div
|
64
|
+
v-show="show"
|
65
|
+
class="fixed inset-0 overflow-y-auto px-4 py-6 sm:px-0 z-50"
|
66
|
+
scroll-region
|
67
|
+
>
|
68
|
+
<Transition
|
69
|
+
enter-active-class="ease-out duration-300"
|
70
|
+
enter-from-class="opacity-0"
|
71
|
+
enter-to-class="opacity-100"
|
72
|
+
leave-active-class="ease-in duration-200"
|
73
|
+
leave-from-class="opacity-100"
|
74
|
+
leave-to-class="opacity-0"
|
75
|
+
>
|
76
|
+
<div
|
77
|
+
v-show="show"
|
78
|
+
class="fixed inset-0 transform transition-all"
|
79
|
+
@click="close"
|
80
|
+
>
|
81
|
+
<div
|
82
|
+
class="absolute inset-0 bg-gray-500 dark:bg-gray-900 opacity-75"
|
83
|
+
/>
|
84
|
+
</div>
|
85
|
+
</Transition>
|
76
86
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
</Transition>
|
93
|
-
</div>
|
87
|
+
<Transition
|
88
|
+
enter-active-class="ease-out duration-300"
|
89
|
+
enter-from-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
90
|
+
enter-to-class="opacity-100 translate-y-0 sm:scale-100"
|
91
|
+
leave-active-class="ease-in duration-200"
|
92
|
+
leave-from-class="opacity-100 translate-y-0 sm:scale-100"
|
93
|
+
leave-to-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
94
|
+
>
|
95
|
+
<div
|
96
|
+
v-show="show"
|
97
|
+
class="mb-6 bg-white dark:bg-gray-800 rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full sm:mx-auto"
|
98
|
+
:class="maxWidthClass"
|
99
|
+
>
|
100
|
+
<slot v-if="show" />
|
101
|
+
</div>
|
94
102
|
</Transition>
|
95
|
-
|
103
|
+
</div>
|
104
|
+
</Transition>
|
105
|
+
</Teleport>
|
96
106
|
</template>
|
@@ -1,21 +1,21 @@
|
|
1
1
|
<script setup lang="ts">
|
2
|
-
import { computed } from 'vue'
|
3
|
-
import { Link } from '@inertiajs/vue3'
|
2
|
+
import { computed } from 'vue'
|
3
|
+
import { Link } from '@inertiajs/vue3'
|
4
4
|
|
5
5
|
const props = defineProps<{
|
6
|
-
|
7
|
-
|
8
|
-
}>()
|
6
|
+
href: string
|
7
|
+
active?: boolean
|
8
|
+
}>()
|
9
9
|
|
10
10
|
const classes = computed(() =>
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
)
|
11
|
+
props.active
|
12
|
+
? 'inline-flex items-center px-1 pt-1 border-b-2 border-indigo-400 dark:border-indigo-600 text-sm font-medium leading-5 text-gray-900 dark:text-gray-100 focus:outline-none focus:border-indigo-700 transition duration-150 ease-in-out'
|
13
|
+
: 'inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-700 focus:outline-none focus:text-gray-700 dark:focus:text-gray-300 focus:border-gray-300 dark:focus:border-gray-700 transition duration-150 ease-in-out',
|
14
|
+
)
|
15
15
|
</script>
|
16
16
|
|
17
17
|
<template>
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
<Link :href="href" :class="classes">
|
19
|
+
<slot />
|
20
|
+
</Link>
|
21
21
|
</template>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<template>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
<button
|
3
|
+
class="inline-flex items-center px-4 py-2 bg-gray-800 dark:bg-gray-200 border border-transparent rounded-md font-semibold text-xs text-white dark:text-gray-800 uppercase tracking-widest hover:bg-gray-700 dark:hover:bg-white focus:bg-gray-700 dark:focus:bg-white active:bg-gray-900 dark:active:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150"
|
4
|
+
>
|
5
|
+
<slot />
|
6
|
+
</button>
|
7
7
|
</template>
|
@@ -1,21 +1,21 @@
|
|
1
1
|
<script setup lang="ts">
|
2
|
-
import { computed } from 'vue'
|
3
|
-
import { Link } from '@inertiajs/vue3'
|
2
|
+
import { computed } from 'vue'
|
3
|
+
import { Link } from '@inertiajs/vue3'
|
4
4
|
|
5
5
|
const props = defineProps<{
|
6
|
-
|
7
|
-
|
8
|
-
}>()
|
6
|
+
href: string
|
7
|
+
active?: boolean
|
8
|
+
}>()
|
9
9
|
|
10
10
|
const classes = computed(() =>
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
)
|
11
|
+
props.active
|
12
|
+
? 'block w-full ps-3 pe-4 py-2 border-l-4 border-indigo-400 dark:border-indigo-600 text-start text-base font-medium text-indigo-700 dark:text-indigo-300 bg-indigo-50 dark:bg-indigo-900/50 focus:outline-none focus:text-indigo-800 dark:focus:text-indigo-200 focus:bg-indigo-100 dark:focus:bg-indigo-900 focus:border-indigo-700 dark:focus:border-indigo-300 transition duration-150 ease-in-out'
|
13
|
+
: 'block w-full ps-3 pe-4 py-2 border-l-4 border-transparent text-start text-base font-medium text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 hover:border-gray-300 dark:hover:border-gray-600 focus:outline-none focus:text-gray-800 dark:focus:text-gray-200 focus:bg-gray-50 dark:focus:bg-gray-700 focus:border-gray-300 dark:focus:border-gray-600 transition duration-150 ease-in-out',
|
14
|
+
)
|
15
15
|
</script>
|
16
16
|
|
17
17
|
<template>
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
<Link :href="href" :class="classes">
|
19
|
+
<slot />
|
20
|
+
</Link>
|
21
21
|
</template>
|
@@ -1,19 +1,19 @@
|
|
1
1
|
<script setup lang="ts">
|
2
2
|
withDefaults(
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
)
|
3
|
+
defineProps<{
|
4
|
+
type?: 'button' | 'submit' | 'reset'
|
5
|
+
}>(),
|
6
|
+
{
|
7
|
+
type: 'button',
|
8
|
+
},
|
9
|
+
)
|
10
10
|
</script>
|
11
11
|
|
12
12
|
<template>
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
<button
|
14
|
+
:type="type"
|
15
|
+
class="inline-flex items-center px-4 py-2 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-500 rounded-md font-semibold text-xs text-gray-700 dark:text-gray-300 uppercase tracking-widest shadow-sm hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 disabled:opacity-25 transition ease-in-out duration-150"
|
16
|
+
>
|
17
|
+
<slot />
|
18
|
+
</button>
|
19
19
|
</template>
|
@@ -1,23 +1,23 @@
|
|
1
1
|
<script setup lang="ts">
|
2
|
-
import { onMounted, ref } from 'vue'
|
2
|
+
import { onMounted, ref } from 'vue'
|
3
3
|
|
4
|
-
const model = defineModel<string>({ required: true })
|
4
|
+
const model = defineModel<string>({ required: true })
|
5
5
|
|
6
|
-
const input = ref<HTMLInputElement | null>(null)
|
6
|
+
const input = ref<HTMLInputElement | null>(null)
|
7
7
|
|
8
8
|
onMounted(() => {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
})
|
9
|
+
if (input.value?.hasAttribute('autofocus')) {
|
10
|
+
input.value?.focus()
|
11
|
+
}
|
12
|
+
})
|
13
13
|
|
14
|
-
defineExpose({ focus: () => input.value?.focus() })
|
14
|
+
defineExpose({ focus: () => input.value?.focus() })
|
15
15
|
</script>
|
16
16
|
|
17
17
|
<template>
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
<input
|
19
|
+
class="border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm"
|
20
|
+
v-model="model"
|
21
|
+
ref="input"
|
22
|
+
/>
|
23
23
|
</template>
|