@twintag/twintag-form 1.0.1 → 1.1.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.
Files changed (69) hide show
  1. package/.turbo/turbo-build.log +6 -6
  2. package/CHANGELOG.md +18 -0
  3. package/README.md +61 -3
  4. package/dev/index.css +2 -0
  5. package/dev/main.tsx +50 -27
  6. package/dist/common/accordion.d.ts +7 -0
  7. package/dist/common/button.d.ts +28 -0
  8. package/dist/common/calendar.d.ts +9 -0
  9. package/dist/common/form.d.ts +1 -1
  10. package/dist/common/icon.d.ts +7 -0
  11. package/dist/common/popover.d.ts +6 -0
  12. package/dist/common/scroll-area.d.ts +5 -0
  13. package/dist/common/select.d.ts +13 -0
  14. package/dist/components/config.d.ts +4 -0
  15. package/dist/components/containers/accordion.d.ts +8 -0
  16. package/dist/components/fields/date-picker.d.ts +3 -0
  17. package/dist/components/{Input/simple.d.ts → fields/input.d.ts} +1 -1
  18. package/dist/components/form.d.ts +3 -1
  19. package/dist/components/index.d.ts +1 -2
  20. package/dist/index.d.ts +2 -0
  21. package/dist/twintag-form.react.js +19844 -6458
  22. package/dist/twintag-form.webcomponent.js +314 -299
  23. package/dist/types/index.d.ts +6 -5
  24. package/dist/utils/data.d.ts +2 -0
  25. package/dist/utils/string.d.ts +3 -0
  26. package/dist/utils/style.d.ts +2 -0
  27. package/index.html +3 -1
  28. package/lib/common/accordion.tsx +77 -0
  29. package/lib/common/button.tsx +3 -0
  30. package/lib/common/calendar.tsx +110 -0
  31. package/lib/common/form.tsx +14 -1
  32. package/lib/common/icon.tsx +35 -0
  33. package/lib/common/input.tsx +2 -1
  34. package/lib/common/popover.tsx +30 -0
  35. package/lib/common/scroll-area.tsx +46 -0
  36. package/lib/common/select.tsx +159 -0
  37. package/lib/common/textarea.tsx +1 -1
  38. package/lib/components/Render/index.tsx +4 -2
  39. package/lib/components/config.tsx +44 -0
  40. package/lib/components/containers/accordion.tsx +105 -0
  41. package/lib/components/containers/category.tsx +48 -0
  42. package/lib/components/fields/date-picker.tsx +117 -0
  43. package/lib/components/{Input → fields}/file.tsx +1 -1
  44. package/lib/components/{Input/simple.tsx → fields/input.tsx} +5 -5
  45. package/lib/components/{Input → fields}/textarea.tsx +2 -2
  46. package/lib/components/form.tsx +19 -3
  47. package/lib/components/index.tsx +0 -3
  48. package/lib/index.tsx +7 -8
  49. package/lib/types/index.ts +13 -11
  50. package/lib/utils/data.ts +18 -0
  51. package/lib/utils/string.ts +12 -0
  52. package/lib/utils/style.ts +8 -0
  53. package/package.json +13 -5
  54. package/tailwind.config.ts +19 -1
  55. package/.turbo/turbo-lint.log +0 -4
  56. package/dist/components/Input/index.d.ts +0 -8
  57. package/lib/components/Input/index.tsx +0 -32
  58. package/lib/components/category.tsx +0 -31
  59. /package/dist/components/{category.d.ts → containers/category.d.ts} +0 -0
  60. /package/dist/components/{Input → fields}/checkbox.d.ts +0 -0
  61. /package/dist/components/{Input → fields}/file.d.ts +0 -0
  62. /package/dist/components/{Input → fields}/radiogroup.d.ts +0 -0
  63. /package/dist/components/{Input → fields}/submit.d.ts +0 -0
  64. /package/dist/components/{Input → fields}/textarea.d.ts +0 -0
  65. /package/dist/components/{Input → fields}/toggle.d.ts +0 -0
  66. /package/lib/components/{Input → fields}/checkbox.tsx +0 -0
  67. /package/lib/components/{Input → fields}/radiogroup.tsx +0 -0
  68. /package/lib/components/{Input → fields}/submit.tsx +0 -0
  69. /package/lib/components/{Input → fields}/toggle.tsx +0 -0
