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

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 (213) 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/package.json +46 -6
  9. package/.eslintrc.json +0 -7
  10. package/.github/workflows/deploy-storybook.yml +0 -75
  11. package/.storybook/main.ts +0 -16
  12. package/.storybook/preview.ts +0 -15
  13. package/components.json +0 -21
  14. package/jest.config.ts +0 -25
  15. package/next.config.ts +0 -7
  16. package/postcss.config.mjs +0 -8
  17. package/public/file.svg +0 -1
  18. package/public/globe.svg +0 -1
  19. package/public/next.svg +0 -1
  20. package/public/vercel.svg +0 -1
  21. package/public/window.svg +0 -1
  22. package/src/app/columns.tsx +0 -178
  23. package/src/app/favicon.ico +0 -0
  24. package/src/app/fonts/GeistMonoVF.woff +0 -0
  25. package/src/app/fonts/GeistVF.woff +0 -0
  26. package/src/app/globals.css +0 -94
  27. package/src/app/layout.tsx +0 -35
  28. package/src/app/page.tsx +0 -7
  29. package/src/components/actions/AlertDialog/AlertDialog.tsx +0 -45
  30. package/src/components/actions/AlertDialog/alert-dialog.stories.tsx +0 -21
  31. package/src/components/actions/AlertDialog/index.ts +0 -1
  32. package/src/components/actions/Button/Button.stories.ts +0 -38
  33. package/src/components/actions/Button/Button.tsx +0 -23
  34. package/src/components/actions/Button/index.ts +0 -1
  35. package/src/components/actions/Collapsible/index.ts +0 -1
  36. package/src/components/actions/Dialog/Dialog.stories.tsx +0 -70
  37. package/src/components/actions/Dialog/Dialog.tsx +0 -87
  38. package/src/components/actions/Dialog/components/DialogWithActions/index.tsx +0 -40
  39. package/src/components/actions/Dialog/index.ts +0 -1
  40. package/src/components/actions/Steps/Steps.stories.tsx +0 -25
  41. package/src/components/actions/Steps/Steps.tsx +0 -51
  42. package/src/components/actions/Steps/index.ts +0 -1
  43. package/src/components/actions/index.ts +0 -5
  44. package/src/components/dataDisplay/Avatar/Avatar.stories.tsx +0 -22
  45. package/src/components/dataDisplay/Avatar/Avatar.tsx +0 -21
  46. package/src/components/dataDisplay/Avatar/index.ts +0 -2
  47. package/src/components/dataDisplay/Badge/Badge.stories.tsx +0 -36
  48. package/src/components/dataDisplay/Badge/index.ts +0 -1
  49. package/src/components/dataDisplay/Card/Card.stories.tsx +0 -24
  50. package/src/components/dataDisplay/Card/Card.tsx +0 -34
  51. package/src/components/dataDisplay/Card/index.ts +0 -1
  52. package/src/components/dataDisplay/DataPairList/DataPairList.tsx +0 -56
  53. package/src/components/dataDisplay/DataPairList/data-pair-list.stories.tsx +0 -87
  54. package/src/components/dataDisplay/DataPairList/index.ts +0 -2
  55. package/src/components/dataDisplay/DataPairList/types.ts +0 -10
  56. package/src/components/dataDisplay/DropDownMenu/index.ts +0 -1
  57. package/src/components/dataDisplay/ErrorMessage/ErrorMessage.tsx +0 -6
  58. package/src/components/dataDisplay/ErrorMessage/index.ts +0 -1
  59. package/src/components/dataDisplay/Icon/Icon.stories.tsx +0 -21
  60. package/src/components/dataDisplay/Icon/Icon.tsx +0 -47
  61. package/src/components/dataDisplay/Icon/index.ts +0 -1
  62. package/src/components/dataDisplay/Icon/types.ts +0 -6
  63. package/src/components/dataDisplay/Label/Label.stories.tsx +0 -21
  64. package/src/components/dataDisplay/Label/Label.tsx +0 -10
  65. package/src/components/dataDisplay/Label/index.ts +0 -1
  66. package/src/components/dataDisplay/Table/Table.tsx +0 -173
  67. package/src/components/dataDisplay/Table/columns.tsx +0 -223
  68. package/src/components/dataDisplay/Table/components/DynamicTable/data-table-column-header.tsx +0 -72
  69. package/src/components/dataDisplay/Table/components/DynamicTable/data-table-pagination.tsx +0 -91
  70. package/src/components/dataDisplay/Table/components/DynamicTable/data-table-toolbar.tsx +0 -17
  71. package/src/components/dataDisplay/Table/components/DynamicTable/data-table-view-options.tsx +0 -58
  72. package/src/components/dataDisplay/Table/components/DynamicTable/data-table.stories.tsx +0 -118
  73. package/src/components/dataDisplay/Table/components/DynamicTable/index.tsx +0 -136
  74. package/src/components/dataDisplay/Table/components/DynamicTable/types.ts +0 -43
  75. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-column-header.tsx +0 -71
  76. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-faceted-filter.tsx +0 -147
  77. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-pagination.tsx +0 -97
  78. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-row-actions.tsx +0 -78
  79. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-toolbar.tsx +0 -60
  80. package/src/components/dataDisplay/Table/custom/CustomTable/data-table-view-options.tsx +0 -59
  81. package/src/components/dataDisplay/Table/custom/CustomTable/data-table.tsx +0 -145
  82. package/src/components/dataDisplay/Table/custom/CustomTable/data.ts +0 -71
  83. package/src/components/dataDisplay/Table/custom/CustomTable/index.tsx +0 -34
  84. package/src/components/dataDisplay/Table/custom/CustomTable/schema.ts +0 -11
  85. package/src/components/dataDisplay/Table/index.ts +0 -2
  86. package/src/components/dataDisplay/Table/table.stories.tsx +0 -147
  87. package/src/components/dataDisplay/Table/types.ts +0 -15
  88. package/src/components/dataDisplay/Tabs/Tabs.stories.tsx +0 -34
  89. package/src/components/dataDisplay/Tabs/Tabs.tsx +0 -53
  90. package/src/components/dataDisplay/Tabs/index.ts +0 -1
  91. package/src/components/dataDisplay/Text/Text.stories.tsx +0 -66
  92. package/src/components/dataDisplay/Text/Text.tsx +0 -56
  93. package/src/components/dataDisplay/Text/index.ts +0 -1
  94. package/src/components/dataDisplay/index.ts +0 -8
  95. package/src/components/dataInput/Input/components/Input/Input.stories.tsx +0 -99
  96. package/src/components/dataInput/Input/components/Input/InputBase.tsx +0 -50
  97. package/src/components/dataInput/Input/components/Input/__tests__/input.test.tsx +0 -38
  98. package/src/components/dataInput/Input/components/Input/index.tsx +0 -48
  99. package/src/components/dataInput/Input/components/Input/types.ts +0 -15
  100. package/src/components/dataInput/Input/components/InputBase/index.tsx +0 -31
  101. package/src/components/dataInput/Input/components/MaskInput/__tests__/mask-input.test.tsx +0 -77
  102. package/src/components/dataInput/Input/components/MaskInput/index.ts +0 -1
  103. package/src/components/dataInput/Input/components/MaskInput/mask-input.stories.tsx +0 -85
  104. package/src/components/dataInput/Input/components/MaskInput/mask-input.tsx +0 -73
  105. package/src/components/dataInput/Input/components/MultipleInput/MultipleInput.tsx +0 -105
  106. package/src/components/dataInput/Input/components/MultipleInput/MultipleInputBase.tsx +0 -100
  107. package/src/components/dataInput/Input/components/MultipleInput/MultipleMaskInput.tsx +0 -35
  108. package/src/components/dataInput/Input/components/MultipleInput/MultipleNumberInput.tsx +0 -35
  109. package/src/components/dataInput/Input/components/MultipleInput/__tests__/multiple-input.test.tsx +0 -152
  110. package/src/components/dataInput/Input/components/MultipleInput/index.ts +0 -2
  111. package/src/components/dataInput/Input/components/MultipleInput/multiple-input.stories.tsx +0 -96
  112. package/src/components/dataInput/Input/components/NumberInput/__tests__/number-input.test.tsx +0 -175
  113. package/src/components/dataInput/Input/components/NumberInput/index.ts +0 -1
  114. package/src/components/dataInput/Input/components/NumberInput/number-input.stories.tsx +0 -76
  115. package/src/components/dataInput/Input/components/NumberInput/number-input.tsx +0 -70
  116. package/src/components/dataInput/Input/index.ts +0 -4
  117. package/src/components/dataInput/Select/MultiSelect/MultiSelect.stories.tsx +0 -119
  118. package/src/components/dataInput/Select/MultiSelect/MultiSelectBase.tsx +0 -135
  119. package/src/components/dataInput/Select/MultiSelect/index.tsx +0 -75
  120. package/src/components/dataInput/Select/Select.stories.tsx +0 -61
  121. package/src/components/dataInput/Select/Select.tsx +0 -73
  122. package/src/components/dataInput/Select/SelectBase.tsx +0 -58
  123. package/src/components/dataInput/Select/index.ts +0 -2
  124. package/src/components/dataInput/Switch/Switch.stories.tsx +0 -75
  125. package/src/components/dataInput/Switch/Switch.tsx +0 -52
  126. package/src/components/dataInput/Switch/index.ts +0 -1
  127. package/src/components/dataInput/checkbox/Checkbox.tsx +0 -57
  128. package/src/components/dataInput/checkbox/Checkbox_old.tsx +0 -58
  129. package/src/components/dataInput/checkbox/Checkout.stories.tsx +0 -62
  130. package/src/components/dataInput/checkbox/index.ts +0 -1
  131. package/src/components/dataInput/form/Form.tsx +0 -47
  132. package/src/components/dataInput/form/index.ts +0 -3
  133. package/src/components/dataInput/index.ts +0 -5
  134. package/src/components/feedback/ErrorLabel/index.tsx +0 -24
  135. package/src/components/feedback/Spinner/index.ts +0 -1
  136. package/src/components/feedback/Toast/Toast.stories.tsx +0 -45
  137. package/src/components/feedback/Toast/index.ts +0 -2
  138. package/src/components/feedback/index.ts +0 -2
  139. package/src/components/index.ts +0 -6
  140. package/src/components/layout/Crud/components/Table/index.tsx +0 -183
  141. package/src/components/layout/Crud/components/Table/types.ts +0 -15
  142. package/src/components/layout/Crud/crud.stories.tsx +0 -317
  143. package/src/components/layout/Crud/hook/useCrudLayout/index.tsx +0 -94
  144. package/src/components/layout/Crud/hook/useRequest/index.tsx +0 -156
  145. package/src/components/layout/Crud/index.tsx +0 -295
  146. package/src/components/layout/Crud/store/CrudLayoutStore.ts +0 -75
  147. package/src/components/layout/Crud/types.ts +0 -14
  148. package/src/components/layout/Drawer/CustomDrawer/index.tsx +0 -33
  149. package/src/components/layout/Drawer/Drawer.stories.tsx +0 -80
  150. package/src/components/layout/Drawer/index.ts +0 -2
  151. package/src/components/layout/PageLayout/PageLayout.stories.tsx +0 -42
  152. package/src/components/layout/PageLayout/index.tsx +0 -28
  153. package/src/components/layout/Separator/index.ts +0 -1
  154. package/src/components/layout/Sheet/Sheet.stories.tsx +0 -28
  155. package/src/components/layout/Sheet/Sheet.tsx +0 -22
  156. package/src/components/layout/Sheet/index.ts +0 -1
  157. package/src/components/layout/Sidebar/Sidebar.stories.tsx +0 -116
  158. package/src/components/layout/Sidebar/Sidebar.tsx +0 -50
  159. package/src/components/layout/Sidebar/components/app-sidebar.tsx +0 -203
  160. package/src/components/layout/Sidebar/components/footer-sidebar.tsx +0 -17
  161. package/src/components/layout/Sidebar/components/header-sidebar.tsx +0 -90
  162. package/src/components/layout/Sidebar/components/menus.tsx +0 -55
  163. package/src/components/layout/Sidebar/components/nav-projects.tsx +0 -88
  164. package/src/components/layout/Sidebar/components/nav-user.tsx +0 -114
  165. package/src/components/layout/Sidebar/components/team-switcher.tsx +0 -85
  166. package/src/components/layout/Sidebar/index.ts +0 -2
  167. package/src/components/layout/Sidebar/provider/index.tsx +0 -51
  168. package/src/components/layout/Tabs/Tabs.tsx +0 -51
  169. package/src/components/layout/Tabs/index.ts +0 -1
  170. package/src/components/layout/Tabs/tabs.stories.tsx +0 -57
  171. package/src/components/layout/index.ts +0 -6
  172. package/src/components/navigation/Breadcrumbs/Breadcrumbs.tsx +0 -66
  173. package/src/components/navigation/Breadcrumbs/index.ts +0 -2
  174. package/src/components/navigation/index.ts +0 -1
  175. package/src/components/ui/alert-dialog.tsx +0 -141
  176. package/src/components/ui/alert.tsx +0 -59
  177. package/src/components/ui/avatar.tsx +0 -50
  178. package/src/components/ui/badge.tsx +0 -40
  179. package/src/components/ui/breadcrumb.tsx +0 -115
  180. package/src/components/ui/button.tsx +0 -57
  181. package/src/components/ui/card.tsx +0 -83
  182. package/src/components/ui/checkbox.tsx +0 -34
  183. package/src/components/ui/collapsible.tsx +0 -11
  184. package/src/components/ui/command.tsx +0 -153
  185. package/src/components/ui/dialog.tsx +0 -124
  186. package/src/components/ui/drawer.tsx +0 -117
  187. package/src/components/ui/dropdown-menu.tsx +0 -201
  188. package/src/components/ui/form.tsx +0 -179
  189. package/src/components/ui/input.tsx +0 -24
  190. package/src/components/ui/label.tsx +0 -30
  191. package/src/components/ui/popover.tsx +0 -33
  192. package/src/components/ui/select.tsx +0 -161
  193. package/src/components/ui/separator.tsx +0 -31
  194. package/src/components/ui/sheet.tsx +0 -140
  195. package/src/components/ui/sidebar.tsx +0 -763
  196. package/src/components/ui/skeleton.tsx +0 -15
  197. package/src/components/ui/sonner.tsx +0 -31
  198. package/src/components/ui/spinner.tsx +0 -54
  199. package/src/components/ui/switch.tsx +0 -33
  200. package/src/components/ui/table.tsx +0 -120
  201. package/src/components/ui/tabs.tsx +0 -55
  202. package/src/components/ui/toast.tsx +0 -130
  203. package/src/components/ui/toaster.tsx +0 -35
  204. package/src/components/ui/tooltip.tsx +0 -32
  205. package/src/hooks/use-conditional-controller.tsx +0 -35
  206. package/src/hooks/use-mask.tsx +0 -116
  207. package/src/hooks/use-mobile.tsx +0 -19
  208. package/src/hooks/use-toast.ts +0 -191
  209. package/src/index.ts +0 -1
  210. package/src/introduction.mdx +0 -132
  211. package/src/lib/utils.ts +0 -6
  212. package/tailwind.config.ts +0 -83
  213. package/tsconfig.json +0 -27
