kaze 0.4.0 → 0.6.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.
- 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,9 +1,20 @@
|
|
1
|
-
import { LabelHTMLAttributes } from 'react'
|
1
|
+
import { LabelHTMLAttributes } from 'react'
|
2
2
|
|
3
|
-
export default function InputLabel({
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
export default function InputLabel({
|
4
|
+
value,
|
5
|
+
className = '',
|
6
|
+
children,
|
7
|
+
...props
|
8
|
+
}: LabelHTMLAttributes<HTMLLabelElement> & { value?: string }) {
|
9
|
+
return (
|
10
|
+
<label
|
11
|
+
{...props}
|
12
|
+
className={
|
13
|
+
`block font-medium text-sm text-gray-700 dark:text-gray-300 ` +
|
14
|
+
className
|
15
|
+
}
|
16
|
+
>
|
17
|
+
{value ? value : children}
|
18
|
+
</label>
|
19
|
+
)
|
9
20
|
}
|
@@ -1,68 +1,68 @@
|
|
1
|
-
import { Fragment, PropsWithChildren } from 'react'
|
2
|
-
import { Dialog, Transition } from '@headlessui/react'
|
1
|
+
import { Fragment, PropsWithChildren } from 'react'
|
2
|
+
import { Dialog, Transition } from '@headlessui/react'
|
3
3
|
|
4
4
|
export default function Modal({
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
children,
|
6
|
+
show = false,
|
7
|
+
maxWidth = '2xl',
|
8
|
+
closeable = true,
|
9
|
+
onClose = () => {},
|
10
10
|
}: PropsWithChildren<{
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
show: boolean
|
12
|
+
maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl'
|
13
|
+
closeable?: boolean
|
14
|
+
onClose: CallableFunction
|
15
15
|
}>) {
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
const close = () => {
|
17
|
+
if (closeable) {
|
18
|
+
onClose()
|
19
|
+
}
|
20
|
+
}
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
const maxWidthClass = {
|
23
|
+
sm: 'sm:max-w-sm',
|
24
|
+
md: 'sm:max-w-md',
|
25
|
+
lg: 'sm:max-w-lg',
|
26
|
+
xl: 'sm:max-w-xl',
|
27
|
+
'2xl': 'sm:max-w-2xl',
|
28
|
+
}[maxWidth]
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
30
|
+
return (
|
31
|
+
<Transition show={show} as={Fragment} leave="duration-200">
|
32
|
+
<Dialog
|
33
|
+
as="div"
|
34
|
+
id="modal"
|
35
|
+
className="fixed inset-0 flex overflow-y-auto px-4 py-6 sm:px-0 items-center z-50 transform transition-all"
|
36
|
+
onClose={close}
|
37
|
+
>
|
38
|
+
<Transition.Child
|
39
|
+
as={Fragment}
|
40
|
+
enter="ease-out duration-300"
|
41
|
+
enterFrom="opacity-0"
|
42
|
+
enterTo="opacity-100"
|
43
|
+
leave="ease-in duration-200"
|
44
|
+
leaveFrom="opacity-100"
|
45
|
+
leaveTo="opacity-0"
|
46
|
+
>
|
47
|
+
<div className="absolute inset-0 bg-gray-500/75 dark:bg-gray-900/75" />
|
48
|
+
</Transition.Child>
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
50
|
+
<Transition.Child
|
51
|
+
as={Fragment}
|
52
|
+
enter="ease-out duration-300"
|
53
|
+
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
54
|
+
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
55
|
+
leave="ease-in duration-200"
|
56
|
+
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
57
|
+
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
58
|
+
>
|
59
|
+
<Dialog.Panel
|
60
|
+
className={`mb-6 bg-white dark:bg-gray-800 rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full sm:mx-auto ${maxWidthClass}`}
|
61
|
+
>
|
62
|
+
{children}
|
63
|
+
</Dialog.Panel>
|
64
|
+
</Transition.Child>
|
65
|
+
</Dialog>
|
66
|
+
</Transition>
|
67
|
+
)
|
68
68
|
}
|
@@ -1,18 +1,23 @@
|
|
1
|
-
import { Link, InertiaLinkProps } from '@inertiajs/react'
|
1
|
+
import { Link, InertiaLinkProps } from '@inertiajs/react'
|
2
2
|
|
3
|
-
export default function NavLink({
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
export default function NavLink({
|
4
|
+
active = false,
|
5
|
+
className = '',
|
6
|
+
children,
|
7
|
+
...props
|
8
|
+
}: InertiaLinkProps & { active: boolean }) {
|
9
|
+
return (
|
10
|
+
<Link
|
11
|
+
{...props}
|
12
|
+
className={
|
13
|
+
'inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium leading-5 transition duration-150 ease-in-out focus:outline-none ' +
|
14
|
+
(active
|
15
|
+
? 'border-indigo-400 dark:border-indigo-600 text-gray-900 dark:text-gray-100 focus:border-indigo-700 '
|
16
|
+
: 'border-transparent 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:text-gray-700 dark:focus:text-gray-300 focus:border-gray-300 dark:focus:border-gray-700 ') +
|
17
|
+
className
|
18
|
+
}
|
19
|
+
>
|
20
|
+
{children}
|
21
|
+
</Link>
|
22
|
+
)
|
18
23
|
}
|
@@ -1,17 +1,22 @@
|
|
1
|
-
import { ButtonHTMLAttributes } from 'react'
|
1
|
+
import { ButtonHTMLAttributes } from 'react'
|
2
2
|
|
3
|
-
export default function PrimaryButton({
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
3
|
+
export default function PrimaryButton({
|
4
|
+
className = '',
|
5
|
+
disabled,
|
6
|
+
children,
|
7
|
+
...props
|
8
|
+
}: ButtonHTMLAttributes<HTMLButtonElement>) {
|
9
|
+
return (
|
10
|
+
<button
|
11
|
+
{...props}
|
12
|
+
className={
|
13
|
+
`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 ${
|
14
|
+
disabled && 'opacity-25'
|
15
|
+
} ` + className
|
16
|
+
}
|
17
|
+
disabled={disabled}
|
18
|
+
>
|
19
|
+
{children}
|
20
|
+
</button>
|
21
|
+
)
|
17
22
|
}
|
@@ -1,16 +1,21 @@
|
|
1
|
-
import { Link, InertiaLinkProps } from '@inertiajs/react'
|
1
|
+
import { Link, InertiaLinkProps } from '@inertiajs/react'
|
2
2
|
|
3
|
-
export default function ResponsiveNavLink({
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
3
|
+
export default function ResponsiveNavLink({
|
4
|
+
active = false,
|
5
|
+
className = '',
|
6
|
+
children,
|
7
|
+
...props
|
8
|
+
}: InertiaLinkProps & { active?: boolean }) {
|
9
|
+
return (
|
10
|
+
<Link
|
11
|
+
{...props}
|
12
|
+
className={`w-full flex items-start ps-3 pe-4 py-2 border-l-4 ${
|
13
|
+
active
|
14
|
+
? 'border-indigo-400 dark:border-indigo-600 text-indigo-700 dark:text-indigo-300 bg-indigo-50 dark:bg-indigo-900/50 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'
|
15
|
+
: 'border-transparent 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: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'
|
16
|
+
} text-base font-medium focus:outline-none transition duration-150 ease-in-out ${className}`}
|
17
|
+
>
|
18
|
+
{children}
|
19
|
+
</Link>
|
20
|
+
)
|
16
21
|
}
|
@@ -1,18 +1,24 @@
|
|
1
|
-
import { ButtonHTMLAttributes } from 'react'
|
1
|
+
import { ButtonHTMLAttributes } from 'react'
|
2
2
|
|
3
|
-
export default function SecondaryButton({
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
export default function SecondaryButton({
|
4
|
+
type = 'button',
|
5
|
+
className = '',
|
6
|
+
disabled,
|
7
|
+
children,
|
8
|
+
...props
|
9
|
+
}: ButtonHTMLAttributes<HTMLButtonElement>) {
|
10
|
+
return (
|
11
|
+
<button
|
12
|
+
{...props}
|
13
|
+
type={type}
|
14
|
+
className={
|
15
|
+
`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
|
+
disabled && 'opacity-25'
|
17
|
+
} ` + className
|
18
|
+
}
|
19
|
+
disabled={disabled}
|
20
|
+
>
|
21
|
+
{children}
|
22
|
+
</button>
|
23
|
+
)
|
18
24
|
}
|
@@ -1,30 +1,41 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
forwardRef,
|
3
|
+
useEffect,
|
4
|
+
useImperativeHandle,
|
5
|
+
useRef,
|
6
|
+
InputHTMLAttributes,
|
7
|
+
} from 'react'
|
2
8
|
|
3
9
|
export default forwardRef(function TextInput(
|
4
|
-
|
5
|
-
|
10
|
+
{
|
11
|
+
type = 'text',
|
12
|
+
className = '',
|
13
|
+
isFocused = false,
|
14
|
+
...props
|
15
|
+
}: InputHTMLAttributes<HTMLInputElement> & { isFocused?: boolean },
|
16
|
+
ref,
|
6
17
|
) {
|
7
|
-
|
18
|
+
const localRef = useRef<HTMLInputElement>(null)
|
8
19
|
|
9
|
-
|
10
|
-
|
11
|
-
|
20
|
+
useImperativeHandle(ref, () => ({
|
21
|
+
focus: () => localRef.current?.focus(),
|
22
|
+
}))
|
12
23
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
24
|
+
useEffect(() => {
|
25
|
+
if (isFocused) {
|
26
|
+
localRef.current?.focus()
|
27
|
+
}
|
28
|
+
}, [])
|
18
29
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
})
|
30
|
+
return (
|
31
|
+
<input
|
32
|
+
{...props}
|
33
|
+
type={type}
|
34
|
+
className={
|
35
|
+
'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 ' +
|
36
|
+
className
|
37
|
+
}
|
38
|
+
ref={localRef}
|
39
|
+
/>
|
40
|
+
)
|
41
|
+
})
|