@komensal/ui 0.1.0 → 0.2.1
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.
- package/dist/index.d.ts +420 -0
- package/dist/index.js +1710 -0
- package/dist/index.js.map +1 -0
- package/dist/locales/index.d.ts +34 -0
- package/dist/locales/index.js +40 -0
- package/dist/locales/index.js.map +1 -0
- package/dist/styles/index.css +8 -0
- package/package.json +24 -8
- package/src/components/alert.tsx +0 -45
- package/src/components/auth-header.tsx +0 -26
- package/src/components/button.tsx +0 -121
- package/src/components/command.tsx +0 -125
- package/src/components/dialog.tsx +0 -118
- package/src/components/form-fields/index.ts +0 -5
- package/src/components/form-fields/input-field.tsx +0 -131
- package/src/components/form-fields/label-field.tsx +0 -20
- package/src/components/form-fields/map-picker-field.tsx +0 -49
- package/src/components/form-fields/otp-field.tsx +0 -76
- package/src/components/form-fields/select-field.tsx +0 -77
- package/src/components/form.tsx +0 -138
- package/src/components/google-map-picker.tsx +0 -243
- package/src/components/input.tsx +0 -40
- package/src/components/label.tsx +0 -17
- package/src/components/loading.tsx +0 -19
- package/src/components/otp-input.tsx +0 -62
- package/src/components/password-checklist.tsx +0 -37
- package/src/components/popover.tsx +0 -31
- package/src/components/select-input.tsx +0 -236
- package/src/components/select.tsx +0 -143
- package/src/components/spinner.tsx +0 -61
- package/src/components/step-header.tsx +0 -16
- package/src/components/stepper.tsx +0 -69
- package/src/components/toast/index.ts +0 -2
- package/src/components/toast/toast-provider.tsx +0 -123
- package/src/components/toast/toast.tsx +0 -106
- package/src/components/tooltip.tsx +0 -56
- package/src/components/wrapper.tsx +0 -12
- package/src/index.ts +0 -27
- package/src/locales/es/ui.json +0 -28
- package/src/locales/index.ts +0 -7
- package/src/styles/index.css +0 -1
- package/src/types/password.ts +0 -12
- package/src/types/toast.ts +0 -19
- package/src/utils/cn.ts +0 -6
- package/src/utils/index.ts +0 -3
- package/src/utils/styles.ts +0 -19
- package/src/utils/toast-emitter.ts +0 -37
- package/src/vite-env.d.ts +0 -3
- /package/{src → dist}/styles/theme.css +0 -0
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { type DialogProps } from '@radix-ui/react-dialog'
|
|
2
|
-
import { MagnifyingGlassIcon } from '@radix-ui/react-icons'
|
|
3
|
-
import { Command as CommandPrimitive } from 'cmdk'
|
|
4
|
-
import * as React from 'react'
|
|
5
|
-
|
|
6
|
-
import { cn } from '../utils'
|
|
7
|
-
import { Dialog, DialogContent } from './dialog'
|
|
8
|
-
|
|
9
|
-
const Command = React.forwardRef<
|
|
10
|
-
React.ElementRef<typeof CommandPrimitive>,
|
|
11
|
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive>
|
|
12
|
-
>(({ className, ...props }, ref) => (
|
|
13
|
-
<CommandPrimitive
|
|
14
|
-
className={cn('bg-surface text-foreground flex h-full w-full flex-col overflow-hidden rounded-md', className)}
|
|
15
|
-
ref={ref}
|
|
16
|
-
{...props}
|
|
17
|
-
/>
|
|
18
|
-
))
|
|
19
|
-
Command.displayName = CommandPrimitive.displayName
|
|
20
|
-
|
|
21
|
-
type CommandDialogProps = DialogProps
|
|
22
|
-
|
|
23
|
-
const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
|
|
24
|
-
return (
|
|
25
|
-
<Dialog {...props}>
|
|
26
|
-
<DialogContent className='overflow-hidden p-0'>
|
|
27
|
-
<Command className='**:[[cmdk-group-heading]]:text-muted [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5 **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group]]:px-2 **:[[cmdk-input]]:h-12 **:[[cmdk-item]]:px-2 **:[[cmdk-item]]:py-3'>
|
|
28
|
-
{children}
|
|
29
|
-
</Command>
|
|
30
|
-
</DialogContent>
|
|
31
|
-
</Dialog>
|
|
32
|
-
)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const CommandInput = React.forwardRef<
|
|
36
|
-
React.ElementRef<typeof CommandPrimitive.Input>,
|
|
37
|
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
|
|
38
|
-
>(({ className, ...props }, ref) => (
|
|
39
|
-
<div className='flex items-center border-b px-3' cmdk-input-wrapper=''>
|
|
40
|
-
<MagnifyingGlassIcon className='mr-2 h-4 w-4 shrink-0 opacity-50' />
|
|
41
|
-
<CommandPrimitive.Input
|
|
42
|
-
className={cn(
|
|
43
|
-
'placeholder:text-placeholder flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
|
44
|
-
className
|
|
45
|
-
)}
|
|
46
|
-
ref={ref}
|
|
47
|
-
{...props}
|
|
48
|
-
/>
|
|
49
|
-
</div>
|
|
50
|
-
))
|
|
51
|
-
|
|
52
|
-
CommandInput.displayName = CommandPrimitive.Input.displayName
|
|
53
|
-
|
|
54
|
-
const CommandList = React.forwardRef<
|
|
55
|
-
React.ElementRef<typeof CommandPrimitive.List>,
|
|
56
|
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
|
|
57
|
-
>(({ className, ...props }, ref) => (
|
|
58
|
-
<CommandPrimitive.List className={cn('max-h-75 overflow-x-hidden overflow-y-auto', className)} ref={ref} {...props} />
|
|
59
|
-
))
|
|
60
|
-
|
|
61
|
-
CommandList.displayName = CommandPrimitive.List.displayName
|
|
62
|
-
|
|
63
|
-
const CommandEmpty = React.forwardRef<
|
|
64
|
-
React.ElementRef<typeof CommandPrimitive.Empty>,
|
|
65
|
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
|
|
66
|
-
>((props, ref) => <CommandPrimitive.Empty className='py-6 text-center text-sm' ref={ref} {...props} />)
|
|
67
|
-
|
|
68
|
-
CommandEmpty.displayName = CommandPrimitive.Empty.displayName
|
|
69
|
-
|
|
70
|
-
const CommandGroup = React.forwardRef<
|
|
71
|
-
React.ElementRef<typeof CommandPrimitive.Group>,
|
|
72
|
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
|
|
73
|
-
>(({ className, ...props }, ref) => (
|
|
74
|
-
<CommandPrimitive.Group
|
|
75
|
-
className={cn(
|
|
76
|
-
'text-foreground **:[[cmdk-group-heading]]:text-muted overflow-hidden p-1 **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-xs **:[[cmdk-group-heading]]:font-medium',
|
|
77
|
-
className
|
|
78
|
-
)}
|
|
79
|
-
ref={ref}
|
|
80
|
-
{...props}
|
|
81
|
-
/>
|
|
82
|
-
))
|
|
83
|
-
|
|
84
|
-
CommandGroup.displayName = CommandPrimitive.Group.displayName
|
|
85
|
-
|
|
86
|
-
const CommandSeparator = React.forwardRef<
|
|
87
|
-
React.ElementRef<typeof CommandPrimitive.Separator>,
|
|
88
|
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
|
|
89
|
-
>(({ className, ...props }, ref) => (
|
|
90
|
-
<CommandPrimitive.Separator className={cn('bg-border -mx-1 h-px', className)} ref={ref} {...props} />
|
|
91
|
-
))
|
|
92
|
-
CommandSeparator.displayName = CommandPrimitive.Separator.displayName
|
|
93
|
-
|
|
94
|
-
const CommandItem = React.forwardRef<
|
|
95
|
-
React.ElementRef<typeof CommandPrimitive.Item>,
|
|
96
|
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
|
|
97
|
-
>(({ className, ...props }, ref) => (
|
|
98
|
-
<CommandPrimitive.Item
|
|
99
|
-
className={cn(
|
|
100
|
-
'relative flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50',
|
|
101
|
-
className
|
|
102
|
-
)}
|
|
103
|
-
ref={ref}
|
|
104
|
-
{...props}
|
|
105
|
-
/>
|
|
106
|
-
))
|
|
107
|
-
|
|
108
|
-
CommandItem.displayName = CommandPrimitive.Item.displayName
|
|
109
|
-
|
|
110
|
-
const CommandShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
|
|
111
|
-
return <span className={cn('text-muted ml-auto text-xs tracking-widest', className)} {...props} />
|
|
112
|
-
}
|
|
113
|
-
CommandShortcut.displayName = 'CommandShortcut'
|
|
114
|
-
|
|
115
|
-
export {
|
|
116
|
-
Command,
|
|
117
|
-
CommandDialog,
|
|
118
|
-
CommandEmpty,
|
|
119
|
-
CommandGroup,
|
|
120
|
-
CommandInput,
|
|
121
|
-
CommandItem,
|
|
122
|
-
CommandList,
|
|
123
|
-
CommandSeparator,
|
|
124
|
-
CommandShortcut
|
|
125
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import * as DialogPrimitive from '@radix-ui/react-dialog'
|
|
2
|
-
import { Cross2Icon } from '@radix-ui/react-icons'
|
|
3
|
-
import * as React from 'react'
|
|
4
|
-
import { useTranslation } from 'react-i18next'
|
|
5
|
-
|
|
6
|
-
import { cn } from '../utils'
|
|
7
|
-
|
|
8
|
-
const Dialog = DialogPrimitive.Root
|
|
9
|
-
|
|
10
|
-
const DialogTrigger = DialogPrimitive.Trigger
|
|
11
|
-
|
|
12
|
-
const DialogPortal = DialogPrimitive.Portal
|
|
13
|
-
|
|
14
|
-
const DialogClose = DialogPrimitive.Close
|
|
15
|
-
|
|
16
|
-
const DialogOverlay = React.forwardRef<
|
|
17
|
-
React.ElementRef<typeof DialogPrimitive.Overlay>,
|
|
18
|
-
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay> & { isAbsolute?: boolean }
|
|
19
|
-
>(({ className, isAbsolute = false, ...props }, ref) => (
|
|
20
|
-
<DialogPrimitive.Overlay
|
|
21
|
-
className={cn(
|
|
22
|
-
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 bg-foreground/10 z-60 backdrop-blur-xs',
|
|
23
|
-
isAbsolute ? 'absolute inset-0' : 'fixed inset-0',
|
|
24
|
-
className
|
|
25
|
-
)}
|
|
26
|
-
ref={ref}
|
|
27
|
-
{...props}
|
|
28
|
-
/>
|
|
29
|
-
))
|
|
30
|
-
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
|
|
31
|
-
|
|
32
|
-
interface DialogContentProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
|
|
33
|
-
container?: HTMLElement | null
|
|
34
|
-
isAbsolute?: boolean
|
|
35
|
-
isCloseIcon?: boolean
|
|
36
|
-
overlayClassName?: string
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const DialogContent = React.forwardRef<React.ElementRef<typeof DialogPrimitive.Content>, DialogContentProps>(
|
|
40
|
-
({ children, className, container, isAbsolute = false, isCloseIcon = false, overlayClassName, ...props }, ref) => {
|
|
41
|
-
const { t } = useTranslation('ui')
|
|
42
|
-
|
|
43
|
-
return (
|
|
44
|
-
<DialogPortal container={container}>
|
|
45
|
-
<DialogOverlay className={overlayClassName} isAbsolute={isAbsolute} />
|
|
46
|
-
|
|
47
|
-
<DialogPrimitive.Content
|
|
48
|
-
className={cn(
|
|
49
|
-
'bg-surface data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] z-70 grid w-[calc(100%-2rem)] max-w-lg translate-x-[-50%] translate-y-[-50%] gap-0 rounded-2xl p-6 px-0 shadow-lg duration-200 outline-none lg:px-0',
|
|
50
|
-
isAbsolute ? 'absolute top-[50%] left-[50%]' : 'fixed top-[50%] left-[50%]',
|
|
51
|
-
className
|
|
52
|
-
)}
|
|
53
|
-
ref={ref}
|
|
54
|
-
{...props}
|
|
55
|
-
>
|
|
56
|
-
{children}
|
|
57
|
-
{isCloseIcon && (
|
|
58
|
-
<DialogPrimitive.Close className='data-[state=open]:text-muted ring-offset-surface focus:ring-ring data-[state=open]:bg-hover border-border bg-border absolute top-11 right-8 flex h-8 w-8 min-w-8 cursor-pointer items-center justify-center rounded-full opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none disabled:pointer-events-none'>
|
|
59
|
-
<Cross2Icon className='text-body hover:text-primary-dark h-4 w-4' />
|
|
60
|
-
<span className='sr-only'>{t('dialog.close')}</span>
|
|
61
|
-
</DialogPrimitive.Close>
|
|
62
|
-
)}
|
|
63
|
-
</DialogPrimitive.Content>
|
|
64
|
-
</DialogPortal>
|
|
65
|
-
)
|
|
66
|
-
}
|
|
67
|
-
)
|
|
68
|
-
DialogContent.displayName = DialogPrimitive.Content.displayName
|
|
69
|
-
|
|
70
|
-
const DialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
|
71
|
-
<div className={cn('flex flex-col space-y-1.5 text-center sm:text-left', className)} {...props} />
|
|
72
|
-
)
|
|
73
|
-
DialogHeader.displayName = 'DialogHeader'
|
|
74
|
-
|
|
75
|
-
const DialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
|
76
|
-
<div
|
|
77
|
-
className={cn('flex flex-col-reverse justify-center rounded-2xl sm:flex-row sm:space-x-2', className)}
|
|
78
|
-
{...props}
|
|
79
|
-
/>
|
|
80
|
-
)
|
|
81
|
-
DialogFooter.displayName = 'DialogFooter'
|
|
82
|
-
|
|
83
|
-
const DialogTitle = React.forwardRef<
|
|
84
|
-
React.ElementRef<typeof DialogPrimitive.Title>,
|
|
85
|
-
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
|
86
|
-
>(({ className, ...props }, ref) => (
|
|
87
|
-
<DialogPrimitive.Title
|
|
88
|
-
className={cn('text-lg leading-none font-semibold tracking-tight', className)}
|
|
89
|
-
ref={ref}
|
|
90
|
-
{...props}
|
|
91
|
-
>
|
|
92
|
-
<span>{props.children}</span>
|
|
93
|
-
</DialogPrimitive.Title>
|
|
94
|
-
))
|
|
95
|
-
DialogTitle.displayName = DialogPrimitive.Title.displayName
|
|
96
|
-
|
|
97
|
-
const DialogDescription = React.forwardRef<
|
|
98
|
-
React.ElementRef<typeof DialogPrimitive.Description>,
|
|
99
|
-
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
|
100
|
-
>(({ className, ...props }, ref) => (
|
|
101
|
-
<DialogPrimitive.Description className={cn('text-muted text-sm', className)} ref={ref} {...props}>
|
|
102
|
-
<span>{props.children}</span>
|
|
103
|
-
</DialogPrimitive.Description>
|
|
104
|
-
))
|
|
105
|
-
DialogDescription.displayName = DialogPrimitive.Description.displayName
|
|
106
|
-
|
|
107
|
-
export {
|
|
108
|
-
Dialog,
|
|
109
|
-
DialogClose,
|
|
110
|
-
DialogContent,
|
|
111
|
-
DialogDescription,
|
|
112
|
-
DialogFooter,
|
|
113
|
-
DialogHeader,
|
|
114
|
-
DialogOverlay,
|
|
115
|
-
DialogPortal,
|
|
116
|
-
DialogTitle,
|
|
117
|
-
DialogTrigger
|
|
118
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { useState } from 'react'
|
|
2
|
-
import { Control, FieldValues, Path } from 'react-hook-form'
|
|
3
|
-
import { useTranslation } from 'react-i18next'
|
|
4
|
-
import { FaRegEye, FaRegEyeSlash } from 'react-icons/fa6'
|
|
5
|
-
import { RxCross2 } from 'react-icons/rx'
|
|
6
|
-
|
|
7
|
-
import { cn } from '../../utils'
|
|
8
|
-
import { FormControl, FormField, FormItem, FormMessage } from '../form'
|
|
9
|
-
import { Input } from '../input'
|
|
10
|
-
import { LabelField } from './label-field'
|
|
11
|
-
|
|
12
|
-
interface InputFieldProps<T extends FieldValues = FieldValues> {
|
|
13
|
-
control: Control<T>
|
|
14
|
-
disabled?: boolean
|
|
15
|
-
inputClassName?: string
|
|
16
|
-
isClearable?: boolean
|
|
17
|
-
label?: string
|
|
18
|
-
labelClassName?: string
|
|
19
|
-
mainClassName?: string
|
|
20
|
-
name: Path<T>
|
|
21
|
-
onClear?: () => void
|
|
22
|
-
placeholder?: string
|
|
23
|
-
type?: string
|
|
24
|
-
visualRequired?: boolean
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const InputField = <T extends FieldValues = FieldValues>({
|
|
28
|
-
control,
|
|
29
|
-
disabled,
|
|
30
|
-
inputClassName,
|
|
31
|
-
isClearable,
|
|
32
|
-
label,
|
|
33
|
-
labelClassName,
|
|
34
|
-
mainClassName,
|
|
35
|
-
name,
|
|
36
|
-
onClear,
|
|
37
|
-
placeholder,
|
|
38
|
-
type = 'text',
|
|
39
|
-
visualRequired
|
|
40
|
-
}: InputFieldProps<T>) => {
|
|
41
|
-
const { t } = useTranslation('ui')
|
|
42
|
-
const [isPasswordVisible, setIsPasswordVisible] = useState(false)
|
|
43
|
-
|
|
44
|
-
const togglePasswordVisibility = () => {
|
|
45
|
-
setIsPasswordVisible((prev) => !prev)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const isPassword = type === 'password'
|
|
49
|
-
const inputType = isPassword ? (isPasswordVisible ? 'text' : 'password') : type === 'plate' ? 'text' : type
|
|
50
|
-
|
|
51
|
-
const isPlate = type === 'plate'
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
<FormField
|
|
55
|
-
control={control}
|
|
56
|
-
name={name}
|
|
57
|
-
render={({ field, fieldState }) => {
|
|
58
|
-
const hasError = !!fieldState.error
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<FormItem className={cn('flex flex-col', mainClassName)}>
|
|
62
|
-
<LabelField
|
|
63
|
-
label={label}
|
|
64
|
-
labelClassName={cn(labelClassName, hasError && 'text-destructive')}
|
|
65
|
-
name={name}
|
|
66
|
-
visualRequired={visualRequired}
|
|
67
|
-
/>
|
|
68
|
-
<FormControl>
|
|
69
|
-
<div className='relative'>
|
|
70
|
-
<Input
|
|
71
|
-
{...field}
|
|
72
|
-
autoComplete={isPassword ? 'current-password' : undefined}
|
|
73
|
-
className={cn(
|
|
74
|
-
inputClassName,
|
|
75
|
-
isPlate && 'uppercase',
|
|
76
|
-
hasError && 'border-destructive',
|
|
77
|
-
isPassword && 'pr-10 [&::-ms-reveal]:hidden'
|
|
78
|
-
)}
|
|
79
|
-
data-no-password-toggle
|
|
80
|
-
disabled={disabled}
|
|
81
|
-
maxLength={isPlate ? 6 : undefined}
|
|
82
|
-
min={type === 'number' ? 0 : undefined}
|
|
83
|
-
onChange={(e) => {
|
|
84
|
-
let value = e.target.value
|
|
85
|
-
|
|
86
|
-
if (isPlate) {
|
|
87
|
-
value = value
|
|
88
|
-
.toUpperCase()
|
|
89
|
-
.replace(/[^A-Z0-9]/g, '')
|
|
90
|
-
.slice(0, 6)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
field.onChange(value)
|
|
94
|
-
}}
|
|
95
|
-
placeholder={placeholder}
|
|
96
|
-
type={inputType}
|
|
97
|
-
value={field.value ?? ''}
|
|
98
|
-
/>
|
|
99
|
-
|
|
100
|
-
<div className='absolute inset-y-0 right-0 flex items-center space-x-2 pr-2'>
|
|
101
|
-
{field.value && isClearable && (
|
|
102
|
-
<button
|
|
103
|
-
className='focus:outline-none'
|
|
104
|
-
onClick={onClear}
|
|
105
|
-
title={t('inputField.clear')}
|
|
106
|
-
type='button'
|
|
107
|
-
>
|
|
108
|
-
<RxCross2 size={18} />
|
|
109
|
-
</button>
|
|
110
|
-
)}
|
|
111
|
-
|
|
112
|
-
{type === 'password' && (
|
|
113
|
-
<button
|
|
114
|
-
className='focus:outline-none'
|
|
115
|
-
onClick={togglePasswordVisibility}
|
|
116
|
-
title={isPasswordVisible ? t('inputField.hidePassword') : t('inputField.showPassword')}
|
|
117
|
-
type='button'
|
|
118
|
-
>
|
|
119
|
-
{isPasswordVisible ? <FaRegEye size={18} /> : <FaRegEyeSlash size={20} />}
|
|
120
|
-
</button>
|
|
121
|
-
)}
|
|
122
|
-
</div>
|
|
123
|
-
</div>
|
|
124
|
-
</FormControl>
|
|
125
|
-
<FormMessage />
|
|
126
|
-
</FormItem>
|
|
127
|
-
)
|
|
128
|
-
}}
|
|
129
|
-
/>
|
|
130
|
-
)
|
|
131
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { cn } from '../../utils'
|
|
2
|
-
import { Label } from '../label'
|
|
3
|
-
|
|
4
|
-
interface LabelFieldProps {
|
|
5
|
-
label?: string
|
|
6
|
-
labelClassName?: string
|
|
7
|
-
name: string
|
|
8
|
-
visualRequired?: boolean
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const LabelField = ({ label, labelClassName, name, visualRequired }: LabelFieldProps) => {
|
|
12
|
-
return (
|
|
13
|
-
<Label
|
|
14
|
-
className={cn('text-body mb-2 text-start text-sm leading-none font-normal tracking-normal', labelClassName)}
|
|
15
|
-
htmlFor={name}
|
|
16
|
-
>
|
|
17
|
-
<span>{label}</span> {visualRequired && <span className='text-destructive'> *</span>}
|
|
18
|
-
</Label>
|
|
19
|
-
)
|
|
20
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { Control, FieldValues, Path } from 'react-hook-form'
|
|
2
|
-
|
|
3
|
-
import { cn } from '../../utils'
|
|
4
|
-
import { FormControl, FormField, FormItem, FormMessage } from '../form'
|
|
5
|
-
import { GoogleMapPicker, type GoogleMapPickerProps } from '../google-map-picker'
|
|
6
|
-
import { LabelField } from './label-field'
|
|
7
|
-
|
|
8
|
-
type MapPickerFieldProps<T extends FieldValues> = Omit<GoogleMapPickerProps, 'hasError' | 'onChange' | 'value'> & {
|
|
9
|
-
control: Control<T>
|
|
10
|
-
label?: string
|
|
11
|
-
labelClassName?: string
|
|
12
|
-
mainClassName?: string
|
|
13
|
-
name: Path<T>
|
|
14
|
-
visualRequired?: boolean
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const MapPickerField = <T extends FieldValues>({
|
|
18
|
-
control,
|
|
19
|
-
label,
|
|
20
|
-
labelClassName,
|
|
21
|
-
mainClassName,
|
|
22
|
-
name,
|
|
23
|
-
visualRequired,
|
|
24
|
-
...pickerProps
|
|
25
|
-
}: MapPickerFieldProps<T>) => (
|
|
26
|
-
<FormField
|
|
27
|
-
control={control}
|
|
28
|
-
name={name}
|
|
29
|
-
render={({ field, fieldState }) => (
|
|
30
|
-
<FormItem className={cn('flex flex-col', mainClassName)}>
|
|
31
|
-
<LabelField
|
|
32
|
-
label={label}
|
|
33
|
-
labelClassName={cn(labelClassName, fieldState.error && 'text-destructive')}
|
|
34
|
-
name={name}
|
|
35
|
-
visualRequired={visualRequired}
|
|
36
|
-
/>
|
|
37
|
-
<FormControl>
|
|
38
|
-
<GoogleMapPicker
|
|
39
|
-
{...pickerProps}
|
|
40
|
-
hasError={!!fieldState.error}
|
|
41
|
-
onChange={field.onChange}
|
|
42
|
-
value={field.value ?? ''}
|
|
43
|
-
/>
|
|
44
|
-
</FormControl>
|
|
45
|
-
<FormMessage />
|
|
46
|
-
</FormItem>
|
|
47
|
-
)}
|
|
48
|
-
/>
|
|
49
|
-
)
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { Control, FieldPath, FieldValues } from 'react-hook-form'
|
|
3
|
-
|
|
4
|
-
import { cn } from '../../utils'
|
|
5
|
-
import { FormControl, FormField, FormItem, FormMessage } from '../form'
|
|
6
|
-
import { Label } from '../label'
|
|
7
|
-
import { InputOTP, InputOTPGroup, InputOTPSlot } from '../otp-input'
|
|
8
|
-
|
|
9
|
-
interface OtpInputFormFieldProps<
|
|
10
|
-
TFieldValues extends FieldValues = FieldValues,
|
|
11
|
-
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
|
|
12
|
-
> {
|
|
13
|
-
autoFocus?: boolean
|
|
14
|
-
className?: string
|
|
15
|
-
containerClassName?: string
|
|
16
|
-
control: Control<TFieldValues>
|
|
17
|
-
disabled?: boolean
|
|
18
|
-
label?: string
|
|
19
|
-
labelClassName?: string
|
|
20
|
-
name: TName
|
|
21
|
-
otpLength?: number
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function OTPField<
|
|
25
|
-
TFieldValues extends FieldValues = FieldValues,
|
|
26
|
-
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
|
|
27
|
-
>({
|
|
28
|
-
autoFocus,
|
|
29
|
-
className,
|
|
30
|
-
containerClassName,
|
|
31
|
-
control,
|
|
32
|
-
disabled,
|
|
33
|
-
label,
|
|
34
|
-
labelClassName,
|
|
35
|
-
name,
|
|
36
|
-
otpLength = 6
|
|
37
|
-
}: OtpInputFormFieldProps<TFieldValues, TName>) {
|
|
38
|
-
return (
|
|
39
|
-
<FormField
|
|
40
|
-
control={control}
|
|
41
|
-
name={name}
|
|
42
|
-
render={({ field, fieldState }) => (
|
|
43
|
-
<FormItem className={cn('flex flex-col', className)}>
|
|
44
|
-
{label ? (
|
|
45
|
-
<Label className={cn('text-start text-sm font-semibold', labelClassName)} htmlFor={name}>
|
|
46
|
-
{label}
|
|
47
|
-
</Label>
|
|
48
|
-
) : null}
|
|
49
|
-
<FormControl>
|
|
50
|
-
<InputOTP
|
|
51
|
-
aria-invalid={fieldState.invalid || undefined}
|
|
52
|
-
autoComplete='one-time-code'
|
|
53
|
-
autoFocus={autoFocus}
|
|
54
|
-
containerClassName={cn('justify-center', containerClassName)}
|
|
55
|
-
disabled={disabled}
|
|
56
|
-
id={name}
|
|
57
|
-
inputMode='numeric'
|
|
58
|
-
maxLength={otpLength}
|
|
59
|
-
onChange={(val: string) => field.onChange(val)}
|
|
60
|
-
onPaste={(e: React.ClipboardEvent<HTMLInputElement>) => field.onChange(e.clipboardData.getData('text'))}
|
|
61
|
-
pattern='[0-9]*'
|
|
62
|
-
value={field.value ?? ''}
|
|
63
|
-
>
|
|
64
|
-
<InputOTPGroup>
|
|
65
|
-
{Array.from({ length: otpLength }).map((_, i) => (
|
|
66
|
-
<InputOTPSlot aria-invalid={fieldState.invalid || undefined} index={i} key={i} />
|
|
67
|
-
))}
|
|
68
|
-
</InputOTPGroup>
|
|
69
|
-
</InputOTP>
|
|
70
|
-
</FormControl>
|
|
71
|
-
<FormMessage />
|
|
72
|
-
</FormItem>
|
|
73
|
-
)}
|
|
74
|
-
/>
|
|
75
|
-
)
|
|
76
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { Control, FieldValues, Path } from 'react-hook-form'
|
|
2
|
-
|
|
3
|
-
import { cn } from '../../utils'
|
|
4
|
-
import { FormControl, FormField, FormItem, FormMessage } from '../form'
|
|
5
|
-
import { SelectInput } from '../select-input'
|
|
6
|
-
import { LabelField } from './label-field'
|
|
7
|
-
|
|
8
|
-
export interface Options {
|
|
9
|
-
label: string
|
|
10
|
-
value: number | string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface SelectFieldProps<T extends FieldValues = FieldValues> {
|
|
14
|
-
ableDeleteOption?: boolean
|
|
15
|
-
className?: string
|
|
16
|
-
control: Control<T>
|
|
17
|
-
disabled?: boolean
|
|
18
|
-
label?: string
|
|
19
|
-
labelClassName?: string
|
|
20
|
-
mainClassName?: string
|
|
21
|
-
name: Path<T>
|
|
22
|
-
onChange?: (...event: unknown[]) => void
|
|
23
|
-
options: Options[] | undefined
|
|
24
|
-
placeholder?: string
|
|
25
|
-
search?: boolean
|
|
26
|
-
visualRequired?: boolean
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export const SelectField = <T extends FieldValues = FieldValues>({
|
|
30
|
-
ableDeleteOption,
|
|
31
|
-
className,
|
|
32
|
-
control,
|
|
33
|
-
disabled,
|
|
34
|
-
label,
|
|
35
|
-
labelClassName,
|
|
36
|
-
mainClassName,
|
|
37
|
-
name,
|
|
38
|
-
options,
|
|
39
|
-
placeholder,
|
|
40
|
-
search,
|
|
41
|
-
visualRequired
|
|
42
|
-
}: SelectFieldProps<T>) => {
|
|
43
|
-
return (
|
|
44
|
-
<FormField
|
|
45
|
-
control={control}
|
|
46
|
-
name={name}
|
|
47
|
-
render={({ field, fieldState }) => {
|
|
48
|
-
const hasError = !!fieldState.error
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<FormItem className={cn('flex flex-col', mainClassName)}>
|
|
52
|
-
<LabelField
|
|
53
|
-
label={label}
|
|
54
|
-
labelClassName={cn(labelClassName, hasError && 'text-destructive')}
|
|
55
|
-
name={name}
|
|
56
|
-
visualRequired={visualRequired}
|
|
57
|
-
/>
|
|
58
|
-
<FormControl>
|
|
59
|
-
<SelectInput
|
|
60
|
-
ableDeleteOption={ableDeleteOption}
|
|
61
|
-
className={className}
|
|
62
|
-
disabled={disabled}
|
|
63
|
-
error={fieldState.error}
|
|
64
|
-
items={options}
|
|
65
|
-
onChange={field.onChange}
|
|
66
|
-
placeholder={placeholder}
|
|
67
|
-
search={search}
|
|
68
|
-
value={typeof field.value === 'number' ? `${field.value}` : field.value}
|
|
69
|
-
/>
|
|
70
|
-
</FormControl>
|
|
71
|
-
<FormMessage />
|
|
72
|
-
</FormItem>
|
|
73
|
-
)
|
|
74
|
-
}}
|
|
75
|
-
/>
|
|
76
|
-
)
|
|
77
|
-
}
|