@phsa.tec/design-system-react 0.1.6 → 0.1.9

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 (217) hide show
  1. package/README.md +390 -209
  2. package/dist/index.d.mts +485 -0
  3. package/dist/index.d.ts +485 -0
  4. package/dist/index.js +4259 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/index.mjs +4186 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/dist/styles.css +2534 -0
  9. package/dist/styles.css.map +1 -0
  10. package/dist/styles.d.mts +2 -0
  11. package/dist/styles.d.ts +2 -0
  12. package/package.json +46 -6
  13. package/.eslintrc.json +0 -7
  14. package/.github/workflows/deploy-storybook.yml +0 -75
  15. package/.storybook/main.ts +0 -16
  16. package/.storybook/preview.ts +0 -15
  17. package/components.json +0 -21
  18. package/jest.config.ts +0 -25
  19. package/next.config.ts +0 -7
  20. package/postcss.config.mjs +0 -8
  21. package/public/file.svg +0 -1
  22. package/public/globe.svg +0 -1
  23. package/public/next.svg +0 -1
  24. package/public/vercel.svg +0 -1
  25. package/public/window.svg +0 -1
  26. package/src/app/columns.tsx +0 -178
  27. package/src/app/favicon.ico +0 -0
  28. package/src/app/fonts/GeistMonoVF.woff +0 -0
  29. package/src/app/fonts/GeistVF.woff +0 -0
  30. package/src/app/globals.css +0 -94
  31. package/src/app/layout.tsx +0 -35
  32. package/src/app/page.tsx +0 -7
  33. package/src/components/actions/AlertDialog/AlertDialog.tsx +0 -45
  34. package/src/components/actions/AlertDialog/alert-dialog.stories.tsx +0 -21
  35. package/src/components/actions/AlertDialog/index.ts +0 -1
  36. package/src/components/actions/Button/Button.stories.ts +0 -38
  37. package/src/components/actions/Button/Button.tsx +0 -23
  38. package/src/components/actions/Button/index.ts +0 -1
  39. package/src/components/actions/Collapsible/index.ts +0 -1
  40. package/src/components/actions/Dialog/Dialog.stories.tsx +0 -70
  41. package/src/components/actions/Dialog/Dialog.tsx +0 -87
  42. package/src/components/actions/Dialog/components/DialogWithActions/index.tsx +0 -40
  43. package/src/components/actions/Dialog/index.ts +0 -1
  44. package/src/components/actions/Steps/Steps.stories.tsx +0 -25
  45. package/src/components/actions/Steps/Steps.tsx +0 -51
  46. package/src/components/actions/Steps/index.ts +0 -1
  47. package/src/components/actions/index.ts +0 -5
  48. package/src/components/dataDisplay/Avatar/Avatar.stories.tsx +0 -22
  49. package/src/components/dataDisplay/Avatar/Avatar.tsx +0 -21
  50. package/src/components/dataDisplay/Avatar/index.ts +0 -2
  51. package/src/components/dataDisplay/Badge/Badge.stories.tsx +0 -36
  52. package/src/components/dataDisplay/Badge/index.ts +0 -1
  53. package/src/components/dataDisplay/Card/Card.stories.tsx +0 -24
  54. package/src/components/dataDisplay/Card/Card.tsx +0 -34
  55. package/src/components/dataDisplay/Card/index.ts +0 -1
  56. package/src/components/dataDisplay/DataPairList/DataPairList.tsx +0 -56
  57. package/src/components/dataDisplay/DataPairList/data-pair-list.stories.tsx +0 -87
  58. package/src/components/dataDisplay/DataPairList/index.ts +0 -2
  59. package/src/components/dataDisplay/DataPairList/types.ts +0 -10
  60. package/src/components/dataDisplay/DropDownMenu/index.ts +0 -1
  61. package/src/components/dataDisplay/ErrorMessage/ErrorMessage.tsx +0 -6
  62. package/src/components/dataDisplay/ErrorMessage/index.ts +0 -1
  63. package/src/components/dataDisplay/Icon/Icon.stories.tsx +0 -21
  64. package/src/components/dataDisplay/Icon/Icon.tsx +0 -47
  65. package/src/components/dataDisplay/Icon/index.ts +0 -1
  66. package/src/components/dataDisplay/Icon/types.ts +0 -6
  67. package/src/components/dataDisplay/Label/Label.stories.tsx +0 -21
  68. package/src/components/dataDisplay/Label/Label.tsx +0 -10
  69. package/src/components/dataDisplay/Label/index.ts +0 -1
  70. package/src/components/dataDisplay/Table/Table.tsx +0 -173
  71. package/src/components/dataDisplay/Table/columns.tsx +0 -223
  72. package/src/components/dataDisplay/Table/components/DynamicTable/data-table-column-header.tsx +0 -72
  73. package/src/components/dataDisplay/Table/components/DynamicTable/data-table-pagination.tsx +0 -91
  74. package/src/components/dataDisplay/Table/components/DynamicTable/data-table-toolbar.tsx +0 -17
  75. package/src/components/dataDisplay/Table/components/DynamicTable/data-table-view-options.tsx +0 -58
  76. package/src/components/dataDisplay/Table/components/DynamicTable/data-table.stories.tsx +0 -118
  77. package/src/components/dataDisplay/Table/components/DynamicTable/index.tsx +0 -136
  78. package/src/components/dataDisplay/Table/components/DynamicTable/types.ts +0 -43
  79. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-column-header.tsx +0 -71
  80. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-faceted-filter.tsx +0 -147
  81. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-pagination.tsx +0 -97
  82. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-row-actions.tsx +0 -78
  83. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-toolbar.tsx +0 -60
  84. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-view-options.tsx +0 -59
  85. package/src/components/dataDisplay/Table/custom/CustomTable/data-table.tsx +0 -145
  86. package/src/components/dataDisplay/Table/custom/CustomTable/data.ts +0 -71
  87. package/src/components/dataDisplay/Table/custom/CustomTable/index.tsx +0 -34
  88. package/src/components/dataDisplay/Table/custom/CustomTable/schema.ts +0 -11
  89. package/src/components/dataDisplay/Table/index.ts +0 -2
  90. package/src/components/dataDisplay/Table/table.stories.tsx +0 -147
  91. package/src/components/dataDisplay/Table/types.ts +0 -15
  92. package/src/components/dataDisplay/Tabs/Tabs.stories.tsx +0 -34
  93. package/src/components/dataDisplay/Tabs/Tabs.tsx +0 -53
  94. package/src/components/dataDisplay/Tabs/index.ts +0 -1
  95. package/src/components/dataDisplay/Text/Text.stories.tsx +0 -66
  96. package/src/components/dataDisplay/Text/Text.tsx +0 -56
  97. package/src/components/dataDisplay/Text/index.ts +0 -1
  98. package/src/components/dataDisplay/index.ts +0 -8
  99. package/src/components/dataInput/Input/components/Input/Input.stories.tsx +0 -99
  100. package/src/components/dataInput/Input/components/Input/InputBase.tsx +0 -50
  101. package/src/components/dataInput/Input/components/Input/__tests__/input.test.tsx +0 -38
  102. package/src/components/dataInput/Input/components/Input/index.tsx +0 -48
  103. package/src/components/dataInput/Input/components/Input/types.ts +0 -15
  104. package/src/components/dataInput/Input/components/InputBase/index.tsx +0 -31
  105. package/src/components/dataInput/Input/components/MaskInput/__tests__/mask-input.test.tsx +0 -77
  106. package/src/components/dataInput/Input/components/MaskInput/index.ts +0 -1
  107. package/src/components/dataInput/Input/components/MaskInput/mask-input.stories.tsx +0 -85
  108. package/src/components/dataInput/Input/components/MaskInput/mask-input.tsx +0 -73
  109. package/src/components/dataInput/Input/components/MultipleInput/MultipleInput.tsx +0 -105
  110. package/src/components/dataInput/Input/components/MultipleInput/MultipleInputBase.tsx +0 -100
  111. package/src/components/dataInput/Input/components/MultipleInput/MultipleMaskInput.tsx +0 -35
  112. package/src/components/dataInput/Input/components/MultipleInput/MultipleNumberInput.tsx +0 -35
  113. package/src/components/dataInput/Input/components/MultipleInput/__tests__/multiple-input.test.tsx +0 -152
  114. package/src/components/dataInput/Input/components/MultipleInput/index.ts +0 -2
  115. package/src/components/dataInput/Input/components/MultipleInput/multiple-input.stories.tsx +0 -96
  116. package/src/components/dataInput/Input/components/NumberInput/__tests__/number-input.test.tsx +0 -175
  117. package/src/components/dataInput/Input/components/NumberInput/index.ts +0 -1
  118. package/src/components/dataInput/Input/components/NumberInput/number-input.stories.tsx +0 -76
  119. package/src/components/dataInput/Input/components/NumberInput/number-input.tsx +0 -70
  120. package/src/components/dataInput/Input/index.ts +0 -4
  121. package/src/components/dataInput/Select/MultiSelect/MultiSelect.stories.tsx +0 -119
  122. package/src/components/dataInput/Select/MultiSelect/MultiSelectBase.tsx +0 -135
  123. package/src/components/dataInput/Select/MultiSelect/index.tsx +0 -75
  124. package/src/components/dataInput/Select/Select.stories.tsx +0 -61
  125. package/src/components/dataInput/Select/Select.tsx +0 -73
  126. package/src/components/dataInput/Select/SelectBase.tsx +0 -58
  127. package/src/components/dataInput/Select/index.ts +0 -2
  128. package/src/components/dataInput/Switch/Switch.stories.tsx +0 -75
  129. package/src/components/dataInput/Switch/Switch.tsx +0 -52
  130. package/src/components/dataInput/Switch/index.ts +0 -1
  131. package/src/components/dataInput/checkbox/Checkbox.tsx +0 -57
  132. package/src/components/dataInput/checkbox/Checkbox_old.tsx +0 -58
  133. package/src/components/dataInput/checkbox/Checkout.stories.tsx +0 -62
  134. package/src/components/dataInput/checkbox/index.ts +0 -1
  135. package/src/components/dataInput/form/Form.tsx +0 -47
  136. package/src/components/dataInput/form/index.ts +0 -3
  137. package/src/components/dataInput/index.ts +0 -5
  138. package/src/components/feedback/ErrorLabel/index.tsx +0 -24
  139. package/src/components/feedback/Spinner/index.ts +0 -1
  140. package/src/components/feedback/Toast/Toast.stories.tsx +0 -45
  141. package/src/components/feedback/Toast/index.ts +0 -2
  142. package/src/components/feedback/index.ts +0 -2
  143. package/src/components/index.ts +0 -6
  144. package/src/components/layout/Crud/components/Table/index.tsx +0 -183
  145. package/src/components/layout/Crud/components/Table/types.ts +0 -15
  146. package/src/components/layout/Crud/crud.stories.tsx +0 -317
  147. package/src/components/layout/Crud/hook/useCrudLayout/index.tsx +0 -94
  148. package/src/components/layout/Crud/hook/useRequest/index.tsx +0 -156
  149. package/src/components/layout/Crud/index.tsx +0 -295
  150. package/src/components/layout/Crud/store/CrudLayoutStore.ts +0 -75
  151. package/src/components/layout/Crud/types.ts +0 -14
  152. package/src/components/layout/Drawer/CustomDrawer/index.tsx +0 -33
  153. package/src/components/layout/Drawer/Drawer.stories.tsx +0 -80
  154. package/src/components/layout/Drawer/index.ts +0 -2
  155. package/src/components/layout/PageLayout/PageLayout.stories.tsx +0 -42
  156. package/src/components/layout/PageLayout/index.tsx +0 -28
  157. package/src/components/layout/Separator/index.ts +0 -1
  158. package/src/components/layout/Sheet/Sheet.stories.tsx +0 -28
  159. package/src/components/layout/Sheet/Sheet.tsx +0 -22
  160. package/src/components/layout/Sheet/index.ts +0 -1
  161. package/src/components/layout/Sidebar/Sidebar.stories.tsx +0 -116
  162. package/src/components/layout/Sidebar/Sidebar.tsx +0 -50
  163. package/src/components/layout/Sidebar/components/app-sidebar.tsx +0 -203
  164. package/src/components/layout/Sidebar/components/footer-sidebar.tsx +0 -17
  165. package/src/components/layout/Sidebar/components/header-sidebar.tsx +0 -90
  166. package/src/components/layout/Sidebar/components/menus.tsx +0 -55
  167. package/src/components/layout/Sidebar/components/nav-projects.tsx +0 -88
  168. package/src/components/layout/Sidebar/components/nav-user.tsx +0 -114
  169. package/src/components/layout/Sidebar/components/team-switcher.tsx +0 -85
  170. package/src/components/layout/Sidebar/index.ts +0 -2
  171. package/src/components/layout/Sidebar/provider/index.tsx +0 -51
  172. package/src/components/layout/Tabs/Tabs.tsx +0 -51
  173. package/src/components/layout/Tabs/index.ts +0 -1
  174. package/src/components/layout/Tabs/tabs.stories.tsx +0 -57
  175. package/src/components/layout/index.ts +0 -6
  176. package/src/components/navigation/Breadcrumbs/Breadcrumbs.tsx +0 -66
  177. package/src/components/navigation/Breadcrumbs/index.ts +0 -2
  178. package/src/components/navigation/index.ts +0 -1
  179. package/src/components/ui/alert-dialog.tsx +0 -141
  180. package/src/components/ui/alert.tsx +0 -59
  181. package/src/components/ui/avatar.tsx +0 -50
  182. package/src/components/ui/badge.tsx +0 -40
  183. package/src/components/ui/breadcrumb.tsx +0 -115
  184. package/src/components/ui/button.tsx +0 -57
  185. package/src/components/ui/card.tsx +0 -83
  186. package/src/components/ui/checkbox.tsx +0 -34
  187. package/src/components/ui/collapsible.tsx +0 -11
  188. package/src/components/ui/command.tsx +0 -153
  189. package/src/components/ui/dialog.tsx +0 -124
  190. package/src/components/ui/drawer.tsx +0 -117
  191. package/src/components/ui/dropdown-menu.tsx +0 -201
  192. package/src/components/ui/form.tsx +0 -179
  193. package/src/components/ui/input.tsx +0 -24
  194. package/src/components/ui/label.tsx +0 -30
  195. package/src/components/ui/popover.tsx +0 -33
  196. package/src/components/ui/select.tsx +0 -161
  197. package/src/components/ui/separator.tsx +0 -31
  198. package/src/components/ui/sheet.tsx +0 -140
  199. package/src/components/ui/sidebar.tsx +0 -763
  200. package/src/components/ui/skeleton.tsx +0 -15
  201. package/src/components/ui/sonner.tsx +0 -31
  202. package/src/components/ui/spinner.tsx +0 -54
  203. package/src/components/ui/switch.tsx +0 -33
  204. package/src/components/ui/table.tsx +0 -120
  205. package/src/components/ui/tabs.tsx +0 -55
  206. package/src/components/ui/toast.tsx +0 -130
  207. package/src/components/ui/toaster.tsx +0 -35
  208. package/src/components/ui/tooltip.tsx +0 -32
  209. package/src/hooks/use-conditional-controller.tsx +0 -35
  210. package/src/hooks/use-mask.tsx +0 -116
  211. package/src/hooks/use-mobile.tsx +0 -19
  212. package/src/hooks/use-toast.ts +0 -191
  213. package/src/index.ts +0 -1
  214. package/src/introduction.mdx +0 -132
  215. package/src/lib/utils.ts +0 -6
  216. package/tailwind.config.ts +0 -83
  217. package/tsconfig.json +0 -27
