@agilant/toga-blox 1.0.32 → 1.0.33

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 (144) hide show
  1. package/dist/components/Dropdown/Dropdown.d.ts +4 -0
  2. package/dist/components/Dropdown/Dropdown.js +20 -0
  3. package/dist/components/Dropdown/Dropdown.stories.d.ts +8 -0
  4. package/dist/components/Dropdown/Dropdown.stories.js +110 -0
  5. package/dist/components/Dropdown/Dropdown.test.d.ts +1 -0
  6. package/dist/components/Dropdown/Dropdown.test.js +43 -0
  7. package/dist/components/Dropdown/Dropdown.types.d.ts +15 -0
  8. package/dist/components/Dropdown/Dropdown.types.js +1 -0
  9. package/dist/components/GenericList/GenericList.d.ts +2 -15
  10. package/dist/components/GenericList/GenericList.js +64 -51
  11. package/dist/components/GenericList/GenericList.stories.d.ts +8 -35
  12. package/dist/components/GenericList/GenericList.stories.js +46 -78
  13. package/dist/components/GenericList/GenericList.test.d.ts +1 -1
  14. package/dist/components/GenericList/GenericList.test.js +112 -22
  15. package/dist/components/GenericList/index.d.ts +2 -0
  16. package/dist/components/GenericList/index.js +2 -0
  17. package/dist/components/GenericList/types.d.ts +16 -0
  18. package/dist/components/GenericList/types.js +1 -0
  19. package/dist/components/Header/Header.stories.js +2 -4
  20. package/dist/components/Input/Input.d.ts +30 -3
  21. package/dist/components/Input/Input.js +70 -48
  22. package/dist/components/Input/Input.stories.js +3 -4
  23. package/dist/components/Input/Input.test.js +74 -42
  24. package/dist/components/InputAndCheck/InputAndCheck.d.ts +47 -0
  25. package/dist/components/InputAndCheck/InputAndCheck.js +74 -0
  26. package/dist/components/InputAndCheck/InputAndCheck.stories.d.ts +9 -0
  27. package/dist/components/InputAndCheck/InputAndCheck.stories.js +201 -0
  28. package/dist/components/InputAndCheck/InputAndCheck.test.d.ts +1 -0
  29. package/dist/components/InputAndCheck/InputAndCheck.test.js +307 -0
  30. package/dist/components/InputAndCheck/index.d.ts +0 -0
  31. package/dist/components/InputAndCheck/index.js +0 -0
  32. package/dist/components/InputAndCheck/types.d.ts +35 -0
  33. package/dist/components/InputAndCheck/types.js +1 -0
  34. package/dist/components/MagnifyingIcon/MagnifyingIcon.d.ts +4 -0
  35. package/dist/components/MagnifyingIcon/MagnifyingIcon.js +60 -0
  36. package/dist/components/MagnifyingIcon/MagnifyingIcon.stories.d.ts +9 -0
  37. package/dist/components/MagnifyingIcon/MagnifyingIcon.stories.js +72 -0
  38. package/dist/components/MagnifyingIcon/MagnifyingIcon.test.d.ts +1 -0
  39. package/dist/components/MagnifyingIcon/MagnifyingIcon.test.js +101 -0
  40. package/dist/components/MagnifyingIcon/index.d.ts +2 -0
  41. package/dist/components/MagnifyingIcon/index.js +2 -0
  42. package/dist/components/MagnifyingIcon/types.d.ts +20 -0
  43. package/dist/components/MagnifyingIcon/types.js +2 -0
  44. package/dist/components/MultiSelect/MultiSelect.d.ts +4 -0
  45. package/dist/components/MultiSelect/MultiSelect.js +30 -0
  46. package/dist/components/MultiSelect/MultiSelect.stories.d.ts +10 -0
  47. package/dist/components/MultiSelect/MultiSelect.stories.js +162 -0
  48. package/dist/components/MultiSelect/MultiSelect.test.d.ts +1 -0
  49. package/dist/components/MultiSelect/MultiSelect.test.js +107 -0
  50. package/dist/components/MultiSelect/MultiSelect.types.d.ts +28 -0
  51. package/dist/components/MultiSelect/MultiSelect.types.js +1 -0
  52. package/dist/components/Page/ViewPageTemplate.stories.js +2 -3
  53. package/dist/components/PrimaryTableHeader/PrimaryTableHeader.d.ts +3 -0
  54. package/dist/components/PrimaryTableHeader/PrimaryTableHeader.js +72 -0
  55. package/dist/components/PrimaryTableHeader/PrimaryTableHeader.stories.d.ts +4 -0
  56. package/dist/components/PrimaryTableHeader/PrimaryTableHeader.stories.js +99 -0
  57. package/dist/components/PrimaryTableHeader/PrimaryTableHeader.test.d.ts +1 -0
  58. package/dist/components/PrimaryTableHeader/PrimaryTableHeader.test.js +124 -0
  59. package/dist/components/PrimaryTableHeader/index.d.ts +0 -0
  60. package/dist/components/PrimaryTableHeader/index.js +0 -0
  61. package/dist/components/PrimaryTableHeader/types.d.ts +35 -0
  62. package/dist/components/PrimaryTableHeader/types.js +2 -0
  63. package/dist/components/SearchInput/SearchInput.d.ts +1 -2
  64. package/dist/components/SearchInput/SearchInput.js +61 -11
  65. package/dist/components/SearchInput/SearchInput.stories.d.ts +2 -4
  66. package/dist/components/SearchInput/SearchInput.stories.js +80 -93
  67. package/dist/components/SearchInput/SearchInput.types.d.ts +37 -24
  68. package/dist/components/SearchInput/SearchNumberInput.d.ts +31 -0
  69. package/dist/components/SearchInput/SearchNumberInput.js +60 -0
  70. package/dist/components/SearchInput/SearchTextInput.d.ts +24 -0
  71. package/dist/components/SearchInput/SearchTextInput.js +65 -0
  72. package/dist/components/SortArrowIcon/SortArrowIcon.d.ts +4 -0
  73. package/dist/components/SortArrowIcon/SortArrowIcon.js +12 -0
  74. package/dist/components/SortArrowIcon/SortArrowIcon.stories.d.ts +17 -0
  75. package/dist/components/SortArrowIcon/SortArrowIcon.stories.js +77 -0
  76. package/dist/components/SortArrowIcon/SortArrowIcon.test.d.ts +1 -0
  77. package/dist/components/SortArrowIcon/SortArrowIcon.test.js +44 -0
  78. package/dist/components/SortArrowIcon/index.d.ts +2 -0
  79. package/dist/components/SortArrowIcon/index.js +2 -0
  80. package/dist/components/SortArrowIcon/types.d.ts +15 -0
  81. package/dist/components/SortArrowIcon/types.js +1 -0
  82. package/dist/components/SortArrows/SortArrows.d.ts +3 -0
  83. package/dist/components/SortArrows/SortArrows.js +33 -0
  84. package/dist/components/SortArrows/SortArrows.stories.d.ts +7 -0
  85. package/dist/components/SortArrows/SortArrows.stories.js +41 -0
  86. package/dist/components/SortArrows/SortArrows.test.d.ts +1 -0
  87. package/dist/components/SortArrows/SortArrows.test.js +150 -0
  88. package/dist/components/SortArrows/index.d.ts +2 -0
  89. package/dist/components/SortArrows/index.js +2 -0
  90. package/dist/components/SortArrows/types.d.ts +21 -0
  91. package/dist/components/SortArrows/types.js +1 -0
  92. package/dist/components/SortArrows/useSortArrowsViewModel.d.ts +30 -0
  93. package/dist/components/SortArrows/useSortArrowsViewModel.js +114 -0
  94. package/dist/components/SortArrows/useSortArrowsViewModel.test.d.ts +1 -0
  95. package/dist/components/SortArrows/useSortArrowsViewModel.test.js +100 -0
  96. package/dist/components/TableCell/TableCell.d.ts +3 -0
  97. package/dist/components/TableCell/TableCell.js +13 -0
  98. package/dist/components/TableCell/TableCell.stories.d.ts +16 -0
  99. package/dist/components/TableCell/TableCell.stories.js +99 -0
  100. package/dist/components/TableCell/TableCell.test.d.ts +1 -0
  101. package/dist/components/TableCell/TableCell.test.js +84 -0
  102. package/dist/components/TableCell/index.d.ts +2 -0
  103. package/dist/components/TableCell/index.js +2 -0
  104. package/dist/components/TableCell/types.d.ts +12 -0
  105. package/dist/components/TableCell/types.js +1 -0
  106. package/dist/components/TableHeaderContent/TableHeaderContent.d.ts +3 -0
  107. package/dist/components/TableHeaderContent/TableHeaderContent.js +5 -0
  108. package/dist/components/TableHeaderContent/TableHeaderContent.stories.d.ts +6 -0
  109. package/dist/components/TableHeaderContent/TableHeaderContent.stories.js +62 -0
  110. package/dist/components/TableHeaderContent/TableHeaderContent.test.d.ts +1 -0
  111. package/dist/components/TableHeaderContent/TableHeaderContent.test.js +41 -0
  112. package/dist/components/TableHeaderContent/index.d.ts +0 -0
  113. package/dist/components/TableHeaderContent/index.js +0 -0
  114. package/dist/components/TableHeaderContent/types.d.ts +5 -0
  115. package/dist/components/TableHeaderContent/types.js +1 -0
  116. package/dist/components/TableHeaderInput/TableHeaderInput.d.ts +3 -0
  117. package/dist/components/TableHeaderInput/TableHeaderInput.js +80 -0
  118. package/dist/components/TableHeaderInput/TableHeaderInput.stories.d.ts +10 -0
  119. package/dist/components/TableHeaderInput/TableHeaderInput.stories.js +82 -0
  120. package/dist/components/TableHeaderInput/TableHeaderInput.test.d.ts +1 -0
  121. package/dist/components/TableHeaderInput/TableHeaderInput.test.js +84 -0
  122. package/dist/components/TableHeaderInput/index.d.ts +1 -0
  123. package/dist/components/TableHeaderInput/index.js +1 -0
  124. package/dist/components/TableHeaderInput/types.d.ts +30 -0
  125. package/dist/components/TableHeaderInput/types.js +1 -0
  126. package/dist/components/TableRow/TableRow.d.ts +15 -0
  127. package/dist/components/TableRow/TableRow.js +21 -0
  128. package/dist/components/TableRow/TableRow.stories.d.ts +9 -0
  129. package/dist/components/TableRow/TableRow.stories.js +195 -0
  130. package/dist/components/TableRow/TableRow.test.d.ts +1 -0
  131. package/dist/components/TableRow/TableRow.test.js +44 -0
  132. package/dist/components/TableRow/index.d.ts +2 -0
  133. package/dist/components/TableRow/index.js +2 -0
  134. package/dist/components/TableRow/types.d.ts +11 -0
  135. package/dist/components/TableRow/types.js +1 -0
  136. package/dist/components/ToggleButton/ToggleButton.d.ts +4 -0
  137. package/dist/components/ToggleButton/ToggleButton.js +41 -0
  138. package/dist/components/ToggleButton/ToggleButton.stories.d.ts +11 -0
  139. package/dist/components/ToggleButton/ToggleButton.stories.js +111 -0
  140. package/dist/components/ToggleButton/ToggleButton.test.d.ts +1 -0
  141. package/dist/components/ToggleButton/ToggleButton.test.js +106 -0
  142. package/dist/components/ToggleButton/ToggleButton.types.d.ts +22 -0
  143. package/dist/components/ToggleButton/ToggleButton.types.js +1 -0
  144. package/package.json +10 -3