@@ -0,0 +1,105 @@
1
+ import type { Props } from '@twintag/twintag-form/types';
2
+ import type { WithChildren } from 'twintag-types/dom';
3
+
4
+ import { type FC } from 'react';
5
+ import { tv } from 'tailwind-variants';
6
+
7
+ import {
8
+ AccordionContent,
9
+ AccordionItem as AccordionItemPrimitive,
10
+ Accordion as AccordionPrimitive,
11
+ AccordionTrigger,
12
+ } from '@twintag/twintag-form/common/accordion';
13
+ import { Icon } from '@twintag/twintag-form/common/icon';
14
+ import { useTwintagForm } from '@twintag/twintag-form/provider';
15
+ import { camelize } from '@twintag/twintag-form/utils/string';
16
+
17
+ type AccordionRootProps = {
18
+ multiple?: boolean;
19
+ } & WithChildren;
20
+
21
+ const accordionRootVariants = tv({
22
+ base: 'border',
23
+ variants: {
24
+ variant: {
25
+ default: 'rounded-md',
26
+ beta: 'rounded-none',
27
+ },
28
+ },
29
+ defaultVariants: {
30
+ variant: 'default',
31
+ },
32
+ });
33
+ const AccordionRoot: FC<AccordionRootProps> = ({
34
+ multiple = true,
35
+ children,
36
+ }) => {
37
+ const { variant } = useTwintagForm();
38
+
39
+ return (
40
+ <AccordionPrimitive
41
+ type={multiple ? 'multiple' : 'single'}
42
+ collapsible={multiple ? undefined : true}
43
+ >
44
+ <div className={accordionRootVariants({ variant })}>{children}</div>
45
+ </AccordionPrimitive>
46
+ );
47
+ };
48
+ AccordionRoot.displayName = 'AccordionRoot';
49
+
50
+ const accordionItemVariants = tv({
51
+ slots: {
52
+ item: 'px-5 last:border-none',
53
+ trigger: 'flex flex-1 items-center gap-2.5 font-tf-font',
54
+ content: 'space-y-4',
55
+ },
56
+ variants: {
57
+ variant: {
58
+ default: {
59
+ trigger: 'text-base font-medium',
60
+ },
61
+ beta: {
62
+ trigger: 'text-sm',
63
+ },
64
+ },
65
+ },
66
+ defaultVariants: {
67
+ variant: 'default',
68
+ },
69
+ });
70
+
71
+ type AccordionItemProps = Omit<Props, 'bind'> & WithChildren;
72
+ const AccordionItem: FC<AccordionItemProps> = ({
73
+ label = '',
74
+ icon,
75
+ children,
76
+ }) => {
77
+ const { variant } = useTwintagForm();
78
+
79
+ const { item, trigger, content } = accordionItemVariants({ variant });
80
+
81
+ return (
82
+ <AccordionItemPrimitive value={camelize(label)} className={item()}>
83
+ <AccordionTrigger className='text-category'>
84
+ <span className={trigger()}>
85
+ {icon ? <Icon name={icon} className='shrink-0' /> : <></>}
86
+ {label}
87
+ </span>
88
+ </AccordionTrigger>
89
+ <AccordionContent className={content()}>{children}</AccordionContent>
90
+ </AccordionItemPrimitive>
91
+ );
92
+ };
93
+ AccordionItem.displayName = 'AccordionItem';
94
+
95
+ type AccordionProps = {
96
+ subtype?: 'item' | 'multiple' | 'single';
97
+ label?: string;
98
+ } & WithChildren;
99
+ const Accordion: FC<AccordionProps> = ({ subtype = 'single', ...rest }) => {
100
+ if (subtype === 'item') return <AccordionItem {...rest} />;
101
+
102
+ return <AccordionRoot {...rest} />;
103
+ };
104
+
105
+ export { Accordion };
@@ -0,0 +1,48 @@
1
+ import type { FC } from 'react';
2
+ import type { WithChildren } from 'twintag-types/dom';
3
+
4
+ import { tv } from 'tailwind-variants';
5
+
6
+ import { useTwintagForm } from '@twintag/twintag-form/provider';
7
+
8
+ const categoryStyle = tv({
9
+ slots: {
10
+ container: 'relative w-full space-y-4',
11
+ heading: 'font-tf-font text-category',
12
+ content: 'grid gap-4',
13
+ },
14
+ variants: {
15
+ variant: {
16
+ default: {
17
+ heading: 'text-base font-medium',
18
+ },
19
+ beta: {
20
+ heading: 'text-sm font-normal',
21
+ },
22
+ },
23
+ },
24
+ defaultVariants: {
25
+ variant: 'default',
26
+ },
27
+ });
28
+
29
+ type Props = {
30
+ label?: string;
31
+ } & WithChildren;
32
+
33
+ const Category: FC<Props> = ({ label, children }) => {
34
+ const { variant } = useTwintagForm();
35
+
36
+ const { container, heading, content } = categoryStyle({ variant });
37
+
38
+ return (
39
+ <section className={container()}>
40
+ {label ? <h3 className={heading()}>{label}</h3> : <></>}
41
+
42
+ <div className={content()}>{children}</div>
43
+ </section>
44
+ );
45
+ };
46
+ Category.displayName = 'Category';
47
+
48
+ export { Category };
@@ -0,0 +1,117 @@
1
+ import type { Props } from '@twintag/twintag-form/types';
2
+
3
+ import * as React from 'react';
4
+ import { format } from 'date-fns';
5
+ import { AsteriskIcon, Calendar as CalendarIcon } from 'lucide-react';
6
+ import { useFormContext } from 'react-hook-form';
7
+ import { tv } from 'tailwind-variants';
8
+
9
+ import { Button } from '@twintag/twintag-form/common/button';
10
+ import { Calendar } from '@twintag/twintag-form/common/calendar';
11
+ import {
12
+ FormControl,
13
+ FormDescription,
14
+ FormField,
15
+ FormItem,
16
+ FormLabel,
17
+ FormMessage,
18
+ } from '@twintag/twintag-form/common/form';
19
+ import {
20
+ Popover,
21
+ PopoverContent,
22
+ PopoverTrigger,
23
+ } from '@twintag/twintag-form/common/popover';
24
+ import { useTwintagForm } from '@twintag/twintag-form/provider';
25
+
26
+ const triggerVariants = tv({
27
+ base: 'w-full justify-start text-left font-normal',
28
+ variants: {
29
+ variant: {
30
+ default: 'px-3',
31
+ beta: 'rounded-none border-x-transparent border-t-transparent px-1 transition-none hover:bg-white hover:text-muted-foreground',
32
+ },
33
+ withValue: {
34
+ true: 'text-muted-foreground',
35
+ false: '',
36
+ },
37
+ },
38
+ });
39
+
40
+ export const DatePicker: React.FC<Props> = ({ label, bind, options }) => {
41
+ const { variant } = useTwintagForm();
42
+
43
+ const { control } = useFormContext();
44
+
45
+ const isOptional = options?.optionalField;
46
+
47
+ return (
48
+ <FormField
49
+ control={control}
50
+ name={bind}
51
+ rules={{
52
+ required: isOptional ? false : options?.error ?? true,
53
+ }}
54
+ render={({ field }) => (
55
+ <FormItem className='flex flex-col [&>div[data-radix-popper-content-wrapper]]:!z-50'>
56
+ <div className='space-y-0.5'>
57
+ <FormLabel>
58
+ {label}
59
+ {!isOptional ? (
60
+ <span className='ml-0.5 inline-block'>
61
+ <AsteriskIcon className='h-3 w-3 text-destructive' />
62
+ </span>
63
+ ) : (
64
+ <></>
65
+ )}
66
+ </FormLabel>
67
+ {options?.description ? (
68
+ <FormDescription>{options.description}</FormDescription>
69
+ ) : (
70
+ <></>
71
+ )}
72
+ </div>
73
+ <Popover>
74
+ <PopoverTrigger asChild>
75
+ <FormControl>
76
+ <Button
77
+ variant='outline'
78
+ className={triggerVariants({
79
+ variant,
80
+ withValue: !field.value,
81
+ className: 'h-10 gap-3',
82
+ })}
83
+ >
84
+ {field.value ? (
85
+ format(field.value, 'PPP')
86
+ ) : (
87
+ <span>{options?.placeholder ?? 'Select a date'}</span>
88
+ )}
89
+ <CalendarIcon className='ml-auto h-4 w-4 opacity-50' />
90
+ </Button>
91
+ </FormControl>
92
+ </PopoverTrigger>
93
+ <PopoverContent className='w-auto p-0' align='start'>
94
+ <Calendar
95
+ fromYear={1970}
96
+ toYear={2050}
97
+ captionLayout='dropdown-buttons'
98
+ mode='single'
99
+ selected={
100
+ !isNaN(new Date(field.value as Date).getTime())
101
+ ? new Date(field.value as Date)
102
+ : undefined
103
+ }
104
+ onSelect={field.onChange}
105
+ disabled={(date) =>
106
+ date > new Date() || date < new Date('1900-01-01')
107
+ }
108
+ initialFocus
109
+ />
110
+ </PopoverContent>
111
+ </Popover>
112
+ <FormMessage className='pt-1' />
113
+ </FormItem>
114
+ )}
115
+ />
116
+ );
117
+ };
@@ -68,7 +68,7 @@ export const File: FC<Props> = ({ label, bind, options }) => {
68
68
  }}