@@ -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
- };
@@ -1,100 +0,0 @@
1
- import { Button } from "../../../../../components/actions";
2
- import { Icon } from "../../../../../components/dataDisplay";
3
- import { useCallback, useMemo, useState } from "react";
4
- import { useFormContext } from "react-hook-form";
5
- import _ from "lodash";
6
-
7
- export type MultipleInputBaseProps = {
8
- children: (params: {
9
- onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
10
- addItem: () => void;
11
- value: string;
12
- error?: string;
13
- }) => React.ReactNode;
14
- data: string[];
15
- name?: string;
16
- onChangeData?: (data: string[]) => void;
17
- error?: string;
18
- };
19
-
20
- export const MultipleInputBase = ({
21
- children,
22
- data = [],
23
- name,
24
- onChangeData = () => {},
25
- error,
26
- }: MultipleInputBaseProps) => {
27
- const form = useFormContext();
28
- const withForm = !!form && !!name;
29
- const [inputValue, setInputValue] = useState("");
30
-
31
- const inputData = useMemo(() => {
32
- if (withForm) {
33
- return _.get(form.watch(), name) || [];
34
- }
35
- return data;
36
- }, [withForm, form, name, data]);
37
-
38
- const errorMessage = useMemo(() => {
39
- if (withForm) {
40
- return _.get(form.formState.errors, name)?.message as string;
41
- }
42
- return error;
43
- }, [error, form, name, withForm]);
44
-
45
- const updateData = useCallback(() => {
46
- if (!inputValue.length) return;
47
- if (withForm) {
48
- form.setValue(name, [...inputData, inputValue]);
49
- } else {
50
- onChangeData?.(inputData.concat(inputValue));
51
- }
52
- setInputValue("");
53
- }, [inputData, inputValue, withForm, form, name, onChangeData]);
54
-
55
- const removeItem = useCallback(
56
- (index: number) => {
57
- if (withForm) {
58
- form.setValue(
59
- name,
60
- inputData.filter((_: string, i: number) => i !== index)
61
- );
62
- } else {
63
- onChangeData?.(inputData.filter((_: string, i: number) => i !== index));
64
- }
65
- },
66
- [withForm, form, name, inputData, onChangeData]
67
- );
68
-
69
- const renderOptions = useCallback(() => {
70
- return inputData?.map((item: string, index: number) => {
71
- return (
72
- <div key={index} className="flex justify-between mt-2">
73
- <div>{item}</div>
74
- <Button
75
- onClick={() => removeItem(index)}
76
- variant={"ghost"}
77
- size={"icon"}
78
- type="button"
79
- >
80
- <Icon name="MdDelete" className="fill-destructive" />
81
- </Button>
82
- </div>
83
- );
84
- });
85
- }, [inputData, removeItem]);
86
-
87
- return (
88
- <div>
89
- {children({
90
- onChange: ({ target: { value } }) => {
91
- setInputValue(value);
92
- },
93
- addItem: updateData,
94
- value: inputValue,
95
- error: errorMessage,
96
- })}
97
- {renderOptions()}
98
- </div>
99
- );
100
- };
@@ -1,35 +0,0 @@
1
- import { Button } from "../../../../../components/actions";
2
- import { MaskInput, MaskInputProps } from "../MaskInput";
3
- import { MultipleInputBase } from "./MultipleInputBase";
4
- import { Icon } from "../../../../../components/dataDisplay";
5
-
6
- export type MultipleMaskInputProps = MaskInputProps & {
7
- data?: string[];
8
- onChangeData?: (data: string[]) => void;
9
- name: string;
10
- };
11
-
12
- export const MultipleMaskInput = ({
13
- data = [],
14
- ...props
15
- }: MultipleMaskInputProps) => {
16
- return (
17
- <MultipleInputBase data={data} {...props}>
18
- {({ onChange, addItem, value }) => {
19
- return (
20
- <MaskInput
21
- {...props}
22
- value={value}
23
- onChange={onChange}
24
- withoutForm
25
- component={
26
- <Button type="button" onClick={() => addItem()}>
27
- <Icon name="MdAdd" />
28
- </Button>
29
- }
30
- />
31
- );
32
- }}
33
- </MultipleInputBase>
34
- );
35
- };
@@ -1,35 +0,0 @@
1
- import { Button } from "../../../../actions/Button";
2
- import { Input, InputProps } from "../Input";
3
- import { MultipleInputBase } from "./MultipleInputBase";
4
- import { Icon } from "../../../../dataDisplay/Icon";
5
-
6
- export type MultipleNumberInputProps = InputProps & {
7
- data: string[];
8
- onChangeData: (data: string[]) => void;
9
- name: string;
10
- };
11
-
12
- export const MultipleNumberInput = ({
13
- data,
14
- ...props
15
- }: MultipleNumberInputProps) => {
16
- return (
17
- <MultipleInputBase data={data} {...props}>
18
- {({ onChange, addItem, value }) => (
19
- <Input
20
- {...props}
21
- value={value}
22
- onChange={(e) => {
23
- onChange(e.target.value);
24
- }}
25
- withoutForm
26
- component={
27
- <Button onClick={() => addItem()}>
28
- <Icon name="MdAdd" />
29
- </Button>
30
- }
31
- />
32
- )}
33
- </MultipleInputBase>
34
- );
35
- };
@@ -1,152 +0,0 @@
1
- import "@testing-library/jest-dom";
2
- import { fireEvent, render, screen } from "@testing-library/react";
3
- import { MultipleInput } from "../MultipleInput";
4
-
5
- describe("MultipleInput", () => {
6
- it("should render label", () => {
7
- render(
8
- <MultipleInput
9
- label="test"
10
- name="test-input"
11
- data-testid="multiple-input"
12
- />
13
- );
14
- const label = screen.getByTestId("multiple-input-label");
15
- expect(label).toBeInTheDocument();
16
- expect(label).toHaveTextContent("test");
17
- });
18
-
19
- it("should render error", () => {
20
- render(
21
- <MultipleInput
22
- error="test"
23
- name="test-input"
24
- data-testid="multiple-input"
25
- />
26
- );
27
- const error = screen.getByTestId("multiple-input-error-label");
28
- expect(error).toBeInTheDocument();
29
- expect(error).toHaveTextContent("test");
30
- });
31
-
32
- it("should be disabled", () => {
33
- render(
34
- <MultipleInput disabled name="test-input" data-testid="multiple-input" />
35
- );
36
- const input = screen.getByTestId("multiple-input");
37
- expect(input).toBeDisabled();
38
- });
39
-
40
- it("should be required", () => {
41
- render(
42
- <MultipleInput
43
- required
44
- name="test-input"
45
- label="test"
46
- data-testid="multiple-input"
47
- />
48
- );
49
- const label = screen.getByTestId("multiple-input-label");
50
- expect(label).toHaveTextContent("test *");
51
- });
52
-
53
- it("should change value", () => {
54
- render(<MultipleInput name="test-input" data-testid="multiple-input" />);
55
- const input = screen.getByTestId("multiple-input");
56
- fireEvent.change(input, { target: { value: "test" } });
57
- expect(input).toHaveValue("test");
58
- });
59
-
60
- it("should render add button", () => {
61
- render(<MultipleInput name="test-input" data-testid="multiple-input" />);
62
- const addButton = screen.getByRole("button");
63
- expect(addButton).toBeInTheDocument();
64
- });
65
-
66
- it("should add item when add button is clicked", () => {
67
- const mockOnAdd = jest.fn();
68
- render(
69
- <MultipleInput
70
- name="test-input"
71
- data-testid="multiple-input"
72
- onAdd={mockOnAdd}
73
- withoutForm
74
- />
75
- );
76
-
77
- const input = screen.getByTestId("multiple-input");
78
- const addButton = screen.getByRole("button");
79
-
80
- fireEvent.change(input, { target: { value: "test item" } });
81
- fireEvent.click(addButton);
82
-
83
- expect(mockOnAdd).toHaveBeenCalledWith("test item");
84
- });
85
-
86
- it("should render with initial data", () => {
87
- const initialData = ["item 1", "item 2"];
88
-
89
- render(
90
- <MultipleInput
91
- name="test-input"
92
- data={initialData}
93
- data-testid="multiple-input"
94
- withoutForm
95
- />
96
- );
97
-
98
- expect(screen.getByText("item 1")).toBeInTheDocument();
99
- expect(screen.getByText("item 2")).toBeInTheDocument();
100
- });
101
-
102
- it("should handle mask prop", () => {
103
- render(
104
- <MultipleInput
105
- name="test-input"
106
- mask="(99) 99999-9999"
107
- data-testid="multiple-input"
108
- />
109
- );
110
-
111
- const input = screen.getByTestId("multiple-input");
112
- expect(input).toBeInTheDocument();
113
- });
114
-
115
- it("should remove item when remove button is clicked", () => {
116
- const mockOnRemove = jest.fn();
117
- const initialData = ["item 1", "item 2"];
118
-
119
- render(
120
- <MultipleInput
121
- name="test-input"
122
- data={initialData}
123
- onRemove={mockOnRemove}
124
- data-testid="multiple-input"
125
- withoutForm
126
- />
127
- );
128
-
129
- const removeButtons = screen.getAllByRole("button");
130
- const removeButton = removeButtons.find((button) =>
131
- button.querySelector('[data-icon="MdDelete"]')
132
- );
133
-
134
- if (removeButton) {
135
- fireEvent.click(removeButton);
136
- expect(mockOnRemove).toHaveBeenCalledWith(0);
137
- }
138
- });
139
-
140
- it("should disable add button when input is empty", () => {
141
- render(
142
- <MultipleInput
143
- name="test-input"
144
- data-testid="multiple-input"
145
- withoutForm
146
- />
147
- );
148
-
149
- const addButton = screen.getByRole("button");
150
- expect(addButton).toBeDisabled();
151
- });
152
- });
@@ -1,2 +0,0 @@
1
- export * from "./MultipleInput";
2
- export * from "./MultipleMaskInput";