@ourtrip/ui 1.0.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 (78) hide show
  1. package/dist/components/accordion.js +19 -0
  2. package/dist/components/alert.js +36 -0
  3. package/dist/components/badge.js +47 -0
  4. package/dist/components/breadcrumbs.js +22 -0
  5. package/dist/components/button.js +155 -0
  6. package/dist/components/card.js +29 -0
  7. package/dist/components/checkbox.js +24 -0
  8. package/dist/components/collapse.js +16 -0
  9. package/dist/components/divider.js +38 -0
  10. package/dist/components/input.js +58 -0
  11. package/dist/components/modal.js +10 -0
  12. package/dist/components/phone.js +53 -0
  13. package/dist/components/popover.js +35 -0
  14. package/dist/components/radio.js +38 -0
  15. package/dist/components/range.js +19 -0
  16. package/dist/components/select.js +84 -0
  17. package/dist/components/sheet.js +82 -0
  18. package/dist/components/stars.js +10 -0
  19. package/dist/components/step-marker.js +18 -0
  20. package/dist/components/switch.js +15 -0
  21. package/dist/components/tag.js +16 -0
  22. package/dist/components/tooltip.js +9 -0
  23. package/dist/index.js +22 -0
  24. package/dist/types/components/accordion.d.ts +7 -0
  25. package/dist/types/components/alert.d.ts +10 -0
  26. package/dist/types/components/badge.d.ts +12 -0
  27. package/dist/types/components/breadcrumbs.d.ts +11 -0
  28. package/dist/types/components/button.d.ts +19 -0
  29. package/dist/types/components/card.d.ts +6 -0
  30. package/dist/types/components/checkbox.d.ts +11 -0
  31. package/dist/types/components/collapse.d.ts +15 -0
  32. package/dist/types/components/divider.d.ts +8 -0
  33. package/dist/types/components/input.d.ts +14 -0
  34. package/dist/types/components/modal.d.ts +10 -0
  35. package/dist/types/components/phone.d.ts +18 -0
  36. package/dist/types/components/popover.d.ts +6 -0
  37. package/dist/types/components/radio.d.ts +8 -0
  38. package/dist/types/components/range.d.ts +10 -0
  39. package/dist/types/components/select.d.ts +13 -0
  40. package/dist/types/components/sheet.d.ts +25 -0
  41. package/dist/types/components/stars.d.ts +6 -0
  42. package/dist/types/components/step-marker.d.ts +11 -0
  43. package/dist/types/components/switch.d.ts +9 -0
  44. package/dist/types/components/tag.d.ts +11 -0
  45. package/dist/types/components/tooltip.d.ts +8 -0
  46. package/dist/types/index.d.ts +22 -0
  47. package/dist/types/utils/classes.d.ts +1 -0
  48. package/dist/types/utils/validation.d.ts +12 -0
  49. package/dist/utils/classes.js +7 -0
  50. package/dist/utils/validation.js +128 -0
  51. package/ourtrip-ui-1.0.0.tgz +0 -0
  52. package/package.json +47 -0
  53. package/src/components/accordion.tsx +52 -0
  54. package/src/components/alert.tsx +56 -0
  55. package/src/components/badge.tsx +84 -0
  56. package/src/components/breadcrumbs.tsx +48 -0
  57. package/src/components/button.tsx +187 -0
  58. package/src/components/card.tsx +23 -0
  59. package/src/components/checkbox.tsx +70 -0
  60. package/src/components/collapse.tsx +56 -0
  61. package/src/components/divider.tsx +28 -0
  62. package/src/components/input.tsx +105 -0
  63. package/src/components/modal.tsx +40 -0
  64. package/src/components/phone.tsx +104 -0
  65. package/src/components/popover.tsx +31 -0
  66. package/src/components/radio.tsx +44 -0
  67. package/src/components/range.tsx +54 -0
  68. package/src/components/select.tsx +160 -0
  69. package/src/components/sheet.tsx +140 -0
  70. package/src/components/stars.tsx +30 -0
  71. package/src/components/step-marker.tsx +49 -0
  72. package/src/components/switch.tsx +42 -0
  73. package/src/components/tag.tsx +52 -0
  74. package/src/components/tooltip.tsx +30 -0
  75. package/src/index.tsx +22 -0
  76. package/src/utils/classes.ts +2 -0
  77. package/src/utils/validation.ts +164 -0
  78. package/tsconfig.json +19 -0