69
69
  />
70
70
  </FormControl>
71
- <FormMessage />
71
+ <FormMessage className='pt-1.5' />
72
72
  </FormItem>
73
73
  )}
74
74
  />
@@ -12,18 +12,18 @@ import {
12
12
  FormLabel,
13
13
  FormMessage,
14
14
  } from '@twintag/twintag-form/common/form';
15
- import { Input } from '@twintag/twintag-form/common/input';
15
+ import { Input as InputPrimitive } from '@twintag/twintag-form/common/input';
16
16
 
17
- export const Simple: FC<Props> = ({ label, bind, options }) => {
17
+ export const Input: FC<Props> = ({ label, bind, options }) => {
18
18
  const { control } = useFormContext();
19
19
 
20
20
  const isOptional = options?.optionalField;
21
21
 
22
22
  return (
23
23
  <FormField
24
+ defaultValue=''
24
25
  control={control}
25
26
  name={bind}
26
- defaultValue=''
27
27
  rules={{
28
28
  required: isOptional ? false : options?.error ?? true,
29
29
  }}
@@ -47,13 +47,13 @@ export const Simple: FC<Props> = ({ label, bind, options }) => {
47
47
  )}
48
48
  </div>
49
49
  <FormControl>
50
- <Input
50
+ <InputPrimitive
51
51
  type='text'
52
52
  placeholder={options?.placeholder ?? 'Write here...'}
53
53
  {...field}
54
54
  />
55
55
  </FormControl>
56
- <FormMessage />
56
+ <FormMessage className='pt-1' />
57
57
  </FormItem>
58
58
  )}
