@geckoui/geckoui 0.0.1-beta0
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/README.md +145 -0
- package/dist/components/Markdown/Markdown.css +138 -0
- package/dist/index.d.mts +4067 -0
- package/dist/index.d.ts +4067 -0
- package/dist/index.js +5405 -0
- package/dist/index.mjs +5383 -0
- package/dist/styles.css +3269 -0
- package/package.json +103 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,4067 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import react__default, { RefObject, SVGProps, ReactNode, FC, InputHTMLAttributes, JSX, ForwardedRef, LabelHTMLAttributes, PropsWithChildren, ButtonHTMLAttributes, DetailedHTMLProps, ReactElement, RefCallback, Dispatch, SetStateAction, HtmlHTMLAttributes, ChangeEvent, HTMLAttributes, JSXElementConstructor } from 'react';
|
|
3
|
+
import * as unified from 'unified';
|
|
4
|
+
import * as hast from 'hast';
|
|
5
|
+
import * as mdast from 'mdast';
|
|
6
|
+
import { ControllerProps, Control, FieldValues, ControllerRenderProps, ControllerFieldState, UseFormStateReturn } from 'react-hook-form';
|
|
7
|
+
import { Placement, Strategy, useFloating } from '@floating-ui/react';
|
|
8
|
+
import { TextareaAutosizeProps } from 'react-textarea-autosize';
|
|
9
|
+
import * as _headlessui_react from '@headlessui/react';
|
|
10
|
+
import { SwitchProps as SwitchProps$1, MenuItemsProps as MenuItemsProps$1, MenuButtonProps as MenuButtonProps$1, MenuItemProps as MenuItemProps$1 } from '@headlessui/react';
|
|
11
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
12
|
+
import { ToasterProps } from 'sonner';
|
|
13
|
+
export { toast } from 'sonner';
|
|
14
|
+
import { MermaidConfig } from 'mermaid';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Reuseable hook to detect clicks outside of a ref element that is passed as an argument
|
|
18
|
+
* @param handler - Function to be called when a click is detected outside of the component
|
|
19
|
+
* @param refs - Ref objects to be checked for clicks outside
|
|
20
|
+
* @returns void
|
|
21
|
+
* @example
|
|
22
|
+
*
|
|
23
|
+
* ```js
|
|
24
|
+
* const ref = useRef(null);
|
|
25
|
+
*
|
|
26
|
+
* useClickOutside(() => {
|
|
27
|
+
* console.log('Clicked outside');
|
|
28
|
+
* }, [ref]); // You can pass multiple refs
|
|
29
|
+
*
|
|
30
|
+
* return (
|
|
31
|
+
* <div ref={ref}>
|
|
32
|
+
* <h1>Click outside</h1>
|
|
33
|
+
* </div>
|
|
34
|
+
* );
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare const useClickOutside: <T extends HTMLElement>(handler?: (event: Event | MouseEvent | TouchEvent) => void, refs?: RefObject<T | null>[]) => void;
|
|
38
|
+
|
|
39
|
+
interface FilePickerFile extends File {
|
|
40
|
+
/** Preview URL of the file */
|
|
41
|
+
preview: string;
|
|
42
|
+
/**
|
|
43
|
+
* Path of the file in the file system
|
|
44
|
+
* These fields will be derived from the `webkitRelativePath` property if it exists
|
|
45
|
+
* if not it will be generated based on `directory` and `name` properties from directory picker
|
|
46
|
+
* */
|
|
47
|
+
path: string;
|
|
48
|
+
/**
|
|
49
|
+
* Name of the file in the file system
|
|
50
|
+
* Due to the fact `File.name` is read-only, we provide a way to edit the name of the file
|
|
51
|
+
* in case you need to rename the file before uploading it
|
|
52
|
+
* */
|
|
53
|
+
editableName: string;
|
|
54
|
+
}
|
|
55
|
+
type FileSize = number | string;
|
|
56
|
+
interface OpenFilePickerOptions {
|
|
57
|
+
/**
|
|
58
|
+
* If `directory` is false, whether to allow multiple files to be selected
|
|
59
|
+
*
|
|
60
|
+
* Default: true
|
|
61
|
+
* */
|
|
62
|
+
multiple?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Open directory picker instead of file picker
|
|
65
|
+
* */
|
|
66
|
+
directory?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Callback function that is called when the file picker changes
|
|
69
|
+
* */
|
|
70
|
+
onChangeStart?: () => void;
|
|
71
|
+
}
|
|
72
|
+
interface UseFilePickerOptions {
|
|
73
|
+
/**
|
|
74
|
+
* File types that can be accepted by the file picker
|
|
75
|
+
*
|
|
76
|
+
* Default: *
|
|
77
|
+
* */
|
|
78
|
+
accept?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Function to transform files before returning them
|
|
81
|
+
* */
|
|
82
|
+
transform?: (files: FilePickerFile[]) => Promise<FilePickerFile[]> | FilePickerFile[];
|
|
83
|
+
/**
|
|
84
|
+
* Whether to keep old files when the file picker changes
|
|
85
|
+
* If true, the file picker will keep old files when new files are selected
|
|
86
|
+
* And return all files selected so far
|
|
87
|
+
*
|
|
88
|
+
* Default: false
|
|
89
|
+
* */
|
|
90
|
+
keepOldFiles?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Whether to remove duplicated files if `keepOldFiles` is true
|
|
93
|
+
* If true, the file picker will remove duplicated files
|
|
94
|
+
*
|
|
95
|
+
* Default: false
|
|
96
|
+
* */
|
|
97
|
+
removeDuplicates?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Callback function that is called when the file picker changes
|
|
100
|
+
* */
|
|
101
|
+
onChange?: (
|
|
102
|
+
/** All files selected so far if `keepOldFiles` is true */
|
|
103
|
+
files: FilePickerFile[],
|
|
104
|
+
/** New files that are selected if */
|
|
105
|
+
newFiles: FilePickerFile[]) => Promise<void> | void;
|
|
106
|
+
/**
|
|
107
|
+
* Callback function that is called when the file picker starts
|
|
108
|
+
* */
|
|
109
|
+
onStart?: () => void;
|
|
110
|
+
/**
|
|
111
|
+
* Callback function that is called when the file picker encounters an error
|
|
112
|
+
* */
|
|
113
|
+
onError?: (error: Error) => void;
|
|
114
|
+
files?: FilePickerFile[];
|
|
115
|
+
setFiles?: (files: FilePickerFile[]) => void;
|
|
116
|
+
}
|
|
117
|
+
type OpenFilePickerFn = (options?: Omit<OpenFilePickerOptions, "onChangeStart">) => Promise<FilePickerFile[] | undefined>;
|
|
118
|
+
interface UseFilePickerReturn<T extends HTMLElement> {
|
|
119
|
+
/**
|
|
120
|
+
* Ref to the element that should be used as the dropzone
|
|
121
|
+
* */
|
|
122
|
+
dropzoneRef: RefObject<T | null>;
|
|
123
|
+
/** Whether the user is currently dragging files over the dropzone */
|
|
124
|
+
dragging: boolean;
|
|
125
|
+
/** Whether the dropzone is currently processing files */
|
|
126
|
+
loading: boolean;
|
|
127
|
+
/** Function to open the file picker */
|
|
128
|
+
openFilePicker: OpenFilePickerFn;
|
|
129
|
+
/**
|
|
130
|
+
* Files selected so far
|
|
131
|
+
* */
|
|
132
|
+
files: FilePickerFile[];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
type DataAttributeProps = Record<`data-${string}`, string>;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* A hook for handling file selection with drag-and-drop, file picker, and directory selection support.
|
|
139
|
+
*
|
|
140
|
+
* Selected files are enhanced with:
|
|
141
|
+
* - `preview`: Object URL for displaying file content
|
|
142
|
+
* - `path`: File system path (from directory picker)
|
|
143
|
+
* - `editableName`: Mutable name property
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```tsx
|
|
147
|
+
* const ImageUploader = () => {
|
|
148
|
+
* const [files, setFiles] = useState<FilePickerFile[]>([]);
|
|
149
|
+
* const { dropzoneRef, dragging, loading, openFilePicker } = useFilePicker({
|
|
150
|
+
* accept: "image/*",
|
|
151
|
+
* files,
|
|
152
|
+
* setFiles,
|
|
153
|
+
* keepOldFiles: true,
|
|
154
|
+
* onChange: (allFiles, newFiles) => console.log('Added:', newFiles.length),
|
|
155
|
+
* });
|
|
156
|
+
*
|
|
157
|
+
* const handleRemove = (preview: string) => {
|
|
158
|
+
* setFiles(files.filter((f) => f.preview !== preview));
|
|
159
|
+
* };
|
|
160
|
+
*
|
|
161
|
+
* return (
|
|
162
|
+
* <div className="flex flex-col gap-3">
|
|
163
|
+
* <div
|
|
164
|
+
* ref={dropzoneRef}
|
|
165
|
+
* onClick={() => openFilePicker()}
|
|
166
|
+
* className={`flex cursor-pointer items-center justify-center rounded-lg border-2 border-dashed p-4 ${
|
|
167
|
+
* dragging ? 'border-primary-400 bg-primary-50' : 'border-gray-300'
|
|
168
|
+
* }`}
|
|
169
|
+
* >
|
|
170
|
+
* <span>{dragging ? 'Drop images here' : 'Click to upload or drag and drop'}</span>
|
|
171
|
+
* {loading && <Spinner />}
|
|
172
|
+
* </div>
|
|
173
|
+
*
|
|
174
|
+
* {!!files.length && (
|
|
175
|
+
* <div className="grid grid-cols-4 gap-2">
|
|
176
|
+
* {files.map((file) => (
|
|
177
|
+
* <div key={file.preview} className="group relative aspect-square">
|
|
178
|
+
* <img src={file.preview} className="h-full w-full rounded-lg object-cover" />
|
|
179
|
+
* <button
|
|
180
|
+
* onClick={() => handleRemove(file.preview)}
|
|
181
|
+
* className="absolute -right-1 -top-1 rounded-full bg-red-500 p-1 text-white opacity-0 group-hover:opacity-100"
|
|
182
|
+
* >
|
|
183
|
+
* ✕
|
|
184
|
+
* </button>
|
|
185
|
+
* </div>
|
|
186
|
+
* ))}
|
|
187
|
+
* </div>
|
|
188
|
+
* )}
|
|
189
|
+
* </div>
|
|
190
|
+
* );
|
|
191
|
+
* };
|
|
192
|
+
* ```
|
|
193
|
+
* */
|
|
194
|
+
declare function useFilePicker<T extends HTMLElement>(options?: UseFilePickerOptions): UseFilePickerReturn<T>;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Prevents the default action of the function passed to it.
|
|
198
|
+
* It is useful when you want to prevent the default action of a function
|
|
199
|
+
* You can simply pass the function to `attachPreventDefault` and it will prevent running the function
|
|
200
|
+
* if you call `preventDefault` before it.
|
|
201
|
+
* Make sure you also expose the `preventDefault` function to the user so they can call it when needed.
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```js
|
|
205
|
+
* const { preventDefault, attachPreventDefault } = usePreventDefault();
|
|
206
|
+
*
|
|
207
|
+
* const onChange = () => {
|
|
208
|
+
* props.onChange({ preventDefault }); -> User can access preventDefault function
|
|
209
|
+
*
|
|
210
|
+
* // You can attach whatever function you want to prevent here
|
|
211
|
+
* attachPreventDefault(() => {
|
|
212
|
+
* // Do something
|
|
213
|
+
* console.log("Prevented");
|
|
214
|
+
* });
|
|
215
|
+
* };
|
|
216
|
+
*
|
|
217
|
+
* <MyComponent onChange={(e) => {
|
|
218
|
+
* e.preventDefault();
|
|
219
|
+
* // console.log("Prevented"); will not be called
|
|
220
|
+
* // because the function is attached to `attachPreventDefault`
|
|
221
|
+
* }} />
|
|
222
|
+
* ```
|
|
223
|
+
* */
|
|
224
|
+
declare const usePreventDefault: () => {
|
|
225
|
+
preventDefault: () => boolean;
|
|
226
|
+
attachPreventDefault: (fn: () => Promise<void> | void) => Promise<void>;
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Reuseable that listens to the `Escape` key press event on the document and calls the callback function when the event is triggered.
|
|
231
|
+
* This hooks won't trigger the callback if the focus is on an input or textarea element.
|
|
232
|
+
* This hooks will also take care of removing the event listener when the component is unmounted.
|
|
233
|
+
*
|
|
234
|
+
* Usage:
|
|
235
|
+
* ```js
|
|
236
|
+
* const MyDrawer = () => {
|
|
237
|
+
* const closeDrawer = () => console.log("Drawer closed");
|
|
238
|
+
*
|
|
239
|
+
* useDocumentEscListener(closeDrawer);
|
|
240
|
+
* }
|
|
241
|
+
* ```
|
|
242
|
+
* */
|
|
243
|
+
declare const useEscListener: (callback?: () => void) => void;
|
|
244
|
+
|
|
245
|
+
type MermaidDiagramBaseProps = Omit<SVGProps<SVGSVGElement>, "id" | "viewBox" | "dangerouslySetInnerHTML">;
|
|
246
|
+
interface MermaidDiagramProps extends MermaidDiagramBaseProps {
|
|
247
|
+
/**
|
|
248
|
+
* Placeholder component to show when the diagram is loading.
|
|
249
|
+
* */
|
|
250
|
+
placeholder?: ReactNode | FC;
|
|
251
|
+
/**
|
|
252
|
+
* Error component to show when the diagram fails to render.
|
|
253
|
+
* If not provided, a simple error message will be shown.
|
|
254
|
+
*
|
|
255
|
+
* ```js
|
|
256
|
+
* <MermaidDiagram error={({ message }) => ...}>
|
|
257
|
+
* ...
|
|
258
|
+
* </MermaidDiagram>
|
|
259
|
+
* ```
|
|
260
|
+
* */
|
|
261
|
+
renderError?: ReactNode | FC<{
|
|
262
|
+
message: string;
|
|
263
|
+
}>;
|
|
264
|
+
/**
|
|
265
|
+
* Mermaid template to render the diagram.
|
|
266
|
+
* */
|
|
267
|
+
children: string;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* useMermaidDiagram is a hook that takes a mermaid template and returns a React component that renders the diagram.
|
|
272
|
+
* It also handle `loading` and `error` states. You rarely need to use this hook directly, use `MermaidDiagram` component instead.
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
*
|
|
276
|
+
* ```js
|
|
277
|
+
* const template = `
|
|
278
|
+
* graph TD;
|
|
279
|
+
* A-->B;
|
|
280
|
+
* A-->C;
|
|
281
|
+
* B-->D;
|
|
282
|
+
* C-->D;
|
|
283
|
+
* `;
|
|
284
|
+
*
|
|
285
|
+
* const { loading, error, Diagram } = useMermaidDiagram(template);
|
|
286
|
+
*
|
|
287
|
+
* if (loading) return <p>Loading...</p>;
|
|
288
|
+
*
|
|
289
|
+
* if (error) return <p>Error: {error}</p>;
|
|
290
|
+
*
|
|
291
|
+
* return <Diagram />;
|
|
292
|
+
* ```
|
|
293
|
+
* */
|
|
294
|
+
declare const useMermaidDiagram: (template: string) => {
|
|
295
|
+
loading: boolean;
|
|
296
|
+
error: string;
|
|
297
|
+
Diagram: react.FC<MermaidDiagramBaseProps> | null;
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
interface MarkdownProcessorOptions {
|
|
301
|
+
/**
|
|
302
|
+
* Enable HTML sanitization to prevent XSS attacks.
|
|
303
|
+
* Only set to false when you 100% trust the source.
|
|
304
|
+
* @default true
|
|
305
|
+
*/
|
|
306
|
+
sanitize?: boolean;
|
|
307
|
+
}
|
|
308
|
+
declare const createMarkdownProcessor: (options?: MarkdownProcessorOptions) => unified.Processor<mdast.Root, mdast.Root, hast.Root, hast.Root, string>;
|
|
309
|
+
|
|
310
|
+
interface UseMarkdownOptions extends MarkdownProcessorOptions {
|
|
311
|
+
/**
|
|
312
|
+
* Render the markdown asynchronously for large markdown content.
|
|
313
|
+
* Not intended for network requests - use for processing large markdown strings.
|
|
314
|
+
* @default false
|
|
315
|
+
* */
|
|
316
|
+
async?: boolean;
|
|
317
|
+
}
|
|
318
|
+
declare const useMarkdown: (str: string, options?: UseMarkdownOptions) => {
|
|
319
|
+
content: string;
|
|
320
|
+
error?: undefined;
|
|
321
|
+
loading?: undefined;
|
|
322
|
+
} | {
|
|
323
|
+
error: string;
|
|
324
|
+
content?: undefined;
|
|
325
|
+
loading?: undefined;
|
|
326
|
+
} | {
|
|
327
|
+
loading: boolean;
|
|
328
|
+
error: string;
|
|
329
|
+
content: string;
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
interface RHFBaseProps {
|
|
333
|
+
/**
|
|
334
|
+
* Name of the input field.(required)
|
|
335
|
+
* This will injected into the RHF Controller.
|
|
336
|
+
* */
|
|
337
|
+
name: string;
|
|
338
|
+
rules?: ControllerProps["rules"];
|
|
339
|
+
/**
|
|
340
|
+
* React Hook Form control object.
|
|
341
|
+
* By default it will use the useFormContext() hook to get the control object.
|
|
342
|
+
* In case you want to use a custom control object, you can pass it here.
|
|
343
|
+
*
|
|
344
|
+
* Eg. You have multiple `FormProvider` in your app and you want to use a specific control object.
|
|
345
|
+
* */
|
|
346
|
+
control?: Control<any>;
|
|
347
|
+
}
|
|
348
|
+
interface RHFRenderArgs<T extends FieldValues> {
|
|
349
|
+
field: ControllerRenderProps<T>;
|
|
350
|
+
fieldState: ControllerFieldState;
|
|
351
|
+
formState: UseFormStateReturn<T>;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
|
|
355
|
+
/**
|
|
356
|
+
* If true, the checkbox will be checked with a IndeterminateIcon.
|
|
357
|
+
* */
|
|
358
|
+
partial?: boolean;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* A customizable checkbox component with support for indeterminate state.
|
|
363
|
+
*
|
|
364
|
+
* Renders a checkbox with custom styling and icons. By default, displays a check icon
|
|
365
|
+
* when checked. Use the `partial` prop to display an indeterminate icon, useful for
|
|
366
|
+
* "select all" scenarios where only some items are selected.
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```tsx
|
|
370
|
+
* // Basic usage
|
|
371
|
+
* const [checked, setChecked] = useState(false);
|
|
372
|
+
* <Checkbox
|
|
373
|
+
* checked={checked}
|
|
374
|
+
* onChange={(e) => setChecked(e.target.checked)}
|
|
375
|
+
* />
|
|
376
|
+
*
|
|
377
|
+
* // Indeterminate state
|
|
378
|
+
* <Checkbox
|
|
379
|
+
* checked={someSelected}
|
|
380
|
+
* partial={someSelected && !allSelected}
|
|
381
|
+
* onChange={handleSelectAll}
|
|
382
|
+
* />
|
|
383
|
+
*
|
|
384
|
+
* // With label
|
|
385
|
+
* <label className="flex items-center gap-2">
|
|
386
|
+
* <Checkbox
|
|
387
|
+
* checked={agreed}
|
|
388
|
+
* onChange={(e) => setAgreed(e.target.checked)}
|
|
389
|
+
* />
|
|
390
|
+
* <span>I agree to the terms</span>
|
|
391
|
+
* </label>
|
|
392
|
+
*
|
|
393
|
+
* // Disabled state
|
|
394
|
+
* <Checkbox checked disabled />
|
|
395
|
+
* ```
|
|
396
|
+
*/
|
|
397
|
+
declare const Checkbox: react.ForwardRefExoticComponent<CheckboxProps & react.RefAttributes<HTMLInputElement>>;
|
|
398
|
+
|
|
399
|
+
type DateFormat$2 = "DD/MM/YYYY" | "MM/DD/YYYY" | "YYYY/MM/DD";
|
|
400
|
+
interface BaseDateInputProps {
|
|
401
|
+
value?: string | null;
|
|
402
|
+
onChange?: (value: string | null) => void;
|
|
403
|
+
onSubmit?: () => void;
|
|
404
|
+
onStateUpdate?: (state: {
|
|
405
|
+
day: string;
|
|
406
|
+
month: string;
|
|
407
|
+
year: string;
|
|
408
|
+
}) => void;
|
|
409
|
+
disabled?: boolean;
|
|
410
|
+
readOnly?: boolean;
|
|
411
|
+
prefix?: FC | ReactNode;
|
|
412
|
+
suffix?: FC | ReactNode;
|
|
413
|
+
hasError?: boolean;
|
|
414
|
+
className?: string;
|
|
415
|
+
format?: DateFormat$2;
|
|
416
|
+
separator?: string;
|
|
417
|
+
placeholder?: string;
|
|
418
|
+
placeholderClassName?: string;
|
|
419
|
+
hideClearIcon?: boolean;
|
|
420
|
+
hideCalendarIcon?: boolean;
|
|
421
|
+
renderCalendarIcon?: ReactNode;
|
|
422
|
+
hasFocus?: boolean;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
type DateFormat$1 = "DD/MM/YYYY" | "MM/DD/YYYY" | "YYYY/MM/DD";
|
|
426
|
+
interface DateInputProps extends Omit<BaseDateInputProps, "hasFocus" | "renderCalendarIcon"> {
|
|
427
|
+
/**
|
|
428
|
+
* Whether to hide the calendar popup. When false (default), calendar will be shown.
|
|
429
|
+
* @default false
|
|
430
|
+
*/
|
|
431
|
+
hideCalendar?: boolean;
|
|
432
|
+
/**
|
|
433
|
+
* Additional CSS class name for the wrapper div that contains input field and calendar
|
|
434
|
+
*/
|
|
435
|
+
wrapperClassName?: string;
|
|
436
|
+
/**
|
|
437
|
+
* Additional CSS class name for the calendar component
|
|
438
|
+
*/
|
|
439
|
+
calendarClassName?: string;
|
|
440
|
+
/**
|
|
441
|
+
* Placement of the calendar popup relative to the input
|
|
442
|
+
* @default "bottom-start"
|
|
443
|
+
*/
|
|
444
|
+
calendarPlacement?: Placement;
|
|
445
|
+
/**
|
|
446
|
+
* Floating strategy for the calendar positioning
|
|
447
|
+
* @default "absolute"
|
|
448
|
+
*/
|
|
449
|
+
floatingStrategy?: Strategy;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* DateInput is an accessible date picker component that provides an intuitive keyboard-driven
|
|
454
|
+
* interface for date entry. It features intelligent auto-completion, cross-field validation,
|
|
455
|
+
* and support for multiple date formats (DD/MM/YYYY, MM/DD/YYYY, YYYY/MM/DD).
|
|
456
|
+
*
|
|
457
|
+
* The component emits ISO 8601 formatted dates (YYYY-MM-DD) while displaying dates in the
|
|
458
|
+
* user's preferred format. It automatically handles leap years, month-specific day limits,
|
|
459
|
+
* and validates date segments in real-time.
|
|
460
|
+
*
|
|
461
|
+
* @example
|
|
462
|
+
* Form integration with validation:
|
|
463
|
+
*
|
|
464
|
+
* ```tsx
|
|
465
|
+
* const [birthDate, setBirthDate] = useState<string | null>(null);
|
|
466
|
+
* const [error, setError] = useState(false);
|
|
467
|
+
*
|
|
468
|
+
* const handleDateChange = (isoDate: string | null) => {
|
|
469
|
+
* setBirthDate(isoDate);
|
|
470
|
+
*
|
|
471
|
+
* if (isoDate) {
|
|
472
|
+
* const age = calculateAge(isoDate);
|
|
473
|
+
* setError(age < 18);
|
|
474
|
+
* }
|
|
475
|
+
* };
|
|
476
|
+
*
|
|
477
|
+
* <DateInput
|
|
478
|
+
* value={birthDate}
|
|
479
|
+
* onChange={handleDateChange}
|
|
480
|
+
* hasError={error}
|
|
481
|
+
* placeholder="Enter your birth date"
|
|
482
|
+
* format="DD/MM/YYYY"
|
|
483
|
+
* separator="/"
|
|
484
|
+
* prefix={<CalendarIcon />}
|
|
485
|
+
* />
|
|
486
|
+
* ```
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* European format with custom styling:
|
|
490
|
+
*
|
|
491
|
+
* ```tsx
|
|
492
|
+
* <DateInput
|
|
493
|
+
* value="2024-12-25"
|
|
494
|
+
* onChange={(date) => updateEvent({ startDate: date })}
|
|
495
|
+
* format="DD/MM/YYYY"
|
|
496
|
+
* separator="."
|
|
497
|
+
* className="w-full border-2 rounded-lg"
|
|
498
|
+
* placeholderClassName="text-gray-400"
|
|
499
|
+
* disabled={isProcessing}
|
|
500
|
+
* />
|
|
501
|
+
* ```
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* Date range picker with state synchronization:
|
|
505
|
+
*
|
|
506
|
+
* ```tsx
|
|
507
|
+
* const [startDate, setStartDate] = useState("");
|
|
508
|
+
* const [endDate, setEndDate] = useState("");
|
|
509
|
+
*
|
|
510
|
+
* <div className="flex gap-4">
|
|
511
|
+
* <DateInput
|
|
512
|
+
* value={startDate}
|
|
513
|
+
* onChange={setStartDate}
|
|
514
|
+
* placeholder="Start date"
|
|
515
|
+
* onSubmit={() => endDateRef.current?.focus()}
|
|
516
|
+
* hideClearIcon
|
|
517
|
+
* />
|
|
518
|
+
* <DateInput
|
|
519
|
+
* ref={endDateRef}
|
|
520
|
+
* value={endDate}
|
|
521
|
+
* onChange={setEndDate}
|
|
522
|
+
* placeholder="End date"
|
|
523
|
+
* hasError={endDate < startDate}
|
|
524
|
+
* hideCalendarIcon
|
|
525
|
+
* />
|
|
526
|
+
* </div>
|
|
527
|
+
* ```
|
|
528
|
+
*
|
|
529
|
+
* @example
|
|
530
|
+
* Read-only display with custom icons:
|
|
531
|
+
*
|
|
532
|
+
* ```tsx
|
|
533
|
+
* <DateInput
|
|
534
|
+
* value="2024-01-15"
|
|
535
|
+
* readOnly
|
|
536
|
+
* suffix={<LockIcon />}
|
|
537
|
+
* className="bg-gray-100"
|
|
538
|
+
* hideClearIcon
|
|
539
|
+
* onStateUpdate={({ month, day, year }) => {
|
|
540
|
+
* logDateSegmentInteraction({ month, day, year });
|
|
541
|
+
* }}
|
|
542
|
+
* />
|
|
543
|
+
* ```
|
|
544
|
+
*/
|
|
545
|
+
declare const DateInput: FC<DateInputProps>;
|
|
546
|
+
|
|
547
|
+
type SelectionMode = "single" | "range";
|
|
548
|
+
interface DateRange {
|
|
549
|
+
from: string | null;
|
|
550
|
+
to?: string | null;
|
|
551
|
+
}
|
|
552
|
+
interface DayCellRenderProps {
|
|
553
|
+
day: number;
|
|
554
|
+
month: number;
|
|
555
|
+
year: number;
|
|
556
|
+
/** Date string in the format 'YYYY-MM-DD' */
|
|
557
|
+
date: string;
|
|
558
|
+
isDisabled: boolean;
|
|
559
|
+
isSelected: boolean;
|
|
560
|
+
/** Indicates if the date belongs to the currently focused month */
|
|
561
|
+
isFocusedMonth: boolean;
|
|
562
|
+
}
|
|
563
|
+
interface CalendarActiveProps {
|
|
564
|
+
/**
|
|
565
|
+
* Year value that is selected in the date picker
|
|
566
|
+
* */
|
|
567
|
+
activeYear: number;
|
|
568
|
+
/**
|
|
569
|
+
* Month value index that is selected in the date picker
|
|
570
|
+
* */
|
|
571
|
+
activeMonth: number;
|
|
572
|
+
}
|
|
573
|
+
interface BaseCalendarProps {
|
|
574
|
+
/**
|
|
575
|
+
* Ref object that is used to call the `moveTo` function
|
|
576
|
+
* */
|
|
577
|
+
calendarRef?: React.Ref<CalendarRef>;
|
|
578
|
+
/**
|
|
579
|
+
* Style object for the calendar container
|
|
580
|
+
* */
|
|
581
|
+
style?: React.CSSProperties;
|
|
582
|
+
/**
|
|
583
|
+
* Style class name for the date picker container
|
|
584
|
+
* */
|
|
585
|
+
className?: string;
|
|
586
|
+
/**
|
|
587
|
+
* Callback function that determines whether a date is disabled or not
|
|
588
|
+
* */
|
|
589
|
+
disableDate?: (date: string) => boolean;
|
|
590
|
+
/**
|
|
591
|
+
* Custom day cell renderer function
|
|
592
|
+
* Use this to customize the appearance of individual day cells
|
|
593
|
+
* */
|
|
594
|
+
renderDayCell?: (props: DayCellRenderProps) => ReactNode;
|
|
595
|
+
}
|
|
596
|
+
interface CalendarSingleModeProps extends BaseCalendarProps {
|
|
597
|
+
/**
|
|
598
|
+
* Selection mode: 'single' for single date selection
|
|
599
|
+
* @default 'single'
|
|
600
|
+
* */
|
|
601
|
+
mode?: "single";
|
|
602
|
+
/**
|
|
603
|
+
* Selected date in the format YYYY-MM-DD
|
|
604
|
+
* */
|
|
605
|
+
selectedDate?: string | null;
|
|
606
|
+
/**
|
|
607
|
+
* Callback function that is called when a date is clicked
|
|
608
|
+
* */
|
|
609
|
+
onSelectDate?: (date: string) => void;
|
|
610
|
+
}
|
|
611
|
+
interface CalendarRangeModeProps extends BaseCalendarProps {
|
|
612
|
+
/**
|
|
613
|
+
* Selection mode: 'range' for date range selection
|
|
614
|
+
* */
|
|
615
|
+
mode: "range";
|
|
616
|
+
/**
|
|
617
|
+
* Selected date range with from and to dates
|
|
618
|
+
* */
|
|
619
|
+
selectedRange?: DateRange;
|
|
620
|
+
/**
|
|
621
|
+
* Callback function that is called when a date range is selected
|
|
622
|
+
* */
|
|
623
|
+
onSelectRange?: (range: DateRange | null) => void;
|
|
624
|
+
/**
|
|
625
|
+
* Number of months to display side by side
|
|
626
|
+
* @default 2
|
|
627
|
+
* */
|
|
628
|
+
numberOfMonths?: 1 | 2;
|
|
629
|
+
}
|
|
630
|
+
type CalendarProps = CalendarSingleModeProps | CalendarRangeModeProps;
|
|
631
|
+
interface CalendarOverload {
|
|
632
|
+
(props: CalendarSingleModeProps): JSX.Element;
|
|
633
|
+
(props: CalendarRangeModeProps): JSX.Element;
|
|
634
|
+
(props: CalendarProps): JSX.Element;
|
|
635
|
+
displayName: string;
|
|
636
|
+
}
|
|
637
|
+
interface CalendarRef {
|
|
638
|
+
/**
|
|
639
|
+
* Moves the date picker to the specified month and year
|
|
640
|
+
* */
|
|
641
|
+
moveTo: (month: number, year: number) => void;
|
|
642
|
+
/**
|
|
643
|
+
* Clears the current selection
|
|
644
|
+
* */
|
|
645
|
+
clearSelection: () => void;
|
|
646
|
+
}
|
|
647
|
+
declare enum CalendarType {
|
|
648
|
+
Day = "day",
|
|
649
|
+
Month = "month",
|
|
650
|
+
Year = "year"
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
type DateFormat = "DD/MM/YYYY" | "MM/DD/YYYY" | "YYYY/MM/DD";
|
|
654
|
+
interface BaseDateRangeInputProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange" | "onBlur" | "prefix" | "onSubmit"> {
|
|
655
|
+
value?: DateRange;
|
|
656
|
+
onChange?: (value: DateRange | null) => void;
|
|
657
|
+
onSubmit?: () => void;
|
|
658
|
+
onStateUpdate?: (state: {
|
|
659
|
+
startDay: string;
|
|
660
|
+
startMonth: string;
|
|
661
|
+
startYear: string;
|
|
662
|
+
endDay: string;
|
|
663
|
+
endMonth: string;
|
|
664
|
+
endYear: string;
|
|
665
|
+
}) => void;
|
|
666
|
+
disabled?: boolean;
|
|
667
|
+
readOnly?: boolean;
|
|
668
|
+
prefix?: FC | ReactNode;
|
|
669
|
+
suffix?: FC | ReactNode;
|
|
670
|
+
hasError?: boolean;
|
|
671
|
+
className?: string;
|
|
672
|
+
format?: DateFormat;
|
|
673
|
+
separator?: string;
|
|
674
|
+
rangeSeparator?: string;
|
|
675
|
+
placeholder?: string;
|
|
676
|
+
placeholderClassName?: string;
|
|
677
|
+
hideClearIcon?: boolean;
|
|
678
|
+
hideCalendarIcon?: boolean;
|
|
679
|
+
renderCalendarIcon?: ReactNode;
|
|
680
|
+
hasFocus?: boolean;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
declare const BaseDateRangeInput: FC<BaseDateRangeInputProps>;
|
|
684
|
+
|
|
685
|
+
interface DateRangeInputProps extends Omit<BaseDateRangeInputProps, "hasFocus" | "renderCalendarIcon"> {
|
|
686
|
+
hideCalendar?: boolean;
|
|
687
|
+
wrapperClassName?: string;
|
|
688
|
+
calendarClassName?: string;
|
|
689
|
+
calendarPlacement?: Placement;
|
|
690
|
+
floatingStrategy?: Strategy;
|
|
691
|
+
numberOfMonths?: 1 | 2;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
declare const DateRangeInput: FC<DateRangeInputProps>;
|
|
695
|
+
|
|
696
|
+
interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "prefix"> {
|
|
697
|
+
/**
|
|
698
|
+
* Class name actual input element.
|
|
699
|
+
* `className` is used for the container div.
|
|
700
|
+
* So if you want to style the input element, eg. placeholder, or even the input itself, use this prop.
|
|
701
|
+
* */
|
|
702
|
+
inputClassName?: string;
|
|
703
|
+
/**
|
|
704
|
+
* Component to render before the input element.
|
|
705
|
+
*/
|
|
706
|
+
prefix?: FC<{
|
|
707
|
+
inputRef: ForwardedRef<HTMLInputElement>;
|
|
708
|
+
}> | ReactNode;
|
|
709
|
+
/**
|
|
710
|
+
* Component to render after the input element.
|
|
711
|
+
*/
|
|
712
|
+
suffix?: FC<{
|
|
713
|
+
inputRef: ForwardedRef<HTMLInputElement>;
|
|
714
|
+
}> | ReactNode;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* A flexible input component with support for prefix and suffix elements.
|
|
719
|
+
*
|
|
720
|
+
* The prefix, suffix, and input elements automatically adjust their width based on content.
|
|
721
|
+
* Use `inputClassName` to style the input element itself (e.g., placeholder styles).
|
|
722
|
+
* Use `className` to style the container that wraps the prefix, input, and suffix.
|
|
723
|
+
*
|
|
724
|
+
* @example
|
|
725
|
+
* ```tsx
|
|
726
|
+
* // Basic input
|
|
727
|
+
* <Input placeholder="Enter your name" />
|
|
728
|
+
*
|
|
729
|
+
* // With prefix (icon or text)
|
|
730
|
+
* <Input
|
|
731
|
+
* prefix={<SearchIcon />}
|
|
732
|
+
* placeholder="Search..."
|
|
733
|
+
* />
|
|
734
|
+
*
|
|
735
|
+
* // With suffix
|
|
736
|
+
* <Input
|
|
737
|
+
* type="email"
|
|
738
|
+
* suffix="@example.com"
|
|
739
|
+
* placeholder="username"
|
|
740
|
+
* />
|
|
741
|
+
*
|
|
742
|
+
* // With both prefix and suffix
|
|
743
|
+
* <Input
|
|
744
|
+
* prefix="$"
|
|
745
|
+
* suffix=".00"
|
|
746
|
+
* type="number"
|
|
747
|
+
* placeholder="0"
|
|
748
|
+
* />
|
|
749
|
+
*
|
|
750
|
+
* // Custom styling
|
|
751
|
+
* <Input
|
|
752
|
+
* className="border-blue-500"
|
|
753
|
+
* inputClassName="placeholder:text-gray-400"
|
|
754
|
+
* placeholder="Custom styled input"
|
|
755
|
+
* />
|
|
756
|
+
*
|
|
757
|
+
* // Disabled state
|
|
758
|
+
* <Input disabled placeholder="Disabled input" />
|
|
759
|
+
* ```
|
|
760
|
+
*/
|
|
761
|
+
declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
|
|
762
|
+
|
|
763
|
+
interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {
|
|
764
|
+
/**
|
|
765
|
+
* If true, adds a red asterisk to the label to indicate that the input is required
|
|
766
|
+
* ---
|
|
767
|
+
* **Note**: This is just a visual indicator and does not enforce any validation
|
|
768
|
+
* */
|
|
769
|
+
required?: boolean;
|
|
770
|
+
/**
|
|
771
|
+
* If you pass a string, exclamation icon will be displayed next to the label
|
|
772
|
+
* and the string will be displayed as a tooltip when hovered over the icon
|
|
773
|
+
* */
|
|
774
|
+
tooltip?: string;
|
|
775
|
+
/**
|
|
776
|
+
* Custom icon to display as a tooltip
|
|
777
|
+
* */
|
|
778
|
+
tooltipIcon?: FC | ReactNode;
|
|
779
|
+
/**
|
|
780
|
+
* Background color of the tooltip
|
|
781
|
+
* */
|
|
782
|
+
tooltipBackgroundColor?: string;
|
|
783
|
+
/**
|
|
784
|
+
* Class name for the tooltip
|
|
785
|
+
* */
|
|
786
|
+
tooltipClassName?: string;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* A label component for input fields with support for required indicators and tooltips.
|
|
791
|
+
*
|
|
792
|
+
* When the `required` prop is true, displays a red asterisk (*) after the label text.
|
|
793
|
+
* When the `tooltip` prop is provided, displays a tooltip icon with the specified content.
|
|
794
|
+
* You can customize the tooltip icon using the `tooltipIcon` prop.
|
|
795
|
+
*
|
|
796
|
+
* @example
|
|
797
|
+
* ```tsx
|
|
798
|
+
* // Basic label
|
|
799
|
+
* <Label htmlFor="username">Username</Label>
|
|
800
|
+
*
|
|
801
|
+
* // Required field
|
|
802
|
+
* <Label htmlFor="email" required>
|
|
803
|
+
* Email Address
|
|
804
|
+
* </Label>
|
|
805
|
+
*
|
|
806
|
+
* // With tooltip
|
|
807
|
+
* <Label
|
|
808
|
+
* htmlFor="password"
|
|
809
|
+
* tooltip="Password must be at least 8 characters long"
|
|
810
|
+
* >
|
|
811
|
+
* Password
|
|
812
|
+
* </Label>
|
|
813
|
+
*
|
|
814
|
+
* // Required with tooltip
|
|
815
|
+
* <Label
|
|
816
|
+
* htmlFor="apiKey"
|
|
817
|
+
* required
|
|
818
|
+
* tooltip="You can find your API key in the settings page"
|
|
819
|
+
* >
|
|
820
|
+
* API Key
|
|
821
|
+
* </Label>
|
|
822
|
+
*
|
|
823
|
+
* // Custom tooltip icon and styling
|
|
824
|
+
* <Label
|
|
825
|
+
* htmlFor="info"
|
|
826
|
+
* tooltip="Additional information"
|
|
827
|
+
* tooltipIcon={InfoIcon}
|
|
828
|
+
* tooltipBackgroundColor="blue"
|
|
829
|
+
* tooltipClassName="custom-tooltip"
|
|
830
|
+
* >
|
|
831
|
+
* Information
|
|
832
|
+
* </Label>
|
|
833
|
+
* ```
|
|
834
|
+
*/
|
|
835
|
+
declare const Label: FC<LabelProps>;
|
|
836
|
+
|
|
837
|
+
interface InputErrorProps extends React.HTMLAttributes<HTMLDivElement>, PropsWithChildren {
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* A component for displaying error messages below input fields.
|
|
842
|
+
*
|
|
843
|
+
* This is a simple div with default error styling, typically used to show
|
|
844
|
+
* validation errors or other feedback related to form inputs.
|
|
845
|
+
*
|
|
846
|
+
* @example
|
|
847
|
+
* ```tsx
|
|
848
|
+
* // Basic error message
|
|
849
|
+
* <InputError>This field is required</InputError>
|
|
850
|
+
*
|
|
851
|
+
* // With form validation
|
|
852
|
+
* <div>
|
|
853
|
+
* <Input type="email" />
|
|
854
|
+
* {errors.email && (
|
|
855
|
+
* <InputError>{errors.email.message}</InputError>
|
|
856
|
+
* )}
|
|
857
|
+
* </div>
|
|
858
|
+
*
|
|
859
|
+
* // Multiple errors
|
|
860
|
+
* <div>
|
|
861
|
+
* <Input type="password" />
|
|
862
|
+
* {errors.password && (
|
|
863
|
+
* <InputError>
|
|
864
|
+
* {errors.password.type === 'required'
|
|
865
|
+
* ? 'Password is required'
|
|
866
|
+
* : 'Password must be at least 8 characters'
|
|
867
|
+
* }
|
|
868
|
+
* </InputError>
|
|
869
|
+
* )}
|
|
870
|
+
* </div>
|
|
871
|
+
*
|
|
872
|
+
* // Custom styling
|
|
873
|
+
* <InputError className="text-red-600 font-semibold">
|
|
874
|
+
* Custom styled error
|
|
875
|
+
* </InputError>
|
|
876
|
+
* ```
|
|
877
|
+
*/
|
|
878
|
+
declare const InputError: FC<InputErrorProps>;
|
|
879
|
+
|
|
880
|
+
/** Extensible variant map - To allow module augmentation */
|
|
881
|
+
interface ButtonVariantMap {
|
|
882
|
+
filled: unknown;
|
|
883
|
+
outlined: unknown;
|
|
884
|
+
ghost: unknown;
|
|
885
|
+
icon: unknown;
|
|
886
|
+
}
|
|
887
|
+
/** Extensible color map - To allow module augmentation */
|
|
888
|
+
interface ButtonColorMap {
|
|
889
|
+
primary: unknown;
|
|
890
|
+
}
|
|
891
|
+
/** Extensible size map - To allow module augmentation */
|
|
892
|
+
interface ButtonSizeMap {
|
|
893
|
+
xs: unknown;
|
|
894
|
+
sm: unknown;
|
|
895
|
+
md: unknown;
|
|
896
|
+
lg: unknown;
|
|
897
|
+
xl: unknown;
|
|
898
|
+
}
|
|
899
|
+
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
900
|
+
/**
|
|
901
|
+
* Button variant to display.(Default: 'filled')
|
|
902
|
+
* */
|
|
903
|
+
variant?: keyof ButtonVariantMap;
|
|
904
|
+
/**
|
|
905
|
+
* Button color to display.(Default: 'primary')
|
|
906
|
+
* */
|
|
907
|
+
color?: keyof ButtonColorMap;
|
|
908
|
+
/**
|
|
909
|
+
* Button size to display.(Default: 'md')
|
|
910
|
+
* */
|
|
911
|
+
size?: keyof ButtonSizeMap;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* A flexible button component that extends the native HTML button with customizable styles.
|
|
916
|
+
*
|
|
917
|
+
* Supports different variants (filled, outlined, ghost, icon), sizes (sm, md, lg), and colors.
|
|
918
|
+
* All styling is applied via TailwindCSS classes, which can be overridden using the `className` prop.
|
|
919
|
+
*
|
|
920
|
+
* By default, the button adds spacing between child elements. You can override this by
|
|
921
|
+
* passing custom gap classes.
|
|
922
|
+
*
|
|
923
|
+
* @example
|
|
924
|
+
* ```tsx
|
|
925
|
+
* // Basic usage
|
|
926
|
+
* <Button variant="outlined" size="md">
|
|
927
|
+
* Add
|
|
928
|
+
* </Button>
|
|
929
|
+
*
|
|
930
|
+
* // With different variants
|
|
931
|
+
* <Button variant="filled">Save</Button>
|
|
932
|
+
* <Button variant="outlined">Cancel</Button>
|
|
933
|
+
* <Button variant="ghost">Learn More</Button>
|
|
934
|
+
*
|
|
935
|
+
* // Custom styling
|
|
936
|
+
* <Button
|
|
937
|
+
* variant="filled"
|
|
938
|
+
* size="sm"
|
|
939
|
+
* className="bg-cyan-500 gap-4 px-4 py-2 disabled:text-red-500"
|
|
940
|
+
* >
|
|
941
|
+
* <span>+</span>
|
|
942
|
+
* <span>Add</span>
|
|
943
|
+
* </Button>
|
|
944
|
+
*
|
|
945
|
+
* // Disabled state
|
|
946
|
+
* <Button disabled>Disabled Button</Button>
|
|
947
|
+
* ```
|
|
948
|
+
*/
|
|
949
|
+
declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
950
|
+
|
|
951
|
+
interface LoadingButtonProps extends ButtonProps {
|
|
952
|
+
/**
|
|
953
|
+
* If `true`, the button will be displayed in a loading state.
|
|
954
|
+
* */
|
|
955
|
+
loading?: boolean;
|
|
956
|
+
/**
|
|
957
|
+
* The position of the loading spinner.
|
|
958
|
+
* */
|
|
959
|
+
spinnerPosition?: "start" | "end";
|
|
960
|
+
/**
|
|
961
|
+
* The text to display when the button is in the loading state.
|
|
962
|
+
* */
|
|
963
|
+
loadingText?: string;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* LoadingButton extends the Button component with built-in loading state visualization.
|
|
968
|
+
* Automatically displays a spinner and optional loading text while preventing user interaction
|
|
969
|
+
* during asynchronous operations.
|
|
970
|
+
*
|
|
971
|
+
* @example
|
|
972
|
+
* Form submission with loading state:
|
|
973
|
+
*
|
|
974
|
+
* ```tsx
|
|
975
|
+
* const [isSubmitting, setIsSubmitting] = useState(false);
|
|
976
|
+
*
|
|
977
|
+
* const handleSubmit = async () => {
|
|
978
|
+
* setIsSubmitting(true);
|
|
979
|
+
* await saveFormData();
|
|
980
|
+
* setIsSubmitting(false);
|
|
981
|
+
* };
|
|
982
|
+
*
|
|
983
|
+
* <LoadingButton
|
|
984
|
+
* loading={isSubmitting}
|
|
985
|
+
* loadingText="Saving..."
|
|
986
|
+
* onClick={handleSubmit}
|
|
987
|
+
* >
|
|
988
|
+
* Save Changes
|
|
989
|
+
* </LoadingButton>
|
|
990
|
+
* ```
|
|
991
|
+
*
|
|
992
|
+
* @example
|
|
993
|
+
* Spinner at end position:
|
|
994
|
+
*
|
|
995
|
+
* ```tsx
|
|
996
|
+
* <LoadingButton
|
|
997
|
+
* loading={isProcessing}
|
|
998
|
+
* spinnerPosition="end"
|
|
999
|
+
* variant="outlined"
|
|
1000
|
+
* size="lg"
|
|
1001
|
+
* >
|
|
1002
|
+
* Process Payment
|
|
1003
|
+
* </LoadingButton>
|
|
1004
|
+
* ```
|
|
1005
|
+
*
|
|
1006
|
+
* @example
|
|
1007
|
+
* Without loading text (keeps original label):
|
|
1008
|
+
*
|
|
1009
|
+
* ```tsx
|
|
1010
|
+
* <LoadingButton loading={isDeleting} color="danger">
|
|
1011
|
+
* Delete Account
|
|
1012
|
+
* </LoadingButton>
|
|
1013
|
+
* ```
|
|
1014
|
+
*/
|
|
1015
|
+
declare const LoadingButton: FC<LoadingButtonProps>;
|
|
1016
|
+
|
|
1017
|
+
interface RHFCheckboxProps extends RHFBaseProps, Omit<CheckboxProps, "name" | "value" | "onChange" | "partial"> {
|
|
1018
|
+
/**
|
|
1019
|
+
* Label that will be displayed next to the checkbox
|
|
1020
|
+
* */
|
|
1021
|
+
label?: string | FC | ReactNode;
|
|
1022
|
+
/**
|
|
1023
|
+
* Additional class name to be added to the label
|
|
1024
|
+
* */
|
|
1025
|
+
labelClassName?: string;
|
|
1026
|
+
/**
|
|
1027
|
+
* Value to set in the form data when the switch is toggled
|
|
1028
|
+
* If value is not provided, value will be toggled between true and false
|
|
1029
|
+
* */
|
|
1030
|
+
value?: unknown;
|
|
1031
|
+
/**
|
|
1032
|
+
* Make the checkbox as single selection
|
|
1033
|
+
* If single is true, form data will be set with the value provided
|
|
1034
|
+
*
|
|
1035
|
+
* Eg. If value is 'a', form data will be set with 'a' when checkbox is checked
|
|
1036
|
+
*
|
|
1037
|
+
* By default, form data will be set with an array of values
|
|
1038
|
+
* */
|
|
1039
|
+
single?: boolean;
|
|
1040
|
+
/**
|
|
1041
|
+
* Value to set in the form data when the checkbox is unchecked
|
|
1042
|
+
* **Works only when `single` is true**
|
|
1043
|
+
* */
|
|
1044
|
+
uncheckedValue?: unknown;
|
|
1045
|
+
/**
|
|
1046
|
+
* Callback fired when the value changes
|
|
1047
|
+
* */
|
|
1048
|
+
onChange?: (value: unknown) => void;
|
|
1049
|
+
/**
|
|
1050
|
+
* Prop to check if the checkbox is partially checked
|
|
1051
|
+
* You can pass boolean or a function that returns a boolean
|
|
1052
|
+
* You can access the renderProps object from RHF to get the field, fieldState, and formState objects
|
|
1053
|
+
*
|
|
1054
|
+
* ---
|
|
1055
|
+
* @example
|
|
1056
|
+
* ```js
|
|
1057
|
+
* <>
|
|
1058
|
+
* <RHFCheckbox
|
|
1059
|
+
* name="checkbox"
|
|
1060
|
+
* value="js"
|
|
1061
|
+
* partial={({ field }) => field.value.length !== 2}
|
|
1062
|
+
* label="JavaScript"
|
|
1063
|
+
* />
|
|
1064
|
+
* <RHFCheckbox
|
|
1065
|
+
* name="checkbox"
|
|
1066
|
+
* value="ts"
|
|
1067
|
+
* partial={({ field }) => field.value.length !== 2}
|
|
1068
|
+
* label="TypeScript"
|
|
1069
|
+
* />
|
|
1070
|
+
* </>
|
|
1071
|
+
* ```
|
|
1072
|
+
* */
|
|
1073
|
+
partial?: boolean | ((args: RHFRenderArgs<Record<string, unknown>>) => boolean);
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
/**
|
|
1077
|
+
* A controlled checkbox component for React Hook Form that preserves value types.
|
|
1078
|
+
*
|
|
1079
|
+
* Unlike native checkboxes that convert values to strings, this component maintains
|
|
1080
|
+
* the original data type. Supports both single-select (like a radio) and multi-select
|
|
1081
|
+
* modes with optional indeterminate state.
|
|
1082
|
+
*
|
|
1083
|
+
* - **Single mode**: Acts like a radio button, stores one value or uncheckedValue
|
|
1084
|
+
* - **Multi mode** (default): Stores an array of selected values
|
|
1085
|
+
*
|
|
1086
|
+
* @example
|
|
1087
|
+
* ```tsx
|
|
1088
|
+
* // Single checkbox - stores "single" or undefined
|
|
1089
|
+
* <RHFCheckbox
|
|
1090
|
+
* name="agreement"
|
|
1091
|
+
* value="agreed"
|
|
1092
|
+
* label="I agree to terms"
|
|
1093
|
+
* single
|
|
1094
|
+
* />
|
|
1095
|
+
*
|
|
1096
|
+
* // Single with custom unchecked value
|
|
1097
|
+
* <RHFCheckbox
|
|
1098
|
+
* name="enabled"
|
|
1099
|
+
* value="yes"
|
|
1100
|
+
* uncheckedValue="no"
|
|
1101
|
+
* label="Enable feature"
|
|
1102
|
+
* single
|
|
1103
|
+
* />
|
|
1104
|
+
*
|
|
1105
|
+
* // Multi-select checkboxes - stores array like ["multi1", "multi2"]
|
|
1106
|
+
* <div>
|
|
1107
|
+
* <RHFCheckbox name="options" value="multi1" label="Option 1" />
|
|
1108
|
+
* <RHFCheckbox name="options" value="multi2" label="Option 2" />
|
|
1109
|
+
* <RHFCheckbox name="options" value="multi3" label="Option 3" />
|
|
1110
|
+
* </div>
|
|
1111
|
+
*
|
|
1112
|
+
* // With indeterminate state
|
|
1113
|
+
* <RHFCheckbox
|
|
1114
|
+
* name="languages"
|
|
1115
|
+
* value="js"
|
|
1116
|
+
* partial={({ field }) => field.value.length !== 2}
|
|
1117
|
+
* label="JavaScript"
|
|
1118
|
+
* />
|
|
1119
|
+
*
|
|
1120
|
+
* // With objects or complex types
|
|
1121
|
+
* <RHFCheckbox
|
|
1122
|
+
* name="settings"
|
|
1123
|
+
* value={{ feature: "advanced", enabled: true }}
|
|
1124
|
+
* label="Advanced Features"
|
|
1125
|
+
* single
|
|
1126
|
+
* />
|
|
1127
|
+
* ```
|
|
1128
|
+
*/
|
|
1129
|
+
declare const RHFCheckbox: FC<RHFCheckboxProps>;
|
|
1130
|
+
|
|
1131
|
+
interface InputTransformer {
|
|
1132
|
+
input?: (value: string) => string;
|
|
1133
|
+
output?: (value: string) => string;
|
|
1134
|
+
}
|
|
1135
|
+
interface RHFInputProps extends RHFBaseProps, Omit<InputProps, "name" | "prefix" | "suffix" | "onChange" | "onBlur"> {
|
|
1136
|
+
/**
|
|
1137
|
+
* This transform object allows you to transform the input value before it is passed to the form.
|
|
1138
|
+
* You can also transform the output value before it is passed to the input element.
|
|
1139
|
+
*
|
|
1140
|
+
* This is the recommended way of transforming in React Hook Form.
|
|
1141
|
+
* See the documentation for more information: https://react-hook-form.com/advanced-usage#TransformandParse
|
|
1142
|
+
* */
|
|
1143
|
+
transform?: InputTransformer;
|
|
1144
|
+
/**
|
|
1145
|
+
* Component to render before the input element.
|
|
1146
|
+
*
|
|
1147
|
+
* You can pass a function that returns a ReactNode or a ReactNode.
|
|
1148
|
+
* If you pass a Function, it will have access to the renderProps object.
|
|
1149
|
+
* So that you can access the field, fieldState, and formState objects.
|
|
1150
|
+
* You can build your prefix component based on these objects.
|
|
1151
|
+
*
|
|
1152
|
+
* @example
|
|
1153
|
+
* ```js
|
|
1154
|
+
* <RHFInput
|
|
1155
|
+
* name="name"
|
|
1156
|
+
* prefix={({ field }) => <span>{field.value}</span>}
|
|
1157
|
+
* />
|
|
1158
|
+
* ```
|
|
1159
|
+
* */
|
|
1160
|
+
prefix?: ControllerProps["render"] | ReactNode | string;
|
|
1161
|
+
/**
|
|
1162
|
+
* Component to render after the input element.
|
|
1163
|
+
* You can pass a function that returns a ReactNode or a ReactNode.
|
|
1164
|
+
* If you pass a Function, it will have access to the renderProps object.
|
|
1165
|
+
* So that you can access the field, fieldState, and formState objects.
|
|
1166
|
+
* You can build your suffix component based on these objects.
|
|
1167
|
+
*
|
|
1168
|
+
* @example
|
|
1169
|
+
* ```js
|
|
1170
|
+
* <RHFInput
|
|
1171
|
+
* name="name"
|
|
1172
|
+
* suffix={({ fieldState }) =>
|
|
1173
|
+
* fieldState.error ? <ErrorIcon /> : null
|
|
1174
|
+
* }
|
|
1175
|
+
* />
|
|
1176
|
+
* ```
|
|
1177
|
+
* */
|
|
1178
|
+
suffix?: ControllerProps["render"] | ReactNode | string;
|
|
1179
|
+
/**
|
|
1180
|
+
* Callback fired when the value changes
|
|
1181
|
+
* This is the actual value of the input not the event object
|
|
1182
|
+
* */
|
|
1183
|
+
onChange?: (value: string | null) => void;
|
|
1184
|
+
/**
|
|
1185
|
+
* Callback fired when the input is blurred
|
|
1186
|
+
* */
|
|
1187
|
+
onBlur?: (value: string) => void;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
/**
|
|
1191
|
+
* An input component integrated with React Hook Form.
|
|
1192
|
+
*
|
|
1193
|
+
* Automatically displays error states with a red border when validation fails.
|
|
1194
|
+
* Supports value transformation for input/output formatting.
|
|
1195
|
+
*
|
|
1196
|
+
* @example
|
|
1197
|
+
* ```tsx
|
|
1198
|
+
* // Basic usage
|
|
1199
|
+
* <RHFInput name="username" />
|
|
1200
|
+
*
|
|
1201
|
+
* // With prefix and suffix
|
|
1202
|
+
* <RHFInput
|
|
1203
|
+
* name="amount"
|
|
1204
|
+
* prefix="$"
|
|
1205
|
+
* suffix="USD"
|
|
1206
|
+
* />
|
|
1207
|
+
*
|
|
1208
|
+
* // Value transformation (e.g., formatting phone numbers)
|
|
1209
|
+
* <RHFInput
|
|
1210
|
+
* name="phone"
|
|
1211
|
+
* transform={{
|
|
1212
|
+
* input: (value) => formatPhoneNumber(value),
|
|
1213
|
+
* output: (value) => sanitizePhoneNumber(value)
|
|
1214
|
+
* }}
|
|
1215
|
+
* />
|
|
1216
|
+
*
|
|
1217
|
+
* // Custom error icon in suffix
|
|
1218
|
+
* <RHFInput
|
|
1219
|
+
* name="email"
|
|
1220
|
+
* suffix={({ fieldState }) =>
|
|
1221
|
+
* fieldState.error ? <ErrorIcon /> : null
|
|
1222
|
+
* }
|
|
1223
|
+
* />
|
|
1224
|
+
* ```
|
|
1225
|
+
*/
|
|
1226
|
+
declare const RHFInput: FC<RHFInputProps>;
|
|
1227
|
+
|
|
1228
|
+
type RHFErrorRenderProps = ControllerFieldState;
|
|
1229
|
+
interface RHFErrorProps extends RHFBaseProps {
|
|
1230
|
+
/**
|
|
1231
|
+
* Class name to be applied on the error message.
|
|
1232
|
+
* Only applicable when `render` prop is not provided.
|
|
1233
|
+
* */
|
|
1234
|
+
className?: string;
|
|
1235
|
+
/**
|
|
1236
|
+
* To customize the error message.
|
|
1237
|
+
* If not provided, default error message will be displayed.
|
|
1238
|
+
*
|
|
1239
|
+
* @example
|
|
1240
|
+
* ```js
|
|
1241
|
+
* <RHFError
|
|
1242
|
+
* name="email"
|
|
1243
|
+
* render={({ error }) => {
|
|
1244
|
+
* return (
|
|
1245
|
+
* <div className="flex items-center space-x-2">
|
|
1246
|
+
* <ExclamationCircleIcon className="h-5 w-5 text-red-500" />
|
|
1247
|
+
* <span className="text-sm font-normal text-red-600">{error}</span>
|
|
1248
|
+
* </div>
|
|
1249
|
+
* );
|
|
1250
|
+
* }}
|
|
1251
|
+
* />
|
|
1252
|
+
* ```
|
|
1253
|
+
* */
|
|
1254
|
+
render?: ReactNode | ((props: RHFErrorRenderProps) => JSX.Element);
|
|
1255
|
+
/**
|
|
1256
|
+
* @deprecated - Use `render` prop instead
|
|
1257
|
+
* */
|
|
1258
|
+
children?: ReactNode;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
/**
|
|
1262
|
+
* A component for displaying form field error messages with React Hook Form.
|
|
1263
|
+
*
|
|
1264
|
+
* Automatically shows validation error messages for the specified field.
|
|
1265
|
+
* Supports custom rendering and styling of error messages.
|
|
1266
|
+
*
|
|
1267
|
+
* @example
|
|
1268
|
+
* ```tsx
|
|
1269
|
+
* // Basic usage
|
|
1270
|
+
* <RHFError name="email" />
|
|
1271
|
+
*
|
|
1272
|
+
* // With custom styling
|
|
1273
|
+
* <RHFError name="email" className="font-bold text-red-700" />
|
|
1274
|
+
*
|
|
1275
|
+
* // Custom error rendering with icon
|
|
1276
|
+
* <RHFError
|
|
1277
|
+
* name="email"
|
|
1278
|
+
* render={({ error }) => {
|
|
1279
|
+
* return (
|
|
1280
|
+
* <div className="flex items-center space-x-2">
|
|
1281
|
+
* <ExclamationCircleIcon className="h-5 w-5 text-red-500" />
|
|
1282
|
+
* <span className="text-sm font-normal text-red-600">
|
|
1283
|
+
* {error?.message}
|
|
1284
|
+
* </span>
|
|
1285
|
+
* </div>
|
|
1286
|
+
* );
|
|
1287
|
+
* }}
|
|
1288
|
+
* />
|
|
1289
|
+
*
|
|
1290
|
+
* // Multiple fields with errors
|
|
1291
|
+
* <div>
|
|
1292
|
+
* <Input name="username" />
|
|
1293
|
+
* <RHFError name="username" />
|
|
1294
|
+
*
|
|
1295
|
+
* <Input name="email" />
|
|
1296
|
+
* <RHFError name="email" />
|
|
1297
|
+
* </div>
|
|
1298
|
+
* ```
|
|
1299
|
+
*/
|
|
1300
|
+
declare const RHFError: FC<RHFErrorProps>;
|
|
1301
|
+
|
|
1302
|
+
interface RHFInputGroupProps extends LabelProps, PropsWithChildren {
|
|
1303
|
+
/**
|
|
1304
|
+
* Label for the input group
|
|
1305
|
+
* */
|
|
1306
|
+
label?: string;
|
|
1307
|
+
/**
|
|
1308
|
+
* Class name for the label element
|
|
1309
|
+
* */
|
|
1310
|
+
labelClassName?: string;
|
|
1311
|
+
/**
|
|
1312
|
+
* Class name for the input group that wraps the label, children, and error message
|
|
1313
|
+
* */
|
|
1314
|
+
className?: string;
|
|
1315
|
+
/**
|
|
1316
|
+
* Error message class name
|
|
1317
|
+
* */
|
|
1318
|
+
errorClassName?: string;
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
/**
|
|
1322
|
+
* RHFInputGroup combines a form field label, input component, and error message into a cohesive unit.
|
|
1323
|
+
* Automatically detects RHF input components in children (even nested) and extracts their name and control
|
|
1324
|
+
* to display validation errors. Reduces boilerplate for standard form field layouts.
|
|
1325
|
+
*
|
|
1326
|
+
* **Note:** This is a layout convenience component. For custom layouts, use Label and RHFError separately.
|
|
1327
|
+
*
|
|
1328
|
+
* @example
|
|
1329
|
+
* Standard form field:
|
|
1330
|
+
*
|
|
1331
|
+
* ```tsx
|
|
1332
|
+
* <RHFInputGroup label="Email Address" required>
|
|
1333
|
+
* <RHFInput
|
|
1334
|
+
* name="email"
|
|
1335
|
+
* type="email"
|
|
1336
|
+
* placeholder="you@example.com"
|
|
1337
|
+
* />
|
|
1338
|
+
* </RHFInputGroup>
|
|
1339
|
+
* ```
|
|
1340
|
+
*
|
|
1341
|
+
* @example
|
|
1342
|
+
* Field with helper text (nested structure):
|
|
1343
|
+
*
|
|
1344
|
+
* ```tsx
|
|
1345
|
+
* <RHFInputGroup
|
|
1346
|
+
* label="Password"
|
|
1347
|
+
* required
|
|
1348
|
+
* tooltip="Must be at least 12 characters"
|
|
1349
|
+
* >
|
|
1350
|
+
* <div className="space-y-2">
|
|
1351
|
+
* <RHFInput name="password" type="password" />
|
|
1352
|
+
* <ul className="text-sm text-gray-600">
|
|
1353
|
+
* <li>✓ At least 8 characters</li>
|
|
1354
|
+
* <li>✓ Include a number</li>
|
|
1355
|
+
* <li>✓ Include a special character</li>
|
|
1356
|
+
* </ul>
|
|
1357
|
+
* </div>
|
|
1358
|
+
* </RHFInputGroup>
|
|
1359
|
+
* ```
|
|
1360
|
+
*
|
|
1361
|
+
* @example
|
|
1362
|
+
* Multiple inputs (only first input's errors shown):
|
|
1363
|
+
*
|
|
1364
|
+
* ```tsx
|
|
1365
|
+
* <RHFInputGroup label="Phone Number">
|
|
1366
|
+
* <div className="flex gap-2">
|
|
1367
|
+
* <RHFInput name="countryCode" placeholder="+1" className="w-20" />
|
|
1368
|
+
* <RHFInput name="phoneNumber" placeholder="555-0100" />
|
|
1369
|
+
* </div>
|
|
1370
|
+
* </RHFInputGroup>
|
|
1371
|
+
* ```
|
|
1372
|
+
*/
|
|
1373
|
+
declare const RHFInputGroup: FC<RHFInputGroupProps>;
|
|
1374
|
+
|
|
1375
|
+
interface RHFNumberInputProps extends RHFInputProps {
|
|
1376
|
+
/**
|
|
1377
|
+
* If true, the input will only accept positive numbers
|
|
1378
|
+
* i.e numbers cannot start with a negative sign (-)
|
|
1379
|
+
* Default: false
|
|
1380
|
+
* */
|
|
1381
|
+
positiveOnly?: boolean;
|
|
1382
|
+
/**
|
|
1383
|
+
* If true, the input will only accept valid numbers
|
|
1384
|
+
* i.e numbers cannot start with zero except for zero and decimal numbers
|
|
1385
|
+
*
|
|
1386
|
+
* Example: 000123.45 is invalid
|
|
1387
|
+
* Example: 123.45 or 0.45 is valid
|
|
1388
|
+
* */
|
|
1389
|
+
strict?: boolean;
|
|
1390
|
+
/**
|
|
1391
|
+
* Max number of decimal places
|
|
1392
|
+
* Example: 123.45 has 2 decimal places
|
|
1393
|
+
* */
|
|
1394
|
+
maxFractionDigits?: number;
|
|
1395
|
+
/**
|
|
1396
|
+
* Max number of whole digit places
|
|
1397
|
+
* Example: 123.45 has 3 whole digit places
|
|
1398
|
+
* */
|
|
1399
|
+
maxWholeDigitPlaces?: number;
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
/**
|
|
1403
|
+
* React hook form controlled number input.
|
|
1404
|
+
* This input only allows numbers and a single decimal point.
|
|
1405
|
+
* You can specify the maximum number of decimal places and whole digit places.
|
|
1406
|
+
* By default the input is strict, meaning it will remove leading zeros and convert into valid numbers.
|
|
1407
|
+
* You can disable this behavior by setting the `strict` prop to `false`.
|
|
1408
|
+
*
|
|
1409
|
+
* @example
|
|
1410
|
+
* ```tsx
|
|
1411
|
+
* // Basic number input
|
|
1412
|
+
* <RHFNumberInput name="balance" />
|
|
1413
|
+
*
|
|
1414
|
+
* // Integer only (no decimals)
|
|
1415
|
+
* <RHFNumberInput
|
|
1416
|
+
* name="quantity"
|
|
1417
|
+
* maxFractionDigits={0}
|
|
1418
|
+
* />
|
|
1419
|
+
*
|
|
1420
|
+
* // Room numbers with leading zeros allowed
|
|
1421
|
+
* <RHFNumberInput
|
|
1422
|
+
* name="roomNumber"
|
|
1423
|
+
* strict={false}
|
|
1424
|
+
* maxWholeDigitPlaces={5}
|
|
1425
|
+
* maxFractionDigits={0}
|
|
1426
|
+
* />
|
|
1427
|
+
*
|
|
1428
|
+
* // Precise decimal values
|
|
1429
|
+
* <RHFNumberInput
|
|
1430
|
+
* name="price"
|
|
1431
|
+
* maxFractionDigits={2}
|
|
1432
|
+
* maxWholeDigitPlaces={10}
|
|
1433
|
+
* />
|
|
1434
|
+
*
|
|
1435
|
+
* // Positive numbers only
|
|
1436
|
+
* <RHFNumberInput
|
|
1437
|
+
* name="age"
|
|
1438
|
+
* positiveOnly
|
|
1439
|
+
* maxFractionDigits={0}
|
|
1440
|
+
* />
|
|
1441
|
+
* ```
|
|
1442
|
+
*/
|
|
1443
|
+
declare const RHFNumberInput: FC<RHFNumberInputProps>;
|
|
1444
|
+
|
|
1445
|
+
interface Currency {
|
|
1446
|
+
symbol: string;
|
|
1447
|
+
code: string;
|
|
1448
|
+
}
|
|
1449
|
+
interface RHFCurrencyInputProps extends Omit<RHFNumberInputProps, "strict"> {
|
|
1450
|
+
/**
|
|
1451
|
+
* The currency to display with the input.
|
|
1452
|
+
* The symbol and code are displayed as a prefix and suffix, respectively.
|
|
1453
|
+
* */
|
|
1454
|
+
currency?: Currency;
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
/**
|
|
1458
|
+
* An enhanced number input component for currency values with React Hook Form.
|
|
1459
|
+
*
|
|
1460
|
+
* Displays currency symbols and codes, and automatically formats values with
|
|
1461
|
+
* thousands separators (e.g., 1,234,567.89). Built on top of RHFNumberInput
|
|
1462
|
+
* with strict mode enabled by default.
|
|
1463
|
+
*
|
|
1464
|
+
* @example
|
|
1465
|
+
* ```tsx
|
|
1466
|
+
* // Basic usage with currency symbol and code
|
|
1467
|
+
* <RHFCurrencyInput
|
|
1468
|
+
* name="price"
|
|
1469
|
+
* currency={{ symbol: '$', code: 'USD' }}
|
|
1470
|
+
* />
|
|
1471
|
+
*
|
|
1472
|
+
* // With only symbol
|
|
1473
|
+
* <RHFCurrencyInput
|
|
1474
|
+
* name="amount"
|
|
1475
|
+
* currency={{ symbol: '€' }}
|
|
1476
|
+
* />
|
|
1477
|
+
*
|
|
1478
|
+
* // With custom decimal places
|
|
1479
|
+
* <RHFCurrencyInput
|
|
1480
|
+
* name="cost"
|
|
1481
|
+
* currency={{ symbol: '¥', code: 'JPY' }}
|
|
1482
|
+
* maxFractionDigits={0}
|
|
1483
|
+
* />
|
|
1484
|
+
*
|
|
1485
|
+
* // Different currencies
|
|
1486
|
+
* <RHFCurrencyInput
|
|
1487
|
+
* name="gbpAmount"
|
|
1488
|
+
* currency={{ symbol: '£', code: 'GBP' }}
|
|
1489
|
+
* />
|
|
1490
|
+
* ```
|
|
1491
|
+
*/
|
|
1492
|
+
declare const RHFCurrencyInput: FC<RHFCurrencyInputProps>;
|
|
1493
|
+
|
|
1494
|
+
interface TextareaProps extends TextareaAutosizeProps {
|
|
1495
|
+
/**
|
|
1496
|
+
* Enable auto resizing of the textarea
|
|
1497
|
+
* @default false
|
|
1498
|
+
* */
|
|
1499
|
+
autoResize?: boolean;
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
/**
|
|
1503
|
+
* A textarea component with optional auto-resizing functionality.
|
|
1504
|
+
*
|
|
1505
|
+
* Built on top of react-textarea-autosize, this component can automatically
|
|
1506
|
+
* adjust its height based on content. Control the minimum and maximum number
|
|
1507
|
+
* of rows displayed.
|
|
1508
|
+
*
|
|
1509
|
+
* @example
|
|
1510
|
+
* ```tsx
|
|
1511
|
+
* // Basic usage
|
|
1512
|
+
* <Textarea placeholder="Type something..." />
|
|
1513
|
+
*
|
|
1514
|
+
* // Auto-resizing textarea
|
|
1515
|
+
* <Textarea autoResize placeholder="Type something..." />
|
|
1516
|
+
*
|
|
1517
|
+
* // With row constraints
|
|
1518
|
+
* <Textarea rows={3} placeholder="Minimum 3 rows" />
|
|
1519
|
+
*
|
|
1520
|
+
* // Auto-resize with max rows
|
|
1521
|
+
* <Textarea
|
|
1522
|
+
* autoResize
|
|
1523
|
+
* rows={2}
|
|
1524
|
+
* maxRows={10}
|
|
1525
|
+
* placeholder="Grows from 2 to 10 rows"
|
|
1526
|
+
* />
|
|
1527
|
+
*
|
|
1528
|
+
* // Controlled component
|
|
1529
|
+
* <Textarea
|
|
1530
|
+
* value={text}
|
|
1531
|
+
* onChange={(e) => setText(e.target.value)}
|
|
1532
|
+
* placeholder="Enter description"
|
|
1533
|
+
* />
|
|
1534
|
+
* ```
|
|
1535
|
+
*/
|
|
1536
|
+
declare const Textarea: react.ForwardRefExoticComponent<TextareaProps & react.RefAttributes<HTMLTextAreaElement>>;
|
|
1537
|
+
|
|
1538
|
+
interface RHFTextareaProps extends RHFBaseProps, Omit<TextareaProps, "name" | "onChange" | "onBlur"> {
|
|
1539
|
+
/**
|
|
1540
|
+
* Callback fired when the value changes
|
|
1541
|
+
* This is the actual value of the textarea not the event object
|
|
1542
|
+
* */
|
|
1543
|
+
onChange?: (value: string | null) => void;
|
|
1544
|
+
/**
|
|
1545
|
+
* Callback fired when the input is blurred
|
|
1546
|
+
* ```
|
|
1547
|
+
* */
|
|
1548
|
+
onBlur?: (value: string) => void;
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
/**
|
|
1552
|
+
* A textarea component integrated with React Hook Form.
|
|
1553
|
+
*
|
|
1554
|
+
* Supports auto-resizing functionality and automatic error state display.
|
|
1555
|
+
* Built on the Textarea component with full React Hook Form integration.
|
|
1556
|
+
*
|
|
1557
|
+
* @example
|
|
1558
|
+
* ```tsx
|
|
1559
|
+
* // Basic usage
|
|
1560
|
+
* <RHFTextarea name="description" />
|
|
1561
|
+
*
|
|
1562
|
+
* // Auto-resizing textarea
|
|
1563
|
+
* <RHFTextarea
|
|
1564
|
+
* name="comments"
|
|
1565
|
+
* autoResize
|
|
1566
|
+
* />
|
|
1567
|
+
*
|
|
1568
|
+
* // With row constraints
|
|
1569
|
+
* <RHFTextarea
|
|
1570
|
+
* name="bio"
|
|
1571
|
+
* autoResize
|
|
1572
|
+
* rows={3}
|
|
1573
|
+
* maxRows={10}
|
|
1574
|
+
* placeholder="Tell us about yourself"
|
|
1575
|
+
* />
|
|
1576
|
+
*
|
|
1577
|
+
* // With callbacks
|
|
1578
|
+
* <RHFTextarea
|
|
1579
|
+
* name="notes"
|
|
1580
|
+
* onChange={(value) => console.log('Text changed:', value)}
|
|
1581
|
+
* onBlur={(value) => console.log('Final value:', value)}
|
|
1582
|
+
* />
|
|
1583
|
+
*
|
|
1584
|
+
* // Disabled state
|
|
1585
|
+
* <RHFTextarea
|
|
1586
|
+
* name="readonly"
|
|
1587
|
+
* disabled
|
|
1588
|
+
* />
|
|
1589
|
+
* ```
|
|
1590
|
+
*/
|
|
1591
|
+
declare const RHFTextarea: FC<RHFTextareaProps>;
|
|
1592
|
+
|
|
1593
|
+
/** Extensible size map - To allow module augmentation */
|
|
1594
|
+
interface SwitchSizeMap {
|
|
1595
|
+
sm: unknown;
|
|
1596
|
+
md: unknown;
|
|
1597
|
+
}
|
|
1598
|
+
interface SwitchProps extends Omit<SwitchProps$1, "className"> {
|
|
1599
|
+
/**
|
|
1600
|
+
* The size of the switch.(default: 'md')
|
|
1601
|
+
* */
|
|
1602
|
+
size?: keyof SwitchSizeMap;
|
|
1603
|
+
/**
|
|
1604
|
+
* Class name for the switch.
|
|
1605
|
+
* */
|
|
1606
|
+
className?: string;
|
|
1607
|
+
/**
|
|
1608
|
+
* Style for the thumb of the switch.
|
|
1609
|
+
* */
|
|
1610
|
+
thumbClassName?: string;
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
/**
|
|
1614
|
+
* Switch is a toggle component built on HeadlessUI that provides an accessible
|
|
1615
|
+
* on/off control. It supports multiple sizes, controlled and uncontrolled modes,
|
|
1616
|
+
* and integrates seamlessly with forms.
|
|
1617
|
+
*
|
|
1618
|
+
* @example
|
|
1619
|
+
* Toggle feature in settings:
|
|
1620
|
+
*
|
|
1621
|
+
* ```tsx
|
|
1622
|
+
* const [notificationsEnabled, setNotificationsEnabled] = useState(true);
|
|
1623
|
+
*
|
|
1624
|
+
* <div className="flex items-center gap-3">
|
|
1625
|
+
* <Switch
|
|
1626
|
+
* checked={notificationsEnabled}
|
|
1627
|
+
* onChange={setNotificationsEnabled}
|
|
1628
|
+
* size="md"
|
|
1629
|
+
* />
|
|
1630
|
+
* <span>Enable email notifications</span>
|
|
1631
|
+
* </div>
|
|
1632
|
+
* ```
|
|
1633
|
+
*
|
|
1634
|
+
* @example
|
|
1635
|
+
* Uncontrolled with default value:
|
|
1636
|
+
*
|
|
1637
|
+
* ```tsx
|
|
1638
|
+
* <Switch defaultChecked={true} size="lg" />
|
|
1639
|
+
* ```
|
|
1640
|
+
*
|
|
1641
|
+
* @example
|
|
1642
|
+
* Custom styling and sizes:
|
|
1643
|
+
*
|
|
1644
|
+
* ```tsx
|
|
1645
|
+
* <Switch
|
|
1646
|
+
* checked={darkMode}
|
|
1647
|
+
* onChange={toggleDarkMode}
|
|
1648
|
+
* size="sm"
|
|
1649
|
+
* className="bg-blue-500 data-[checked]:bg-green-600"
|
|
1650
|
+
* thumbClassName="shadow-lg"
|
|
1651
|
+
* />
|
|
1652
|
+
* ```
|
|
1653
|
+
*
|
|
1654
|
+
* @see https://headlessui.com/react/switch for advanced usage
|
|
1655
|
+
*/
|
|
1656
|
+
declare const Switch: react.ForwardRefExoticComponent<SwitchProps & react.RefAttributes<null>>;
|
|
1657
|
+
|
|
1658
|
+
interface RHFSwitchProps extends RHFBaseProps, Omit<SwitchProps, "name" | "value"> {
|
|
1659
|
+
/**
|
|
1660
|
+
* Value to set in the form data when the switch is toggled
|
|
1661
|
+
* If value is not provided, value will be toggled between true and false
|
|
1662
|
+
* */
|
|
1663
|
+
value?: unknown;
|
|
1664
|
+
/**
|
|
1665
|
+
* Value to set in the form data when the switch is toggled off
|
|
1666
|
+
* **Works only when `value` is provided**
|
|
1667
|
+
* */
|
|
1668
|
+
uncheckedValue?: unknown;
|
|
1669
|
+
/**
|
|
1670
|
+
* Callback fired when the value changes
|
|
1671
|
+
* */
|
|
1672
|
+
onChange?: (value: unknown) => void;
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
/**
|
|
1676
|
+
* A controlled switch component for React Hook Form.
|
|
1677
|
+
*
|
|
1678
|
+
* By default, the switch stores boolean values (true/false) in the form state.
|
|
1679
|
+
* You can customize the checked and unchecked values using the `value` and `uncheckedValue` props.
|
|
1680
|
+
* Unlike native radio inputs, values maintain their original data types and are not converted to strings.
|
|
1681
|
+
*
|
|
1682
|
+
* @example
|
|
1683
|
+
* ```tsx
|
|
1684
|
+
* // Basic usage - stores boolean (true or false)
|
|
1685
|
+
* <RHFSwitch name="switch" />
|
|
1686
|
+
*
|
|
1687
|
+
* // Custom value when checked, undefined when unchecked
|
|
1688
|
+
* <RHFSwitch name="switch" value="custom-value" />
|
|
1689
|
+
*
|
|
1690
|
+
* // Custom value with object
|
|
1691
|
+
* <RHFSwitch name="switch2" value={{ key: 'value' }} />
|
|
1692
|
+
*
|
|
1693
|
+
* // Custom values for both checked and unchecked states
|
|
1694
|
+
* <RHFSwitch name="switch" value={1} uncheckedValue={0} />
|
|
1695
|
+
* <RHFSwitch name="enabled" value="yes" uncheckedValue="no" />
|
|
1696
|
+
* ```
|
|
1697
|
+
*/
|
|
1698
|
+
declare const RHFSwitch: FC<RHFSwitchProps>;
|
|
1699
|
+
|
|
1700
|
+
type RadioProps = Omit<InputHTMLAttributes<HTMLInputElement>, "type">;
|
|
1701
|
+
|
|
1702
|
+
/**
|
|
1703
|
+
* A styled radio button input component that extends the native HTML radio input.
|
|
1704
|
+
*
|
|
1705
|
+
* This component provides consistent styling and focus states for radio buttons
|
|
1706
|
+
* throughout your application. It accepts all standard input props.
|
|
1707
|
+
*
|
|
1708
|
+
* @example
|
|
1709
|
+
* ```tsx
|
|
1710
|
+
* // Basic usage
|
|
1711
|
+
* <Radio name="option" value="1" />
|
|
1712
|
+
*
|
|
1713
|
+
* // With label
|
|
1714
|
+
* <label className="flex items-center gap-2">
|
|
1715
|
+
* <Radio name="choice" value="yes" />
|
|
1716
|
+
* <span>Yes</span>
|
|
1717
|
+
* </label>
|
|
1718
|
+
*
|
|
1719
|
+
* // Radio group
|
|
1720
|
+
* <div>
|
|
1721
|
+
* <label>
|
|
1722
|
+
* <Radio name="size" value="small" defaultChecked />
|
|
1723
|
+
* Small
|
|
1724
|
+
* </label>
|
|
1725
|
+
* <label>
|
|
1726
|
+
* <Radio name="size" value="medium" />
|
|
1727
|
+
* Medium
|
|
1728
|
+
* </label>
|
|
1729
|
+
* <label>
|
|
1730
|
+
* <Radio name="size" value="large" />
|
|
1731
|
+
* Large
|
|
1732
|
+
* </label>
|
|
1733
|
+
* </div>
|
|
1734
|
+
*
|
|
1735
|
+
* // Controlled component
|
|
1736
|
+
* <Radio
|
|
1737
|
+
* name="plan"
|
|
1738
|
+
* value="pro"
|
|
1739
|
+
* checked={selectedPlan === 'pro'}
|
|
1740
|
+
* onChange={(e) => setSelectedPlan(e.target.value)}
|
|
1741
|
+
* />
|
|
1742
|
+
* ```
|
|
1743
|
+
*/
|
|
1744
|
+
declare const Radio: react.ForwardRefExoticComponent<RadioProps & react.RefAttributes<HTMLInputElement>>;
|
|
1745
|
+
|
|
1746
|
+
interface RHFRadioProps extends RHFBaseProps, Omit<RadioProps, "name" | "value" | "onChange"> {
|
|
1747
|
+
/**
|
|
1748
|
+
* Label to display next to the radio button
|
|
1749
|
+
* */
|
|
1750
|
+
label?: string | ReactNode | FC;
|
|
1751
|
+
/**
|
|
1752
|
+
* Style for the label of the radio button.
|
|
1753
|
+
* */
|
|
1754
|
+
labelClassName?: string;
|
|
1755
|
+
/**
|
|
1756
|
+
* Value to set in the form data when the radio button is selected
|
|
1757
|
+
* Value can be any type and it will be set in the form data as it is without any transformation
|
|
1758
|
+
* eg. In native radio input, the value is always a string but in RHFRadio it can be any type
|
|
1759
|
+
* */
|
|
1760
|
+
value?: unknown;
|
|
1761
|
+
/**
|
|
1762
|
+
* Callback fired when the value changes
|
|
1763
|
+
* */
|
|
1764
|
+
onChange?: (value: unknown) => void;
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
/**
|
|
1768
|
+
* A controlled radio input component for React Hook Form.
|
|
1769
|
+
*
|
|
1770
|
+
* Unlike native radio inputs that convert values to strings, this component preserves
|
|
1771
|
+
* the original data type of the value. You can use objects, arrays, booleans, strings,
|
|
1772
|
+
* or any other value type (except undefined).
|
|
1773
|
+
*
|
|
1774
|
+
* @example
|
|
1775
|
+
* ```tsx
|
|
1776
|
+
* // With object value
|
|
1777
|
+
* <RHFRadio name="radio" value={{ key: "value" }} label="Object" />
|
|
1778
|
+
*
|
|
1779
|
+
* // With array value
|
|
1780
|
+
* <RHFRadio name="radio" value={[1, 2, 3, 4, 5]} label="Array" />
|
|
1781
|
+
*
|
|
1782
|
+
* // With boolean value
|
|
1783
|
+
* <RHFRadio name="radio" value={true} label="Boolean" />
|
|
1784
|
+
*
|
|
1785
|
+
* // With string value
|
|
1786
|
+
* <RHFRadio name="radio" value="string" label="String" />
|
|
1787
|
+
*
|
|
1788
|
+
* // Radio group example
|
|
1789
|
+
* <div>
|
|
1790
|
+
* <RHFRadio name="plan" value="free" label="Free Plan" />
|
|
1791
|
+
* <RHFRadio name="plan" value="pro" label="Pro Plan" />
|
|
1792
|
+
* <RHFRadio name="plan" value="enterprise" label="Enterprise Plan" />
|
|
1793
|
+
* </div>
|
|
1794
|
+
*
|
|
1795
|
+
* // With onChange callback
|
|
1796
|
+
* <RHFRadio
|
|
1797
|
+
* name="radio"
|
|
1798
|
+
* value="option1"
|
|
1799
|
+
* label="Option 1"
|
|
1800
|
+
* onChange={(value) => console.log('Selected:', value)}
|
|
1801
|
+
* />
|
|
1802
|
+
* ```
|
|
1803
|
+
*/
|
|
1804
|
+
declare const RHFRadio: FC<RHFRadioProps>;
|
|
1805
|
+
|
|
1806
|
+
interface RHFDateInputProps extends RHFBaseProps, Omit<DateInputProps, "hasError"> {
|
|
1807
|
+
/**
|
|
1808
|
+
* Whether the input is disabled
|
|
1809
|
+
*/
|
|
1810
|
+
disabled?: boolean;
|
|
1811
|
+
/**
|
|
1812
|
+
* Callback function when date changes (in addition to form field update)
|
|
1813
|
+
*/
|
|
1814
|
+
onChange?: (date: string | null) => void;
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
/**
|
|
1818
|
+
* React Hook Form wrapper for the DateInput component.
|
|
1819
|
+
*
|
|
1820
|
+
* Integrates DateInput with React Hook Form for seamless form management with
|
|
1821
|
+
* automatic validation and error handling.
|
|
1822
|
+
*
|
|
1823
|
+
* @example
|
|
1824
|
+
* ```tsx
|
|
1825
|
+
* // Basic usage
|
|
1826
|
+
* <RHFDateInput name="birthDate" />
|
|
1827
|
+
*
|
|
1828
|
+
* // With callbacks
|
|
1829
|
+
* <RHFDateInput
|
|
1830
|
+
* name="appointmentDate"
|
|
1831
|
+
* onBlur={(value) => console.log('Date changed:', value)}
|
|
1832
|
+
* />
|
|
1833
|
+
*
|
|
1834
|
+
* // Disabled state
|
|
1835
|
+
* <RHFDateInput
|
|
1836
|
+
* name="startDate"
|
|
1837
|
+
* disabled
|
|
1838
|
+
* />
|
|
1839
|
+
*
|
|
1840
|
+
* // With custom styling
|
|
1841
|
+
* <RHFDateInput
|
|
1842
|
+
* name="endDate"
|
|
1843
|
+
* className="custom-date-input"
|
|
1844
|
+
* />
|
|
1845
|
+
* ```
|
|
1846
|
+
*/
|
|
1847
|
+
declare const RHFDateInput: FC<RHFDateInputProps>;
|
|
1848
|
+
|
|
1849
|
+
declare const _default: CalendarOverload;
|
|
1850
|
+
|
|
1851
|
+
interface RHFDateRangeInputProps extends RHFBaseProps, Omit<DateRangeInputProps, "hasError" | "value" | "onChange"> {
|
|
1852
|
+
disabled?: boolean;
|
|
1853
|
+
onChange?: (value: DateRange | null) => void;
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
declare const RHFDateRangeInput: FC<RHFDateRangeInputProps>;
|
|
1857
|
+
|
|
1858
|
+
type FileWithPreview = File & {
|
|
1859
|
+
preview?: string;
|
|
1860
|
+
};
|
|
1861
|
+
interface RHFFileInputProps extends RHFBaseProps, Omit<InputHTMLAttributes<HTMLInputElement>, "multiple" | "children" | "name" | "type" | "onChange"> {
|
|
1862
|
+
/**
|
|
1863
|
+
* Class name actual input element.
|
|
1864
|
+
* `className` is used for the container div.
|
|
1865
|
+
* So if you want to style the input element, eg. placeholder, or even the input itself, use this prop.
|
|
1866
|
+
* */
|
|
1867
|
+
inputClassName?: string;
|
|
1868
|
+
/**
|
|
1869
|
+
* Callback fired when the value changes
|
|
1870
|
+
* This is the actual value of the file input not the event object
|
|
1871
|
+
* */
|
|
1872
|
+
onChange?: (data?: FileWithPreview | FileWithPreview[] | null) => void;
|
|
1873
|
+
/**
|
|
1874
|
+
* If true, the user can select multiple files(Default: false)
|
|
1875
|
+
* */
|
|
1876
|
+
multiple?: boolean;
|
|
1877
|
+
/**
|
|
1878
|
+
* Render custom component instead of the default input element
|
|
1879
|
+
* You also have access to the Controller renderProps object
|
|
1880
|
+
* So that you can access the field, fieldState, and formState objects and use accordingly
|
|
1881
|
+
*
|
|
1882
|
+
* If you pass render, the input element will be hidden using the `hidden` class
|
|
1883
|
+
* */
|
|
1884
|
+
render?: ReactNode | ControllerProps["render"];
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
/**
|
|
1888
|
+
* File input component that integrates with react-hook-form.
|
|
1889
|
+
*
|
|
1890
|
+
* You can pass `render` to render custom component instead of the default input element
|
|
1891
|
+
*
|
|
1892
|
+
* You have access to the Controller renderProps object in the `render` function
|
|
1893
|
+
* So that you can access the field, fieldState, and formState objects and use them accordingly
|
|
1894
|
+
*
|
|
1895
|
+
* @example
|
|
1896
|
+
* ```tsx
|
|
1897
|
+
* // Basic usage - single file selection
|
|
1898
|
+
* // Automatically creates a preview URL for the selected file
|
|
1899
|
+
* <RHFFileInput name="file" />
|
|
1900
|
+
*
|
|
1901
|
+
* // Multiple file selection
|
|
1902
|
+
* <RHFFileInput name="files" multiple />
|
|
1903
|
+
*
|
|
1904
|
+
* // Restrict file types
|
|
1905
|
+
* <RHFFileInput name="avatar" accept="image/*" />
|
|
1906
|
+
*
|
|
1907
|
+
* // With custom render
|
|
1908
|
+
* <RHFFileInput
|
|
1909
|
+
* name="file"
|
|
1910
|
+
* accept="image/*"
|
|
1911
|
+
* render={({ field: { value } }) => {
|
|
1912
|
+
* return (
|
|
1913
|
+
* <div className="flex rounded overflow-hidden items-center justify-center cursor-pointer border-2 p-4 w-full border-dotted border-gray-300 h-[200px]">
|
|
1914
|
+
* {value ? (
|
|
1915
|
+
* <img
|
|
1916
|
+
* className="inline-block object-contain w-full h-full"
|
|
1917
|
+
* src={value.preview}
|
|
1918
|
+
* alt="Preview"
|
|
1919
|
+
* />
|
|
1920
|
+
* ) : (
|
|
1921
|
+
* <span>Upload File</span>
|
|
1922
|
+
* )}
|
|
1923
|
+
* </div>
|
|
1924
|
+
* );
|
|
1925
|
+
* }}
|
|
1926
|
+
* />
|
|
1927
|
+
* ```
|
|
1928
|
+
*/
|
|
1929
|
+
declare const RHFFileInput: FC<RHFFileInputProps>;
|
|
1930
|
+
|
|
1931
|
+
interface OTPInputProps {
|
|
1932
|
+
/**
|
|
1933
|
+
* Value of the OTP input
|
|
1934
|
+
* */
|
|
1935
|
+
value: string;
|
|
1936
|
+
/**
|
|
1937
|
+
* Function to call when the OTP input value changes
|
|
1938
|
+
* */
|
|
1939
|
+
onChange: (value: string) => void;
|
|
1940
|
+
/**
|
|
1941
|
+
* Function to call when the OTP input is blurred
|
|
1942
|
+
* */
|
|
1943
|
+
onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
|
|
1944
|
+
/**
|
|
1945
|
+
* Function to call when the OTP input completely filled
|
|
1946
|
+
* i.e when the length of the OTP input is equal to the length prop
|
|
1947
|
+
* */
|
|
1948
|
+
onOTPComplete?: (value: string) => void;
|
|
1949
|
+
/**
|
|
1950
|
+
* If true, only numbers can be entered in the OTP input. (Default: true)
|
|
1951
|
+
* */
|
|
1952
|
+
numberOnly?: boolean;
|
|
1953
|
+
/**
|
|
1954
|
+
* Classname for the wrapper div that contains input fields
|
|
1955
|
+
* */
|
|
1956
|
+
className?: string;
|
|
1957
|
+
/**
|
|
1958
|
+
* Classname for the input fields
|
|
1959
|
+
* */
|
|
1960
|
+
inputClassName?: string;
|
|
1961
|
+
/**
|
|
1962
|
+
* Length of the OTP input(Default: 6)
|
|
1963
|
+
* Inputs will be created based on this length
|
|
1964
|
+
* */
|
|
1965
|
+
length?: number;
|
|
1966
|
+
/**
|
|
1967
|
+
* Aspect ratio of the OTP input (Default: 0.94)
|
|
1968
|
+
* */
|
|
1969
|
+
aspectRatio?: string | number;
|
|
1970
|
+
/**
|
|
1971
|
+
* If true, the OTP input will be disabled
|
|
1972
|
+
* */
|
|
1973
|
+
disabled?: boolean;
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
/**
|
|
1977
|
+
* OTPInput provides a segmented input field for entering one-time passwords or verification codes.
|
|
1978
|
+
* Each digit is displayed in a separate box with automatic focus management and keyboard navigation.
|
|
1979
|
+
* Supports both numeric-only mode (default) and alphanumeric input.
|
|
1980
|
+
*
|
|
1981
|
+
* @example
|
|
1982
|
+
* Two-factor authentication:
|
|
1983
|
+
*
|
|
1984
|
+
* ```tsx
|
|
1985
|
+
* const [verificationCode, setVerificationCode] = useState('');
|
|
1986
|
+
*
|
|
1987
|
+
* <OTPInput
|
|
1988
|
+
* value={verificationCode}
|
|
1989
|
+
* onChange={setVerificationCode}
|
|
1990
|
+
* length={6}
|
|
1991
|
+
* numberOnly
|
|
1992
|
+
* onOTPComplete={async (code) => {
|
|
1993
|
+
* await verifyTwoFactorCode(code);
|
|
1994
|
+
* }}
|
|
1995
|
+
* />
|
|
1996
|
+
* ```
|
|
1997
|
+
*
|
|
1998
|
+
* @example
|
|
1999
|
+
* Alphanumeric code with custom styling:
|
|
2000
|
+
*
|
|
2001
|
+
* ```tsx
|
|
2002
|
+
* <OTPInput
|
|
2003
|
+
* value={activationCode}
|
|
2004
|
+
* onChange={setActivationCode}
|
|
2005
|
+
* length={8}
|
|
2006
|
+
* numberOnly={false}
|
|
2007
|
+
* className="gap-2"
|
|
2008
|
+
* inputClassName="border-2 rounded-md"
|
|
2009
|
+
* />
|
|
2010
|
+
* ```
|
|
2011
|
+
*
|
|
2012
|
+
* @example
|
|
2013
|
+
* SMS verification with aspect ratio:
|
|
2014
|
+
*
|
|
2015
|
+
* ```tsx
|
|
2016
|
+
* <OTPInput
|
|
2017
|
+
* value={smsCode}
|
|
2018
|
+
* onChange={setSmsCode}
|
|
2019
|
+
* length={4}
|
|
2020
|
+
* aspectRatio={1}
|
|
2021
|
+
* onOTPComplete={(code) => submitVerification(code)}
|
|
2022
|
+
* disabled={isVerifying}
|
|
2023
|
+
* />
|
|
2024
|
+
* ```
|
|
2025
|
+
*/
|
|
2026
|
+
declare const OTPInput: react__default.ForwardRefExoticComponent<OTPInputProps & react__default.RefAttributes<HTMLInputElement>>;
|
|
2027
|
+
|
|
2028
|
+
interface RHFOTPInputProps extends RHFBaseProps, Omit<OTPInputProps, "value" | "onChange"> {
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
/**
|
|
2032
|
+
* An OTP (One-Time Password) input component integrated with React Hook Form.
|
|
2033
|
+
*
|
|
2034
|
+
* By default, only numeric input is allowed. You can change this behavior
|
|
2035
|
+
* by setting the `numberOnly` prop to false to allow alphanumeric input.
|
|
2036
|
+
*
|
|
2037
|
+
* @example
|
|
2038
|
+
* ```tsx
|
|
2039
|
+
* // Basic usage - numbers only, default 6 digits
|
|
2040
|
+
* <RHFOTPInput name="otp" />
|
|
2041
|
+
*
|
|
2042
|
+
* // Custom length
|
|
2043
|
+
* <RHFOTPInput name="code" length={4} />
|
|
2044
|
+
*
|
|
2045
|
+
* // Allow alphanumeric input
|
|
2046
|
+
* <RHFOTPInput
|
|
2047
|
+
* name="verificationCode"
|
|
2048
|
+
* numberOnly={false}
|
|
2049
|
+
* length={8}
|
|
2050
|
+
* />
|
|
2051
|
+
*
|
|
2052
|
+
* // With completion callback
|
|
2053
|
+
* <RHFOTPInput
|
|
2054
|
+
* name="otp"
|
|
2055
|
+
* onOTPComplete={(value) => {
|
|
2056
|
+
* console.log('OTP entered:', value);
|
|
2057
|
+
* // Auto-submit or verify OTP
|
|
2058
|
+
* }}
|
|
2059
|
+
* />
|
|
2060
|
+
* ```
|
|
2061
|
+
*/
|
|
2062
|
+
declare const RHFOTPInput: FC<RHFOTPInputProps>;
|
|
2063
|
+
|
|
2064
|
+
interface RHFFilePickerRenderProps<T extends HTMLElement = HTMLDivElement> extends UseFilePickerReturn<T>, RHFRenderArgs<Record<string, FilePickerFile[]>> {
|
|
2065
|
+
}
|
|
2066
|
+
type FilePickerOptions = Omit<UseFilePickerOptions, "onStart">;
|
|
2067
|
+
interface RHFFilePickerBaseProps<T extends HTMLElement = HTMLDivElement> extends FilePickerOptions {
|
|
2068
|
+
render?: (
|
|
2069
|
+
/** Additional props to be used on the dropzone element */
|
|
2070
|
+
props: RHFFilePickerRenderProps<T>) => ReactNode;
|
|
2071
|
+
}
|
|
2072
|
+
interface RHFFilePickerProps<T extends HTMLElement = HTMLDivElement> extends RHFBaseProps, RHFFilePickerBaseProps<T> {
|
|
2073
|
+
}
|
|
2074
|
+
interface RHFFilePickerRendererProps<T extends HTMLElement = HTMLDivElement> extends RHFRenderArgs<Record<string, FilePickerFile[]>>, RHFFilePickerBaseProps<T> {
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
/**
|
|
2078
|
+
* A file picker component with drag-and-drop support for React Hook Form.
|
|
2079
|
+
*
|
|
2080
|
+
* Features include:
|
|
2081
|
+
* - File and directory selection
|
|
2082
|
+
* - Drag-and-drop support
|
|
2083
|
+
* - File preview URLs
|
|
2084
|
+
* - Duplicate detection and optional removal
|
|
2085
|
+
* - Custom UI via render prop
|
|
2086
|
+
*
|
|
2087
|
+
* Selected files have additional properties:
|
|
2088
|
+
* - `preview`: URL for displaying file content
|
|
2089
|
+
* - `duplicatedWith`: Array of files this file duplicates
|
|
2090
|
+
*
|
|
2091
|
+
* @example
|
|
2092
|
+
* ```tsx
|
|
2093
|
+
* // Basic usage - accept all file types
|
|
2094
|
+
* <RHFFilePicker name="files" />
|
|
2095
|
+
*
|
|
2096
|
+
* // Restrict to images only
|
|
2097
|
+
* <RHFFilePicker name="images" accept="image/*" />
|
|
2098
|
+
*
|
|
2099
|
+
* // Remove duplicates automatically
|
|
2100
|
+
* <RHFFilePicker
|
|
2101
|
+
* name="files"
|
|
2102
|
+
* accept="image/*"
|
|
2103
|
+
* removeDuplicates
|
|
2104
|
+
* />
|
|
2105
|
+
* ```
|
|
2106
|
+
*
|
|
2107
|
+
* Custom UI example (compact image grid):
|
|
2108
|
+
* ```tsx
|
|
2109
|
+
* <RHFFilePicker
|
|
2110
|
+
* name="customImages"
|
|
2111
|
+
* accept="image/*"
|
|
2112
|
+
* render={({
|
|
2113
|
+
* dropzoneRef,
|
|
2114
|
+
* dragging,
|
|
2115
|
+
* loading,
|
|
2116
|
+
* field: { value: files, onChange },
|
|
2117
|
+
* openFilePicker,
|
|
2118
|
+
* }) => {
|
|
2119
|
+
* const handleRemove = (preview: string) => {
|
|
2120
|
+
* onChange(files.filter((f) => f.preview !== preview));
|
|
2121
|
+
* };
|
|
2122
|
+
*
|
|
2123
|
+
* return (
|
|
2124
|
+
* <div className="flex flex-col gap-3">
|
|
2125
|
+
* <div
|
|
2126
|
+
* ref={dropzoneRef}
|
|
2127
|
+
* onClick={() => openFilePicker()}
|
|
2128
|
+
* className={`relative flex cursor-pointer items-center justify-center rounded-lg border-2 border-dashed p-4 transition-colors ${
|
|
2129
|
+
* dragging ? 'border-primary-400 bg-primary-50' : 'border-gray-300 hover:border-primary-300'
|
|
2130
|
+
* }`}
|
|
2131
|
+
* >
|
|
2132
|
+
* <div className="flex items-center gap-3 text-sm text-gray-500">
|
|
2133
|
+
* <UploadIcon className="h-5 w-5" />
|
|
2134
|
+
* <span>{dragging ? 'Drop images here' : 'Click to upload or drag and drop'}</span>
|
|
2135
|
+
* </div>
|
|
2136
|
+
* {loading && (
|
|
2137
|
+
* <div className="absolute inset-0 flex items-center justify-center rounded-lg bg-white/50">
|
|
2138
|
+
* <Spinner className="h-5 w-5" />
|
|
2139
|
+
* </div>
|
|
2140
|
+
* )}
|
|
2141
|
+
* </div>
|
|
2142
|
+
*
|
|
2143
|
+
* {!!files?.length && (
|
|
2144
|
+
* <div className="grid grid-cols-4 gap-2 sm:grid-cols-5 md:grid-cols-6">
|
|
2145
|
+
* {files.map((file) => (
|
|
2146
|
+
* <div key={file.preview} className="group relative aspect-square">
|
|
2147
|
+
* <img
|
|
2148
|
+
* src={file.preview}
|
|
2149
|
+
* alt={file.name}
|
|
2150
|
+
* className="h-full w-full rounded-lg border object-cover"
|
|
2151
|
+
* />
|
|
2152
|
+
* <button
|
|
2153
|
+
* type="button"
|
|
2154
|
+
* onClick={() => handleRemove(file.preview)}
|
|
2155
|
+
* className="absolute -right-1.5 -top-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-red-500 text-white opacity-0 shadow-sm hover:bg-red-600 group-hover:opacity-100"
|
|
2156
|
+
* >
|
|
2157
|
+
* <XIcon className="h-3 w-3" />
|
|
2158
|
+
* </button>
|
|
2159
|
+
* </div>
|
|
2160
|
+
* ))}
|
|
2161
|
+
* </div>
|
|
2162
|
+
* )}
|
|
2163
|
+
* </div>
|
|
2164
|
+
* );
|
|
2165
|
+
* }}
|
|
2166
|
+
* />
|
|
2167
|
+
* ```
|
|
2168
|
+
*
|
|
2169
|
+
* */
|
|
2170
|
+
declare function RHFFilePicker<T extends HTMLElement = HTMLDivElement>(props: RHFFilePickerProps<T>): react_jsx_runtime.JSX.Element;
|
|
2171
|
+
declare namespace RHFFilePicker {
|
|
2172
|
+
var displayName: string;
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
/**
|
|
2176
|
+
* A wrapper around React Hook Form's Controller component that auto-injects the control prop.
|
|
2177
|
+
*
|
|
2178
|
+
* Automatically retrieves the `control` prop from `useFormContext`, eliminating the need to
|
|
2179
|
+
* pass it manually. This simplifies usage with FormProvider and reduces boilerplate code.
|
|
2180
|
+
*
|
|
2181
|
+
* **When to pass `control` explicitly:**
|
|
2182
|
+
* Only pass the `control` prop when you have nested FormProviders and need to connect to a
|
|
2183
|
+
* specific form instance. For example, when one form is rendered inside another FormProvider,
|
|
2184
|
+
* you'll need to pass the parent form's control explicitly to avoid using the inner form's context.
|
|
2185
|
+
*
|
|
2186
|
+
* @example
|
|
2187
|
+
* ```tsx
|
|
2188
|
+
* // Basic usage - control auto-injected from FormProvider
|
|
2189
|
+
* <FormProvider {...methods}>
|
|
2190
|
+
* <RHFController
|
|
2191
|
+
* name="email"
|
|
2192
|
+
* render={({ field }) => (
|
|
2193
|
+
* <input
|
|
2194
|
+
* {...field}
|
|
2195
|
+
* type="email"
|
|
2196
|
+
* placeholder="Enter email"
|
|
2197
|
+
* />
|
|
2198
|
+
* )}
|
|
2199
|
+
* />
|
|
2200
|
+
* </FormProvider>
|
|
2201
|
+
*
|
|
2202
|
+
* // With validation rules
|
|
2203
|
+
* <RHFController
|
|
2204
|
+
* name="username"
|
|
2205
|
+
* rules={{ required: 'Username is required' }}
|
|
2206
|
+
* render={({ field, fieldState }) => (
|
|
2207
|
+
* <div>
|
|
2208
|
+
* <input {...field} />
|
|
2209
|
+
* {fieldState.error && <span>{fieldState.error.message}</span>}
|
|
2210
|
+
* </div>
|
|
2211
|
+
* )}
|
|
2212
|
+
* />
|
|
2213
|
+
*
|
|
2214
|
+
* // Custom component integration
|
|
2215
|
+
* <RHFController
|
|
2216
|
+
* name="customField"
|
|
2217
|
+
* render={({ field, fieldState, formState }) => (
|
|
2218
|
+
* <CustomComponent
|
|
2219
|
+
* value={field.value}
|
|
2220
|
+
* onChange={field.onChange}
|
|
2221
|
+
* error={fieldState.error}
|
|
2222
|
+
* isDirty={formState.isDirty}
|
|
2223
|
+
* />
|
|
2224
|
+
* )}
|
|
2225
|
+
* />
|
|
2226
|
+
*
|
|
2227
|
+
* // Nested FormProviders - explicit control needed
|
|
2228
|
+
* <FormProvider {...outerForm}>
|
|
2229
|
+
* <FormProvider {...innerForm}>
|
|
2230
|
+
* // This will use innerForm's control by default
|
|
2231
|
+
* <RHFController name="innerField" render={...} />
|
|
2232
|
+
*
|
|
2233
|
+
* // Pass control explicitly to use outerForm
|
|
2234
|
+
* <RHFController
|
|
2235
|
+
* name="outerField"
|
|
2236
|
+
* control={outerForm.control}
|
|
2237
|
+
* render={({ field }) => <input {...field} />}
|
|
2238
|
+
* />
|
|
2239
|
+
* </FormProvider>
|
|
2240
|
+
* </FormProvider>
|
|
2241
|
+
* ```
|
|
2242
|
+
*/
|
|
2243
|
+
declare const RHFController: FC<ControllerProps>;
|
|
2244
|
+
|
|
2245
|
+
interface SelectButtonProps {
|
|
2246
|
+
/**
|
|
2247
|
+
* Additional class name for the select button
|
|
2248
|
+
* */
|
|
2249
|
+
className?: string;
|
|
2250
|
+
/**
|
|
2251
|
+
* Prefix for the select button
|
|
2252
|
+
* */
|
|
2253
|
+
prefix?: FC | ReactNode;
|
|
2254
|
+
/**
|
|
2255
|
+
* Suffix for the select button
|
|
2256
|
+
* */
|
|
2257
|
+
suffix?: FC | ReactNode;
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
type HtmlButtonProps = DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLDivElement>, HTMLDivElement>;
|
|
2261
|
+
interface SelectOptionConfig<T> {
|
|
2262
|
+
/**
|
|
2263
|
+
* Value of the option
|
|
2264
|
+
* */
|
|
2265
|
+
value: T;
|
|
2266
|
+
/**
|
|
2267
|
+
* Used to identify the option in the list and filtering
|
|
2268
|
+
* If you don't pass anything, children textContent will be used as label
|
|
2269
|
+
* */
|
|
2270
|
+
label: string;
|
|
2271
|
+
visibility?: SelectOptionProps<T>["visibility"];
|
|
2272
|
+
/**
|
|
2273
|
+
* This is just a placeholder for the rest of the props in case we might need them in the future
|
|
2274
|
+
* */
|
|
2275
|
+
props: Omit<SelectOptionProps<T>, "children">;
|
|
2276
|
+
}
|
|
2277
|
+
interface CustomSelectOptionBaseArgs<T> extends Pick<SelectOptionConfig<T>, "value"> {
|
|
2278
|
+
/**
|
|
2279
|
+
* Whether the option is selected or not
|
|
2280
|
+
* */
|
|
2281
|
+
selected: boolean;
|
|
2282
|
+
/**
|
|
2283
|
+
* Whether the option has focus or not
|
|
2284
|
+
* */
|
|
2285
|
+
focused: boolean;
|
|
2286
|
+
}
|
|
2287
|
+
interface CustomSelectOptionArgs<T> extends CustomSelectOptionBaseArgs<T> {
|
|
2288
|
+
/**
|
|
2289
|
+
* Function to prevent the default onClick function
|
|
2290
|
+
* If you call this function, You need to handle the onClick function yourself
|
|
2291
|
+
* You can use `selectCurrentOption` to trigger the default onClick function
|
|
2292
|
+
* or you can write your own onClick function according to your needs
|
|
2293
|
+
* */
|
|
2294
|
+
preventDefault: () => void;
|
|
2295
|
+
/**
|
|
2296
|
+
* Default onClick function that is called when the option is clicked
|
|
2297
|
+
* It will select or deselect the option and close the menu if it's a single select
|
|
2298
|
+
* */
|
|
2299
|
+
selectCurrentOption: () => void;
|
|
2300
|
+
/**
|
|
2301
|
+
* Callback to close the select menu
|
|
2302
|
+
* */
|
|
2303
|
+
closeMenu: () => void;
|
|
2304
|
+
/**
|
|
2305
|
+
* Filtered keyword that is currently being used to filter the options
|
|
2306
|
+
* */
|
|
2307
|
+
filteredKeyword: string;
|
|
2308
|
+
}
|
|
2309
|
+
interface SelectOptionProps<T> extends Omit<SelectOptionConfig<T>, "props">, Omit<HtmlButtonProps, "children" | "value" | "className" | "onClick"> {
|
|
2310
|
+
/**
|
|
2311
|
+
* If you want to hide default check icon
|
|
2312
|
+
* */
|
|
2313
|
+
hideCheckIcon?: boolean;
|
|
2314
|
+
className?: string | ((props: CustomSelectOptionBaseArgs<T>) => string);
|
|
2315
|
+
children?: ReactNode | ((props: Omit<CustomSelectOptionArgs<T>, "preventDefault">) => ReactNode);
|
|
2316
|
+
onClick?: (args: CustomSelectOptionArgs<T>) => void;
|
|
2317
|
+
/**
|
|
2318
|
+
* This will only be called when the option is selected and multiple is true
|
|
2319
|
+
* */
|
|
2320
|
+
onRemove?: (args: CustomSelectOptionArgs<T>) => void;
|
|
2321
|
+
/**
|
|
2322
|
+
* If you want to display the option always, even if it's empty
|
|
2323
|
+
* i.e. when the user is filtering the options and no option is found
|
|
2324
|
+
*
|
|
2325
|
+
* if you want to display the option only when the options are empty
|
|
2326
|
+
* then you can pass "empty" as value and if you want to display the option always
|
|
2327
|
+
* then you can pass "always" as value
|
|
2328
|
+
*
|
|
2329
|
+
* If you want to display the option only when the options are empty and the user is filtering
|
|
2330
|
+
* and that filter matches the option then you can pass "filtered-and-empty" as value
|
|
2331
|
+
*
|
|
2332
|
+
* Default: "default"
|
|
2333
|
+
* */
|
|
2334
|
+
visibility?: "default" | "always" | "empty" | "filtered-and-empty";
|
|
2335
|
+
}
|
|
2336
|
+
type SelectOptionElement<T = unknown> = ReactElement<SelectOptionProps<T>>;
|
|
2337
|
+
|
|
2338
|
+
interface BaseSelectProps extends PropsWithChildren, SelectButtonProps {
|
|
2339
|
+
inputRef?: RefCallback<HTMLInputElement | null> | RefObject<HTMLInputElement | null>;
|
|
2340
|
+
/**
|
|
2341
|
+
* Placeholder that will be shown when the select is empty
|
|
2342
|
+
* */
|
|
2343
|
+
placeholder?: string;
|
|
2344
|
+
/**
|
|
2345
|
+
* Additional class name for the placeholder
|
|
2346
|
+
* */
|
|
2347
|
+
placeholderClassName?: string;
|
|
2348
|
+
wrapperClassName?: string;
|
|
2349
|
+
/**
|
|
2350
|
+
* Additional class name for the menu
|
|
2351
|
+
* */
|
|
2352
|
+
menuClassName?: string;
|
|
2353
|
+
/**
|
|
2354
|
+
* Select is disabled or not
|
|
2355
|
+
* */
|
|
2356
|
+
disabled?: boolean;
|
|
2357
|
+
/**
|
|
2358
|
+
* Whether to show the input for filtering the options
|
|
2359
|
+
* Default is false
|
|
2360
|
+
* */
|
|
2361
|
+
filterable?: boolean | "inline" | "dropdown";
|
|
2362
|
+
/**
|
|
2363
|
+
* Whether to close the menu when an option is selected
|
|
2364
|
+
* Default is true for single select and false for multi select
|
|
2365
|
+
* */
|
|
2366
|
+
closeMenuOnSelect?: boolean;
|
|
2367
|
+
/**
|
|
2368
|
+
* Placement of the menu
|
|
2369
|
+
* Default is "bottom-start"
|
|
2370
|
+
* */
|
|
2371
|
+
placement?: Placement;
|
|
2372
|
+
/**
|
|
2373
|
+
* Floating strategy for the menu
|
|
2374
|
+
* */
|
|
2375
|
+
floatingStrategy?: Strategy;
|
|
2376
|
+
/**
|
|
2377
|
+
* Whether to hide the default empty UI when the select is empty
|
|
2378
|
+
* If you pass `SelectEmpty` as children, this will set to true
|
|
2379
|
+
* */
|
|
2380
|
+
hideDefaultEmptyUI?: boolean;
|
|
2381
|
+
}
|
|
2382
|
+
interface SingleSelectProps<T> extends BaseSelectProps {
|
|
2383
|
+
/**
|
|
2384
|
+
* The value of the select
|
|
2385
|
+
* */
|
|
2386
|
+
value: T;
|
|
2387
|
+
/**
|
|
2388
|
+
* Callback to be called when the value changes
|
|
2389
|
+
* */
|
|
2390
|
+
onChange: (value: T) => void;
|
|
2391
|
+
/**
|
|
2392
|
+
* Disabling multiple select
|
|
2393
|
+
* */
|
|
2394
|
+
multiple?: false;
|
|
2395
|
+
}
|
|
2396
|
+
interface MultiSelectProps<T> extends BaseSelectProps {
|
|
2397
|
+
/**
|
|
2398
|
+
* The value of the select in array format
|
|
2399
|
+
* */
|
|
2400
|
+
value: T[];
|
|
2401
|
+
/**
|
|
2402
|
+
* Callback to be called when the value changes
|
|
2403
|
+
* */
|
|
2404
|
+
onChange: (value: T[]) => void;
|
|
2405
|
+
/**
|
|
2406
|
+
* For enabling multiple select
|
|
2407
|
+
* */
|
|
2408
|
+
multiple: true;
|
|
2409
|
+
}
|
|
2410
|
+
type SelectProps<T> = SingleSelectProps<T> | MultiSelectProps<T>;
|
|
2411
|
+
interface SelectOverload {
|
|
2412
|
+
<T>(props: SingleSelectProps<T>): JSX.Element;
|
|
2413
|
+
<T>(props: MultiSelectProps<T>): JSX.Element;
|
|
2414
|
+
<T>(props: SelectProps<T>): JSX.Element;
|
|
2415
|
+
displayName: string;
|
|
2416
|
+
}
|
|
2417
|
+
interface FocusedOption<T = unknown> extends SelectOptionConfig<T> {
|
|
2418
|
+
focusType?: "keyboard" | "mouse";
|
|
2419
|
+
}
|
|
2420
|
+
interface SelectContextProps<T> extends Pick<BaseSelectProps, "disabled" | "prefix" | "suffix" | "placeholder" | "closeMenuOnSelect">, Omit<MultiSelectProps<T>, "value" | "onChange" | "multiple" | "renderDisplay"> {
|
|
2421
|
+
/**
|
|
2422
|
+
* The value of the select
|
|
2423
|
+
* */
|
|
2424
|
+
value: T | T[];
|
|
2425
|
+
/**
|
|
2426
|
+
* For checking if the select is multiple or single
|
|
2427
|
+
* */
|
|
2428
|
+
multiple?: boolean;
|
|
2429
|
+
/**
|
|
2430
|
+
* Input ref for the filter input
|
|
2431
|
+
* Use this to work with keyword filter in custom select
|
|
2432
|
+
* */
|
|
2433
|
+
setInputRef: (_: any) => RefCallback<HTMLElement | null> | RefObject<HTMLElement | null> | undefined;
|
|
2434
|
+
/**
|
|
2435
|
+
* Ref for the input
|
|
2436
|
+
* */
|
|
2437
|
+
inputRef: RefObject<HTMLInputElement | null>;
|
|
2438
|
+
/**
|
|
2439
|
+
* For managing the open state of the menu
|
|
2440
|
+
* */
|
|
2441
|
+
open: boolean;
|
|
2442
|
+
/**
|
|
2443
|
+
* Setter for open state for the menu
|
|
2444
|
+
* */
|
|
2445
|
+
setOpen: Dispatch<SetStateAction<boolean>>;
|
|
2446
|
+
/**
|
|
2447
|
+
* Array of labels and values that are passed down as `SelectOption` to children
|
|
2448
|
+
* */
|
|
2449
|
+
options: SelectOptionConfig<T>[];
|
|
2450
|
+
/**
|
|
2451
|
+
* For filtering options that are binded to the input
|
|
2452
|
+
* If you use custom `SelectButton` you should bind this to the input
|
|
2453
|
+
* */
|
|
2454
|
+
keyword: string;
|
|
2455
|
+
/**
|
|
2456
|
+
* Setter for filter keyword
|
|
2457
|
+
* */
|
|
2458
|
+
setKeyword: Dispatch<SetStateAction<string>>;
|
|
2459
|
+
/**
|
|
2460
|
+
* For managing the floating state of the menu
|
|
2461
|
+
* *you rarely need to use this if you build custom select*
|
|
2462
|
+
* */
|
|
2463
|
+
floating: ReturnType<typeof useFloating>;
|
|
2464
|
+
/**
|
|
2465
|
+
* Open the select menu
|
|
2466
|
+
* */
|
|
2467
|
+
openMenu: () => void;
|
|
2468
|
+
/**
|
|
2469
|
+
* Close the select menu
|
|
2470
|
+
* */
|
|
2471
|
+
closeMenu: () => void;
|
|
2472
|
+
/**
|
|
2473
|
+
* Toggle the select menu
|
|
2474
|
+
* */
|
|
2475
|
+
toggleMenu: () => void;
|
|
2476
|
+
/**
|
|
2477
|
+
* Reusable function to check if the option is selected
|
|
2478
|
+
* Usage:
|
|
2479
|
+
* ```js
|
|
2480
|
+
* isSelected("optionValue")
|
|
2481
|
+
* ```
|
|
2482
|
+
* */
|
|
2483
|
+
isSelected: (optionValue: T) => boolean;
|
|
2484
|
+
/**
|
|
2485
|
+
* Reusable function to handle the change of the select
|
|
2486
|
+
* This function handle the option value base on the select type(multiple or single)
|
|
2487
|
+
* If multiple select, it will add or remove the value from the array
|
|
2488
|
+
* and if single select, it will replace the value
|
|
2489
|
+
*
|
|
2490
|
+
* Usage:
|
|
2491
|
+
* ```js
|
|
2492
|
+
* handleChange("optionValue")
|
|
2493
|
+
* ```
|
|
2494
|
+
* */
|
|
2495
|
+
handleChange: (optionValue: T) => void;
|
|
2496
|
+
/**
|
|
2497
|
+
* Current focused option that is selected by keyboard or mouse hover
|
|
2498
|
+
* */
|
|
2499
|
+
focusedOption: FocusedOption<T> | null;
|
|
2500
|
+
/**
|
|
2501
|
+
* Setter for focused option in case you want to update the focused option to a specific option
|
|
2502
|
+
* */
|
|
2503
|
+
setFocusedOption: Dispatch<SetStateAction<FocusedOption<T> | null>>;
|
|
2504
|
+
/**
|
|
2505
|
+
* Whether the select is empty when the filter is applied
|
|
2506
|
+
* */
|
|
2507
|
+
isEmpty: boolean;
|
|
2508
|
+
/**
|
|
2509
|
+
* Ref for the menu scroll container
|
|
2510
|
+
* Used internally for scrolling focused options into view
|
|
2511
|
+
* */
|
|
2512
|
+
menuScrollContainerRef: RefObject<HTMLDivElement | null>;
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
/**
|
|
2516
|
+
* A customizable select dropdown component with support for single and multiple selections.
|
|
2517
|
+
*
|
|
2518
|
+
* Features include:
|
|
2519
|
+
* - Single or multiple selection modes
|
|
2520
|
+
* - Keyboard navigation and search
|
|
2521
|
+
* - Custom positioning with floating-ui
|
|
2522
|
+
* - Click-outside to close
|
|
2523
|
+
* - Customizable trigger and menu components
|
|
2524
|
+
*
|
|
2525
|
+
* @example
|
|
2526
|
+
* ```tsx
|
|
2527
|
+
* // Basic single select
|
|
2528
|
+
* <Select value={selectedValue} onChange={setSelectedValue}>
|
|
2529
|
+
* <SelectOption value="option1" label="Option 1" />
|
|
2530
|
+
* <SelectOption value="option2" label="Option 2" />
|
|
2531
|
+
* </Select>
|
|
2532
|
+
*
|
|
2533
|
+
* // Multiple select
|
|
2534
|
+
* <Select
|
|
2535
|
+
* multiple
|
|
2536
|
+
* value={selectedValues}
|
|
2537
|
+
* onChange={setSelectedValues}
|
|
2538
|
+
* >
|
|
2539
|
+
* <SelectOption value="opt1" label="Option 1" />
|
|
2540
|
+
* <SelectOption value="opt2" label="Option 2" />
|
|
2541
|
+
* <SelectOption value="opt3" label="Option 3" />
|
|
2542
|
+
* </Select>
|
|
2543
|
+
*
|
|
2544
|
+
* // With custom placement
|
|
2545
|
+
* <Select
|
|
2546
|
+
* value={value}
|
|
2547
|
+
* onChange={setValue}
|
|
2548
|
+
* placement="top-start"
|
|
2549
|
+
* >
|
|
2550
|
+
* <SelectOption value="a" label="Choice A" />
|
|
2551
|
+
* <SelectOption value="b" label="Choice B" />
|
|
2552
|
+
* </Select>
|
|
2553
|
+
* ```
|
|
2554
|
+
*/
|
|
2555
|
+
declare const Select: SelectOverload;
|
|
2556
|
+
|
|
2557
|
+
/**
|
|
2558
|
+
* An individual selectable option within a Select dropdown component.
|
|
2559
|
+
*
|
|
2560
|
+
* Features:
|
|
2561
|
+
* - Automatic keyboard and mouse focus management
|
|
2562
|
+
* - Custom content rendering via render props
|
|
2563
|
+
* - Visibility control (default, always, empty, filtered-and-empty)
|
|
2564
|
+
* - Custom click handlers with access to selection state
|
|
2565
|
+
* - preventDefault support for complete custom click behavior control
|
|
2566
|
+
* - Auto-scrolling when focused via keyboard
|
|
2567
|
+
* - Support for both single and multiple selection modes
|
|
2568
|
+
* - Optional check icon display
|
|
2569
|
+
* - Disabled state support
|
|
2570
|
+
*
|
|
2571
|
+
* @example
|
|
2572
|
+
* ```tsx
|
|
2573
|
+
* // Basic option
|
|
2574
|
+
* <Select value={value} onChange={setValue}>
|
|
2575
|
+
* <SelectOption value="react" label="React" />
|
|
2576
|
+
* <SelectOption value="vue" label="Vue" />
|
|
2577
|
+
* <SelectOption value="angular" label="Angular" />
|
|
2578
|
+
* </Select>
|
|
2579
|
+
*
|
|
2580
|
+
* // Custom content with render function
|
|
2581
|
+
* <Select value={value} onChange={setValue}>
|
|
2582
|
+
* <SelectOption value="user1" label="John Doe">
|
|
2583
|
+
* {({ selected, focused }) => (
|
|
2584
|
+
* <div className={focused ? 'font-bold' : ''}>
|
|
2585
|
+
* <Avatar src="/john.jpg" />
|
|
2586
|
+
* <span>John Doe</span>
|
|
2587
|
+
* {selected && <CheckIcon />}
|
|
2588
|
+
* </div>
|
|
2589
|
+
* )}
|
|
2590
|
+
* </SelectOption>
|
|
2591
|
+
* </Select>
|
|
2592
|
+
*
|
|
2593
|
+
* // Hide check icon
|
|
2594
|
+
* <Select value={value} onChange={setValue}>
|
|
2595
|
+
* <SelectOption value="opt1" label="Option 1" hideCheckIcon />
|
|
2596
|
+
* <SelectOption value="opt2" label="Option 2" hideCheckIcon />
|
|
2597
|
+
* </Select>
|
|
2598
|
+
*
|
|
2599
|
+
* // Custom onClick handler (default behavior still runs)
|
|
2600
|
+
* <Select value={value} onChange={setValue}>
|
|
2601
|
+
* <SelectOption
|
|
2602
|
+
* value="custom"
|
|
2603
|
+
* label="Custom Action"
|
|
2604
|
+
* onClick={({ selectCurrentOption, closeMenu }) => {
|
|
2605
|
+
* console.log('Custom action triggered');
|
|
2606
|
+
* selectCurrentOption(); // Manually trigger selection
|
|
2607
|
+
* closeMenu();
|
|
2608
|
+
* }}
|
|
2609
|
+
* />
|
|
2610
|
+
* </Select>
|
|
2611
|
+
*
|
|
2612
|
+
* // Using preventDefault to completely override default behavior
|
|
2613
|
+
* <Select value={value} onChange={setValue}>
|
|
2614
|
+
* <SelectOption
|
|
2615
|
+
* value="confirm"
|
|
2616
|
+
* label="Delete Item"
|
|
2617
|
+
* onClick={({ preventDefault, value, closeMenu }) => {
|
|
2618
|
+
* preventDefault(); // Prevents default selection behavior
|
|
2619
|
+
*
|
|
2620
|
+
* // Implement completely custom logic
|
|
2621
|
+
* if (window.confirm('Are you sure you want to delete?')) {
|
|
2622
|
+
* handleDelete(value);
|
|
2623
|
+
* closeMenu();
|
|
2624
|
+
* }
|
|
2625
|
+
* // Note: Item is NOT selected unless you manually call selectCurrentOption
|
|
2626
|
+
* }}
|
|
2627
|
+
* />
|
|
2628
|
+
* </Select>
|
|
2629
|
+
*
|
|
2630
|
+
* // preventDefault with conditional selection
|
|
2631
|
+
* <Select value={value} onChange={setValue}>
|
|
2632
|
+
* <SelectOption
|
|
2633
|
+
* value="premium"
|
|
2634
|
+
* label="Premium Feature"
|
|
2635
|
+
* onClick={({ preventDefault, selectCurrentOption, value }) => {
|
|
2636
|
+
* preventDefault();
|
|
2637
|
+
*
|
|
2638
|
+
* if (userHasPremium) {
|
|
2639
|
+
* selectCurrentOption(); // Allow selection for premium users
|
|
2640
|
+
* } else {
|
|
2641
|
+
* openUpgradeModal(); // Show upgrade prompt for free users
|
|
2642
|
+
* }
|
|
2643
|
+
* }}
|
|
2644
|
+
* />
|
|
2645
|
+
* </Select>
|
|
2646
|
+
*
|
|
2647
|
+
* // preventDefault for custom async operations
|
|
2648
|
+
* <Select value={value} onChange={setValue}>
|
|
2649
|
+
* <SelectOption
|
|
2650
|
+
* value="createNew"
|
|
2651
|
+
* label="+ Create New Category"
|
|
2652
|
+
* onClick={async ({ preventDefault, selectCurrentOption, closeMenu }) => {
|
|
2653
|
+
* preventDefault();
|
|
2654
|
+
*
|
|
2655
|
+
* const newCategory = await openCreateDialog();
|
|
2656
|
+
* if (newCategory) {
|
|
2657
|
+
* await saveCategory(newCategory);
|
|
2658
|
+
* selectCurrentOption(); // Select after async operation
|
|
2659
|
+
* closeMenu();
|
|
2660
|
+
* }
|
|
2661
|
+
* }}
|
|
2662
|
+
* />
|
|
2663
|
+
* </Select>
|
|
2664
|
+
*
|
|
2665
|
+
* // Visibility variants
|
|
2666
|
+
* <Select value={value} onChange={setValue}>
|
|
2667
|
+
* <SelectDropdownSearch />
|
|
2668
|
+
* <SelectOption value="opt1" label="Normal Option" visibility="default" />
|
|
2669
|
+
* <SelectOption value="add" label="+ Add New" visibility="always" />
|
|
2670
|
+
* <SelectOption value="create" label="Create New Item" visibility="empty" />
|
|
2671
|
+
* </Select>
|
|
2672
|
+
*
|
|
2673
|
+
* // Disabled option
|
|
2674
|
+
* <Select value={value} onChange={setValue}>
|
|
2675
|
+
* <SelectOption value="enabled" label="Enabled Option" />
|
|
2676
|
+
* <SelectOption value="disabled" label="Disabled Option" disabled />
|
|
2677
|
+
* </Select>
|
|
2678
|
+
*
|
|
2679
|
+
* // Custom className based on state
|
|
2680
|
+
* <Select value={value} onChange={setValue}>
|
|
2681
|
+
* <SelectOption
|
|
2682
|
+
* value="premium"
|
|
2683
|
+
* label="Premium Option"
|
|
2684
|
+
* className={({ selected, focused }) =>
|
|
2685
|
+
* `${selected ? 'bg-blue-500' : ''} ${focused ? 'ring-2' : ''}`
|
|
2686
|
+
* }
|
|
2687
|
+
* />
|
|
2688
|
+
* </Select>
|
|
2689
|
+
*
|
|
2690
|
+
* // Multiple select with onRemove
|
|
2691
|
+
* <Select multiple value={values} onChange={setValues}>
|
|
2692
|
+
* <SelectOption
|
|
2693
|
+
* value="tag1"
|
|
2694
|
+
* label="Tag 1"
|
|
2695
|
+
* onRemove={({ value }) => console.log('Removing', value)}
|
|
2696
|
+
* />
|
|
2697
|
+
* </Select>
|
|
2698
|
+
* ```
|
|
2699
|
+
*/
|
|
2700
|
+
declare const SelectOption: {
|
|
2701
|
+
<T>({ children, ...props }: SelectOptionProps<T>): react_jsx_runtime.JSX.Element | null;
|
|
2702
|
+
displayName: string;
|
|
2703
|
+
};
|
|
2704
|
+
|
|
2705
|
+
interface SelectEmptyProps extends PropsWithChildren, HtmlHTMLAttributes<HTMLDivElement> {
|
|
2706
|
+
}
|
|
2707
|
+
|
|
2708
|
+
/**
|
|
2709
|
+
* Displays a placeholder message when no options match the search filter in a Select component.
|
|
2710
|
+
*
|
|
2711
|
+
* This component only renders when the Select is in an empty state (no matching options).
|
|
2712
|
+
* Use it inside a Select component to provide feedback when search/filter returns no results.
|
|
2713
|
+
*
|
|
2714
|
+
* @example
|
|
2715
|
+
* ```tsx
|
|
2716
|
+
* // Basic usage with default message
|
|
2717
|
+
* <Select value={value} onChange={setValue}>
|
|
2718
|
+
* <SelectDropdownSearch />
|
|
2719
|
+
* <SelectOption value="apple" label="Apple" />
|
|
2720
|
+
* <SelectOption value="banana" label="Banana" />
|
|
2721
|
+
* <SelectEmpty />
|
|
2722
|
+
* </Select>
|
|
2723
|
+
*
|
|
2724
|
+
* // Custom empty message
|
|
2725
|
+
* <Select value={value} onChange={setValue}>
|
|
2726
|
+
* <SelectDropdownSearch />
|
|
2727
|
+
* <SelectOption value="react" label="React" />
|
|
2728
|
+
* <SelectOption value="vue" label="Vue" />
|
|
2729
|
+
* <SelectEmpty>
|
|
2730
|
+
* No frameworks found. Try a different search.
|
|
2731
|
+
* </SelectEmpty>
|
|
2732
|
+
* </Select>
|
|
2733
|
+
*
|
|
2734
|
+
* // With custom styling
|
|
2735
|
+
* <Select value={value} onChange={setValue}>
|
|
2736
|
+
* <SelectDropdownSearch />
|
|
2737
|
+
* <SelectOption value="opt1" label="Option 1" />
|
|
2738
|
+
* <SelectEmpty className="text-red-500 italic">
|
|
2739
|
+
* ⚠️ No results found
|
|
2740
|
+
* </SelectEmpty>
|
|
2741
|
+
* </Select>
|
|
2742
|
+
* ```
|
|
2743
|
+
*/
|
|
2744
|
+
declare const SelectEmpty: {
|
|
2745
|
+
({ children, className, ...rest }: SelectEmptyProps): react_jsx_runtime.JSX.Element | null;
|
|
2746
|
+
displayName: string;
|
|
2747
|
+
};
|
|
2748
|
+
|
|
2749
|
+
/**
|
|
2750
|
+
* A search input component for filtering Select options with full keyboard navigation support.
|
|
2751
|
+
*
|
|
2752
|
+
* Features:
|
|
2753
|
+
* - Real-time filtering of select options as you type
|
|
2754
|
+
* - Keyboard navigation with Arrow Up/Down keys
|
|
2755
|
+
* - Enter key to select focused option
|
|
2756
|
+
* - Tab key support for navigation
|
|
2757
|
+
* - Auto-focuses first matching option during search
|
|
2758
|
+
* - Works seamlessly with single and multiple select modes
|
|
2759
|
+
*
|
|
2760
|
+
* @example
|
|
2761
|
+
* ```tsx
|
|
2762
|
+
* // Basic usage
|
|
2763
|
+
* <Select value={value} onChange={setValue}>
|
|
2764
|
+
* <SelectDropdownSearch />
|
|
2765
|
+
* <SelectOption value="apple" label="Apple" />
|
|
2766
|
+
* <SelectOption value="banana" label="Banana" />
|
|
2767
|
+
* <SelectOption value="cherry" label="Cherry" />
|
|
2768
|
+
* <SelectEmpty>No fruits found</SelectEmpty>
|
|
2769
|
+
* </Select>
|
|
2770
|
+
*
|
|
2771
|
+
* // Custom placeholder
|
|
2772
|
+
* <Select value={value} onChange={setValue}>
|
|
2773
|
+
* <SelectDropdownSearch placeholder="Search countries..." />
|
|
2774
|
+
* <SelectOption value="us" label="United States" />
|
|
2775
|
+
* <SelectOption value="uk" label="United Kingdom" />
|
|
2776
|
+
* <SelectOption value="ca" label="Canada" />
|
|
2777
|
+
* </Select>
|
|
2778
|
+
*
|
|
2779
|
+
* // With custom styling
|
|
2780
|
+
* <Select value={value} onChange={setValue}>
|
|
2781
|
+
* <SelectDropdownSearch
|
|
2782
|
+
* placeholder="Find your option"
|
|
2783
|
+
* className="border-2 border-blue-500"
|
|
2784
|
+
* />
|
|
2785
|
+
* <SelectOption value="opt1" label="Option 1" />
|
|
2786
|
+
* <SelectOption value="opt2" label="Option 2" />
|
|
2787
|
+
* </Select>
|
|
2788
|
+
*
|
|
2789
|
+
* // Multiple select with search
|
|
2790
|
+
* <Select multiple value={values} onChange={setValues}>
|
|
2791
|
+
* <SelectDropdownSearch placeholder="Search tags..." />
|
|
2792
|
+
* <SelectOption value="react" label="React" />
|
|
2793
|
+
* <SelectOption value="vue" label="Vue" />
|
|
2794
|
+
* <SelectOption value="angular" label="Angular" />
|
|
2795
|
+
* </Select>
|
|
2796
|
+
* ```
|
|
2797
|
+
*/
|
|
2798
|
+
declare const SelectDropdownSearch: {
|
|
2799
|
+
({ placeholder, className, ...rest }: Omit<InputProps, "value" | "onChange" | "onKeyDown">): react_jsx_runtime.JSX.Element;
|
|
2800
|
+
displayName: string;
|
|
2801
|
+
};
|
|
2802
|
+
|
|
2803
|
+
interface SelectTriggerBaseRenderProps<T> extends Pick<SelectContextProps<T>, "toggleMenu" | "open" | "openMenu" | "closeMenu" | "placeholder" | "handleChange" | "keyword"> {
|
|
2804
|
+
/**
|
|
2805
|
+
* Select has a value or not, use this prop to display placeholder or something.
|
|
2806
|
+
* */
|
|
2807
|
+
hasValue: boolean;
|
|
2808
|
+
/**
|
|
2809
|
+
* Filtered options
|
|
2810
|
+
* */
|
|
2811
|
+
filteredOptions: SelectOptionConfig<T>[];
|
|
2812
|
+
/**
|
|
2813
|
+
* All options that are available
|
|
2814
|
+
* */
|
|
2815
|
+
options: SelectOptionConfig<T>[];
|
|
2816
|
+
/**
|
|
2817
|
+
* Pre defined function to update the filtered options
|
|
2818
|
+
* */
|
|
2819
|
+
handleInputChange: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
2820
|
+
/**
|
|
2821
|
+
* Pre defined function to update the focused option or menu state
|
|
2822
|
+
* like open or close,
|
|
2823
|
+
* */
|
|
2824
|
+
handleKeyboardInteraction: (e: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
2825
|
+
}
|
|
2826
|
+
interface SingleSelectTriggerRenderProps<T> extends SelectTriggerBaseRenderProps<T> {
|
|
2827
|
+
selectedOptions: Pick<SelectOptionConfig<T>, "label" | "value">;
|
|
2828
|
+
}
|
|
2829
|
+
interface MultiSelectTriggerRenderProps<T> extends SelectTriggerBaseRenderProps<T> {
|
|
2830
|
+
selectedOptions: Pick<SelectOptionConfig<T>, "label" | "value">[];
|
|
2831
|
+
}
|
|
2832
|
+
interface SingleSelectTriggerProps<T> {
|
|
2833
|
+
multiple?: false;
|
|
2834
|
+
children: (childrenProps: SingleSelectTriggerRenderProps<T>) => ReactNode;
|
|
2835
|
+
}
|
|
2836
|
+
interface MultiSelectTriggerProps<T> {
|
|
2837
|
+
multiple: true;
|
|
2838
|
+
children: (childrenProps: MultiSelectTriggerRenderProps<T>) => ReactNode;
|
|
2839
|
+
}
|
|
2840
|
+
interface SelectTriggerProps<T> {
|
|
2841
|
+
multiple?: boolean;
|
|
2842
|
+
children: SingleSelectTriggerProps<T>["children"] | MultiSelectTriggerProps<T>["children"];
|
|
2843
|
+
}
|
|
2844
|
+
interface SelectTriggerOverload {
|
|
2845
|
+
<T>(props: SingleSelectTriggerProps<T>): ReactNode;
|
|
2846
|
+
<T>(props: MultiSelectTriggerProps<T>): ReactNode;
|
|
2847
|
+
<T>(props: SelectTriggerProps<T>): ReactNode;
|
|
2848
|
+
displayName: string;
|
|
2849
|
+
}
|
|
2850
|
+
|
|
2851
|
+
/**
|
|
2852
|
+
* Custom trigger component for the Select component.
|
|
2853
|
+
*
|
|
2854
|
+
* Example usage:
|
|
2855
|
+
* ```js
|
|
2856
|
+
<RHFSelect multiple name="select">
|
|
2857
|
+
<SelectTrigger multiple>
|
|
2858
|
+
{({
|
|
2859
|
+
openMenu,
|
|
2860
|
+
keyword,
|
|
2861
|
+
selectedOptions,
|
|
2862
|
+
handleChange,
|
|
2863
|
+
handleInputChange,
|
|
2864
|
+
handleKeyboardInteraction,
|
|
2865
|
+
}) => {
|
|
2866
|
+
return (
|
|
2867
|
+
<div>
|
|
2868
|
+
<Input
|
|
2869
|
+
placeholder="Search......"
|
|
2870
|
+
value={keyword}
|
|
2871
|
+
onChange={handleInputChange}
|
|
2872
|
+
onKeyDown={handleKeyboardInteraction}
|
|
2873
|
+
autoComplete="off"
|
|
2874
|
+
autoCapitalize="off"
|
|
2875
|
+
autoCorrect="off"
|
|
2876
|
+
onFocus={openMenu}
|
|
2877
|
+
spellCheck={false}
|
|
2878
|
+
/>
|
|
2879
|
+
|
|
2880
|
+
{!!selectedOptions.length && (
|
|
2881
|
+
<div className="mt-2 flex flex-wrap items-center gap-x-2 gap-y-1">
|
|
2882
|
+
{selectedOptions.map((option) => {
|
|
2883
|
+
return (
|
|
2884
|
+
<Button
|
|
2885
|
+
className="flex gap-2"
|
|
2886
|
+
type="button"
|
|
2887
|
+
onClick={(e) => {
|
|
2888
|
+
e.stopPropagation();
|
|
2889
|
+
handleChange(option.value);
|
|
2890
|
+
}}>
|
|
2891
|
+
<span>{option.label}</span>
|
|
2892
|
+
</Button>
|
|
2893
|
+
);
|
|
2894
|
+
})}
|
|
2895
|
+
</div>
|
|
2896
|
+
)}
|
|
2897
|
+
</div>
|
|
2898
|
+
);
|
|
2899
|
+
}}
|
|
2900
|
+
</SelectTrigger>
|
|
2901
|
+
|
|
2902
|
+
{Array.from({ length: 12 }, (_, i) => (
|
|
2903
|
+
<SelectOption
|
|
2904
|
+
key={i}
|
|
2905
|
+
value={i}
|
|
2906
|
+
label={new Date(0, i).toLocaleString("default", { month: "long" })}
|
|
2907
|
+
/>
|
|
2908
|
+
))}
|
|
2909
|
+
</RHFSelect>
|
|
2910
|
+
*
|
|
2911
|
+
* ---
|
|
2912
|
+
* ```
|
|
2913
|
+
* */
|
|
2914
|
+
declare const SelectTrigger: SelectTriggerOverload;
|
|
2915
|
+
|
|
2916
|
+
interface SelectConsumerProps<T> {
|
|
2917
|
+
render: (props: SelectContextProps<T>) => ReactNode;
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
declare const SelectConsumer: {
|
|
2921
|
+
<T>({ render }: SelectConsumerProps<T>): ReactNode;
|
|
2922
|
+
displayName: string;
|
|
2923
|
+
};
|
|
2924
|
+
|
|
2925
|
+
declare const useSelect: <T = unknown>() => SelectContextProps<T>;
|
|
2926
|
+
|
|
2927
|
+
interface RHFSingleSelectProps<T> extends Omit<SingleSelectProps<T>, "value" | "onChange">, RHFBaseProps {
|
|
2928
|
+
onChange?: (value: T) => void;
|
|
2929
|
+
}
|
|
2930
|
+
interface RHFMultiSelectProps<T> extends Omit<MultiSelectProps<T>, "value" | "onChange">, RHFBaseProps {
|
|
2931
|
+
onChange?: (value: T[]) => void;
|
|
2932
|
+
}
|
|
2933
|
+
type RHFSelectProps<T> = RHFSingleSelectProps<T> | RHFMultiSelectProps<T>;
|
|
2934
|
+
interface RHFSelectOverload {
|
|
2935
|
+
displayName: string;
|
|
2936
|
+
<T>(props: RHFSingleSelectProps<T>): JSX.Element;
|
|
2937
|
+
<T>(props: RHFMultiSelectProps<T>): JSX.Element;
|
|
2938
|
+
}
|
|
2939
|
+
|
|
2940
|
+
/**
|
|
2941
|
+
* A select dropdown component integrated with React Hook Form.
|
|
2942
|
+
*
|
|
2943
|
+
* Supports both single and multiple selection modes with automatic error state display.
|
|
2944
|
+
* Built on the Select component with full React Hook Form integration.
|
|
2945
|
+
*
|
|
2946
|
+
* @example
|
|
2947
|
+
* ```tsx
|
|
2948
|
+
* // Basic single select
|
|
2949
|
+
* <RHFSelect name="country">
|
|
2950
|
+
* <SelectOption value="us" label="United States" />
|
|
2951
|
+
* <SelectOption value="uk" label="United Kingdom" />
|
|
2952
|
+
* <SelectOption value="ca" label="Canada" />
|
|
2953
|
+
* </RHFSelect>
|
|
2954
|
+
*
|
|
2955
|
+
* // Multiple selection
|
|
2956
|
+
* <RHFSelect name="skills" multiple>
|
|
2957
|
+
* <SelectOption value="js" label="JavaScript" />
|
|
2958
|
+
* <SelectOption value="ts" label="TypeScript" />
|
|
2959
|
+
* <SelectOption value="react" label="React" />
|
|
2960
|
+
* </RHFSelect>
|
|
2961
|
+
*
|
|
2962
|
+
* // With custom option styling
|
|
2963
|
+
* <RHFSelect name="priority">
|
|
2964
|
+
* {['low', 'medium', 'high'].map((priority) => (
|
|
2965
|
+
* <SelectOption
|
|
2966
|
+
* key={priority}
|
|
2967
|
+
* value={priority}
|
|
2968
|
+
* label={priority.charAt(0).toUpperCase() + priority.slice(1)}
|
|
2969
|
+
* className={({ selected }) =>
|
|
2970
|
+
* selected ? "text-blue-600 font-bold" : "text-gray-700"
|
|
2971
|
+
* }
|
|
2972
|
+
* />
|
|
2973
|
+
* ))}
|
|
2974
|
+
* </RHFSelect>
|
|
2975
|
+
*
|
|
2976
|
+
* // With onChange callback
|
|
2977
|
+
* <RHFSelect
|
|
2978
|
+
* name="category"
|
|
2979
|
+
* onChange={(value) => {
|
|
2980
|
+
* console.log('Selected:', value);
|
|
2981
|
+
* fetchSubcategories(value);
|
|
2982
|
+
* }}
|
|
2983
|
+
* >
|
|
2984
|
+
* <SelectOption value="1" label="Category 1" />
|
|
2985
|
+
* <SelectOption value="2" label="Category 2" />
|
|
2986
|
+
* </RHFSelect>
|
|
2987
|
+
* ```
|
|
2988
|
+
*/
|
|
2989
|
+
declare const RHFSelect: RHFSelectOverload;
|
|
2990
|
+
|
|
2991
|
+
interface TooltipProps extends PropsWithChildren {
|
|
2992
|
+
/**
|
|
2993
|
+
* The content of the tooltip
|
|
2994
|
+
* */
|
|
2995
|
+
content?: string | ReactNode | FC;
|
|
2996
|
+
/**
|
|
2997
|
+
* The duration of the delay before the tooltip appears
|
|
2998
|
+
* */
|
|
2999
|
+
delayDuration?: number;
|
|
3000
|
+
/**
|
|
3001
|
+
* Classname to apply to the tooltip
|
|
3002
|
+
* */
|
|
3003
|
+
className?: string;
|
|
3004
|
+
/**
|
|
3005
|
+
* Classname to apply to the tooltip trigger
|
|
3006
|
+
* ie. the element that triggers the tooltip to appear
|
|
3007
|
+
* @example
|
|
3008
|
+
*
|
|
3009
|
+
* ```js
|
|
3010
|
+
* <Tooltip content="hello world">
|
|
3011
|
+
* <Button>Hover me</Button> // <-- This is the tooltip trigger
|
|
3012
|
+
* </Tooltip>
|
|
3013
|
+
* ```
|
|
3014
|
+
* */
|
|
3015
|
+
triggerClassName?: string;
|
|
3016
|
+
/**
|
|
3017
|
+
* Whether consider the trigger as a child
|
|
3018
|
+
* Use this to avoid invalid button nesting errors when using a button as the trigger
|
|
3019
|
+
* If you use custom components as the trigger, you might need to wrap with `forwardRef`
|
|
3020
|
+
* */
|
|
3021
|
+
triggerAsChild?: boolean;
|
|
3022
|
+
/**
|
|
3023
|
+
* The background color of the tooltip and the arrow pointing to the target
|
|
3024
|
+
* */
|
|
3025
|
+
backgroundColor?: string;
|
|
3026
|
+
/**
|
|
3027
|
+
* The side of the tooltip to display
|
|
3028
|
+
* */
|
|
3029
|
+
side?: "top" | "right" | "bottom" | "left";
|
|
3030
|
+
/**
|
|
3031
|
+
* The offset of the tooltip from the trigger
|
|
3032
|
+
* */
|
|
3033
|
+
sideOffset?: number;
|
|
3034
|
+
}
|
|
3035
|
+
|
|
3036
|
+
/**
|
|
3037
|
+
* Tooltip displays contextual information in a floating overlay when users hover over or focus on an element.
|
|
3038
|
+
* Built on Radix UI, it provides accessible tooltips with customizable positioning, delays, and styling.
|
|
3039
|
+
* Returns children unchanged if no content is provided.
|
|
3040
|
+
*
|
|
3041
|
+
* @example
|
|
3042
|
+
* Icon button with helpful hint:
|
|
3043
|
+
*
|
|
3044
|
+
* ```tsx
|
|
3045
|
+
* <Tooltip content="Add new item" side="right" delayDuration={300}>
|
|
3046
|
+
* <button className="p-2">
|
|
3047
|
+
* <PlusIcon />
|
|
3048
|
+
* </button>
|
|
3049
|
+
* </Tooltip>
|
|
3050
|
+
* ```
|
|
3051
|
+
*
|
|
3052
|
+
* @example
|
|
3053
|
+
* Complex tooltip content:
|
|
3054
|
+
*
|
|
3055
|
+
* ```tsx
|
|
3056
|
+
* <Tooltip
|
|
3057
|
+
* content={
|
|
3058
|
+
* <div>
|
|
3059
|
+
* <strong>Premium Feature</strong>
|
|
3060
|
+
* <p>Upgrade to access this feature</p>
|
|
3061
|
+
* </div>
|
|
3062
|
+
* }
|
|
3063
|
+
* backgroundColor="#1f2937"
|
|
3064
|
+
* sideOffset={10}
|
|
3065
|
+
* >
|
|
3066
|
+
* <LockIcon />
|
|
3067
|
+
* </Tooltip>
|
|
3068
|
+
* ```
|
|
3069
|
+
*
|
|
3070
|
+
* @example
|
|
3071
|
+
* Bottom-positioned with custom delay:
|
|
3072
|
+
*
|
|
3073
|
+
* ```tsx
|
|
3074
|
+
* <Tooltip
|
|
3075
|
+
* content="Last updated: 2 hours ago"
|
|
3076
|
+
* side="bottom"
|
|
3077
|
+
* delayDuration={500}
|
|
3078
|
+
* >
|
|
3079
|
+
* <span>Status: Active</span>
|
|
3080
|
+
* </Tooltip>
|
|
3081
|
+
* ```
|
|
3082
|
+
*/
|
|
3083
|
+
declare const Tooltip: FC<TooltipProps>;
|
|
3084
|
+
|
|
3085
|
+
/** Extensible variant map - To allow module augmentation */
|
|
3086
|
+
interface AlertVariantMap {
|
|
3087
|
+
error: unknown;
|
|
3088
|
+
warning: unknown;
|
|
3089
|
+
info: unknown;
|
|
3090
|
+
success: unknown;
|
|
3091
|
+
default: unknown;
|
|
3092
|
+
}
|
|
3093
|
+
interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
|
3094
|
+
/**
|
|
3095
|
+
* Alert variant to display.(Default: 'error')
|
|
3096
|
+
* */
|
|
3097
|
+
variant?: keyof AlertVariantMap;
|
|
3098
|
+
/**
|
|
3099
|
+
* Determines if the alert should be condensed.(Default: false)
|
|
3100
|
+
* */
|
|
3101
|
+
condensed?: boolean;
|
|
3102
|
+
/**
|
|
3103
|
+
* Main message to display in the alert.
|
|
3104
|
+
*/
|
|
3105
|
+
title: ReactNode | FC;
|
|
3106
|
+
/**
|
|
3107
|
+
* Extra description to display in the alert.
|
|
3108
|
+
*/
|
|
3109
|
+
description?: ReactNode | FC;
|
|
3110
|
+
/**
|
|
3111
|
+
* Callback function to handle the remove event.
|
|
3112
|
+
*/
|
|
3113
|
+
onRemove?: () => void;
|
|
3114
|
+
/**
|
|
3115
|
+
* Custom icon to display in the alert.
|
|
3116
|
+
* If provided, iconClassName will be ignored.
|
|
3117
|
+
*/
|
|
3118
|
+
icon?: ReactNode | FC;
|
|
3119
|
+
/**
|
|
3120
|
+
* Custom class name for the icon.
|
|
3121
|
+
* Only used if icon is not provided.
|
|
3122
|
+
*/
|
|
3123
|
+
iconClassName?: string;
|
|
3124
|
+
}
|
|
3125
|
+
|
|
3126
|
+
/**
|
|
3127
|
+
* An alert component for displaying important messages with different severity levels.
|
|
3128
|
+
*
|
|
3129
|
+
* Supports multiple variants (error, success, warning, info), optional descriptions,
|
|
3130
|
+
* custom icons, and dismissal functionality. The `condensed` prop reduces vertical padding
|
|
3131
|
+
* for a more compact appearance.
|
|
3132
|
+
*
|
|
3133
|
+
* @example
|
|
3134
|
+
* ```tsx
|
|
3135
|
+
* // Basic alert
|
|
3136
|
+
* <Alert title="This is an alert message" />
|
|
3137
|
+
*
|
|
3138
|
+
* // Different variants
|
|
3139
|
+
* <Alert variant="success" title="Success!" />
|
|
3140
|
+
* <Alert variant="warning" title="Warning!" />
|
|
3141
|
+
* <Alert variant="info" title="Information" />
|
|
3142
|
+
*
|
|
3143
|
+
* // Condensed style
|
|
3144
|
+
* <Alert variant="success" condensed title="This is a success message" />
|
|
3145
|
+
*
|
|
3146
|
+
* // With description and remove button
|
|
3147
|
+
* <Alert
|
|
3148
|
+
* variant="warning"
|
|
3149
|
+
* title="Warning!"
|
|
3150
|
+
* description="This is a detailed warning message with more context."
|
|
3151
|
+
* onRemove={() => console.log('Alert dismissed')}
|
|
3152
|
+
* />
|
|
3153
|
+
*
|
|
3154
|
+
* // With custom icon
|
|
3155
|
+
* <Alert
|
|
3156
|
+
* variant="info"
|
|
3157
|
+
* title="Custom Icon"
|
|
3158
|
+
* icon={<CustomIcon />}
|
|
3159
|
+
* />
|
|
3160
|
+
* ```
|
|
3161
|
+
*/
|
|
3162
|
+
declare const Alert: FC<AlertProps>;
|
|
3163
|
+
|
|
3164
|
+
interface PaginationProps {
|
|
3165
|
+
/**
|
|
3166
|
+
* Current page number.
|
|
3167
|
+
*/
|
|
3168
|
+
currentPage: number;
|
|
3169
|
+
/**
|
|
3170
|
+
* Total number of pages.
|
|
3171
|
+
*/
|
|
3172
|
+
totalPages: number;
|
|
3173
|
+
/**
|
|
3174
|
+
* Callback function to handle the page change event.
|
|
3175
|
+
*/
|
|
3176
|
+
onChange: (page: number) => void;
|
|
3177
|
+
/**
|
|
3178
|
+
* Custom styling(classname) to apply to the component.
|
|
3179
|
+
*/
|
|
3180
|
+
className?: string;
|
|
3181
|
+
}
|
|
3182
|
+
|
|
3183
|
+
/**
|
|
3184
|
+
* A pagination component for navigating through multiple pages of content.
|
|
3185
|
+
*
|
|
3186
|
+
* Automatically handles ellipsis display for large page counts and hides itself
|
|
3187
|
+
* when there is only one page. Features previous/next buttons and direct page
|
|
3188
|
+
* number navigation.
|
|
3189
|
+
*
|
|
3190
|
+
* @example
|
|
3191
|
+
* ```tsx
|
|
3192
|
+
* // Basic usage
|
|
3193
|
+
* const [page, setPage] = useState(1);
|
|
3194
|
+
* <Pagination
|
|
3195
|
+
* currentPage={page}
|
|
3196
|
+
* totalPages={10}
|
|
3197
|
+
* onChange={setPage}
|
|
3198
|
+
* />
|
|
3199
|
+
*
|
|
3200
|
+
* // With API data fetching
|
|
3201
|
+
* <Pagination
|
|
3202
|
+
* currentPage={currentPage}
|
|
3203
|
+
* totalPages={Math.ceil(totalItems / itemsPerPage)}
|
|
3204
|
+
* onChange={(newPage) => {
|
|
3205
|
+
* setCurrentPage(newPage);
|
|
3206
|
+
* fetchData(newPage);
|
|
3207
|
+
* }}
|
|
3208
|
+
* />
|
|
3209
|
+
*
|
|
3210
|
+
* // Custom styling
|
|
3211
|
+
* <Pagination
|
|
3212
|
+
* currentPage={page}
|
|
3213
|
+
* totalPages={20}
|
|
3214
|
+
* onChange={setPage}
|
|
3215
|
+
* className="justify-center mt-8"
|
|
3216
|
+
* />
|
|
3217
|
+
* ```
|
|
3218
|
+
*/
|
|
3219
|
+
declare const Pagination: FC<PaginationProps>;
|
|
3220
|
+
|
|
3221
|
+
interface DialogContentProps extends DialogOptions {
|
|
3222
|
+
/**
|
|
3223
|
+
* Function to close the dialog.
|
|
3224
|
+
* In case you want to close the dialog programmatically.
|
|
3225
|
+
* */
|
|
3226
|
+
dismiss: () => void;
|
|
3227
|
+
}
|
|
3228
|
+
interface ActionsArgs extends DialogContentProps {
|
|
3229
|
+
/**
|
|
3230
|
+
* Function to be prevented to close the dialog.
|
|
3231
|
+
* By default, the dialog will be closed after the action is executed.
|
|
3232
|
+
* You can prevent the dialog from closing by calling this function.
|
|
3233
|
+
*
|
|
3234
|
+
* @example
|
|
3235
|
+
* ```tsx
|
|
3236
|
+
* const handleConfirm = ({ preventDefault }) => {
|
|
3237
|
+
* // Do something
|
|
3238
|
+
* preventDefault();
|
|
3239
|
+
* };
|
|
3240
|
+
* */
|
|
3241
|
+
preventDefault: () => void;
|
|
3242
|
+
}
|
|
3243
|
+
interface DialogOptions {
|
|
3244
|
+
/**
|
|
3245
|
+
* Content to be displayed in the confirm dialog.
|
|
3246
|
+
* */
|
|
3247
|
+
content?: ReactNode | FC<DialogContentProps>;
|
|
3248
|
+
/**
|
|
3249
|
+
* Additional class name for the confirm modal
|
|
3250
|
+
* */
|
|
3251
|
+
className?: string;
|
|
3252
|
+
/**
|
|
3253
|
+
* Dismiss the dialog on pressing the `Escape` key.
|
|
3254
|
+
* Default is `true`.
|
|
3255
|
+
* */
|
|
3256
|
+
dismissOnEsc?: boolean;
|
|
3257
|
+
/**
|
|
3258
|
+
* Dismiss the dialog on clicking outside the dialog.
|
|
3259
|
+
* Default is `true`.
|
|
3260
|
+
* */
|
|
3261
|
+
dismissOnOutsideClick?: boolean;
|
|
3262
|
+
/** Data attributes to be added to the dialog */
|
|
3263
|
+
[key: `data-${string}`]: string;
|
|
3264
|
+
}
|
|
3265
|
+
|
|
3266
|
+
/**
|
|
3267
|
+
* Dialog is a lightweight, imperative modal component that renders content in a centered overlay.
|
|
3268
|
+
* It serves as the foundational layer for more complex dialog patterns like ConfirmDialog.
|
|
3269
|
+
*
|
|
3270
|
+
* The component automatically handles focus management, escape key dismissal, and click-outside
|
|
3271
|
+
* behavior. Content can be provided as a React component or render function that receives
|
|
3272
|
+
* a dismiss callback for programmatic control.
|
|
3273
|
+
*
|
|
3274
|
+
* @example
|
|
3275
|
+
* Image lightbox with custom controls:
|
|
3276
|
+
*
|
|
3277
|
+
* ```tsx
|
|
3278
|
+
* const openImageViewer = (imageUrl: string) => {
|
|
3279
|
+
* Dialog.show({
|
|
3280
|
+
* content: ({ dismiss }) => (
|
|
3281
|
+
* <div className="relative">
|
|
3282
|
+
* <img src={imageUrl} alt="Preview" className="max-w-4xl" />
|
|
3283
|
+
* <button
|
|
3284
|
+
* onClick={dismiss}
|
|
3285
|
+
* className="absolute top-4 right-4"
|
|
3286
|
+
* >
|
|
3287
|
+
* ✕
|
|
3288
|
+
* </button>
|
|
3289
|
+
* </div>
|
|
3290
|
+
* ),
|
|
3291
|
+
* className: "bg-transparent shadow-none",
|
|
3292
|
+
* dismissOnEsc: true,
|
|
3293
|
+
* dismissOnOutsideClick: true
|
|
3294
|
+
* });
|
|
3295
|
+
* };
|
|
3296
|
+
* ```
|
|
3297
|
+
*
|
|
3298
|
+
* @example
|
|
3299
|
+
* Form modal with data submission:
|
|
3300
|
+
*
|
|
3301
|
+
* ```tsx
|
|
3302
|
+
* const showUserForm = (userId?: string) => {
|
|
3303
|
+
* Dialog.show({
|
|
3304
|
+
* content: ({ dismiss }) => {
|
|
3305
|
+
* const [formData, setFormData] = useState({});
|
|
3306
|
+
*
|
|
3307
|
+
* const handleSubmit = async () => {
|
|
3308
|
+
* await saveUser(userId, formData);
|
|
3309
|
+
* dismiss();
|
|
3310
|
+
* showSuccessToast("User saved");
|
|
3311
|
+
* };
|
|
3312
|
+
*
|
|
3313
|
+
* return (
|
|
3314
|
+
* <UserForm
|
|
3315
|
+
* data={formData}
|
|
3316
|
+
* onChange={setFormData}
|
|
3317
|
+
* onSubmit={handleSubmit}
|
|
3318
|
+
* onCancel={dismiss}
|
|
3319
|
+
* />
|
|
3320
|
+
* );
|
|
3321
|
+
* },
|
|
3322
|
+
* className: "max-w-2xl p-6",
|
|
3323
|
+
* dismissOnEsc: false,
|
|
3324
|
+
* dismissOnOutsideClick: false
|
|
3325
|
+
* });
|
|
3326
|
+
* };
|
|
3327
|
+
* ```
|
|
3328
|
+
*
|
|
3329
|
+
* @example
|
|
3330
|
+
* Video player modal with tracking:
|
|
3331
|
+
*
|
|
3332
|
+
* ```tsx
|
|
3333
|
+
* Dialog.show({
|
|
3334
|
+
* content: () => (
|
|
3335
|
+
* <VideoPlayer
|
|
3336
|
+
* src="/tutorial.mp4"
|
|
3337
|
+
* autoPlay
|
|
3338
|
+
* onEnded={() => {
|
|
3339
|
+
* trackAnalytics("video_completed");
|
|
3340
|
+
* Dialog.dismiss();
|
|
3341
|
+
* }}
|
|
3342
|
+
* />
|
|
3343
|
+
* ),
|
|
3344
|
+
* className: "w-screen h-screen max-w-none",
|
|
3345
|
+
* dismissOnEsc: true,
|
|
3346
|
+
* "data-video-modal": "true"
|
|
3347
|
+
* });
|
|
3348
|
+
* ```
|
|
3349
|
+
*
|
|
3350
|
+
* @example
|
|
3351
|
+
* Loading state with external dismissal:
|
|
3352
|
+
*
|
|
3353
|
+
* ```tsx
|
|
3354
|
+
* // Show loading dialog
|
|
3355
|
+
* Dialog.show({
|
|
3356
|
+
* content: () => <LoadingSpinner text="Processing payment..." />,
|
|
3357
|
+
* className: "w-64",
|
|
3358
|
+
* dismissOnEsc: false,
|
|
3359
|
+
* dismissOnOutsideClick: false
|
|
3360
|
+
* });
|
|
3361
|
+
*
|
|
3362
|
+
* // Dismiss from anywhere after async operation
|
|
3363
|
+
* await processPayment();
|
|
3364
|
+
* Dialog.dismiss();
|
|
3365
|
+
* ```
|
|
3366
|
+
*
|
|
3367
|
+
* @note
|
|
3368
|
+
* For dialogs requiring user confirmation with standardized action buttons,
|
|
3369
|
+
* consider using the `ConfirmDialog` component instead, which provides a
|
|
3370
|
+
* more opinionated interface for confirmation workflows.
|
|
3371
|
+
*/
|
|
3372
|
+
declare const Dialog: {
|
|
3373
|
+
show: (options: DialogOptions) => void;
|
|
3374
|
+
dismiss: () => void;
|
|
3375
|
+
};
|
|
3376
|
+
|
|
3377
|
+
interface ConfirmDialogContentProps extends ConfirmDialogOptions {
|
|
3378
|
+
/**
|
|
3379
|
+
* Function to close the dialog.
|
|
3380
|
+
* In case you want to close the dialog programmatically.
|
|
3381
|
+
* */
|
|
3382
|
+
dismiss: () => void;
|
|
3383
|
+
}
|
|
3384
|
+
interface ConfirmDialogActionsArgs extends ConfirmDialogContentProps {
|
|
3385
|
+
/**
|
|
3386
|
+
* Function to be prevented to close the dialog.
|
|
3387
|
+
* By default, the dialog will be closed after the action is executed.
|
|
3388
|
+
* You can prevent the dialog from closing by calling this function.
|
|
3389
|
+
*
|
|
3390
|
+
* @example
|
|
3391
|
+
* ```tsx
|
|
3392
|
+
* const handleConfirm = ({ preventDefault }) => {
|
|
3393
|
+
* // Do something
|
|
3394
|
+
* preventDefault();
|
|
3395
|
+
* };
|
|
3396
|
+
* */
|
|
3397
|
+
preventDefault: () => void;
|
|
3398
|
+
}
|
|
3399
|
+
interface ConfirmDialogOptions extends Omit<DialogOptions, "content" | "className"> {
|
|
3400
|
+
/**
|
|
3401
|
+
* Title of the confirm dialog
|
|
3402
|
+
* */
|
|
3403
|
+
title?: string;
|
|
3404
|
+
/**
|
|
3405
|
+
* Content to be displayed in the confirm dialog.
|
|
3406
|
+
* */
|
|
3407
|
+
content?: ReactNode | FC<ConfirmDialogContentProps>;
|
|
3408
|
+
/**
|
|
3409
|
+
* Label for the confirm button.
|
|
3410
|
+
* */
|
|
3411
|
+
confirmButtonLabel?: string;
|
|
3412
|
+
/**
|
|
3413
|
+
* Label for the cancel button.
|
|
3414
|
+
* */
|
|
3415
|
+
cancelButtonLabel?: string;
|
|
3416
|
+
/**
|
|
3417
|
+
* Additional class name for the confirm modal
|
|
3418
|
+
* */
|
|
3419
|
+
className?: string;
|
|
3420
|
+
/**
|
|
3421
|
+
* Additional class name for the title
|
|
3422
|
+
* */
|
|
3423
|
+
titleClassName?: string;
|
|
3424
|
+
/**
|
|
3425
|
+
* Additional class name for the content
|
|
3426
|
+
* */
|
|
3427
|
+
contentClassName?: string;
|
|
3428
|
+
/**
|
|
3429
|
+
* Optional function to be called when the user confirms the action in the dialog.
|
|
3430
|
+
* */
|
|
3431
|
+
onConfirm?: (e: ConfirmDialogActionsArgs) => void;
|
|
3432
|
+
/**
|
|
3433
|
+
* Optional function to be called when the user cancel the action in the dialog.
|
|
3434
|
+
* */
|
|
3435
|
+
onCancel?: (e: ConfirmDialogActionsArgs) => void;
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3438
|
+
/**
|
|
3439
|
+
* ConfirmDialog is a flexible confirmation modal component that prompts users for action validation.
|
|
3440
|
+
* Built on top of the Dialog component, it provides a standardized interface for displaying
|
|
3441
|
+
* confirmation prompts with customizable content, buttons, and behavior.
|
|
3442
|
+
*
|
|
3443
|
+
* @example
|
|
3444
|
+
* Delete confirmation with simple text:
|
|
3445
|
+
*
|
|
3446
|
+
* ```tsx
|
|
3447
|
+
* ConfirmDialog.show({
|
|
3448
|
+
* title: "Delete Account",
|
|
3449
|
+
* content: "Are you sure you want to permanently delete your account? This action cannot be undone.",
|
|
3450
|
+
* confirmButtonLabel: "Delete",
|
|
3451
|
+
* cancelButtonLabel: "Keep Account",
|
|
3452
|
+
* onConfirm: async () => {
|
|
3453
|
+
* showSuccessNotification("Account deleted successfully");
|
|
3454
|
+
* },
|
|
3455
|
+
* onCancel: () => {
|
|
3456
|
+
* trackAnalytics("account_deletion_cancelled");
|
|
3457
|
+
* }
|
|
3458
|
+
* });
|
|
3459
|
+
* ```
|
|
3460
|
+
*
|
|
3461
|
+
* @example
|
|
3462
|
+
* By default, if you pass an async function to `onConfirm` or `onCancel`, the dialog
|
|
3463
|
+
* will show a loading state on the respective button until the promise resolves.
|
|
3464
|
+
*
|
|
3465
|
+
* ```tsx
|
|
3466
|
+
* ConfirmDialog.show({
|
|
3467
|
+
* title: "Save Changes",
|
|
3468
|
+
* content: "Would you like to save your changes before leaving?",
|
|
3469
|
+
* confirmButtonLabel: "Save & Exit",
|
|
3470
|
+
* cancelButtonLabel: "Discard",
|
|
3471
|
+
* className: "max-w-[500px]",
|
|
3472
|
+
* onConfirm: async () => {
|
|
3473
|
+
* try {
|
|
3474
|
+
* await saveFormData();
|
|
3475
|
+
* router.push("/dashboard");
|
|
3476
|
+
* } catch (error) {
|
|
3477
|
+
* showError("Failed to save changes");
|
|
3478
|
+
* dismiss();
|
|
3479
|
+
* }
|
|
3480
|
+
* }
|
|
3481
|
+
* });
|
|
3482
|
+
* ```
|
|
3483
|
+
*
|
|
3484
|
+
* @example
|
|
3485
|
+
* Rich content with custom component:
|
|
3486
|
+
*
|
|
3487
|
+
* ```tsx
|
|
3488
|
+
* ConfirmDialog.show({
|
|
3489
|
+
* title: "Transfer Ownership",
|
|
3490
|
+
* content: ({ dismiss }) => (
|
|
3491
|
+
* <div className="space-y-4">
|
|
3492
|
+
* <p>Transfer project ownership to:</p>
|
|
3493
|
+
* <UserSelector onSelect={setSelectedUser} />
|
|
3494
|
+
* <Button variant="link" onClick={dismiss}>
|
|
3495
|
+
* Cancel transfer
|
|
3496
|
+
* </Button>
|
|
3497
|
+
* </div>
|
|
3498
|
+
* ),
|
|
3499
|
+
* confirmButtonLabel: "Transfer Now",
|
|
3500
|
+
* cancelButtonLabel: "Go Back",
|
|
3501
|
+
* titleClassName: "text-warning",
|
|
3502
|
+
* contentClassName: "min-h-[200px]",
|
|
3503
|
+
* onConfirm: ({ dismiss }) => {
|
|
3504
|
+
* performTransfer();
|
|
3505
|
+
* dismiss();
|
|
3506
|
+
* }
|
|
3507
|
+
* });
|
|
3508
|
+
* ```
|
|
3509
|
+
*
|
|
3510
|
+
* @example
|
|
3511
|
+
* Programmatic dismissal from external code:
|
|
3512
|
+
*
|
|
3513
|
+
* ```tsx
|
|
3514
|
+
* // Show dialog
|
|
3515
|
+
* ConfirmDialog.show({
|
|
3516
|
+
* title: "Processing",
|
|
3517
|
+
* content: "Please wait while we process your request..."
|
|
3518
|
+
* });
|
|
3519
|
+
*
|
|
3520
|
+
* // Close from anywhere in your app
|
|
3521
|
+
* ConfirmDialog.dismiss();
|
|
3522
|
+
* ```
|
|
3523
|
+
*/
|
|
3524
|
+
declare const ConfirmDialog: {
|
|
3525
|
+
show: (options: ConfirmDialogOptions) => void;
|
|
3526
|
+
dismiss: () => void;
|
|
3527
|
+
};
|
|
3528
|
+
|
|
3529
|
+
interface GeckoUIPortalProps {
|
|
3530
|
+
mermaidConfig?: MermaidConfig;
|
|
3531
|
+
toastOptions?: ToasterProps;
|
|
3532
|
+
}
|
|
3533
|
+
|
|
3534
|
+
/**
|
|
3535
|
+
* GeckoUIPortal is a container component that wraps the Toast, ConfirmDialog, and other components that need to mount at the top level of the application.
|
|
3536
|
+
*
|
|
3537
|
+
* Please refer to [MermaidOptions](https://mermaid.js.org/config/schema-docs/config.html#mermaid-config-schema) to see the available options for the `mermaidOptions` prop.
|
|
3538
|
+
* @example
|
|
3539
|
+
*
|
|
3540
|
+
* ```js
|
|
3541
|
+
* import { GeckoUIPortal } from '@geckoui/geckoui';
|
|
3542
|
+
*
|
|
3543
|
+
* renderApp(
|
|
3544
|
+
* <>
|
|
3545
|
+
* <App />
|
|
3546
|
+
* <GeckoUIPortal
|
|
3547
|
+
* toastOptions={{
|
|
3548
|
+
* position: 'bottom-right',
|
|
3549
|
+
* ... other options
|
|
3550
|
+
* }},
|
|
3551
|
+
* mermaidConfig={{
|
|
3552
|
+
* startOnLoad: true,
|
|
3553
|
+
* }}
|
|
3554
|
+
* />
|
|
3555
|
+
* </>
|
|
3556
|
+
* )
|
|
3557
|
+
* ```
|
|
3558
|
+
* */
|
|
3559
|
+
declare const GeckoUIPortal: FC<GeckoUIPortalProps>;
|
|
3560
|
+
|
|
3561
|
+
/** Extensible placement map - To allow module augmentation */
|
|
3562
|
+
interface DrawerPlacementMap {
|
|
3563
|
+
top: unknown;
|
|
3564
|
+
bottom: unknown;
|
|
3565
|
+
left: unknown;
|
|
3566
|
+
right: unknown;
|
|
3567
|
+
}
|
|
3568
|
+
interface DrawerProps {
|
|
3569
|
+
/**
|
|
3570
|
+
* Open/Close the drawer
|
|
3571
|
+
* */
|
|
3572
|
+
open: boolean;
|
|
3573
|
+
/**
|
|
3574
|
+
* Allow clicking outside of drawer to close
|
|
3575
|
+
* If true, you can click through backdrop to close the drawer
|
|
3576
|
+
* If you pass `handleClose` prop, you can use it to close the drawer
|
|
3577
|
+
* Use it with caution, it may cause bad UX in some cases
|
|
3578
|
+
* Eg. let's say you have an `a` tag that points to another page,
|
|
3579
|
+
* if you click on that element, it will close the drawer and navigate to the new page
|
|
3580
|
+
*
|
|
3581
|
+
* ---
|
|
3582
|
+
* Default: false
|
|
3583
|
+
* */
|
|
3584
|
+
allowClickOutside?: boolean;
|
|
3585
|
+
/**
|
|
3586
|
+
* Callback fired when click on outside of drawer
|
|
3587
|
+
* */
|
|
3588
|
+
handleClose?: () => void;
|
|
3589
|
+
/**
|
|
3590
|
+
* Backdrop show/hide If true,
|
|
3591
|
+
* This is just a visual effect just setting opacity to 0
|
|
3592
|
+
* So, you can still click the backdrop to close the drawer if you pass `handleClose` prop to close the drawer
|
|
3593
|
+
* */
|
|
3594
|
+
hideBackdrop?: boolean;
|
|
3595
|
+
/**
|
|
3596
|
+
* Display the content of the drawer
|
|
3597
|
+
* */
|
|
3598
|
+
children?: ReactNode;
|
|
3599
|
+
/**
|
|
3600
|
+
* The placement of Drawer
|
|
3601
|
+
*
|
|
3602
|
+
* Default: 'right'
|
|
3603
|
+
* */
|
|
3604
|
+
placement?: keyof DrawerPlacementMap;
|
|
3605
|
+
/**
|
|
3606
|
+
* Additional class name for the backdrop
|
|
3607
|
+
* */
|
|
3608
|
+
backdropClassName?: string;
|
|
3609
|
+
/**
|
|
3610
|
+
* Additional class name for drawer
|
|
3611
|
+
* */
|
|
3612
|
+
className?: string;
|
|
3613
|
+
/**
|
|
3614
|
+
* If true, the drawer will dismiss when the escape key is pressed
|
|
3615
|
+
* Default is true
|
|
3616
|
+
* */
|
|
3617
|
+
dismissOnEscape?: boolean;
|
|
3618
|
+
}
|
|
3619
|
+
|
|
3620
|
+
/**
|
|
3621
|
+
* Drawer is a slide-out panel component that displays auxiliary content from any edge of the viewport.
|
|
3622
|
+
* It provides a less intrusive alternative to modals for navigation menus, settings panels, filters,
|
|
3623
|
+
* and contextual information.
|
|
3624
|
+
*
|
|
3625
|
+
* The component supports four placement directions (top, right, bottom, left) with smooth transitions,
|
|
3626
|
+
* optional backdrop overlay, and flexible dismissal behaviors including ESC key and click-outside handling.
|
|
3627
|
+
*
|
|
3628
|
+
* @example
|
|
3629
|
+
* Mobile navigation menu:
|
|
3630
|
+
*
|
|
3631
|
+
* ```tsx
|
|
3632
|
+
* const [menuOpen, setMenuOpen] = useState(false);
|
|
3633
|
+
*
|
|
3634
|
+
* <button onClick={() => setMenuOpen(true)}>
|
|
3635
|
+
* <MenuIcon />
|
|
3636
|
+
* </button>
|
|
3637
|
+
*
|
|
3638
|
+
* <Drawer
|
|
3639
|
+
* open={menuOpen}
|
|
3640
|
+
* handleClose={() => setMenuOpen(false)}
|
|
3641
|
+
* placement="left"
|
|
3642
|
+
* allowClickOutside
|
|
3643
|
+
* dismissOnEscape
|
|
3644
|
+
* className="w-80 bg-white shadow-xl"
|
|
3645
|
+
* >
|
|
3646
|
+
* <nav className="p-6">
|
|
3647
|
+
* <NavigationLinks />
|
|
3648
|
+
* </nav>
|
|
3649
|
+
* </Drawer>
|
|
3650
|
+
* ```
|
|
3651
|
+
*
|
|
3652
|
+
* @example
|
|
3653
|
+
* Filter panel with backdrop:
|
|
3654
|
+
*
|
|
3655
|
+
* ```tsx
|
|
3656
|
+
* const [filtersOpen, setFiltersOpen] = useState(false);
|
|
3657
|
+
*
|
|
3658
|
+
* <Drawer
|
|
3659
|
+
* open={filtersOpen}
|
|
3660
|
+
* handleClose={() => setFiltersOpen(false)}
|
|
3661
|
+
* placement="right"
|
|
3662
|
+
* allowClickOutside={true}
|
|
3663
|
+
* backdropClassName="bg-black/60"
|
|
3664
|
+
* className="w-96 p-6"
|
|
3665
|
+
* >
|
|
3666
|
+
* <FilterPanel
|
|
3667
|
+
* onApply={(filters) => {
|
|
3668
|
+
* applyFilters(filters);
|
|
3669
|
+
* setFiltersOpen(false);
|
|
3670
|
+
* }}
|
|
3671
|
+
* />
|
|
3672
|
+
* </Drawer>
|
|
3673
|
+
* ```
|
|
3674
|
+
*
|
|
3675
|
+
* @example
|
|
3676
|
+
* Notification center from top:
|
|
3677
|
+
*
|
|
3678
|
+
* ```tsx
|
|
3679
|
+
* <Drawer
|
|
3680
|
+
* open={showNotifications}
|
|
3681
|
+
* handleClose={() => setShowNotifications(false)}
|
|
3682
|
+
* placement="top"
|
|
3683
|
+
* hideBackdrop={false}
|
|
3684
|
+
* allowClickOutside
|
|
3685
|
+
* className="h-96 border-b shadow-lg"
|
|
3686
|
+
* >
|
|
3687
|
+
* <NotificationList
|
|
3688
|
+
* notifications={notifications}
|
|
3689
|
+
* onMarkAllRead={handleMarkAllRead}
|
|
3690
|
+
* />
|
|
3691
|
+
* </Drawer>
|
|
3692
|
+
* ```
|
|
3693
|
+
*
|
|
3694
|
+
* @example
|
|
3695
|
+
* Bottom sheet for mobile actions:
|
|
3696
|
+
*
|
|
3697
|
+
* ```tsx
|
|
3698
|
+
* <Drawer
|
|
3699
|
+
* open={isBottomSheetOpen}
|
|
3700
|
+
* handleClose={() => setBottomSheetOpen(false)}
|
|
3701
|
+
* placement="bottom"
|
|
3702
|
+
* allowClickOutside
|
|
3703
|
+
* dismissOnEscape={false}
|
|
3704
|
+
* backdropClassName="bg-black/40"
|
|
3705
|
+
* className="h-64 rounded-t-2xl"
|
|
3706
|
+
* >
|
|
3707
|
+
* <ActionSheet
|
|
3708
|
+
* actions={mobileActions}
|
|
3709
|
+
* onSelect={handleActionSelect}
|
|
3710
|
+
* />
|
|
3711
|
+
* </Drawer>
|
|
3712
|
+
* ```
|
|
3713
|
+
*
|
|
3714
|
+
* @example
|
|
3715
|
+
* Settings panel without backdrop:
|
|
3716
|
+
*
|
|
3717
|
+
* ```tsx
|
|
3718
|
+
* <Drawer
|
|
3719
|
+
* open={settingsVisible}
|
|
3720
|
+
* handleClose={() => setSettingsVisible(false)}
|
|
3721
|
+
* placement="right"
|
|
3722
|
+
* hideBackdrop
|
|
3723
|
+
* allowClickOutside={false}
|
|
3724
|
+
* className="w-[600px] border-l"
|
|
3725
|
+
* >
|
|
3726
|
+
* <SettingsPanel
|
|
3727
|
+
* sections={settingsSections}
|
|
3728
|
+
* onSave={saveSettings}
|
|
3729
|
+
* />
|
|
3730
|
+
* </Drawer>
|
|
3731
|
+
* ```
|
|
3732
|
+
*/
|
|
3733
|
+
declare function Drawer({ open, allowClickOutside, handleClose, hideBackdrop, placement, backdropClassName, className, children, dismissOnEscape }: DrawerProps): react_jsx_runtime.JSX.Element;
|
|
3734
|
+
declare namespace Drawer {
|
|
3735
|
+
var show: (node: ReactNode, options?: Omit<DrawerProps, "open" | "children">) => void;
|
|
3736
|
+
var dismiss: () => void;
|
|
3737
|
+
}
|
|
3738
|
+
|
|
3739
|
+
type ReactTag = keyof JSX.IntrinsicElements | JSXElementConstructor<any>;
|
|
3740
|
+
type MenuButtonProps<T extends ReactTag> = MenuButtonProps$1<T>;
|
|
3741
|
+
type MenuItemsProps<T extends ReactTag> = MenuItemsProps$1<T>;
|
|
3742
|
+
type MenuItemProps<T extends ReactTag> = MenuItemProps$1<T>;
|
|
3743
|
+
|
|
3744
|
+
/**
|
|
3745
|
+
* Menu is a styled wrapper around HeadlessUI's Menu for creating dropdown menus and action lists.
|
|
3746
|
+
* Provides pre-styled components for building accessible, keyboard-navigable menus.
|
|
3747
|
+
* @see https://headlessui.com/react/menu for complete API documentation
|
|
3748
|
+
*/
|
|
3749
|
+
declare const Menu: _headlessui_react._internal_ComponentMenu & {
|
|
3750
|
+
Button: _headlessui_react._internal_ComponentMenuButton;
|
|
3751
|
+
Items: _headlessui_react._internal_ComponentMenuItems;
|
|
3752
|
+
Item: _headlessui_react._internal_ComponentMenuItem;
|
|
3753
|
+
Section: _headlessui_react._internal_ComponentMenuSection;
|
|
3754
|
+
Heading: _headlessui_react._internal_ComponentMenuHeading;
|
|
3755
|
+
Separator: _headlessui_react._internal_ComponentMenuSeparator;
|
|
3756
|
+
};
|
|
3757
|
+
/**
|
|
3758
|
+
* MenuButton triggers the menu dropdown when clicked or activated.
|
|
3759
|
+
* Supports polymorphic rendering via the `as` prop.
|
|
3760
|
+
* @see https://headlessui.com/react/menu for complete API documentation
|
|
3761
|
+
*/
|
|
3762
|
+
declare const MenuButton: <T extends ReactTag>({ as, ...rest }: MenuButtonProps<T>) => react_jsx_runtime.JSX.Element;
|
|
3763
|
+
/**
|
|
3764
|
+
* MenuItems contains the dropdown panel with all menu options.
|
|
3765
|
+
* Automatically handles positioning, animations, and focus management.
|
|
3766
|
+
* @see https://headlessui.com/react/menu for complete API documentation
|
|
3767
|
+
*/
|
|
3768
|
+
declare const MenuItems: <T extends ReactTag>({ as, ...rest }: MenuItemsProps<T>) => react_jsx_runtime.JSX.Element;
|
|
3769
|
+
/**
|
|
3770
|
+
* MenuItem represents an individual selectable option within the menu.
|
|
3771
|
+
* Receives active and disabled states for conditional styling.
|
|
3772
|
+
* @see https://headlessui.com/react/menu for complete API documentation
|
|
3773
|
+
*/
|
|
3774
|
+
declare const MenuItem: <T extends ReactTag>({ children, as, ...rest }: MenuItemProps<T>) => react_jsx_runtime.JSX.Element;
|
|
3775
|
+
/**
|
|
3776
|
+
* MenuHeading displays a non-interactive header within menu sections.
|
|
3777
|
+
* @see https://headlessui.com/react/menu for complete API documentation
|
|
3778
|
+
*/
|
|
3779
|
+
declare const MenuHeading: _headlessui_react._internal_ComponentMenuHeading;
|
|
3780
|
+
/**
|
|
3781
|
+
* MenuSection groups related menu items together under a heading.
|
|
3782
|
+
* @see https://headlessui.com/react/menu for complete API documentation
|
|
3783
|
+
*/
|
|
3784
|
+
declare const MenuSection: _headlessui_react._internal_ComponentMenuSection;
|
|
3785
|
+
/**
|
|
3786
|
+
* MenuSeparator provides a visual divider between menu groups or items.
|
|
3787
|
+
* @see https://headlessui.com/react/menu for complete API documentation
|
|
3788
|
+
*/
|
|
3789
|
+
declare const MenuSeparator: _headlessui_react._internal_ComponentMenuSeparator;
|
|
3790
|
+
|
|
3791
|
+
type DropdownClassName<T> = string | ((item: T, index: number) => string | undefined);
|
|
3792
|
+
interface DropdownItem {
|
|
3793
|
+
label: ReactNode | FC;
|
|
3794
|
+
disabled?: boolean;
|
|
3795
|
+
className?: string;
|
|
3796
|
+
onClick?: () => void;
|
|
3797
|
+
}
|
|
3798
|
+
interface DropdownProps extends PropsWithChildren {
|
|
3799
|
+
anchor?: MenuItemsProps<"button">["anchor"];
|
|
3800
|
+
/**
|
|
3801
|
+
* Items to be displayed in the dropdown
|
|
3802
|
+
* */
|
|
3803
|
+
items: DropdownItem[];
|
|
3804
|
+
/**
|
|
3805
|
+
* Additional class name for the dropdown button
|
|
3806
|
+
* */
|
|
3807
|
+
className?: string;
|
|
3808
|
+
/**
|
|
3809
|
+
* Additional class name for the dropdown menu
|
|
3810
|
+
* */
|
|
3811
|
+
menuClassName?: string;
|
|
3812
|
+
/**
|
|
3813
|
+
* Icon to be displayed on the dropdown button
|
|
3814
|
+
* If you want to hide the icon, pass `null`
|
|
3815
|
+
* */
|
|
3816
|
+
icon?: ReactNode | FC;
|
|
3817
|
+
/**
|
|
3818
|
+
* Hide the icon on the dropdown button
|
|
3819
|
+
* */
|
|
3820
|
+
iconClassName?: string;
|
|
3821
|
+
/**
|
|
3822
|
+
* Hide arrow icon on the dropdown button
|
|
3823
|
+
* */
|
|
3824
|
+
hideArrowIcon?: boolean;
|
|
3825
|
+
[key: `data-${string}`]: string;
|
|
3826
|
+
}
|
|
3827
|
+
|
|
3828
|
+
/**
|
|
3829
|
+
* Fast and easy dropdown component extended from `Menu` and `Button` components.
|
|
3830
|
+
* So this won't have much customization options like the `Menu` component.
|
|
3831
|
+
* If you think this component is not enough for your use case, you can use the `Menu` component directly.
|
|
3832
|
+
*
|
|
3833
|
+
* @example
|
|
3834
|
+
*
|
|
3835
|
+
* ```js
|
|
3836
|
+
* import { Dropdown } from "@geckoui/geckoui";
|
|
3837
|
+
*
|
|
3838
|
+
* const items = [
|
|
3839
|
+
* { label: "Item 1", onClick: () => console.log("Item 1 clicked") },
|
|
3840
|
+
* { label: "Item 2", onClick: () => console.log("Item 2 clicked") },
|
|
3841
|
+
* { label: "Item 3", onClick: () => console.log("Item 3 clicked") },
|
|
3842
|
+
* ];
|
|
3843
|
+
*
|
|
3844
|
+
* <Dropdown items={items} />
|
|
3845
|
+
* ```
|
|
3846
|
+
* */
|
|
3847
|
+
declare function Dropdown({ items, anchor, icon, className, menuClassName, iconClassName, children, hideArrowIcon, ...rest }: DropdownProps): react_jsx_runtime.JSX.Element;
|
|
3848
|
+
declare namespace Dropdown {
|
|
3849
|
+
var displayName: string;
|
|
3850
|
+
}
|
|
3851
|
+
|
|
3852
|
+
/**
|
|
3853
|
+
* MermaidDiagram renders diagrams from Mermaid syntax with automatic loading and error state management.
|
|
3854
|
+
* Supports flowcharts, sequence diagrams, class diagrams, and all other Mermaid diagram types.
|
|
3855
|
+
* Provides custom placeholder and error rendering options.
|
|
3856
|
+
*
|
|
3857
|
+
* @example
|
|
3858
|
+
* Flowchart for user workflow:
|
|
3859
|
+
*
|
|
3860
|
+
* ```tsx
|
|
3861
|
+
* <MermaidDiagram>
|
|
3862
|
+
* {`
|
|
3863
|
+
* flowchart LR
|
|
3864
|
+
* Start[User Login] --> Auth{Authenticated?}
|
|
3865
|
+
* Auth -->|Yes| Dashboard[Show Dashboard]
|
|
3866
|
+
* Auth -->|No| Login[Login Page]
|
|
3867
|
+
* Login --> Auth
|
|
3868
|
+
* `}
|
|
3869
|
+
* </MermaidDiagram>
|
|
3870
|
+
* ```
|
|
3871
|
+
*
|
|
3872
|
+
* @example
|
|
3873
|
+
* Sequence diagram with custom loading:
|
|
3874
|
+
*
|
|
3875
|
+
* ```tsx
|
|
3876
|
+
* <MermaidDiagram
|
|
3877
|
+
* placeholder={<div className="animate-pulse">Loading diagram...</div>}
|
|
3878
|
+
* renderError={(props) => <ErrorBoundary message={props.message} />}
|
|
3879
|
+
* >
|
|
3880
|
+
* {`
|
|
3881
|
+
* sequenceDiagram
|
|
3882
|
+
* participant Client
|
|
3883
|
+
* participant API
|
|
3884
|
+
* participant Database
|
|
3885
|
+
* Client->>API: Request Data
|
|
3886
|
+
* API->>Database: Query
|
|
3887
|
+
* Database-->>API: Results
|
|
3888
|
+
* API-->>Client: Response
|
|
3889
|
+
* `}
|
|
3890
|
+
* </MermaidDiagram>
|
|
3891
|
+
* ```
|
|
3892
|
+
*
|
|
3893
|
+
* @example
|
|
3894
|
+
* Class diagram for documentation:
|
|
3895
|
+
*
|
|
3896
|
+
* ```tsx
|
|
3897
|
+
* <MermaidDiagram className="border rounded-lg p-4">
|
|
3898
|
+
* {`
|
|
3899
|
+
* classDiagram
|
|
3900
|
+
* class User {
|
|
3901
|
+
* +String email
|
|
3902
|
+
* +String name
|
|
3903
|
+
* +login()
|
|
3904
|
+
* +logout()
|
|
3905
|
+
* }
|
|
3906
|
+
* class Admin {
|
|
3907
|
+
* +manageUsers()
|
|
3908
|
+
* }
|
|
3909
|
+
* User <|-- Admin
|
|
3910
|
+
* `}
|
|
3911
|
+
* </MermaidDiagram>
|
|
3912
|
+
* ```
|
|
3913
|
+
*
|
|
3914
|
+
* @see https://mermaid.js.org/ for diagram syntax reference
|
|
3915
|
+
*/
|
|
3916
|
+
declare const MermaidDiagram: FC<MermaidDiagramProps>;
|
|
3917
|
+
|
|
3918
|
+
interface MarkdownBaseProps<T extends keyof JSX.IntrinsicElements> extends UseMarkdownOptions {
|
|
3919
|
+
/**
|
|
3920
|
+
* HTML tag to render the markdown content.
|
|
3921
|
+
* @default "div"
|
|
3922
|
+
*/
|
|
3923
|
+
as?: T;
|
|
3924
|
+
/**
|
|
3925
|
+
* Placeholder component to show while async rendering is in progress.
|
|
3926
|
+
* Will be ignored if async is false.
|
|
3927
|
+
*/
|
|
3928
|
+
renderPlaceholder?: ReactNode | FC;
|
|
3929
|
+
/**
|
|
3930
|
+
* Error component to show when the markdown fails to render.
|
|
3931
|
+
* If not provided, a simple error message will be shown.
|
|
3932
|
+
*/
|
|
3933
|
+
renderError?: ReactNode | FC<{
|
|
3934
|
+
message: string;
|
|
3935
|
+
}>;
|
|
3936
|
+
/**
|
|
3937
|
+
* Markdown content to render.
|
|
3938
|
+
*/
|
|
3939
|
+
children: string;
|
|
3940
|
+
}
|
|
3941
|
+
type InferredProps<T extends keyof JSX.IntrinsicElements> = JSX.IntrinsicElements[T] & {
|
|
3942
|
+
className?: string;
|
|
3943
|
+
};
|
|
3944
|
+
type MarkdownProps<T extends keyof JSX.IntrinsicElements = "div"> = MarkdownBaseProps<T> & Omit<InferredProps<T>, "children">;
|
|
3945
|
+
|
|
3946
|
+
/**
|
|
3947
|
+
* Markdown renders formatted markdown text as HTML with support for both synchronous
|
|
3948
|
+
* and asynchronous rendering. Includes built-in loading states, error handling, and
|
|
3949
|
+
* HTML sanitization enabled by default for security.
|
|
3950
|
+
*
|
|
3951
|
+
* @example
|
|
3952
|
+
* Basic usage (synchronous rendering with sanitization enabled by default):
|
|
3953
|
+
*
|
|
3954
|
+
* ```tsx
|
|
3955
|
+
* <Markdown className="prose">{docs}</Markdown>
|
|
3956
|
+
* ```
|
|
3957
|
+
*
|
|
3958
|
+
* @example
|
|
3959
|
+
* Async rendering for large markdown content (not for network requests):
|
|
3960
|
+
*
|
|
3961
|
+
* ```tsx
|
|
3962
|
+
* const [largeContent, setLargeContent] = useState('');
|
|
3963
|
+
*
|
|
3964
|
+
* <Markdown
|
|
3965
|
+
* async
|
|
3966
|
+
* renderPlaceholder={<Spinner />}
|
|
3967
|
+
* renderError={(props) => <Alert variant="error">{props.message}</Alert>}
|
|
3968
|
+
* >
|
|
3969
|
+
* {largeContent}
|
|
3970
|
+
* </Markdown>
|
|
3971
|
+
* ```
|
|
3972
|
+
*
|
|
3973
|
+
* @example
|
|
3974
|
+
* Disabling HTML sanitization (⚠️ WARNING: Only use when you 100% trust the source):
|
|
3975
|
+
*
|
|
3976
|
+
* ```tsx
|
|
3977
|
+
* <Markdown sanitize={false} as="article">
|
|
3978
|
+
* {trustedMarkdown}
|
|
3979
|
+
* </Markdown>
|
|
3980
|
+
* ```
|
|
3981
|
+
*
|
|
3982
|
+
* @example
|
|
3983
|
+
* Using with anchor tag and href prop:
|
|
3984
|
+
*
|
|
3985
|
+
* ```tsx
|
|
3986
|
+
* <Markdown as="a" href="https://example.com" target="_blank">
|
|
3987
|
+
* {linkMarkdown}
|
|
3988
|
+
* </Markdown>
|
|
3989
|
+
* ```
|
|
3990
|
+
*/
|
|
3991
|
+
declare function Markdown<T extends keyof JSX.IntrinsicElements = "div">({ children, renderError, renderPlaceholder, as, async, className, sanitize, ...props }: MarkdownProps<T>): react_jsx_runtime.JSX.Element;
|
|
3992
|
+
declare namespace Markdown {
|
|
3993
|
+
var displayName: string;
|
|
3994
|
+
}
|
|
3995
|
+
|
|
3996
|
+
type BaseIconProps = SVGProps<SVGSVGElement>;
|
|
3997
|
+
|
|
3998
|
+
/**
|
|
3999
|
+
* A loading spinner icon component that displays an animated circular indicator.
|
|
4000
|
+
*
|
|
4001
|
+
* The spinner uses the current text color (via `currentColor`) for its stroke,
|
|
4002
|
+
* making it easy to theme by changing the text color of its parent element.
|
|
4003
|
+
*
|
|
4004
|
+
* @example
|
|
4005
|
+
* ```tsx
|
|
4006
|
+
* // Basic usage
|
|
4007
|
+
* <Spinner />
|
|
4008
|
+
*
|
|
4009
|
+
* // With custom color
|
|
4010
|
+
* <Spinner className="stroke-red-500" />
|
|
4011
|
+
* <Spinner stroke="green" />
|
|
4012
|
+
*
|
|
4013
|
+
* // Custom size
|
|
4014
|
+
* <Spinner className="w-8 h-8" />
|
|
4015
|
+
* ```
|
|
4016
|
+
*/
|
|
4017
|
+
declare const Spinner: FC<BaseIconProps>;
|
|
4018
|
+
|
|
4019
|
+
/**
|
|
4020
|
+
* Convert a number to a string with a thousands separator and a fixed number of decimal places.
|
|
4021
|
+
* @param value - The number to convert.
|
|
4022
|
+
* @param maxFractionDigits - The maximum number of decimal places.
|
|
4023
|
+
*
|
|
4024
|
+
* @example
|
|
4025
|
+
* toThousandsSeparatorFormat(1234567.89, 2); // '1,234,567.89'
|
|
4026
|
+
*
|
|
4027
|
+
* */
|
|
4028
|
+
declare const toThousandsSeparatorFormat: (value?: string) => string;
|
|
4029
|
+
|
|
4030
|
+
declare function fileToUInt8Array(file: File, start?: number, end?: number): Promise<Uint8Array<ArrayBuffer>>;
|
|
4031
|
+
|
|
4032
|
+
declare function isTwoFileEqualByFileContent(file1: File, file2: File): Promise<boolean>;
|
|
4033
|
+
|
|
4034
|
+
/**
|
|
4035
|
+
* Check ReactNode is a valid element and has a specific displayName
|
|
4036
|
+
* Usage:
|
|
4037
|
+
* ```js
|
|
4038
|
+
* const isMyElement = hasDisplayName("MyElement");
|
|
4039
|
+
*
|
|
4040
|
+
* nodeArray.filter(isMyElement) // filter out all elements that are not MyElement
|
|
4041
|
+
* ```
|
|
4042
|
+
* */
|
|
4043
|
+
declare const hasDisplayName: (displayName: string) => (e: ReactNode) => boolean;
|
|
4044
|
+
|
|
4045
|
+
declare const getDataAttributes: (props: Record<string, any>) => Record<string, string>;
|
|
4046
|
+
|
|
4047
|
+
declare function isAsyncFn(fn: unknown): boolean;
|
|
4048
|
+
|
|
4049
|
+
declare class BaseFilePickerHandler {
|
|
4050
|
+
accept: string;
|
|
4051
|
+
removeDuplicates: boolean;
|
|
4052
|
+
oldFiles: FilePickerFile[];
|
|
4053
|
+
constructor(accept?: string, removeDuplicates?: boolean, opts?: {
|
|
4054
|
+
oldFiles?: FilePickerFile[];
|
|
4055
|
+
});
|
|
4056
|
+
onDrop(_: DataTransferItemList | undefined): Promise<FilePickerFile[]>;
|
|
4057
|
+
open(options?: OpenFilePickerOptions): Promise<FilePickerFile[]>;
|
|
4058
|
+
protected addFileIfValid(file: FilePickerFile, data?: FilePickerFile[]): Promise<FilePickerFile[]>;
|
|
4059
|
+
}
|
|
4060
|
+
|
|
4061
|
+
declare class FileOnlyPickerHandler extends BaseFilePickerHandler {
|
|
4062
|
+
onDrop(items?: DataTransferItemList): Promise<FilePickerFile[]>;
|
|
4063
|
+
}
|
|
4064
|
+
|
|
4065
|
+
declare const FilePicker: typeof FileOnlyPickerHandler;
|
|
4066
|
+
|
|
4067
|
+
export { type ActionsArgs, Alert, type AlertProps, type AlertVariantMap, BaseDateRangeInput, type BaseDateRangeInputProps, type BaseSelectProps, Button, type ButtonColorMap, type ButtonProps, type ButtonSizeMap, type ButtonVariantMap, _default as Calendar, type CalendarActiveProps, type CalendarOverload, type CalendarProps, type CalendarRangeModeProps, type CalendarRef, type CalendarSingleModeProps, CalendarType, Checkbox, type CheckboxProps, ConfirmDialog, type ConfirmDialogActionsArgs, type ConfirmDialogContentProps, type ConfirmDialogOptions, type CustomSelectOptionArgs, type CustomSelectOptionBaseArgs, type DataAttributeProps, type DateFormat$1 as DateFormat, DateInput, type DateInputProps, type DateRange, DateRangeInput, type DateRangeInputProps, type DayCellRenderProps, Dialog, type DialogContentProps, type DialogOptions, Drawer, type DrawerPlacementMap, type DrawerProps, Dropdown, type DropdownClassName, type DropdownItem, type DropdownProps, FilePicker, type FilePickerFile, type FilePickerOptions, type FileSize, type FileWithPreview, type FocusedOption, GeckoUIPortal, type GeckoUIPortalProps, Input, InputError, type InputErrorProps, type InputProps, Label, type LabelProps, LoadingButton, type LoadingButtonProps, Markdown, type MarkdownBaseProps, type MarkdownProcessorOptions, type MarkdownProps, Menu, MenuButton, type MenuButtonProps, MenuHeading, MenuItem, type MenuItemProps, MenuItems, type MenuItemsProps, MenuSection, MenuSeparator, MermaidDiagram, type MermaidDiagramBaseProps, type MermaidDiagramProps, type MultiSelectProps, type MultiSelectTriggerProps, type MultiSelectTriggerRenderProps, OTPInput, type OTPInputProps, type OpenFilePickerFn, type OpenFilePickerOptions, Pagination, type PaginationProps, type RHFBaseProps, RHFCheckbox, type RHFCheckboxProps, RHFController, RHFCurrencyInput, type RHFCurrencyInputProps, RHFDateInput, type RHFDateInputProps, RHFDateRangeInput, type RHFDateRangeInputProps, RHFError, type RHFErrorProps, type RHFErrorRenderProps, RHFFileInput, type RHFFileInputProps, RHFFilePicker, type RHFFilePickerBaseProps, type RHFFilePickerProps, type RHFFilePickerRenderProps, type RHFFilePickerRendererProps, RHFInput, RHFInputGroup, type RHFInputGroupProps, type RHFInputProps, RHFNumberInput, type RHFNumberInputProps, RHFOTPInput, type RHFOTPInputProps, RHFRadio, type RHFRadioProps, type RHFRenderArgs, RHFSelect, type RHFSelectOverload, type RHFSelectProps, RHFSwitch, type RHFSwitchProps, RHFTextarea, type RHFTextareaProps, Radio, type RadioProps, type ReactTag, Select, SelectConsumer, type SelectConsumerProps, type SelectContextProps, SelectDropdownSearch, SelectEmpty, type SelectEmptyProps, SelectOption, type SelectOptionConfig, type SelectOptionElement, type SelectOptionProps, type SelectOverload, type SelectProps, SelectTrigger, type SelectTriggerBaseRenderProps, type SelectTriggerOverload, type SelectTriggerProps, type SelectionMode, type SingleSelectProps, type SingleSelectTriggerProps, type SingleSelectTriggerRenderProps, Spinner, Switch, type SwitchProps, type SwitchSizeMap, Textarea, type TextareaProps, Tooltip, type TooltipProps, type UseFilePickerOptions, type UseFilePickerReturn, createMarkdownProcessor, fileToUInt8Array, getDataAttributes, hasDisplayName, isAsyncFn, isTwoFileEqualByFileContent, toThousandsSeparatorFormat, useClickOutside, useEscListener, useFilePicker, useMarkdown, useMermaidDiagram, usePreventDefault, useSelect };
|