@nerds-with-charisma/revit-ui 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +208 -1
- package/dist/index.d.ts +60 -2
- package/dist/index.js +382 -203
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,6 +25,213 @@ export const App = () => {
|
|
|
25
25
|
}
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
Pass a custom token object to `RevitUIProvider` to restyle without forking components.
|
|
28
|
+
Pass a custom token object to `RevitUIProvider` to restyle without forking components. Omit `tokens` and the kit uses `revitTokens`. The object must be complete (no merge / partials):
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import type { RevitThemeTokens } from '@nerds-with-charisma/revit-ui'
|
|
32
|
+
|
|
33
|
+
const myTokens: RevitThemeTokens = {
|
|
34
|
+
colors: {
|
|
35
|
+
background: string
|
|
36
|
+
foreground: string
|
|
37
|
+
card: string
|
|
38
|
+
cardForeground: string
|
|
39
|
+
popover: string
|
|
40
|
+
popoverForeground: string
|
|
41
|
+
primary: string
|
|
42
|
+
primaryForeground: string
|
|
43
|
+
secondary: string
|
|
44
|
+
secondaryForeground: string
|
|
45
|
+
muted: string
|
|
46
|
+
mutedForeground: string
|
|
47
|
+
accent: string
|
|
48
|
+
accentForeground: string
|
|
49
|
+
destructive: string
|
|
50
|
+
destructiveForeground: string
|
|
51
|
+
border: string
|
|
52
|
+
input: string
|
|
53
|
+
ring: string
|
|
54
|
+
brand: {
|
|
55
|
+
yellow: string
|
|
56
|
+
yellowLight: string
|
|
57
|
+
offBlack: string
|
|
58
|
+
pink: string
|
|
59
|
+
purple: string
|
|
60
|
+
blue: string
|
|
61
|
+
gold: string
|
|
62
|
+
brown: string
|
|
63
|
+
umber: string
|
|
64
|
+
mist: string
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
colorsDark: {
|
|
68
|
+
background: string
|
|
69
|
+
foreground: string
|
|
70
|
+
card: string
|
|
71
|
+
cardForeground: string
|
|
72
|
+
popover: string
|
|
73
|
+
popoverForeground: string
|
|
74
|
+
primary: string
|
|
75
|
+
primaryForeground: string
|
|
76
|
+
secondary: string
|
|
77
|
+
secondaryForeground: string
|
|
78
|
+
muted: string
|
|
79
|
+
mutedForeground: string
|
|
80
|
+
accent: string
|
|
81
|
+
accentForeground: string
|
|
82
|
+
destructive: string
|
|
83
|
+
destructiveForeground: string
|
|
84
|
+
border: string
|
|
85
|
+
input: string
|
|
86
|
+
ring: string
|
|
87
|
+
brand: {
|
|
88
|
+
yellow: string
|
|
89
|
+
yellowLight: string
|
|
90
|
+
offBlack: string
|
|
91
|
+
pink: string
|
|
92
|
+
purple: string
|
|
93
|
+
blue: string
|
|
94
|
+
gold: string
|
|
95
|
+
brown: string
|
|
96
|
+
umber: string
|
|
97
|
+
mist: string
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
radius: {
|
|
101
|
+
sm: string
|
|
102
|
+
md: string
|
|
103
|
+
lg: string
|
|
104
|
+
xl: string
|
|
105
|
+
pill: string
|
|
106
|
+
}
|
|
107
|
+
fontFamily: {
|
|
108
|
+
sans: string
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
<RevitUIProvider tokens={myTokens}>{children}</RevitUIProvider>
|
|
113
|
+
```
|
|
29
114
|
|
|
30
115
|
Tokens only: `import { revitTokens } from '@nerds-with-charisma/revit-ui/theme/revit'`
|
|
116
|
+
|
|
117
|
+
## Forms (`RevitForm`)
|
|
118
|
+
|
|
119
|
+
Config-driven forms — pass a `fields` array, `RevitForm` handles react-hook-form + labels, validation messages, and wiring.
|
|
120
|
+
|
|
121
|
+
### Example (sign-in)
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
'use client'
|
|
125
|
+
|
|
126
|
+
import { RevitForm } from '@nerds-with-charisma/revit-ui'
|
|
127
|
+
|
|
128
|
+
type SignInValues = {
|
|
129
|
+
email: string
|
|
130
|
+
password: string
|
|
131
|
+
remember: boolean
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export const SignInForm = () => {
|
|
135
|
+
return (
|
|
136
|
+
<RevitForm<SignInValues>
|
|
137
|
+
defaultValues={{ email: '', password: '', remember: false }}
|
|
138
|
+
submitLabel="Sign in"
|
|
139
|
+
onSubmit={(values) => console.log(values)}
|
|
140
|
+
fields={[
|
|
141
|
+
{
|
|
142
|
+
name: 'email',
|
|
143
|
+
label: 'Email',
|
|
144
|
+
type: 'input',
|
|
145
|
+
placeholder: 'you@example.com',
|
|
146
|
+
inputProps: { type: 'email', autoComplete: 'email' },
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: 'password',
|
|
150
|
+
label: 'Password',
|
|
151
|
+
type: 'password',
|
|
152
|
+
placeholder: '••••••••',
|
|
153
|
+
showPasswordToggle: true,
|
|
154
|
+
forgotPassword: {
|
|
155
|
+
label: 'Forgot Password?',
|
|
156
|
+
href: '/forgot-password',
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: 'remember',
|
|
161
|
+
label: 'Remember me',
|
|
162
|
+
type: 'checkbox',
|
|
163
|
+
},
|
|
164
|
+
]}
|
|
165
|
+
/>
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Field types
|
|
171
|
+
|
|
172
|
+
| `type` | Renders | Notes |
|
|
173
|
+
| ------------ | ------------------------------- | ------------------------------------------ |
|
|
174
|
+
| `input` | `Input` | `placeholder`, `inputProps` |
|
|
175
|
+
| `password` | `PasswordInput` | `showPasswordToggle`, `forgotPassword` |
|
|
176
|
+
| `textarea` | `Textarea` | `placeholder`, `textareaProps` |
|
|
177
|
+
| `checkbox` | `Checkbox` | Inline label |
|
|
178
|
+
| `switch` | `Switch` | Inline label |
|
|
179
|
+
| `select` | `Select` | `options: { value, label }[]` |
|
|
180
|
+
| `radio` | `RadioGroup` | `options: { value, label }[]` |
|
|
181
|
+
|
|
182
|
+
Every field supports optional `description` (helper text below the control).
|
|
183
|
+
|
|
184
|
+
### `RevitForm` props
|
|
185
|
+
|
|
186
|
+
| Prop | Type | Default | Description |
|
|
187
|
+
| --------------- | ---------------------------- | ---------- | ------------------------------------ |
|
|
188
|
+
| `defaultValues` | object | required | Initial field values |
|
|
189
|
+
| `fields` | `RevitFormField[]` | required | Field config array |
|
|
190
|
+
| `onSubmit` | `(values) => void` | required | Called with validated values |
|
|
191
|
+
| `submitLabel` | string | `"Submit"` | Submit button text |
|
|
192
|
+
| `hideSubmit` | boolean | `false` | Hide the built-in submit button |
|
|
193
|
+
| `resolver` | RHF `Resolver` | — | Pass a zod/yup resolver for validation |
|
|
194
|
+
| `className` | string | — | Classes on the `<form>` element |
|
|
195
|
+
| `fieldClassName`| string | — | Classes on each `FormItem` |
|
|
196
|
+
|
|
197
|
+
### Password field extras
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
{
|
|
201
|
+
name: 'password',
|
|
202
|
+
label: 'Password',
|
|
203
|
+
type: 'password',
|
|
204
|
+
showPasswordToggle: true, // default true — eye icon inside the input
|
|
205
|
+
forgotPassword: {
|
|
206
|
+
label: 'Forgot Password?', // default
|
|
207
|
+
href: '/forgot-password', // renders <a> (top-right, above input)
|
|
208
|
+
// onClick: () => {}, // use instead of href for a <button>
|
|
209
|
+
},
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
`PasswordInput` is also exported standalone if you need it outside `RevitForm`.
|
|
214
|
+
|
|
215
|
+
### Validation (optional)
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
import { zodResolver } from '@hookform/resolvers/zod'
|
|
219
|
+
import { z } from 'zod'
|
|
220
|
+
|
|
221
|
+
const schema = z.object({
|
|
222
|
+
email: z.string().email(),
|
|
223
|
+
password: z.string().min(8),
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
<RevitForm
|
|
227
|
+
resolver={zodResolver(schema)}
|
|
228
|
+
defaultValues={{ email: '', password: '' }}
|
|
229
|
+
onSubmit={onSubmit}
|
|
230
|
+
fields={[/* ... */]}
|
|
231
|
+
/>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Low-level escape hatch
|
|
235
|
+
|
|
236
|
+
`Form`, `FormField`, `FormItem`, `FormLabel`, `FormControl`, `FormMessage`, and `useForm` are still exported for custom fields that don't fit the config shape.
|
|
237
|
+
|
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,8 @@ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
|
16
16
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
17
17
|
import * as SliderPrimitive from '@radix-ui/react-slider';
|
|
18
18
|
import * as react_hook_form from 'react-hook-form';
|
|
19
|
-
import { FieldValues, FieldPath, ControllerProps } from 'react-hook-form';
|
|
19
|
+
import { FieldValues, FieldPath, ControllerProps, DefaultValues, Resolver } from 'react-hook-form';
|
|
20
|
+
export { useForm } from 'react-hook-form';
|
|
20
21
|
import { Slot } from '@radix-ui/react-slot';
|
|
21
22
|
import { Toaster as Toaster$1 } from 'sonner';
|
|
22
23
|
export { toast } from 'sonner';
|
|
@@ -346,6 +347,63 @@ declare const useFormField: () => {
|
|
|
346
347
|
formMessageId: string;
|
|
347
348
|
};
|
|
348
349
|
|
|
350
|
+
type PasswordInputProps = Omit<ComponentProps<typeof Input>, 'type'> & {
|
|
351
|
+
showPasswordToggle?: boolean;
|
|
352
|
+
};
|
|
353
|
+
declare const PasswordInput: ({ className, showPasswordToggle, ...props }: PasswordInputProps) => react.JSX.Element;
|
|
354
|
+
|
|
355
|
+
type RevitFormOption = {
|
|
356
|
+
value: string;
|
|
357
|
+
label: string;
|
|
358
|
+
};
|
|
359
|
+
type RevitFormFieldBase = {
|
|
360
|
+
name: string;
|
|
361
|
+
label: string;
|
|
362
|
+
description?: string;
|
|
363
|
+
};
|
|
364
|
+
type RevitFormForgotPassword = {
|
|
365
|
+
label?: string;
|
|
366
|
+
href?: string;
|
|
367
|
+
onClick?: () => void;
|
|
368
|
+
};
|
|
369
|
+
type RevitFormField = (RevitFormFieldBase & {
|
|
370
|
+
type: 'input';
|
|
371
|
+
placeholder?: string;
|
|
372
|
+
inputProps?: Omit<InputProps, 'name' | 'value' | 'defaultValue' | 'onChange' | 'onBlur' | 'ref'>;
|
|
373
|
+
}) | (RevitFormFieldBase & {
|
|
374
|
+
type: 'password';
|
|
375
|
+
placeholder?: string;
|
|
376
|
+
showPasswordToggle?: boolean;
|
|
377
|
+
forgotPassword?: RevitFormForgotPassword;
|
|
378
|
+
inputProps?: Omit<PasswordInputProps, 'name' | 'value' | 'defaultValue' | 'onChange' | 'onBlur' | 'ref' | 'showPasswordToggle'>;
|
|
379
|
+
}) | (RevitFormFieldBase & {
|
|
380
|
+
type: 'textarea';
|
|
381
|
+
placeholder?: string;
|
|
382
|
+
textareaProps?: Omit<TextareaProps, 'name' | 'value' | 'defaultValue' | 'onChange' | 'onBlur' | 'ref'>;
|
|
383
|
+
}) | (RevitFormFieldBase & {
|
|
384
|
+
type: 'checkbox';
|
|
385
|
+
}) | (RevitFormFieldBase & {
|
|
386
|
+
type: 'switch';
|
|
387
|
+
}) | (RevitFormFieldBase & {
|
|
388
|
+
type: 'select';
|
|
389
|
+
placeholder?: string;
|
|
390
|
+
options: RevitFormOption[];
|
|
391
|
+
}) | (RevitFormFieldBase & {
|
|
392
|
+
type: 'radio';
|
|
393
|
+
options: RevitFormOption[];
|
|
394
|
+
});
|
|
395
|
+
type RevitFormProps<TFieldValues extends FieldValues = FieldValues> = {
|
|
396
|
+
defaultValues: DefaultValues<TFieldValues>;
|
|
397
|
+
fields: RevitFormField[];
|
|
398
|
+
onSubmit: (values: TFieldValues) => void | Promise<void>;
|
|
399
|
+
resolver?: Resolver<TFieldValues>;
|
|
400
|
+
submitLabel?: string;
|
|
401
|
+
hideSubmit?: boolean;
|
|
402
|
+
className?: string;
|
|
403
|
+
fieldClassName?: string;
|
|
404
|
+
};
|
|
405
|
+
declare const RevitForm: <TFieldValues extends FieldValues = FieldValues>({ className, defaultValues, fieldClassName, fields, hideSubmit, onSubmit, resolver, submitLabel, }: RevitFormProps<TFieldValues>) => react.JSX.Element;
|
|
406
|
+
|
|
349
407
|
type FormItemProps = HTMLAttributes<HTMLDivElement>;
|
|
350
408
|
declare const FormItem: ({ className, ...props }: FormItemProps) => react.JSX.Element;
|
|
351
409
|
|
|
@@ -643,4 +701,4 @@ declare const tokensToCssVars: (tokens: RevitThemeTokens) => {
|
|
|
643
701
|
};
|
|
644
702
|
declare const tokensToStylesheet: (tokens: RevitThemeTokens) => string;
|
|
645
703
|
|
|
646
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, BrandGradient, Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, type CardProps, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, Checkbox, type CheckboxProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, type ComboboxOption, type ComboboxProps, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, ConfirmDialog, ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Drawer, DrawerContent, DrawerDescription, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, FrostFab, FrostNav, FrostPanel, FrostTile, HoverCard, HoverCardContent, HoverCardTrigger, ImageScrim, Input, InputOTP, InputOTPGroup, InputOTPSlot, type InputProps, Label, type LabelProps, Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, Pagination, PaginationBar, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, RevitThemeTokens, RevitUIProvider, ScrollArea, ScrollBar, SearchBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, type SelectTriggerProps, SelectValue, Separator, Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger, Skeleton, Slider, Switch, type SwitchProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, alertVariants, badgeVariants, buttonVariants, cardVariants, cn, inputVariants, labelVariants, selectTriggerVariants, surfaces, textareaVariants, toggleVariants, tokensToCssVars, tokensToStylesheet, useFormField, useSidebar };
|
|
704
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, type AlertProps, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, BrandGradient, Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, type CardProps, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartContainer, Checkbox, type CheckboxProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, type ComboboxOption, type ComboboxProps, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, ConfirmDialog, ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Drawer, DrawerContent, DrawerDescription, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, FrostFab, FrostNav, FrostPanel, FrostTile, HoverCard, HoverCardContent, HoverCardTrigger, ImageScrim, Input, InputOTP, InputOTPGroup, InputOTPSlot, type InputProps, Label, type LabelProps, Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, Pagination, PaginationBar, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PasswordInput, type PasswordInputProps, Popover, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, RevitForm, type RevitFormField, type RevitFormForgotPassword, type RevitFormOption, type RevitFormProps, RevitThemeTokens, RevitUIProvider, ScrollArea, ScrollBar, SearchBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, type SelectTriggerProps, SelectValue, Separator, Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger, Skeleton, Slider, Switch, type SwitchProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, alertVariants, badgeVariants, buttonVariants, cardVariants, cn, inputVariants, labelVariants, selectTriggerVariants, surfaces, textareaVariants, toggleVariants, tokensToCssVars, tokensToStylesheet, useFormField, useSidebar };
|