@@ -0,0 +1,195 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import TableRow from "./TableRow";
3
+ // Sample data for testing
4
+ const sampleData = {
5
+ uuid: "12345",
6
+ name: "John Doe",
7
+ age: 30,
8
+ address: "123 Main St, Springfield, IL, 62701, United States of America",
9
+ email: "john.doe@example.com",
10
+ phone: "+1 555-123-4567",
11
+ status: "Active",
12
+ };
13
+ // Mock row data
14
+ const mockRow = {
15
+ index: 0,
16
+ rowUuid: sampleData.uuid,
17
+ cells: [
18
+ {
19
+ value: sampleData.name,
20
+ render: (type) => type === "Cell" ? sampleData.name : null,
21
+ getCellProps: () => ({}),
22
+ },
23
+ {
24
+ value: sampleData.age,
25
+ render: (type) => type === "Cell" ? sampleData.age.toString() : null,
26
+ getCellProps: () => ({}),
27
+ },
28
+ {
29
+ value: sampleData.address,
30
+ render: (type) => type === "Cell" ? sampleData.address : null,
31
+ getCellProps: () => ({}),
32
+ },
33
+ {
34
+ value: sampleData.email,
35
+ render: (type) => type === "Cell" ? sampleData.email : null,
36
+ getCellProps: () => ({}),
37
+ },
38
+ {
39
+ value: sampleData.phone,
40
+ render: (type) => type === "Cell" ? sampleData.phone : null,
41
+ getCellProps: () => ({}),
42
+ },
43
+ {
44
+ value: sampleData.status,
45
+ render: (type) => type === "Cell" ? (_jsx("span", { className: "text-green-500", children: sampleData.status })) : null,
46
+ getCellProps: () => ({}),
47
+ },
48
+ ],
49
+ getRowProps: () => ({}),
50
+ };
51
+ // Mock prepareRow function
52
+ const prepareRow = (row) => { };
53
+ const meta = {
54
+ title: "Table/TableRow",
55
+ component: TableRow,
56
+ argTypes: {
57
+ row: {
58
+ control: "object",
59
+ description: "The row data to be displayed.",
60
+ },
61
+ prepareRow: {
62
+ control: "function",
63
+ description: "A function to prepare the row for rendering.",
64
+ },
65
+ globalTrimActive: {
66
+ control: "boolean",
67
+ description: "Toggle to enable or disable text trimming for long strings.",
68
+ },
69
+ rowUuid: {
70
+ control: "text",
71
+ description: "Unique identifier for the row.",
72
+ },
73
+ columnInputs: {
74
+ control: "object",
75
+ description: "Array of column inputs (if any).",
76
+ },
77
+ rowHoverClasses: {
78
+ control: "text",
79
+ description: "CSS classes to apply when the row is hovered. Defaults to `hover:bg-navy-100 hover:cursor-pointer`.",
80
+ },
81
+ onRowClick: {
82
+ control: "function",
83
+ description: "A callback function triggered when the row is clicked. It receives the row index, row UUID, and the click event as arguments.",
84
+ },
85
+ activeIndex: {
86
+ control: "number",
87
+ description: "The index of the currently active row. If the row's index matches this value, the row will be highlighted.",
88
+ },
89
+ },
90
+ tags: ["autodocs"],
91
+ parameters: {
92
+ layout: "centered",
93
+ docs: {
94
+ description: {
95
+ component: "A table row component that renders a row of data with optional hover effects, active states, and click handlers. It supports text trimming and custom rendering for individual cells.",
96
+ },
97
+ },
98
+ },
99
+ };
100
+ export default meta;
101
+ // Template for the story
102
+ const Template = (args) => (_jsx("table", { children: _jsx("tbody", { children: _jsx(TableRow, { ...args }) }) }));
103
+ // Default story
104
+ export const Default = Template.bind({});
105
+ Default.args = {
106
+ row: mockRow,
107
+ prepareRow,
108
+ globalTrimActive: true,
109
+ rowUuid: sampleData.uuid,
110
+ columnInputs: [],
111
+ rowHoverClasses: "hover:bg-red-100 hover:cursor-pointer",
112
+ };
113
+ Default.parameters = {
114
+ docs: {
115
+ description: {
116
+ story: "Default table row with text trimming enabled. Long text will be truncated to 30 characters.",
117
+ },
118
+ },
119
+ };
120
+ // Story with active row
121
+ export const ActiveRow = Template.bind({});
122
+ ActiveRow.args = {
123
+ ...Default.args,
124
+ activeIndex: 0,
125
+ };
126
+ ActiveRow.parameters = {
127
+ docs: {
128
+ description: {
129
+ story: "Table row with an active state. The active row is highlighted to indicate selection.",
130
+ },
131
+ },
132
+ };
133
+ // Story with custom row click handler
134
+ export const WithRowClickHandler = Template.bind({});
135
+ WithRowClickHandler.args = {
136
+ ...Default.args,
137
+ onRowClick: (index, rowUuid, event) => {
138
+ alert(`Row clicked!\nIndex: ${index}\nRow UUID: ${rowUuid}`);
139
+ console.log("Row clicked:", index, rowUuid, event);
140
+ },
141
+ };
142
+ WithRowClickHandler.parameters = {
143
+ docs: {
144
+ description: {
145
+ story: "Table row with a custom click handler. The `onRowClick` prop is used to handle row click events. In this example, an alert is shown when the row is clicked.",
146
+ },
147
+ },
148
+ };
149
+ // Story with disabled text trimming
150
+ export const NoTrimming = Template.bind({});
151
+ NoTrimming.args = {
152
+ ...Default.args,
153
+ globalTrimActive: false, // Disable text trimming
154
+ };
155
+ NoTrimming.parameters = {
156
+ docs: {
157
+ description: {
158
+ story: "Table row with text trimming disabled. The full text is displayed for each cell.",
159
+ },
160
+ },
161
+ };
162
+ // Story with custom cell rendering
163
+ export const CustomCellRendering = Template.bind({});
164
+ CustomCellRendering.args = {
165
+ ...Default.args,
166
+ row: {
167
+ ...mockRow,
168
+ cells: [
169
+ {
170
+ value: sampleData.name,
171
+ id: "name",
172
+ render: (type) => type === "Cell" ? _jsx("strong", { children: sampleData.name }) : null,
173
+ getCellProps: () => ({}),
174
+ },
175
+ {
176
+ value: sampleData.age,
177
+ id: "age",
178
+ render: (type) => type === "Cell" ? (_jsx("span", { className: "text-blue-500", children: sampleData.age })) : null,
179
+ getCellProps: () => ({}),
180
+ },
181
+ {
182
+ value: sampleData.address,
183
+ render: (type) => type === "Cell" ? sampleData.address : null,
184
+ getCellProps: () => ({}),
185
+ },
186
+ ],
187
+ },
188
+ };
189
+ CustomCellRendering.parameters = {
190
+ docs: {
191
+ description: {
192
+ story: "Table row with custom rendering for individual cells. The `render` function is used to customize the appearance of cell content (e.g., bold text, colored text).",
193
+ },
194
+ },
195
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, it, expect, vi } from "vitest";
3
+ import { render, screen, fireEvent } from "@testing-library/react";
4
+ import TableRow from "./TableRow";
5
+ describe("TableRow - Branch Coverage Tests", () => {
6
+ const mockPrepareRow = vi.fn();
7
+ // Basic row object
8
+ const baseMockRow = {
9
+ index: 0,
10
+ getRowProps: vi.fn(() => ({})),
11
+ cells: [
12
+ {
13
+ getCellProps: vi.fn(() => ({ key: "cell-0" })),
14
+ render: vi.fn(() => "Cell 0"),
15
+ },
16
+ ],
17
+ };
18
+ it("covers isActive = true (row is active)", () => {
19
+ render(_jsx("table", { children: _jsx("tbody", { children: _jsx(TableRow, { row: { ...baseMockRow, index: 5 }, prepareRow: mockPrepareRow, activeIndex: 5 }) }) }));
20
+ expect(screen.getByTestId("table-row")).toHaveClass("activeRow");
21
+ });
22
+ it("covers isActive = false (row is NOT active)", () => {
23
+ render(_jsx("table", { children: _jsx("tbody", { children: _jsx(TableRow, { row: { ...baseMockRow, index: 2 }, prepareRow: mockPrepareRow, activeIndex: 5 }) }) }));
24
+ expect(screen.getByTestId("table-row")).not.toHaveClass("activeRow");
25
+ });
26
+ it("covers onRowClick = defined + rowUuid = provided", () => {
27
+ const mockOnRowClick = vi.fn();
28
+ render(_jsx("table", { children: _jsx("tbody", { children: _jsx(TableRow, { row: baseMockRow, prepareRow: mockPrepareRow, onRowClick: mockOnRowClick, rowUuid: "some-uuid" }) }) }));
29
+ fireEvent.click(screen.getByTestId("table-row"));
30
+ // Because rowUuid is defined, we expect 'some-uuid'
31
+ expect(mockOnRowClick).toHaveBeenCalledWith(baseMockRow.index, "some-uuid", expect.anything() // Synthetic event
32
+ );
33
+ });
34
+ it("covers onRowClick = defined + rowUuid = undefined (so calls empty string)", () => {
35
+ const mockOnRowClick = vi.fn();
36
+ render(_jsx("table", { children: _jsx("tbody", { children: _jsx(TableRow, { row: baseMockRow, prepareRow: mockPrepareRow, onRowClick: mockOnRowClick }) }) }));
37
+ fireEvent.click(screen.getByTestId("table-row"));
38
+ expect(mockOnRowClick).toHaveBeenCalledWith(baseMockRow.index, "", expect.anything());
39
+ });
40
+ it("covers onRowClick = NOT defined", () => {
41
+ render(_jsx("table", { children: _jsx("tbody", { children: _jsx(TableRow, { row: baseMockRow, prepareRow: mockPrepareRow }) }) }));
42
+ fireEvent.click(screen.getByTestId("table-row"));
43
+ });
44
+ });
@@ -0,0 +1,2 @@
1
+ export { default } from "./TableRow";
2
+ export * from "./types";
@@ -0,0 +1,2 @@
1
+ export { default } from "./TableRow";
2
+ export * from "./types";
@@ -0,0 +1,11 @@
1
+ import { Row } from "react-table";
2
+ export interface TableRowProps<T extends object> {
3
+ row: Row<T>;
4
+ prepareRow: (row: Row<T>) => void;
5
+ globalTrimActive: boolean;
6
+ rowUuid?: string;
7
+ activeIndex: number;
8
+ columnInputs?: string[];
9
+ rowHoverClasses?: string;
10
+ addRowToClickedRows?: (rowUuid: string) => void;
11
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ import { ToggleProps } from "./ToggleButton.types";
3
+ declare const ToggleButton: React.FC<ToggleProps>;
4
+ export default ToggleButton;
@@ -0,0 +1,41 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Text from "../Text/Text";
3
+ const textPositionMap = {
4
+ left: "flex items-center",
5
+ right: "flex items-center flex-row-reverse",
6
+ top: "flex flex-col items-start",
7
+ bottom: "flex flex-col-reverse items-start",
8
+ };
9
+ const getToggleClasses = (status, smallToggle, borderStyle, activeColorBorder, inactiveColorBorder, activeColorBackground, inactiveColorBackground) => {
10
+ const baseClasses = "peer rounded-full border";
11
+ const borderToggleClasses = "after:absolute after:left-[4px] after:top-1 after:h-3 after:w-3 after:rounded-full after:bg-navy-300 after:transition-all after:content-['']";
12
+ const borderToggleCircleClasses = "peer-checked:after:translate-x-full peer-checked:after:border-white peer-checked:after:bg-supply-blue-500";
13
+ const smallBackgroundToggleClasses = "after:absolute after:left-[4px] after:top-1 after:h-3 after:w-3 after:rounded-full after:bg-navy-300 after:transition-all after:content-['']";
14
+ const largeBackgroundToggleClasses = "after:absolute after:left-[3px] after:top-[4.5px] after:h-[19px] after:w-[19px] after:rounded-full after:bg-white after:transition-all after:content-['']";
15
+ switch (true) {
16
+ // small toggle with border style
17
+ case smallToggle && borderStyle:
18
+ return `${baseClasses} h-[1.25rem] w-[2rem] ${status ? activeColorBorder : inactiveColorBorder} ${borderToggleClasses} ${status ? borderToggleCircleClasses : ""} `;
19
+ // small toggle with background style
20
+ case smallToggle && !borderStyle:
21
+ return `${baseClasses} h-[1.25rem] w-[2rem] ${status ? activeColorBackground : inactiveColorBackground} ${smallBackgroundToggleClasses} ${status ? "peer-checked:after:translate-x-full " : ""}`;
22
+ // large toggle with background style
23
+ case !smallToggle && !borderStyle:
24
+ return `${baseClasses} h-7 w-11 ${status ? activeColorBackground : inactiveColorBackground} ${largeBackgroundToggleClasses} ${status ? "peer-checked:after:translate-x-full " : ""}`;
25
+ default:
26
+ return `${baseClasses} h-7 w-11 ${status ? activeColorBorder : inactiveColorBorder} ${status ? activeColorBackground : inactiveColorBackground} ${largeBackgroundToggleClasses} ${status ? "peer-checked:after:translate-x-full " : ""}`;
27
+ }
28
+ };
29
+ const ToggleButton = ({ initialStatus, onClick, id, textPosition, textSize, activeColorBackground, inactiveColorBackground, activeColorBorder, inactiveColorBorder, activeLabel, inactiveLabel, additionalClasses, hasDisabledStatus, hasDivider, fontFamily, activeTextColor, inactiveTextColor, smallToggle, pillHeight, borderStyle, }) => {
30
+ const handleToggle = () => {
31
+ const newValue = !initialStatus;
32
+ onClick(newValue);
33
+ };
34
+ const textColor = initialStatus === true ? activeTextColor : inactiveTextColor;
35
+ const textPositionClasses = textPositionMap[textPosition];
36
+ const toggleClasses = getToggleClasses(initialStatus, smallToggle, borderStyle, activeColorBorder, inactiveColorBorder, activeColorBackground, inactiveColorBackground);
37
+ return (_jsx("div", { className: `flex justify-center ${hasDivider && textPosition === "right"
38
+ ? "border-r-1 border-navy-200 pr-2"
39
+ : ""} mr-2 ${pillHeight}`, children: hasDisabledStatus ? (_jsx("div", { className: `${pillHeight}`, children: _jsx(Text, { fontFamily: fontFamily, size: textSize, color: textColor, text: initialStatus ? activeLabel : inactiveLabel }) })) : (_jsxs("div", { className: `justify-between w-full ${textPositionClasses} ${textSize} ${textColor} ${additionalClasses} `, children: [_jsx("label", { htmlFor: id, "data-testid": "inactive-label", className: `flex justify-center ${smallToggle ? " min-w-10" : "min-w-20"}`, children: initialStatus ? activeLabel : inactiveLabel }), _jsxs("label", { className: "relative inline-flex cursor-pointer items-center", children: [_jsx("input", { id: id, type: "checkbox", className: "peer sr-only", checked: initialStatus, onChange: handleToggle }), _jsx("div", { className: toggleClasses })] })] })) }));
40
+ };
41
+ export default ToggleButton;
@@ -0,0 +1,11 @@
1
+ import { Meta } from "@storybook/react";
2
+ declare const _default: Meta;
3
+ export default _default;
4
+ export declare const Default: any;
5
+ export declare const SmallToggle: any;
6
+ export declare const DisabledStatus: any;
7
+ export declare const CustomColorsAndBorder: any;
8
+ export declare const TextPositionLeft: any;
9
+ export declare const TextPositionTop: any;
10
+ export declare const TextPositionBottom: any;
11
+ export declare const NoLabels: any;
@@ -0,0 +1,111 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import ToggleButton from "./ToggleButton";
4
+ export default {
5
+ title: "Components/ToggleButton",
6
+ component: ToggleButton,
7
+ tags: ["autodocs"],
8
+ argTypes: {
9
+ initialStatus: { control: "boolean" },
10
+ textPosition: {
11
+ control: "select",
12
+ options: ["left", "right", "top", "bottom"],
13
+ },
14
+ textSize: {
15
+ control: "text",
16
+ },
17
+ activeColorBackground: { control: "color" },
18
+ inactiveColorBackground: { control: "color" },
19
+ activeColorBorder: { control: "color" },
20
+ inactiveColorBorder: { control: "color" },
21
+ activeTextColor: { control: "color" },
22
+ inactiveTextColor: { control: "color" },
23
+ smallToggle: { control: "boolean" },
24
+ hasDisabledStatus: { control: "boolean" },
25
+ hasDivider: { control: "boolean" },
26
+ additionalClasses: { control: "text" },
27
+ pillHeight: { control: "text" },
28
+ borderStyle: { control: "boolean" },
29
+ },
30
+ parameters: { layout: "centered" },
31
+ };
32
+ // Template with State Management
33
+ const Template = (args) => {
34
+ const [toggleStatus, setToggleStatus] = useState(args.initialStatus);
35
+ return (_jsx(ToggleButton, { ...args, initialStatus: toggleStatus, onClick: (newStatus) => {
36
+ setToggleStatus(newStatus); // Update state when clicked
37
+ console.log(`Toggled to: ${newStatus}`); // Log the new state
38
+ } }));
39
+ };
40
+ // Default Story
41
+ export const Default = Template.bind({});
42
+ Default.args = {
43
+ initialStatus: false,
44
+ onClick: (status) => console.log(`Toggled to: ${status}`),
45
+ textPosition: "right",
46
+ textSize: "text-sm",
47
+ activeColorBackground: "bg-green-500",
48
+ inactiveColorBackground: "bg-gray-300",
49
+ activeColorBorder: "border-green-500",
50
+ inactiveColorBorder: "border-gray-300",
51
+ activeTextColor: "text-green-500",
52
+ inactiveTextColor: "text-gray-500",
53
+ activeLabel: "Active",
54
+ inactiveLabel: "Inactive",
55
+ smallToggle: false,
56
+ hasDisabledStatus: false,
57
+ hasDivider: false,
58
+ additionalClasses: "flex items-center",
59
+ pillHeight: "h-8",
60
+ borderStyle: false,
61
+ };
62
+ // Small Toggle
63
+ export const SmallToggle = Template.bind({});
64
+ SmallToggle.args = {
65
+ ...Default.args,
66
+ smallToggle: true,
67
+ activeLabel: "ON",
68
+ inactiveLabel: "OFF",
69
+ pillHeight: "h-6",
70
+ };
71
+ // Disabled Status
72
+ export const DisabledStatus = Template.bind({});
73
+ DisabledStatus.args = {
74
+ ...Default.args,
75
+ hasDisabledStatus: true,
76
+ };
77
+ // Custom Colors
78
+ export const CustomColorsAndBorder = Template.bind({});
79
+ CustomColorsAndBorder.args = {
80
+ ...Default.args,
81
+ borderStyle: true,
82
+ activeColorBackground: "bg-blue-500",
83
+ inactiveColorBackground: "bg-red-500",
84
+ activeTextColor: "text-blue-500",
85
+ inactiveTextColor: "text-red-500",
86
+ activeColorBorder: "border-black",
87
+ inactiveColorBorder: "border-black",
88
+ };
89
+ // Text Position Variations
90
+ export const TextPositionLeft = Template.bind({});
91
+ TextPositionLeft.args = {
92
+ ...Default.args,
93
+ textPosition: "left",
94
+ };
95
+ export const TextPositionTop = Template.bind({});
96
+ TextPositionTop.args = {
97
+ ...Default.args,
98
+ textPosition: "top",
99
+ };
100
+ export const TextPositionBottom = Template.bind({});
101
+ TextPositionBottom.args = {
102
+ ...Default.args,
103
+ textPosition: "bottom",
104
+ };
105
+ // No Text Labels
106
+ export const NoLabels = Template.bind({});
107
+ NoLabels.args = {
108
+ ...Default.args,
109
+ activeLabel: "",
110
+ inactiveLabel: "",
111
+ };
@@ -0,0 +1,106 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render, screen, fireEvent, waitFor, } from "@testing-library/react";
3
+ import { describe, expect, beforeEach, test, vi } from "vitest";
4
+ import ToggleButton from "./ToggleButton";
5
+ describe("<ToggleButton />", () => {
6
+ const defaultProps = {
7
+ initialStatus: false,
8
+ onClick: vi.fn(),
9
+ textPosition: "right",
10
+ textSize: "text-sm",
11
+ activeColorBackground: "bg-green-500",
12
+ inactiveColorBackground: "bg-gray-300",
13
+ activeColorBorder: "border-green-500",
14
+ inactiveColorBorder: "border-gray-300",
15
+ activeTextColor: "text-green-500",
16
+ inactiveTextColor: "text-gray-500",
17
+ activeLabel: "Active",
18
+ inactiveLabel: "Inactive",
19
+ smallToggle: false,
20
+ hasDisabledStatus: false,
21
+ hasDivider: false,
22
+ additionalClasses: "flex items-center",
23
+ pillHeight: "h-8",
24
+ borderStyle: false,
25
+ id: "toggle-button",
26
+ };
27
+ beforeEach(() => {
28
+ render(_jsx(ToggleButton, { ...defaultProps }));
29
+ });
30
+ // test("renders correct element for divider", () => {
31
+ // const { container } = render(
32
+ // <ToggleButton
33
+ // {...defaultProps}
34
+ // hasDivider={true}
35
+ // textPosition="right"
36
+ // />
37
+ // );
38
+ // expect(container.firstChild).toHaveClass("border-r-1");
39
+ // expect(container.firstChild).toHaveClass("pr-2");
40
+ // });
41
+ test("renders ToggleButton component", () => {
42
+ expect(screen.getByLabelText("Inactive")).toBeInTheDocument();
43
+ });
44
+ test("renders with the correct initial status", () => {
45
+ const toggleInput = screen.getByLabelText("Inactive");
46
+ expect(toggleInput).toBeInTheDocument();
47
+ expect(toggleInput).not.toBeChecked();
48
+ });
49
+ test("renders the correct labels", () => {
50
+ expect(screen.getByText("Inactive")).toBeInTheDocument();
51
+ });
52
+ test("renders correct text position", () => {
53
+ const container = screen.getByLabelText("Inactive").closest("div");
54
+ expect(container).toHaveClass("flex items-center flex-row-reverse");
55
+ });
56
+ test("applies correct text size", () => {
57
+ const container = screen.getByText("Inactive");
58
+ expect(container.closest("div")).toHaveClass("text-sm");
59
+ });
60
+ test("applies correct colors based on status", () => {
61
+ const toggleButton = screen.getByLabelText("Inactive")
62
+ .nextSibling;
63
+ expect(toggleButton.className).toContain("bg-gray-300");
64
+ });
65
+ test("toggles status on click", () => {
66
+ const toggleInput = screen.getByLabelText("Inactive");
67
+ fireEvent.click(toggleInput);
68
+ expect(defaultProps.onClick).toHaveBeenCalledWith(true);
69
+ });
70
+ test("renders correct classes for small toggle", () => {
71
+ render(_jsx(ToggleButton, { ...defaultProps, smallToggle: true }));
72
+ const toggleButton = screen.getByLabelText("Inactive")
73
+ .nextSibling;
74
+ expect(toggleButton.className).toContain("h-7");
75
+ expect(toggleButton.className).toContain("w-11");
76
+ });
77
+ test("renders correct disabled state", () => {
78
+ render(_jsx(ToggleButton, { ...defaultProps, hasDisabledStatus: true }));
79
+ const disabledText = screen.getAllByText("Inactive")[1]; // Target the specific occurrence
80
+ expect(disabledText).toBeInTheDocument();
81
+ });
82
+ test("renders correct element for divider", async () => {
83
+ render(_jsx(ToggleButton, { ...defaultProps, hasDivider: true, textPosition: "right" }));
84
+ const toggleContainer = screen
85
+ .getByLabelText("Inactive")
86
+ .closest("div");
87
+ const parentDiv = toggleContainer?.parentElement;
88
+ // Wait for styles to be applied
89
+ await waitFor(() => {
90
+ expect(parentDiv?.className).toContain("mr-2");
91
+ // expect(parentDiv?.className).toContain("border-navy-200");
92
+ }, { timeout: 2000 });
93
+ });
94
+ test("handles custom text size class", () => {
95
+ render(_jsx(ToggleButton, { ...defaultProps, textSize: "2xl" }));
96
+ // Use `getByText` with a more specific query
97
+ const inactiveLabel = screen
98
+ .getAllByText("Inactive")
99
+ .find((label) => label.closest("div")?.classList.contains("text-2xl"));
100
+ // Assert that the desired element is found
101
+ expect(inactiveLabel).not.toBeNull();
102
+ const container = inactiveLabel?.closest("div");
103
+ // Assert the desired class is applied
104
+ expect(container).toHaveClass("text-2xl");
105
+ });
106
+ });
@@ -0,0 +1,22 @@
1
+ export interface ToggleProps {
2
+ initialStatus?: boolean;
3
+ onClick: (value: boolean) => void;
4
+ textPosition: "left" | "right" | "top" | "bottom" | "none";
5
+ activeColorBackground?: string;
6
+ inactiveColorBackground?: string;
7
+ activeColorBorder?: string;
8
+ inactiveColorBorder?: string;
9
+ textSize?: string;
10
+ additionalClasses?: string;
11
+ hasDisabledStatus?: boolean;
12
+ hasDivider?: boolean;
13
+ fontFamily?: string;
14
+ activeLabel: string;
15
+ inactiveLabel: string;
16
+ activeTextColor?: string;
17
+ inactiveTextColor?: string;
18
+ id?: string;
19
+ smallToggle: boolean;
20
+ pillHeight?: string;
21
+ borderStyle: boolean;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agilant/toga-blox",
3
3
  "private": false,
4
- "version": "1.0.32",
4
+ "version": "1.0.33",
5
5
  "description": "",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -32,7 +32,11 @@
32
32
  "nouislider": "^15.8.1",
33
33
  "react": "^18.2.0",
34
34
  "react-dom": "^18.2.0",
35
+ "react-multi-select-component": "^4.3.4",
35
36
  "react-router-dom": "^6.16.0",
37
+ "react-select": "^5.10.0",
38
+ "react-table": "^7.8.0",
39
+ "react-table-sticky": "^1.1.3",
36
40
  "storybook-addon-react-router-v6": "^2.0.15",
37
41
  "tslib": "^2.3.0"
38
42
  },