@@ -1,99 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/nextjs";
2
- import { Input } from "./index";
3
- import { useForm } from "react-hook-form";
4
- import { Form } from "@/components/ui/form";
5
- import { Button } from "@/components/actions";
6
-
7
- const meta: Meta<typeof Input> = {
8
- title: "Data Input/Input/Input",
9
- component: Input,
10
- tags: ["autodocs"],
11
- parameters: {
12
- layout: "centered",
13
- },
14
- };
15
-
16
- export default meta;
17
- type Story = StoryObj<typeof Input>;
18
-
19
- export const Default: Story = {
20
- args: {
21
- label: "Default Input",
22
- placeholder: "Type something...",
23
- name: "default",
24
- mask: "999.999.999-99",
25
- },
26
- };
27
-
28
- export const Required: Story = {
29
- args: {
30
- label: "Required Input",
31
- placeholder: "This field is required",
32
- name: "required",
33
- required: true,
34
- },
35
- };
36
-
37
- export const WithForm: Story = {
38
- args: {
39
- label: "Input with Form",
40
- placeholder: "Standalone input",
41
- name: "test",
42
- },
43
- decorators: [
44
- (Story: React.ComponentType) => {
45
- const form = useForm();
46
- return (
47
- <Form {...form}>
48
- <Story />
49
- </Form>
50
- );
51
- },
52
- ],
53
- };
54
-
55
- export const WithFormMask: Story = {
56
- args: {
57
- label: "Input with Form",
58
- placeholder: "Standalone input",
59
- name: "standalone",
60
- mask: "999.999.999-99",
61
- },
62
- decorators: [
63
- (Story: React.ComponentType) => {
64
- const form = useForm();
65
- return (
66
- <Form {...form}>
67
- <Story />
68
- </Form>
69
- );
70
- },
71
- ],
72
- };
73
-
74
- export const Disabled: Story = {
75
- args: {
76
- label: "Disabled Input",
77
- placeholder: "You cannot type here",
78
- name: "disabled",
79
- disabled: true,
80
- },
81
- };
82
-
83
- export const Error: Story = {
84
- args: {
85
- label: "Error Input",
86
- placeholder: "This field is required",
87
- name: "error",
88
- error: "This is an error message",
89
- },
90
- };
91
-
92
- export const WithButton: Story = {
93
- args: {
94
- label: "Input with Button",
95
- placeholder: "Type something...",
96
- name: "default",
97
- component: <Button>Click me</Button>,
98
- },
99
- };
@@ -1,50 +0,0 @@
1
- import React, { forwardRef, useCallback, useImperativeHandle } from "react";
2
- import { Input, InputProps } from "../../../../ui/input";
3
- import { mask as remask } from "remask";
4
- import { cn } from "@/lib/utils";
5
-
6
- export type InputBaseProps = InputProps & {
7
- onChangeText?: (text: string) => void;
8
- mask?: string | string[];
9
- "data-testid"?: string;
10
- };
11
-
12
- export const InputBase = forwardRef<HTMLInputElement, InputBaseProps>(
13
- ({ mask, className, ...props }, ref) => {
14
- const { onChangeText = () => {}, ...rest } = props;
15
- const inputRef = React.useRef<HTMLInputElement>(null);
16
-
17
- const setMask = useCallback(
18
- (value?: string | number | readonly string[] | undefined) => {
19
- const inputValue = value || "";
20
- if (!mask) return String(inputValue);
21
- return remask(String(inputValue), mask);
22
- },
23
- [mask]
24
- );
25
-
26
- useImperativeHandle(ref, () => inputRef.current!);
27
-
28
- return (
29
- <Input
30
- {...rest}
31
- ref={inputRef}
32
- className={cn(
33
- "border-0 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0",
34
- "p-0 h-auto bg-transparent",
35
- className
36
- )}
37
- onChange={(e) => {
38
- const value = setMask(e.target.value);
39
- if (inputRef.current) {
40
- inputRef.current.value = value;
41
- }
42
- props.onChange?.(e);
43
- onChangeText(value);
44
- }}
45
- />
46
- );
47
- }
48
- );
49
-
50
- InputBase.displayName = "InputBase";
@@ -1,38 +0,0 @@
1
- import "@testing-library/jest-dom";
2
- import { fireEvent, render, screen } from "@testing-library/react";
3
- import { Input } from "../index";
4
-
5
- describe("Input", () => {
6
- it("should render label", () => {
7
- render(<Input label="test" data-testid="input" />);
8
- const label = screen.getByTestId("input-label");
9
- expect(label).toBeInTheDocument();
10
- expect(label).toHaveTextContent("test");
11
- });
12
-
13
- it("should render error", () => {
14
- render(<Input error="test" data-testid="input" />);
15
- const error = screen.getByTestId("input-error-label");
16
- expect(error).toBeInTheDocument();
17
- expect(error).toHaveTextContent("test");
18
- });
19
-
20
- it("should is disabled", () => {
21
- render(<Input disabled data-testid="input" />);
22
- const input = screen.getByTestId("input");
23
- expect(input).toBeDisabled();
24
- });
25
-
26
- it("should is required", () => {
27
- render(<Input required data-testid="input" label="test" />);
28
- const label = screen.getByTestId("input-label");
29
- expect(label).toHaveTextContent("test *");
30
- });
31
-
32
- it("should change value", () => {
33
- render(<Input data-testid="input" />);
34
- const input = screen.getByTestId("input");
35
- fireEvent.change(input, { target: { value: "test" } });
36
- expect(input).toHaveValue("test");
37
- });
38
- });
@@ -1,48 +0,0 @@
1
- import { Input as InputUI } from "@/components/ui/input";
2
- import { InputProps } from "./types";
3
- import { useMemo } from "react";
4
- import { InputBase } from "../InputBase";
5
- import { useConditionalController } from "@/hooks/use-conditional-controller";
6
- import { cn } from "@/lib/utils";
7
-
8
- export const Input = ({
9
- "data-testid": dataTestId,
10
- withoutForm = false,
11
- extraElement,
12
- containerClassName,
13
- ...props
14
- }: InputProps) => {
15
- const formData = useConditionalController({
16
- name: props.name || "",
17
- withoutForm,
18
- });
19
-
20
- const inputProps = useMemo(() => {
21
- return {
22
- ...formData,
23
- ...props,
24
- };
25
- }, [formData, props]);
26
-
27
- return (
28
- <InputBase
29
- label={props.label}
30
- error={props.error}
31
- required={props.required}
32
- data-testid={dataTestId}
33
- >
34
- <div className={cn("flex items-center gap-2", containerClassName)}>
35
- <InputUI
36
- {...inputProps}
37
- data-testid={dataTestId}
38
- className={cn(
39
- props.className,
40
- props.error &&
41
- "border-destructive focus:border-destructive focus-visible:ring-0"
42
- )}
43
- />
44
- {extraElement}
45
- </div>
46
- </InputBase>
47
- );
48
- };
@@ -1,15 +0,0 @@
1
- import { InputBaseProps } from "./InputBase";
2
-
3
- export type InputProps = Omit<InputBaseProps, "children"> & {
4
- component?: React.ReactNode;
5
- error?: string;
6
- withoutForm?: boolean;
7
- label?: string;
8
- leftIcon?: React.ReactNode;
9
- rightIcon?: React.ReactNode;
10
- helperText?: string;
11
- floatingLabel?: boolean;
12
- "data-testid"?: string;
13
- extraElement?: React.ReactNode;
14
- containerClassName?: string;
15
- };
@@ -1,31 +0,0 @@
1
- import { ErrorLabel } from "@/components/feedback/ErrorLabel";
2
- import { InputProps as InputPropsUI } from "../../../../ui/input";
3
- import { Label } from "../../../../ui/label";
4
-
5
- export type InputBaseProps = Omit<InputPropsUI, "children"> & {
6
- label?: string;
7
- error?: string;
8
- required?: boolean;
9
- children: React.ReactNode;
10
- "data-testid"?: string;
11
- };
12
-
13
- export const InputBase = ({
14
- label,
15
- error,
16
- children,
17
- required,
18
- "data-testid": testId,
19
- }: InputBaseProps) => {
20
- return (
21
- <div>
22
- {label && (
23
- <Label data-testid={`${testId}-label`}>
24
- {`${label} ${required ? "*" : ""}`}{" "}
25
- </Label>
26
- )}
27
- {children}
28
- {error && <ErrorLabel data-testid={testId}>{error}</ErrorLabel>}
29
- </div>
30
- );
31
- };
@@ -1,77 +0,0 @@
1
- import "@testing-library/jest-dom";
2
- import { render, screen } from "@testing-library/react";
3
- import userEvent from "@testing-library/user-event";
4
- import { MaskInput } from "../mask-input";
5
-
6
- describe("MaskInput", () => {
7
- it("should render label", () => {
8
- render(
9
- <MaskInput label="test" data-testid="mask-input" mask="999.999.999-99" />
10
- );
11
- const label = screen.getByTestId("mask-input-label");
12
- expect(label).toBeInTheDocument();
13
- expect(label).toHaveTextContent("test");
14
- });
15
-
16
- it("should render error", () => {
17
- render(
18
- <MaskInput error="test" data-testid="mask-input" mask="999.999.999-99" />
19
- );
20
- const error = screen.getByTestId("mask-input-error-label");
21
- expect(error).toBeInTheDocument();
22
- expect(error).toHaveTextContent("test");
23
- });
24
-
25
- it("should be disabled", () => {
26
- render(
27
- <MaskInput disabled data-testid="mask-input" mask="999.999.999-99" />
28
- );
29
- const input = screen.getByTestId("mask-input");
30
- expect(input).toBeDisabled();
31
- });
32
-
33
- it("should be required", () => {
34
- render(
35
- <MaskInput
36
- required
37
- data-testid="mask-input"
38
- label="test"
39
- mask="999.999.999-99"
40
- />
41
- );
42
- const label = screen.getByTestId("mask-input-label");
43
- expect(label).toHaveTextContent("test *");
44
- });
45
-
46
- it("should apply mask to input value", async () => {
47
- const user = userEvent.setup();
48
- render(<MaskInput data-testid="mask-input" mask="999.999.999-99" />);
49
- const input = screen.getByTestId("mask-input");
50
-
51
- await user.type(input, "12345678901");
52
-
53
- expect(input).toHaveValue("123.456.789-01");
54
- });
55
-
56
- it("should handle placeholder", () => {
57
- render(
58
- <MaskInput
59
- data-testid="mask-input"
60
- mask="999.999.999-99"
61
- placeholder="Digite seu CPF"
62
- />
63
- );
64
- const input = screen.getByTestId("mask-input");
65
-
66
- expect(input).toHaveAttribute("placeholder", "Digite seu CPF");
67
- });
68
-
69
- it("should handle name attribute", () => {
70
- render(
71
- <MaskInput data-testid="mask-input" mask="999.999.999-99" name="cpf" />
72
- );
73
- const input = screen.getByTestId("mask-input");
74
-
75
- expect(input).toHaveAttribute("name", "cpf");
76
- });
77
- });
@@ -1 +0,0 @@
1
- export * from "./mask-input";
@@ -1,85 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/nextjs";
2
- import { MaskInput } from "./mask-input";
3
- import { useForm } from "react-hook-form";
4
- import { Form } from "../../../../../components/ui/form";
5
-
6
- const meta = {
7
- title: "Data Input/Input/MaskInput",
8
- component: MaskInput,
9
- parameters: {
10
- layout: "centered",
11
- },
12
- tags: ["autodocs"],
13
- } satisfies Meta<typeof MaskInput>;
14
-
15
- export default meta;
16
- type Story = StoryObj<typeof meta>;
17
-
18
- export const Default: Story = {
19
- args: {
20
- placeholder: "99999-999",
21
- label: "CEP",
22
- mask: "99999-999",
23
- },
24
- };
25
-
26
- export const CPF: Story = {
27
- args: {
28
- placeholder: "999.999.999-99",
29
- label: "CPF",
30
- mask: "999.999.999-99",
31
- },
32
- };
33
-
34
- export const Phone: Story = {
35
- args: {
36
- placeholder: "(99) 99999-9999",
37
- label: "Telefone",
38
- mask: "(99) 99999-9999",
39
- },
40
- };
41
-
42
- export const Date: Story = {
43
- args: {
44
- placeholder: "99/99/9999",
45
- label: "Data",
46
- mask: "99/99/9999",
47
- },
48
- };
49
-
50
- export const LettersExample: Story = {
51
- args: {
52
- placeholder: "AAA-9999",
53
- label: "Código com Letras",
54
- mask: "AAA-9999",
55
- },
56
- };
57
-
58
- export const MixedExample: Story = {
59
- args: {
60
- placeholder: "A99-AAA-999",
61
- label: "Código Misto",
62
- mask: "A99-AAA-999",
63
- },
64
- };
65
-
66
- export const WithForm = () => {
67
- const form = useForm({
68
- defaultValues: {
69
- cpf: "",
70
- },
71
- });
72
-
73
- return (
74
- <Form {...form}>
75
- <form className="space-y-6">
76
- <MaskInput
77
- name="cpf"
78
- label="CPF"
79
- placeholder="999.999.999-99"
80
- mask="999.999.999-99"
81
- />
82
- </form>
83
- </Form>
84
- );
85
- };
@@ -1,73 +0,0 @@
1
- "use client";
2
- import * as React from "react";
3
- import { Input } from "../Input";
4
- import { useConditionalController } from "@/hooks/use-conditional-controller";
5
- import { InputProps } from "../Input/types";
6
- import { useMask } from "@/hooks/use-mask";
7
- import { useRef } from "react";
8
-
9
- export type MaskInputProps = {
10
- mask?: string;
11
- } & InputProps;
12
-
13
- export const MaskInput = ({
14
- "data-testid": dataTestId,
15
- withoutForm = false,
16
- extraElement,
17
- mask = "",
18
- ...props
19
- }: MaskInputProps) => {
20
- const formData = useConditionalController({
21
- name: props.name || "",
22
- withoutForm,
23
- });
24
-
25
- const inputProps = React.useMemo(() => {
26
- return {
27
- ...formData,
28
- ...props,
29
- };
30
- }, [formData, props]);
31
-
32
- const { applyMask } = useMask({ mask });
33
-
34
- const inputRef = useRef<HTMLInputElement>(null);
35
-
36
- const applyMaskToInput = React.useCallback(
37
- (value: string) => {
38
- if (inputRef.current && mask) {
39
- const maskedValue = applyMask(value);
40
- inputRef.current.value = maskedValue;
41
- }
42
- },
43
- [applyMask, mask]
44
- );
45
-
46
- const handleChange = React.useCallback(
47
- (e: React.ChangeEvent<HTMLInputElement>) => {
48
- const maskedValue = mask ? applyMask(e.target.value) : e.target.value;
49
-
50
- const response = {
51
- ...e,
52
- target: {
53
- ...e.target,
54
- value: maskedValue,
55
- },
56
- };
57
- applyMaskToInput(maskedValue);
58
- return inputProps?.onChange?.(response);
59
- },
60
- [applyMask, inputProps, mask, applyMaskToInput]
61
- );
62
-
63
- return (
64
- <Input
65
- {...inputProps}
66
- ref={inputRef}
67
- onChange={handleChange}
68
- extraElement={extraElement}
69
- data-testid={dataTestId}
70
- withoutForm={true}
71
- />
72
- );
73
- };
@@ -1,105 +0,0 @@
1
- import { Button } from "../../../../actions/Button";
2
- import { Icon } from "../../../../dataDisplay/Icon";
3
- import { useCallback, useMemo, useState } from "react";
4
- import { useConditionalController } from "@/hooks/use-conditional-controller";
5
- import { MaskInput, MaskInputProps } from "../MaskInput";
6
-
7
- export type MultipleInputProps = MaskInputProps & {
8
- data?: string[];
9
- onAdd?: (data: string) => void;
10
- onRemove?: (position: number) => void;
11
- name: string;
12
- defaultValue?: string;
13
- "data-testid"?: string;
14
- };
15
-
16
- export const MultipleInput = ({
17
- data = [],
18
- onAdd = () => {},
19
- defaultValue = "",
20
- onRemove = () => {},
21
- withoutForm = false,
22
- ...props
23
- }: MultipleInputProps) => {
24
- const [inputValue, setInputValue] = useState(defaultValue);
25
-
26
- const formData = useConditionalController({
27
- name: props.name || "",
28
- withoutForm,
29
- });
30
-
31
- const inputItems = useMemo(() => {
32
- if (formData?.value) {
33
- return formData.value;
34
- }
35
- return data;
36
- }, [data, formData]);
37
-
38
- const onAddData = useCallback(() => {
39
- const trimmedValue = inputValue.trim();
40
- if (trimmedValue) {
41
- if (formData?.onChange) {
42
- formData.onChange([...inputItems, trimmedValue]);
43
- } else {
44
- onAdd(trimmedValue);
45
- }
46
- setInputValue("");
47
- }
48
- }, [inputValue, formData, onAdd, inputItems]);
49
-
50
- const onRemoveData = useCallback(
51
- (index: number) => {
52
- if (formData?.onChange) {
53
- const newData = inputItems.filter(
54
- (_: string, i: number) => i !== index
55
- );
56
- formData.onChange(newData);
57
- } else {
58
- onRemove(index);
59
- }
60
- },
61
- [formData, inputItems, onRemove]
62
- );
63
-
64
- const renderItens = useCallback(() => {
65
- return inputItems?.map((item: string, index: number) => {
66
- return (
67
- <div key={item} className="flex justify-between">
68
- {item}
69
- <Button
70
- variant="ghost"
71
- className="text-destructive"
72
- size={"icon"}
73
- onClick={() => onRemoveData(index)}
74
- >
75
- <Icon name="MdDelete" />
76
- </Button>
77
- </div>
78
- );
79
- });
80
- }, [inputItems, onRemoveData]);
81
-
82
- const extraElement = useMemo(
83
- () => (
84
- <Button type="button" onClick={onAddData} disabled={!inputValue}>
85
- <Icon name="MdAdd" />
86
- </Button>
87
- ),
88
- [onAddData, inputValue]
89
- );
90
-
91
- return (
92
- <div className="flex flex-col gap-2">
93
- <MaskInput
94
- {...props}
95
- withoutForm
96
- extraElement={extraElement}
97
- onChange={(e) => {
98
- setInputValue(e.target.value);
99
- }}
100
- value={inputValue}
101
- />
102
- {renderItens()}
103
- </div>
104
- );
105
- };