feat: add Combobox component for subscription selection and integrate with form validation

This commit is contained in:
Ardeman 2025-03-04 08:55:01 +08:00
parent c20022f58c
commit 78287cc6c5
5 changed files with 271 additions and 9 deletions

View File

@ -14,7 +14,7 @@ export const userRegisterRequest = async (payload: TRegisterSchema) => {
const { subscribe_plan, ...restPayload } = payload const { subscribe_plan, ...restPayload } = payload
const transformedPayload = { const transformedPayload = {
...restPayload, ...restPayload,
subscribe_plan_id: subscribe_plan, subscribe_plan_id: subscribe_plan.id,
} }
const { data } = await HttpServer().post( const { data } = await HttpServer().post(
'/api/user/register', '/api/user/register',

View File

@ -0,0 +1,115 @@
import {
Field,
Label,
Combobox as HeadlessCombobox,
ComboboxInput,
ComboboxButton,
ComboboxOptions,
ComboboxOption,
} from '@headlessui/react'
import { CheckIcon, ChevronDownIcon } from '@heroicons/react/20/solid'
import { useState, type ComponentProps, type ReactNode } from 'react'
import {
get,
type FieldError,
type FieldValues,
type Path,
type RegisterOptions,
Controller,
} from 'react-hook-form'
import { useRemixFormContext } from 'remix-hook-form'
import { twMerge } from 'tailwind-merge'
type TComboboxOption = {
code: string
name: string
id: string
}
type TInputProperties<T extends FieldValues> = ComponentProps<
typeof HeadlessCombobox
> & {
id: string
label?: ReactNode
name: Path<T>
rules?: RegisterOptions
placeholder?: string
options?: TComboboxOption[]
}
export const Combobox = <TFormValues extends Record<string, unknown>>(
properties: TInputProperties<TFormValues>,
) => {
const { id, label, name, rules, disabled, placeholder, options, ...rest } =
properties
const {
control,
formState: { errors },
} = useRemixFormContext()
const [query, setQuery] = useState('')
const filteredOptions =
query === ''
? options
: options?.filter((option) =>
option.name.toLowerCase().includes(query.toLowerCase()),
)
const error: FieldError = get(errors, name)
return (
<Field
className="relative"
disabled={disabled}
id={id}
>
<Label className="mb-1 block text-gray-700">
{label} {error && <span className="text-red-500">{error.message}</span>}
</Label>
<Controller
name={name}
control={control}
rules={rules}
render={({ field }) => (
<HeadlessCombobox
value={field.value}
onChange={field.onChange}
disabled={disabled}
immediate
{...rest}
>
<div className="relative">
<ComboboxInput
placeholder={placeholder}
displayValue={(option: TComboboxOption) => option?.name}
onChange={(event) => setQuery(event.target.value)}
className="focus:inheriten h-[42px] w-full rounded-md border border-[#DFDFDF] p-2"
/>
<ComboboxButton className="group absolute inset-y-0 right-0 px-2.5">
<ChevronDownIcon className="size-4 fill-gray-500" />
</ComboboxButton>
</div>
<ComboboxOptions
anchor={{ to: 'bottom', gap: '8px' }}
transition
className={twMerge(
'w-[var(--input-width)] rounded-md border border-[#DFDFDF] p-1 empty:invisible',
'bg-white transition duration-100 ease-in data-[leave]:data-[closed]:opacity-0',
)}
>
{filteredOptions?.map((person) => (
<ComboboxOption
key={person.id}
value={person}
className="group flex cursor-default items-center gap-2 rounded-lg px-3 py-1.5 select-none data-[focus]:bg-white/10"
>
<CheckIcon className="invisible size-4 group-data-[selected]:visible" />
<div className="text-sm/6">{person.name}</div>
</ComboboxOption>
))}
</ComboboxOptions>
</HeadlessCombobox>
)}
/>
</Field>
)
}

View File

@ -1,3 +1,4 @@
import { DevTool } from '@hookform/devtools'
import { zodResolver } from '@hookform/resolvers/zod' import { zodResolver } from '@hookform/resolvers/zod'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { useFetcher, useRouteLoaderData } from 'react-router' import { useFetcher, useRouteLoaderData } from 'react-router'
@ -5,8 +6,8 @@ import { RemixFormProvider, useRemixForm } from 'remix-hook-form'
import { z } from 'zod' import { z } from 'zod'
import { Button } from '~/components/ui/button' import { Button } from '~/components/ui/button'
import { Combobox } from '~/components/ui/combobox'
import { Input } from '~/components/ui/input' import { Input } from '~/components/ui/input'
import { Select } from '~/components/ui/select'
import { useNewsContext } from '~/contexts/news' import { useNewsContext } from '~/contexts/news'
import type { loader } from '~/routes/_layout' import type { loader } from '~/routes/_layout'
@ -16,7 +17,17 @@ export const registerSchema = z
password: z.string().min(6, 'Kata sandi minimal 6 karakter'), password: z.string().min(6, 'Kata sandi minimal 6 karakter'),
rePassword: z.string().min(6, 'Kata sandi minimal 6 karakter'), rePassword: z.string().min(6, 'Kata sandi minimal 6 karakter'),
phone: z.string().min(10, 'No telepon tidak valid'), phone: z.string().min(10, 'No telepon tidak valid'),
subscribe_plan: z.string().min(1, 'Pilih salah satu subscription'), subscribe_plan: z
.object({
id: z.string(),
code: z.string(),
name: z.string(),
})
.optional()
.nullable()
.refine((data) => !!data, {
message: 'Please select a subscription',
}),
}) })
.refine((field) => field.password === field.rePassword, { .refine((field) => field.password === field.rePassword, {
message: 'Kata sandi tidak sama', message: 'Kata sandi tidak sama',
@ -40,7 +51,7 @@ export const FormRegister = () => {
resolver: zodResolver(registerSchema), resolver: zodResolver(registerSchema),
}) })
const { handleSubmit } = formMethods const { handleSubmit, control } = formMethods
useEffect(() => { useEffect(() => {
if (!fetcher.data?.success) { if (!fetcher.data?.success) {
@ -96,7 +107,7 @@ export const FormRegister = () => {
name="phone" name="phone"
/> />
<Select <Combobox
id="subscribe_plan" id="subscribe_plan"
name="subscribe_plan" name="subscribe_plan"
label="Subscription" label="Subscription"
@ -134,6 +145,7 @@ export const FormRegister = () => {
</Button> </Button>
</div> </div>
</div> </div>
<DevTool control={control} />
</div> </div>
) )
} }

View File

@ -46,6 +46,7 @@
"@commitlint/format": "^19.5.0", "@commitlint/format": "^19.5.0",
"@commitlint/is-ignored": "^19.6.0", "@commitlint/is-ignored": "^19.6.0",
"@eslint/js": "^9.19.0", "@eslint/js": "^9.19.0",
"@hookform/devtools": "^4.3.3",
"@react-router/dev": "^7.1.3", "@react-router/dev": "^7.1.3",
"@tailwindcss/typography": "^0.5.16", "@tailwindcss/typography": "^0.5.16",
"@tailwindcss/vite": "^4.0.0", "@tailwindcss/vite": "^4.0.0",

142
pnpm-lock.yaml generated
View File

@ -99,6 +99,9 @@ importers:
'@eslint/js': '@eslint/js':
specifier: ^9.19.0 specifier: ^9.19.0
version: 9.19.0 version: 9.19.0
'@hookform/devtools':
specifier: ^4.3.3
version: 4.3.3(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@react-router/dev': '@react-router/dev':
specifier: ^7.1.3 specifier: ^7.1.3
version: 7.1.3(@react-router/serve@7.1.3(react-router@7.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(typescript@5.7.3))(@types/node@20.17.16)(babel-plugin-macros@3.1.0)(lightningcss@1.29.1)(react-router@7.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(typescript@5.7.3)(vite@5.4.14(@types/node@20.17.16)(lightningcss@1.29.1)) version: 7.1.3(@react-router/serve@7.1.3(react-router@7.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(typescript@5.7.3))(@types/node@20.17.16)(babel-plugin-macros@3.1.0)(lightningcss@1.29.1)(react-router@7.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(typescript@5.7.3)(vite@5.4.14(@types/node@20.17.16)(lightningcss@1.29.1))
@ -170,7 +173,7 @@ importers:
version: 0.6.11(prettier@3.4.2) version: 0.6.11(prettier@3.4.2)
react-router-devtools: react-router-devtools:
specifier: ^1.1.0 specifier: ^1.1.0
version: 1.1.0(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react-router@7.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(vite@5.4.14(@types/node@20.17.16)(lightningcss@1.29.1)) version: 1.1.0(@emotion/is-prop-valid@1.3.1)(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react-router@7.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(vite@5.4.14(@types/node@20.17.16)(lightningcss@1.29.1))
tailwindcss: tailwindcss:
specifier: ^4.0.0 specifier: ^4.0.0
version: 4.0.1 version: 4.0.1
@ -415,18 +418,45 @@ packages:
'@emotion/hash@0.9.2': '@emotion/hash@0.9.2':
resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==}
'@emotion/is-prop-valid@1.3.1':
resolution: {integrity: sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==}
'@emotion/memoize@0.9.0': '@emotion/memoize@0.9.0':
resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==}
'@emotion/react@11.14.0':
resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==}
peerDependencies:
'@types/react': '*'
react: '>=16.8.0'
peerDependenciesMeta:
'@types/react':
optional: true
'@emotion/serialize@1.3.3': '@emotion/serialize@1.3.3':
resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==}
'@emotion/sheet@1.4.0': '@emotion/sheet@1.4.0':
resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==}
'@emotion/styled@11.14.0':
resolution: {integrity: sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==}
peerDependencies:
'@emotion/react': ^11.0.0-rc.0
'@types/react': '*'
react: '>=16.8.0'
peerDependenciesMeta:
'@types/react':
optional: true
'@emotion/unitless@0.10.0': '@emotion/unitless@0.10.0':
resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==}
'@emotion/use-insertion-effect-with-fallbacks@1.2.0':
resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==}
peerDependencies:
react: '>=16.8.0'
'@emotion/utils@1.4.2': '@emotion/utils@1.4.2':
resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==}
@ -626,6 +656,12 @@ packages:
peerDependencies: peerDependencies:
react: '>= 16 || ^19.0.0-rc' react: '>= 16 || ^19.0.0-rc'
'@hookform/devtools@4.3.3':
resolution: {integrity: sha512-W9MipDe6P5y2XLos9coN4/fZhbt0YE2c+PaUx7tiKdc9XNQ2UOWCYTtysCnbj7fipZWEJht8J/UyQmXprWEhgw==}
peerDependencies:
react: ^16.8.0 || ^17 || ^18 || ^19
react-dom: ^16.8.0 || ^17 || ^18 || ^19
'@hookform/resolvers@4.1.1': '@hookform/resolvers@4.1.1':
resolution: {integrity: sha512-S9YN1RgNWG+klUz5uQaV6rjE4pr6Py2tamj7ekshzLcMyg+/Pal1KZAYgGszV0+doiy41dUiQgXL3uRS9stndQ==} resolution: {integrity: sha512-S9YN1RgNWG+klUz5uQaV6rjE4pr6Py2tamj7ekshzLcMyg+/Pal1KZAYgGszV0+doiy41dUiQgXL3uRS9stndQ==}
peerDependencies: peerDependencies:
@ -1550,6 +1586,9 @@ packages:
'@types/linkify-it@5.0.0': '@types/linkify-it@5.0.0':
resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
'@types/lodash@4.17.16':
resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==}
'@types/markdown-it@14.1.2': '@types/markdown-it@14.1.2':
resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
@ -2708,6 +2747,9 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
hoist-non-react-statics@3.3.2:
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
hosted-git-info@2.8.9: hosted-git-info@2.8.9:
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
@ -3140,6 +3182,11 @@ packages:
resolution: {integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==} resolution: {integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==}
engines: {node: '>=18.0.0'} engines: {node: '>=18.0.0'}
little-state-machine@4.8.1:
resolution: {integrity: sha512-liPHqaWMQ7rzZryQUDnbZ1Gclnnai3dIyaJ0nAgwZRXMzqbYrydrlCI0NDojRUbE5VYh5vu6hygEUZiH77nQkQ==}
peerDependencies:
react: ^16.8.0 || ^17 || ^18 || ^19
locate-path@5.0.0: locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -3825,6 +3872,11 @@ packages:
react-dom: react-dom:
optional: true optional: true
react-simple-animate@3.5.3:
resolution: {integrity: sha512-Ob+SmB5J1tXDEZyOe2Hf950K4M8VaWBBmQ3cS2BUnTORqHjhK0iKG8fB+bo47ZL15t8d3g/Y0roiqH05UBjG7A==}
peerDependencies:
react-dom: ^16.8.0 || ^17 || ^18 || ^19
react-style-singleton@2.2.3: react-style-singleton@2.2.3:
resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -4356,6 +4408,12 @@ packages:
'@types/react': '@types/react':
optional: true optional: true
use-deep-compare-effect@1.8.1:
resolution: {integrity: sha512-kbeNVZ9Zkc0RFGpfMN3MNfaKNvcLNyxOAAd9O4CBZ+kCBXXscn9s/4I+8ytUER4RDpEYs5+O6Rs4PqiZ+rHr5Q==}
engines: {node: '>=10', npm: '>=6'}
peerDependencies:
react: '>=16.13'
use-sidecar@1.1.3: use-sidecar@1.1.3:
resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -4904,8 +4962,28 @@ snapshots:
'@emotion/hash@0.9.2': {} '@emotion/hash@0.9.2': {}
'@emotion/is-prop-valid@1.3.1':
dependencies:
'@emotion/memoize': 0.9.0
'@emotion/memoize@0.9.0': {} '@emotion/memoize@0.9.0': {}
'@emotion/react@11.14.0(@types/react@19.0.8)(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.7
'@emotion/babel-plugin': 11.13.5
'@emotion/cache': 11.14.0
'@emotion/serialize': 1.3.3
'@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.0.0)
'@emotion/utils': 1.4.2
'@emotion/weak-memoize': 0.4.0
hoist-non-react-statics: 3.3.2
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.8
transitivePeerDependencies:
- supports-color
'@emotion/serialize@1.3.3': '@emotion/serialize@1.3.3':
dependencies: dependencies:
'@emotion/hash': 0.9.2 '@emotion/hash': 0.9.2
@ -4916,8 +4994,27 @@ snapshots:
'@emotion/sheet@1.4.0': {} '@emotion/sheet@1.4.0': {}
'@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@19.0.0))(@types/react@19.0.8)(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.7
'@emotion/babel-plugin': 11.13.5
'@emotion/is-prop-valid': 1.3.1
'@emotion/react': 11.14.0(@types/react@19.0.8)(react@19.0.0)
'@emotion/serialize': 1.3.3
'@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.0.0)
'@emotion/utils': 1.4.2
react: 19.0.0
optionalDependencies:
'@types/react': 19.0.8
transitivePeerDependencies:
- supports-color
'@emotion/unitless@0.10.0': {} '@emotion/unitless@0.10.0': {}
'@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.0.0)':
dependencies:
react: 19.0.0
'@emotion/utils@1.4.2': {} '@emotion/utils@1.4.2': {}
'@emotion/weak-memoize@0.4.0': {} '@emotion/weak-memoize@0.4.0': {}
@ -5054,6 +5151,22 @@ snapshots:
dependencies: dependencies:
react: 19.0.0 react: 19.0.0
'@hookform/devtools@4.3.3(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@emotion/react': 11.14.0(@types/react@19.0.8)(react@19.0.0)
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@19.0.0))(@types/react@19.0.8)(react@19.0.0)
'@types/lodash': 4.17.16
little-state-machine: 4.8.1(react@19.0.0)
lodash: 4.17.21
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
react-simple-animate: 3.5.3(react-dom@19.0.0(react@19.0.0))
use-deep-compare-effect: 1.8.1(react@19.0.0)
uuid: 8.3.2
transitivePeerDependencies:
- '@types/react'
- supports-color
'@hookform/resolvers@4.1.1(react-hook-form@7.54.2(react@19.0.0))': '@hookform/resolvers@4.1.1(react-hook-form@7.54.2(react@19.0.0))':
dependencies: dependencies:
caniuse-lite: 1.0.30001700 caniuse-lite: 1.0.30001700
@ -5972,6 +6085,8 @@ snapshots:
'@types/linkify-it@5.0.0': {} '@types/linkify-it@5.0.0': {}
'@types/lodash@4.17.16': {}
'@types/markdown-it@14.1.2': '@types/markdown-it@14.1.2':
dependencies: dependencies:
'@types/linkify-it': 5.0.0 '@types/linkify-it': 5.0.0
@ -7207,12 +7322,13 @@ snapshots:
forwarded@0.2.0: {} forwarded@0.2.0: {}
framer-motion@11.18.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0): framer-motion@11.18.2(@emotion/is-prop-valid@1.3.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies: dependencies:
motion-dom: 11.18.1 motion-dom: 11.18.1
motion-utils: 11.18.1 motion-utils: 11.18.1
tslib: 2.8.1 tslib: 2.8.1
optionalDependencies: optionalDependencies:
'@emotion/is-prop-valid': 1.3.1
react: 19.0.0 react: 19.0.0
react-dom: 19.0.0(react@19.0.0) react-dom: 19.0.0(react@19.0.0)
@ -7370,6 +7486,10 @@ snapshots:
dependencies: dependencies:
function-bind: 1.1.2 function-bind: 1.1.2
hoist-non-react-statics@3.3.2:
dependencies:
react-is: 16.13.1
hosted-git-info@2.8.9: {} hosted-git-info@2.8.9: {}
hosted-git-info@6.1.3: hosted-git-info@6.1.3:
@ -7786,6 +7906,10 @@ snapshots:
rfdc: 1.4.1 rfdc: 1.4.1
wrap-ansi: 9.0.0 wrap-ansi: 9.0.0
little-state-machine@4.8.1(react@19.0.0):
dependencies:
react: 19.0.0
locate-path@5.0.0: locate-path@5.0.0:
dependencies: dependencies:
p-locate: 4.1.0 p-locate: 4.1.0
@ -8400,7 +8524,7 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/react': 19.0.8 '@types/react': 19.0.8
react-router-devtools@1.1.0(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react-router@7.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(vite@5.4.14(@types/node@20.17.16)(lightningcss@1.29.1)): react-router-devtools@1.1.0(@emotion/is-prop-valid@1.3.1)(@types/react-dom@19.0.3(@types/react@19.0.8))(@types/react@19.0.8)(react-dom@19.0.0(react@19.0.0))(react-router@7.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)(vite@5.4.14(@types/node@20.17.16)(lightningcss@1.29.1)):
dependencies: dependencies:
'@babel/core': 7.26.7 '@babel/core': 7.26.7
'@babel/generator': 7.26.5 '@babel/generator': 7.26.5
@ -8413,7 +8537,7 @@ snapshots:
chalk: 5.4.1 chalk: 5.4.1
clsx: 2.1.1 clsx: 2.1.1
date-fns: 4.1.0 date-fns: 4.1.0
framer-motion: 11.18.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) framer-motion: 11.18.2(@emotion/is-prop-valid@1.3.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react: 19.0.0 react: 19.0.0
react-d3-tree: 3.6.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react-d3-tree: 3.6.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react-diff-viewer-continued: 3.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react-diff-viewer-continued: 3.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@ -8440,6 +8564,10 @@ snapshots:
optionalDependencies: optionalDependencies:
react-dom: 19.0.0(react@19.0.0) react-dom: 19.0.0(react@19.0.0)
react-simple-animate@3.5.3(react-dom@19.0.0(react@19.0.0)):
dependencies:
react-dom: 19.0.0(react@19.0.0)
react-style-singleton@2.2.3(@types/react@19.0.8)(react@19.0.0): react-style-singleton@2.2.3(@types/react@19.0.8)(react@19.0.0):
dependencies: dependencies:
get-nonce: 1.0.1 get-nonce: 1.0.1
@ -9023,6 +9151,12 @@ snapshots:
optionalDependencies: optionalDependencies:
'@types/react': 19.0.8 '@types/react': 19.0.8
use-deep-compare-effect@1.8.1(react@19.0.0):
dependencies:
'@babel/runtime': 7.26.7
dequal: 2.0.3
react: 19.0.0
use-sidecar@1.1.3(@types/react@19.0.8)(react@19.0.0): use-sidecar@1.1.3(@types/react@19.0.8)(react@19.0.0):
dependencies: dependencies:
detect-node-es: 1.1.0 detect-node-es: 1.1.0