@@ -48,10 +52,11 @@
48
52
  "@storybook/react": "^7.6.6",
49
53
  "@storybook/react-vite": "^7.6.6",
50
54
  "@storybook/test": "^7.6.6",
51
- "@testing-library/jest-dom": "^6.4.6",
52
- "@testing-library/react": "^14.3.1",
55
+ "@testing-library/jest-dom": "^6.6.3",
56
+ "@testing-library/react": "^16.2.0",
53
57
  "@testing-library/user-event": "^14.5.2",
54
58
  "@types/react-router-dom": "^5.3.3",
59
+ "@types/react-table": "^7.7.14",
55
60
  "@vitejs/plugin-react": "^4.2.1",
56
61
  "@vitest/coverage-istanbul": "^1.2.1",
57
62
  "@vitest/coverage-v8": "^1.2.1",
@@ -59,6 +64,7 @@
59
64
  "jsdom": "^23.2.0",
60
65
  "nodemon": "^3.0.2",
61
66
  "postcss": "^8.4.32",
67
+ "react-hook-form": "^7.43.9",
62
68
  "react-router-dom": "^6.16.0",
63
69
  "storybook": "^7.6.6",
64
70
  "tailwindcss": "^3.4.0",
@@ -71,6 +77,7 @@
71
77
  "@fortawesome/fontawesome-svg-core": "^1.2.35",
72
78
  "@fortawesome/free-solid-svg-icons": "^6.5.2",
73
79
  "@fortawesome/react-fontawesome": "^0.2.2",
80
+ "react-hook-form": "^7.43.9",
74
81
  "react-router-dom": "^6.16.0"
75
82
  }
76
83
  }