59
59
  />
@@ -21,9 +21,9 @@ export const Textarea: FC<Props> = ({ label, bind, options }) => {
21
21
 
22
22
  return (
23
23
  <FormField
24
+ defaultValue=''
24
25
  control={control}
25
26
  name={bind}
26
- defaultValue=''
27
27
  rules={{
28
28
  required: isOptional ? false : options?.error ?? true,
29
29
  }}
@@ -52,7 +52,7 @@ export const Textarea: FC<Props> = ({ label, bind, options }) => {
52
52
  placeholder={options?.placeholder ?? 'Write here...'}
53
53
  />
54
54
  </FormControl>
55
- <FormMessage />
55
+ <FormMessage className='pt-1' />
56
56
  </FormItem>
57
57
  )}
58
58
  />
@@ -7,21 +7,36 @@ import { useForm } from 'react-hook-form';
7
7
  import { Form } from '@twintag/twintag-form/common/form';
8
8
 
9
9
  type Props = {
10
+ defaultValues?: FieldValues;
10
11
  resetOnSubmit?: boolean;
11
12
  } & WithChildren;
12
13
 
13
- export const TwintagForm = ({ resetOnSubmit, children }: Props) => {
14
+ export const TwintagForm = ({
15
+ defaultValues,
16
+ resetOnSubmit,
17
+ children,
18
+ }: Props) => {
14
19
  const ref = useRef<HTMLFormElement>(null);
15
20
 
16
- const form = useForm();
21
+ const form = useForm({
22
+ defaultValues,
23
+ });
17
24
 
18
25
  useEffect(() => {
19
26
  if (form.formState.isSubmitSuccessful && resetOnSubmit) {
20
- form.reset();
27
+ if (defaultValues) {
28
+ form.reset(
29
+ Object.keys(defaultValues).reduce(
30
+ (acc, key) => ({ ...acc, [key]: '' }),
31
+ {},
32
+ ),
33
+ );
34
+ }
21
35
  }
22
36
  }, [form.formState]);
23
37
 
24
38
  const onValid = (data: FieldValues) => {
39
+ console.log('form', data);
25
40
  const customSubmit = new CustomEvent('twintag-form-valid', {
26
41
  detail: data,
27
42
  bubbles: true,
@@ -64,6 +79,7 @@ export const TwintagForm = ({ resetOnSubmit, children }: Props) => {
64
79
  return (
65
80
  <Form {...form}>
66
81
  <form
82
+ id='twintag-form'
67
83
  ref={ref}
68
84
  className='relative space-y-4 font-tf-font'
69
85
  onSubmit={form.handleSubmit(onValid, onInvalid)}
@@ -3,9 +3,6 @@ import type { RawJsonComponent } from '@twintag/twintag-form/types';
3
3
  import { Renderer } from '@twintag/twintag-form/components/Render';
4
4
  import { useJson } from '@twintag/twintag-form/components/Render/useJson';
5
5
 
6
- export { Input } from './Input';
7
- export { Category } from './category';
8
-
9
6
  type Props = {
10
7
  config: RawJsonComponent | RawJsonComponent[];
11
8
  };
package/lib/index.tsx CHANGED
@@ -1,19 +1,15 @@
1
- import type { ComponentProps, ElementType } from 'react';
1
+ import type { ComponentProps } from 'react';
2
2
  import type { RawJsonComponent } from '@twintag/twintag-form/types';
3
3
 
4
4
  import { TwintagJsonRenderer } from '@twintag/twintag-form/components';
5
- import { Category } from '@twintag/twintag-form/components/category';
5
+ import { components } from '@twintag/twintag-form/components/config';
6
6
  import { TwintagForm } from '@twintag/twintag-form/components/form';
7
- import { Input } from '@twintag/twintag-form/components/Input';
8
7
  import { TwintagFormProvider } from '@twintag/twintag-form/provider';
9
8
 
10
- const components = new Map<string, ElementType>()
11
- .set('input', Input)
12
- .set('category', Category);
13
-
14
9
  type Props = {
15
10
  config: RawJsonComponent[];
16
11
  options?: Partial<{
12
+ defaultValues?: ComponentProps<typeof TwintagForm>['defaultValues'];
17
13
  variant?: ComponentProps<typeof TwintagFormProvider>['variant'];
18
14
  resetOnSubmit?: boolean;
19
15
  }>;
@@ -22,7 +18,10 @@ type Props = {
22
18
  export const Form = ({ config, options }: Props) => {
23
19
  return (
24
20
  <TwintagFormProvider variant={options?.variant} components={components}>
25
- <TwintagForm resetOnSubmit={options?.resetOnSubmit}>
21
+ <TwintagForm
22
+ defaultValues={options?.defaultValues}
23
+ resetOnSubmit={options?.resetOnSubmit}
24
+ >
26
25
  {config.map((item, idx) => (
27
26
  <TwintagJsonRenderer key={idx} config={item} />
28
27
  ))}
@@ -9,6 +9,7 @@ type RawProps = Partial<{
9
9
  bind: string;
10
10
  subtype: string;
11
11
  label: string;
12
+ icon: string;
12
13
  options: Partial<{
13
14
  description: string;
14
15
  placeholder: string;
@@ -17,17 +18,13 @@ type RawProps = Partial<{
17
18
  }>;
18
19
  }>;
19
20
 
20
- export type RawJsonComponent = RawProps & {
21
- type: string;
22
- children?: RawJsonComponent[];
23
- } & {
24
- props?: RawProps;
25
- };
26
-
27
- export type Props = Omit<RawProps, 'subtype'> & {
28
- bind: string;
29
- items?: ParsedJsonComponent[];
30
- };
21
+ export type RawJsonComponent = RawProps &
22
+ Record<string, unknown> & {
23
+ type: string;
24
+ children?: RawJsonComponent[];
25
+ } & {
26
+ props?: RawProps;
27
+ };
31
28
 
32
29
  export type ParsedJsonComponent = Props & {
33
30
  id: string;
@@ -35,3 +32,8 @@ export type ParsedJsonComponent = Props & {
35
32
  subtype?: string;
36
33
  comp?: ElementType;
37
34
  };
35
+
36
+ export type Props = Omit<RawProps, 'subtype'> & {
37
+ bind: string;
38
+ items?: ParsedJsonComponent[];
39
+ };
@@ -0,0 +1,18 @@
1
+ import type { Props } from '@twintag/twintag-form/types';
2
+
3
+ export const getBindSetFromItems = (items: Props[]): Set<string> => {
4
+ const binds = new Set<string>();
5
+
6
+ items.forEach((item) => {
7
+ if (item.bind) {
8
+ binds.add(item.bind);
9
+ }
10
+
11
+ if (item.items) {
12
+ const subBinds = getBindSetFromItems(item.items);
13
+ subBinds.forEach((bind) => binds.add(bind));
14
+ }
15
+ });
16
+
17
+ return binds;
18
+ };
@@ -0,0 +1,12 @@
1
+ export const camelize = (str: string) => {
2
+ return str
3
+ .replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) {
4
+ return index === 0 ? word.toLowerCase() : word.toUpperCase();
5
+ })
6
+ .replace(/\s+/g, '');
7
+ };
8
+
9
+ export const camelizeKebab = (s: string) =>
10
+ s.replace(/-./g, (x) => x[1].toUpperCase());
11
+
12
+ export const capitalize = (s: string) => s && s[0].toUpperCase() + s.slice(1);
@@ -0,0 +1,8 @@
1
+ import type { ClassValue } from 'clsx';
2
+
3
+ import { clsx } from 'clsx';
4
+ import { twMerge } from 'tailwind-merge';
5
+
6
+ export function cn(...inputs: ClassValue[]) {
7
+ return twMerge(clsx(inputs));
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twintag/twintag-form",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "author": "Twintag",
5
5
  "type": "module",
6
6
  "exports": {
@@ -14,12 +14,16 @@
14
14
  }
15
15
  },
16
16
  "dependencies": {
17
- "@heroicons/react": "^2.0.16",
17
+ "@heroicons/react": "^2.1.1",
18
18
  "@r2wc/react-to-web-component": "^2.0.3",
19
+ "@radix-ui/react-accordion": "^1.1.2",
19
20
  "@radix-ui/react-checkbox": "^1.0.4",
20
21
  "@radix-ui/react-icons": "^1.3.0",
21
22
  "@radix-ui/react-label": "^2.0.2",
23
+ "@radix-ui/react-popover": "^1.0.7",
22
24
  "@radix-ui/react-radio-group": "^1.1.3",
25
+ "@radix-ui/react-scroll-area": "^1.0.5",
26
+ "@radix-ui/react-select": "^2.0.0",
23
27
  "@radix-ui/react-slot": "^1.0.2",
24
28
  "@radix-ui/react-switch": "^1.0.2",
25
29
  "@storybook/react": "7.0.2",
@@ -27,10 +31,14 @@
27
31
  "@twind/preset-autoprefix": "^1.0.7",
28
32
  "@twind/preset-tailwind": "^1.1.4",
29
33
  "@twind/with-web-components": "^1.1.3",
34
+ "clsx": "^2.1.0",
35
+ "date-fns": "^3.3.1",
30
36
  "lucide-react": "^0.269.0",
31
37
  "react": "^18.2.0",
38
+ "react-day-picker": "^8.10.0",
32
39
  "react-dom": "^18.2.0",
33
- "react-hook-form": "^7.47.0",
40
+ "react-hook-form": "^7.50.1",
41
+ "tailwind-merge": "^2.2.1",
34
42
  "uuid": "^9.0.1"
35
43
  },
36
44
  "devDependencies": {
@@ -43,9 +51,9 @@
43
51
  "tailwindcss": "^3.3.6",
44
52
  "vite": "^4.4.9",
45
53
  "vite-plugin-dts": "^3.0.3",
54
+ "eslint-config-custom": "1.0.0",
46
55
  "tsconfig": "0.0.0",
47
- "twintag-types": "0.2.0",
48
- "eslint-config-custom": "1.0.0"
56
+ "twintag-types": "0.2.0"
49
57
  },
50
58
  "publishConfig": {
51
59
  "access": "public"
@@ -3,13 +3,16 @@ import type { Config } from 'tailwindcss';
3
3
  import { fontFamily } from 'tailwindcss/defaultTheme';
4
4
 
5
5
  const config = {
6
- content: ['./dev/main.tsx', './lib/**/*.{ts,tsx}', './index.html'],
6
+ content: ['./lib/**/*.{ts,tsx}'],
7
7
  theme: {
8
8
  extend: {
9
9
  colors: {
10
10
  category: 'hsl(var(--tf-category) / <alpha-value>)',
11
11
  label: 'hsl(var(--tf-label) / <alpha-value>)',
12
+
12
13
  background: 'hsl(var(--tf-background) / <alpha-value>)',
14
+ foreground: 'hsl(var(--tf-foreground) / <alpha-value>)',
15
+
13
16
  primary: {
14
17
  DEFAULT: 'hsl(var(--tf-primary) / <alpha-value>)',
15
18
  foreground: 'hsl(var(--tf-primary-foreground) / <alpha-value>)',
@@ -26,6 +29,7 @@ const config = {
26
29
  DEFAULT: 'hsl(var(--tf-muted) / <alpha-value>)',
27
30
  foreground: 'hsl(var(--tf-muted-foreground) / <alpha-value>)',
28
31
  },
32
+
29
33
  input: 'hsl(var(--tf-input) / <alpha-value>)',
30
34
  ring: 'hsl(var(--tf-ring) / <alpha-value>)',
31
35
  },
@@ -37,6 +41,20 @@ const config = {
37
41
  fontFamily: {
38
42
  'tf-font': ['var(--tf-font)', ...fontFamily.sans],
39
43
  },
44
+ keyframes: {
45
+ 'accordion-down': {
46
+ from: { height: '0' },
47
+ to: { height: 'var(--radix-accordion-content-height)' },
48
+ },
49
+ 'accordion-up': {
50
+ from: { height: 'var(--radix-accordion-content-height)' },
51
+ to: { height: '0' },
52
+ },
53
+ },
54
+ animation: {
55
+ 'accordion-down': 'accordion-down 0.2s ease-out',
56
+ 'accordion-up': 'accordion-up 0.2s ease-out',
57
+ },
40
58
  },
41
59
  },
42
60
  } satisfies Config;
@@ -1,4 +0,0 @@
1
-
2
- > @twintag/twintag-form@0.6.0 lint C:\Users\daryl\Desktop\twintag-projects\twintag-admin\packages\twintag-form
3
- > eslint . --ext .ts,.tsx
4
-
@@ -1,8 +0,0 @@
1
- import type { FC } from 'react';
2
- type Props = {
3
- subtype?: string;
4
- label?: string;
5
- bind?: string;
6
- };
7
- export declare const Input: FC<Props>;
8
- export {};
@@ -1,32 +0,0 @@
1
- import type { ElementType, FC } from 'react';
2
-
3
- import { Checkbox } from './checkbox';
4
- import { File } from './file';
5
- import { RadioGroup } from './radiogroup';
6
- import { Simple } from './simple';
7
- import { Submit } from './submit';
8
- import { Textarea } from './textarea';
9
- import { Toggle } from './toggle';
10
-
11
- const Inputs = new Map<string, ElementType>()
12
- .set('simple', Simple)
13
- .set('textarea', Textarea)
14
- .set('toggle', Toggle)
15
- .set('file', File)
16
- .set('submit', Submit)
17
- .set('checkbox', Checkbox)
18
- .set('radiogroup', RadioGroup);
19
-
20
- type Props = {
21
- subtype?: string;
22
- label?: string;
23
- bind?: string;
24
- };
25
-
26
- export const Input: FC<Props> = ({ subtype = 'simple', ...rest }) => {
27
- const Comp = Inputs.get(subtype);
28
-
29
- if (!Comp) return <></>;
30
-
31
- return <Comp {...rest} />;
32
- };