@@ -0,0 +1,140 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import * as SheetPrimitive from '@radix-ui/react-dialog';
5
+ import { cva, type VariantProps } from 'class-variance-authority';
6
+ import { X } from '@phosphor-icons/react';
7
+
8
+ import cn from 'classnames';
9
+
10
+ const Sheet = SheetPrimitive.Root;
11
+
12
+ const SheetTrigger = SheetPrimitive.Trigger;
13
+
14
+ const SheetClose = SheetPrimitive.Close;
15
+
16
+ const SheetPortal = SheetPrimitive.Portal;
17
+
18
+ const SheetOverlay = React.forwardRef<
19
+ React.ElementRef<typeof SheetPrimitive.Overlay>,
20
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
21
+ >(({ className, ...props }, ref) => (
22
+ <SheetPrimitive.Overlay
23
+ className={cn(
24
+ 'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=open]:fade-in-0',
25
+ className
26
+ )}
27
+ {...props}
28
+ ref={ref}
29
+ />
30
+ ));
31
+ SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
32
+
33
+ const sheetVariants = cva(
34
+ 'fixed z-50 gap-4 bg-white p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=open]:duration-500',
35
+ {
36
+ variants: {
37
+ side: {
38
+ top: 'inset-x-0 top-0 border-b data-[state=open]:slide-in-from-top',
39
+ bottom:
40
+ 'inset-x-0 bottom-0 border-t data-[state=open]:slide-in-from-bottom',
41
+ left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=open]:slide-in-from-left sm:max-w-sm',
42
+ right:
43
+ 'inset-y-0 right-0 h-full w-3/4 border-l data-[state=open]:slide-in-from-right sm:max-w-sm'
44
+ }
45
+ },
46
+ defaultVariants: {
47
+ side: 'right'
48
+ }
49
+ }
50
+ );
51
+
52
+ interface SheetContentProps
53
+ extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
54
+ VariantProps<typeof sheetVariants> {}
55
+
56
+ const SheetContent = React.forwardRef<
57
+ React.ElementRef<typeof SheetPrimitive.Content>,
58
+ SheetContentProps
59
+ >(({ side = 'right', className, children, ...props }, ref) => (
60
+ <SheetPortal>
61
+ <SheetOverlay />
62
+ <SheetPrimitive.Content
63
+ ref={ref}
64
+ className={cn(sheetVariants({ side }), className)}
65
+ {...props}
66
+ >
67
+ {children}
68
+ <SheetPrimitive.Close className='absolute right-4 top-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary'>
69
+ <X className='h-4 w-4' />
70
+ <span className='sr-only'>Close</span>
71
+ </SheetPrimitive.Close>
72
+ </SheetPrimitive.Content>
73
+ </SheetPortal>
74
+ ));
75
+ SheetContent.displayName = SheetPrimitive.Content.displayName;
76
+
77
+ const SheetHeader = ({
78
+ className,
79
+ ...props
80
+ }: React.HTMLAttributes<HTMLDivElement>) => (
81
+ <div
82
+ className={cn(
83
+ 'flex flex-col space-y-2 text-center sm:text-left',
84
+ className
85
+ )}
86
+ {...props}
87
+ />
88
+ );
89
+ SheetHeader.displayName = 'SheetHeader';
90
+
91
+ const SheetFooter = ({
92
+ className,
93
+ ...props
94
+ }: React.HTMLAttributes<HTMLDivElement>) => (
95
+ <div
96
+ className={cn(
97
+ 'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
98
+ className
99
+ )}
100
+ {...props}
101
+ />
102
+ );
103
+ SheetFooter.displayName = 'SheetFooter';
104
+
105
+ const SheetTitle = React.forwardRef<
106
+ React.ElementRef<typeof SheetPrimitive.Title>,
107
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
108
+ >(({ className, ...props }, ref) => (
109
+ <SheetPrimitive.Title
110
+ ref={ref}
111
+ className={cn('text-lg font-semibold text-foreground', className)}
112
+ {...props}
113
+ />
114
+ ));
115
+ SheetTitle.displayName = SheetPrimitive.Title.displayName;
116
+
117
+ const SheetDescription = React.forwardRef<
118
+ React.ElementRef<typeof SheetPrimitive.Description>,
119
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
120
+ >(({ className, ...props }, ref) => (
121
+ <SheetPrimitive.Description
122
+ ref={ref}
123
+ className={cn('text-sm text-muted-foreground', className)}
124
+ {...props}
125
+ />
126
+ ));
127
+ SheetDescription.displayName = SheetPrimitive.Description.displayName;
128
+
129
+ export {
130
+ Sheet,
131
+ SheetPortal,
132
+ SheetOverlay,
133
+ SheetTrigger,
134
+ SheetClose,
135
+ SheetContent,
136
+ SheetHeader,
137
+ SheetFooter,
138
+ SheetTitle,
139
+ SheetDescription
140
+ };
@@ -0,0 +1,30 @@
1
+ 'use client';
2
+
3
+ import React, { FC } from 'react';
4
+ import { Star } from '@phosphor-icons/react';
5
+
6
+ interface IStars {
7
+ rate: number;
8
+ }
9
+
10
+ const Stars: FC<IStars> = ({ rate }: IStars) => {
11
+ return (
12
+ <div className='flex items-center gap-0.5'>
13
+ {Array.from({ length: 5 }).map((_, index) => (
14
+ <Star
15
+ key={`${rate}${index}`}
16
+ weight={rate > index ? 'fill' : 'light'}
17
+ className={`text-yellow-300 ${
18
+ rate > index ? 'text-yellow-300' : ''
19
+ } ${index > 0 ? 'hidden md:block' : ''}`}
20
+ size={12}
21
+ />
22
+ ))}
23
+ <p className='text-sm text-primary-900 font-medium block md:hidden'>
24
+ {rate}
25
+ </p>
26
+ </div>
27
+ );
28
+ };
29
+
30
+ export default Stars;
@@ -0,0 +1,49 @@
1
+ 'use client';
2
+
3
+ import React, { FC } from 'react';
4
+ import { Check } from '@phosphor-icons/react';
5
+ import classNames from 'classnames';
6
+
7
+ type StepMarkerProps = {
8
+ step: number;
9
+ title: string;
10
+ subtitle?: string;
11
+ checked: boolean;
12
+ active: boolean;
13
+ onClick?: () => void;
14
+ };
15
+
16
+ const StepMarker: FC<StepMarkerProps> = ({
17
+ step,
18
+ title,
19
+ subtitle,
20
+ checked,
21
+ active,
22
+ onClick
23
+ }) => {
24
+ const classes = classNames(
25
+ 'w-full md:w-12 h-12 flex-none rounded-default flex justify-center items-center font-medium',
26
+ {
27
+ 'bg-green-500 text-white': checked,
28
+ 'bg-white text-gray-500': !checked,
29
+ 'border-2 bg-gray-100 border-primary-500': active
30
+ }
31
+ );
32
+
33
+ return (
34
+ <div
35
+ className='w-full flex flex-col items-center text-center gap-3 md:flex-row md:items-center md:text-left'
36
+ onClick={onClick}
37
+ >
38
+ <div className={classes}>{checked ? <Check size={22} /> : step}</div>
39
+ <div>
40
+ <h3 className='text-sm md:text-base whitespace-nowrap'>{title}</h3>
41
+ {subtitle && (
42
+ <p className='text-sm text-gray-500 whitespace-nowrap'>{subtitle}</p>
43
+ )}
44
+ </div>
45
+ </div>
46
+ );
47
+ };
48
+
49
+ export default StepMarker;
@@ -0,0 +1,42 @@
1
+ 'use client';
2
+
3
+ import React, { FC } from 'react';
4
+ import { motion } from 'framer-motion';
5
+
6
+ interface ISwitch {
7
+ onChange?: (on: boolean) => void;
8
+ on: boolean;
9
+ disabled?: boolean;
10
+ label: string;
11
+ }
12
+
13
+ const spring = {
14
+ type: 'spring',
15
+ stiffness: 700,
16
+ damping: 30
17
+ };
18
+ const Switch: FC<ISwitch> = ({ on, onChange, disabled, label }: ISwitch) => {
19
+ return (
20
+ <button
21
+ className='flex flex-row items-center cursor-pointer select-none border-none bg-transparent'
22
+ disabled={disabled}
23
+ onClick={() => onChange?.(!on)}
24
+ aria-label={label}
25
+ >
26
+ <div
27
+ className={`w-[35px] h-[20px] flex flex-row items-center p-[5px] rounded-[50px] transition-colors duration-200 ${
28
+ on ? 'bg-primary-500 justify-end' : 'bg-gray-200 justify-start'
29
+ }`}
30
+ >
31
+ <motion.div
32
+ className={`w-[10px] h-[10px] rounded-full ${
33
+ on ? 'bg-white' : 'bg-gray-500'
34
+ }`}
35
+ transition={spring}
36
+ />
37
+ </div>
38
+ </button>
39
+ );
40
+ };
41
+
42
+ export default Switch;
@@ -0,0 +1,52 @@
1
+ 'use client';
2
+
3
+ import React, { FC, ReactNode } from 'react';
4
+
5
+ export type TagColor = 'primary' | 'secondary' | 'white';
6
+
7
+ interface ITagProps {
8
+ color: TagColor;
9
+ children: ReactNode;
10
+ onClick?: () => void;
11
+ iconLeft?: ReactNode;
12
+ iconRight?: ReactNode;
13
+ }
14
+
15
+ const Tag: FC<ITagProps> = ({
16
+ color,
17
+ children,
18
+ onClick,
19
+ iconLeft,
20
+ iconRight
21
+ }) => {
22
+ const baseClasses =
23
+ 'rounded-button px-4 py-2 flex items-center justify-between border-0 cursor-pointer transition-all duration-300 ease-in-out font-medium';
24
+
25
+ const colorClasses = {
26
+ primary: 'text-primary-900 bg-white hover:bg-gray-200',
27
+ secondary:
28
+ 'text-secondary-800 bg-secondary-100 hover:text-white hover:bg-secondary-800',
29
+ white: 'text-primary-900 bg-white hover:bg-gray-200'
30
+ };
31
+
32
+ return (
33
+ <button
34
+ onClick={() => onClick?.()}
35
+ className={`${baseClasses} ${colorClasses[color]}`}
36
+ >
37
+ {iconLeft && (
38
+ <span className='flex items-center justify-center mr-2'>
39
+ {iconLeft}
40
+ </span>
41
+ )}
42
+ {children}
43
+ {iconRight && (
44
+ <span className='flex items-center justify-center ml-2'>
45
+ {iconRight}
46
+ </span>
47
+ )}
48
+ </button>
49
+ );
50
+ };
51
+
52
+ export default Tag;
@@ -0,0 +1,30 @@
1
+ 'use client';
2
+
3
+ import React, { FC, ReactNode } from 'react';
4
+
5
+ interface ITooltip {
6
+ text: string;
7
+ active: boolean;
8
+ children: ReactNode;
9
+ }
10
+
11
+ const Tooltip: FC<ITooltip> = ({ text, active, children }: ITooltip) => {
12
+ return (
13
+ <div className='relative flex flex-col justify-center items-center group'>
14
+ <div className='w-full'>{children}</div>
15
+ <div
16
+ className={`
17
+ absolute top-[calc(100%+8px)] p-[5px_10px] text-white bg-primary-900
18
+ text-[14px] rounded-[8px] flex-col items-center gap-[5px] transition-all
19
+ ${active ? 'group-hover:flex' : 'hidden'}
20
+ before:content-[''] before:absolute before:w-2 before:h-2 before:bg-primary-900
21
+ before:rotate-45 before:top-[-4px]
22
+ `}
23
+ >
24
+ {text}
25
+ </div>
26
+ </div>
27
+ );
28
+ };
29
+
30
+ export default Tooltip;
package/src/index.tsx ADDED
@@ -0,0 +1,22 @@
1
+ export { default as Accordion } from './components/accordion';
2
+ export { default as Alert } from './components/alert';
3
+ export { default as Badge } from './components/badge';
4
+ export { default as Breadcrumbs } from './components/breadcrumbs';
5
+ export { default as Button } from './components/button';
6
+ export { default as Card } from './components/card';
7
+ export { default as Checkbox } from './components/checkbox';
8
+ export { default as Collapse } from './components/collapse';
9
+ export { default as Divider } from './components/divider';
10
+ export { default as Input } from './components/input';
11
+ export { default as Modal } from './components/modal';
12
+ export { default as PhoneInput } from './components/phone';
13
+ export { Popover, PopoverContent, PopoverTrigger } from './components/popover';
14
+ export { default as Radio } from './components/radio';
15
+ export { default as Range } from './components/range';
16
+ export { Select, SelectContent, SelectTrigger } from './components/select';
17
+ export { Sheet, SheetContent, SheetTrigger } from './components/sheet';
18
+ export { default as Stars } from './components/stars';
19
+ export { default as StepMarker } from './components/step-marker';
20
+ export { default as Switch } from './components/switch';
21
+ export { default as Tag } from './components/tag';
22
+ export { default as Tooltip } from './components/tooltip';
@@ -0,0 +1,2 @@
1
+ export const cn = (...args: (string | undefined)[]): string =>
2
+ args.filter(Boolean).join(' ');
@@ -0,0 +1,164 @@
1
+ import { isBefore, isValid, parse, subYears } from 'date-fns';
2
+
3
+ export const isValidCpf = (formatedCpf: string): boolean => {
4
+ const cpf = formatedCpf.replace(/\D/g, '');
5
+
6
+ if (cpf.length !== 11 || /^(\d)\1+$/.test(cpf)) {
7
+ return false;
8
+ }
9
+
10
+ // Calcular el primer dígito verificador
11
+ let soma = 0;
12
+
13
+ for (let i = 0; i < 9; i++) {
14
+ soma += parseInt(cpf.charAt(i), 10) * (10 - i);
15
+ }
16
+ let digito1 = 11 - (soma % 11);
17
+ if (digito1 > 9) {
18
+ digito1 = 0;
19
+ }
20
+
21
+ // Calcular el segundo dígito verificador
22
+ soma = 0;
23
+ for (let i = 0; i < 10; i++) {
24
+ soma += parseInt(cpf.charAt(i), 10) * (11 - i);
25
+ }
26
+ let digito2 = 11 - (soma % 11);
27
+ if (digito2 > 9) {
28
+ digito2 = 0;
29
+ }
30
+
31
+ // Verificar si los dígitos verificadores son iguales a los últimos dos dígitos del CPF
32
+ if (
33
+ parseInt(cpf.charAt(9), 10) === digito1 &&
34
+ parseInt(cpf.charAt(10), 10) === digito2
35
+ ) {
36
+ return true;
37
+ }
38
+ return false;
39
+ };
40
+
41
+ export const isValidCNPJ = (formatedCnpj: string): boolean => {
42
+ const cnpj = formatedCnpj.replace(/[^\d]+/g, '');
43
+
44
+ if (cnpj.length !== 14) {
45
+ return false;
46
+ }
47
+
48
+ if (/^(\d)\1+$/.test(cnpj)) {
49
+ return false;
50
+ }
51
+
52
+ let length = cnpj.length - 2;
53
+ let numbers = cnpj.substring(0, length);
54
+ const digitosVerificadores = cnpj.substring(length);
55
+
56
+ let soma = 0;
57
+ let pos = length - 7;
58
+
59
+ for (let i = length; i >= 1; i--) {
60
+ soma += parseInt(numbers.charAt(length - i), 10) * pos--;
61
+ if (pos < 2) {
62
+ pos = 9;
63
+ }
64
+ }
65
+
66
+ const resultado = soma % 11 < 2 ? 0 : 11 - (soma % 11);
67
+
68
+ if (resultado !== parseInt(digitosVerificadores.charAt(0), 10)) {
69
+ return false;
70
+ }
71
+
72
+ length += 1;
73
+ numbers = cnpj.substring(0, length);
74
+ soma = 0;
75
+ pos = length - 7;
76
+
77
+ for (let i = length; i >= 1; i--) {
78
+ soma += parseInt(numbers.charAt(length - i), 10) * pos--;
79
+ if (pos < 2) {
80
+ pos = 9;
81
+ }
82
+ }
83
+
84
+ const segundoDigito = soma % 11 < 2 ? 0 : 11 - (soma % 11);
85
+
86
+ return segundoDigito === parseInt(digitosVerificadores.charAt(1), 10);
87
+ };
88
+
89
+ export const isCPF = (document: string) => {
90
+ const onlyNumbers = document?.replace(/\D/g, '');
91
+
92
+ if (onlyNumbers?.length === 11 && isValidCpf(onlyNumbers)) return true;
93
+
94
+ return false;
95
+ };
96
+
97
+ export const isCNPJ = (document: string) => {
98
+ const onlyNumbers = document?.replace(/\D/g, '');
99
+
100
+ if (onlyNumbers?.length === 14 && isValidCNPJ(onlyNumbers)) return true;
101
+
102
+ return false;
103
+ };
104
+
105
+ export const isFullName = (name: string) =>
106
+ /^(?:[A-Za-zÀ-ÿ]{2,}(?: [A-Za-zÀ-ÿ]{2,})+)$/.test(name.trim());
107
+
108
+ export const isValidName = (name: string) =>
109
+ /^[A-Za-zÀ-ÿ\s.'-]+(?: [A-Za-zÀ-ÿ\s.'-]+)*$/.test(name.trim());
110
+
111
+ export const isValidEmail = (email: string) =>
112
+ /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/.test(email.trim());
113
+
114
+ export const isValidPhoneNumber = (number: string) => {
115
+ const phoneNumber = number.replace('-', '');
116
+ return /^\d{8}$/.test(phoneNumber) || /^\d{9}$/.test(phoneNumber);
117
+ };
118
+
119
+ export const isValidNumberCode = (numberCode: string) =>
120
+ /^\d{2}$/.test(numberCode.replace(/[()]/g, ''));
121
+
122
+ export const isValidDDD = (areaCode: string) => {
123
+ const dddList = [
124
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 24, 27, 28, 31, 32, 33, 34, 35,
125
+ 37, 38, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, 53, 54, 55, 61, 62, 64, 63,
126
+ 65, 66, 67, 68, 69, 71, 73, 74, 75, 77, 79, 81, 82, 83, 84, 85, 86, 87, 88,
127
+ 89, 91, 92, 93, 94, 95, 96, 97, 98, 99
128
+ ];
129
+
130
+ return dddList.includes(parseFloat(areaCode?.replace(/\D/g, '')));
131
+ };
132
+
133
+ export const isValidChildDate = (date?: string) => {
134
+ if (!date) return 'Data inválida';
135
+
136
+ const birthDate = parse(date, 'yyyy-MM-dd', new Date());
137
+
138
+ if (!isValid(birthDate)) {
139
+ return 'Data inválida';
140
+ }
141
+
142
+ const currentDate = new Date();
143
+ const adultAge = subYears(currentDate, 18);
144
+
145
+ if (isBefore(adultAge, birthDate) && isBefore(birthDate, currentDate)) {
146
+ return true;
147
+ }
148
+
149
+ return 'Idade deve ser entre 1 a 17 anos';
150
+ };
151
+
152
+ export const isValidAdult = (date?: string) => {
153
+ if (!date) return 'Data inválida';
154
+
155
+ const birthDate = parse(date, 'yyyy-MM-dd', new Date());
156
+
157
+ if (!isValid(birthDate)) {
158
+ return 'Data inválida';
159
+ }
160
+
161
+ const adultAge = subYears(new Date(), 18);
162
+
163
+ return isBefore(birthDate, adultAge) || 'Adulto deve ter mais de 18 anos';
164
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES5",
4
+ "module": "ESNext",
5
+ "lib": ["dom", "es6", "es2017"],
6
+ "jsx": "react",
7
+ "declaration": true,
8
+ "declarationDir": "dist/types",
9
+ "outDir": "dist",
10
+ "strict": true,
11
+ "moduleResolution": "node",
12
+ "esModuleInterop": true,
13
+ "skipLibCheck": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "allowSyntheticDefaultImports": true
16
+ },
17
+ "include": ["src"],
18
+ "exclude": ["node_modules", "dist"]
19
+ }