@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.
- package/dist/components/Dropdown/Dropdown.d.ts +4 -0
- package/dist/components/Dropdown/Dropdown.js +20 -0
- package/dist/components/Dropdown/Dropdown.stories.d.ts +8 -0
- package/dist/components/Dropdown/Dropdown.stories.js +110 -0
- package/dist/components/Dropdown/Dropdown.test.d.ts +1 -0
- package/dist/components/Dropdown/Dropdown.test.js +43 -0
- package/dist/components/Dropdown/Dropdown.types.d.ts +15 -0
- package/dist/components/Dropdown/Dropdown.types.js +1 -0
- package/dist/components/GenericList/GenericList.d.ts +2 -15
- package/dist/components/GenericList/GenericList.js +64 -51
- package/dist/components/GenericList/GenericList.stories.d.ts +8 -35
- package/dist/components/GenericList/GenericList.stories.js +46 -78
- package/dist/components/GenericList/GenericList.test.d.ts +1 -1
- package/dist/components/GenericList/GenericList.test.js +112 -22
- package/dist/components/GenericList/index.d.ts +2 -0
- package/dist/components/GenericList/index.js +2 -0
- package/dist/components/GenericList/types.d.ts +16 -0
- package/dist/components/GenericList/types.js +1 -0
- package/dist/components/Header/Header.stories.js +2 -4
- package/dist/components/Input/Input.d.ts +30 -3
- package/dist/components/Input/Input.js +70 -48
- package/dist/components/Input/Input.stories.js +3 -4
- package/dist/components/Input/Input.test.js +74 -42
- package/dist/components/InputAndCheck/InputAndCheck.d.ts +47 -0
- package/dist/components/InputAndCheck/InputAndCheck.js +74 -0
- package/dist/components/InputAndCheck/InputAndCheck.stories.d.ts +9 -0
- package/dist/components/InputAndCheck/InputAndCheck.stories.js +201 -0
- package/dist/components/InputAndCheck/InputAndCheck.test.d.ts +1 -0
- package/dist/components/InputAndCheck/InputAndCheck.test.js +307 -0
- package/dist/components/InputAndCheck/index.d.ts +0 -0
- package/dist/components/InputAndCheck/index.js +0 -0
- package/dist/components/InputAndCheck/types.d.ts +35 -0
- package/dist/components/InputAndCheck/types.js +1 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.d.ts +4 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.js +60 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.stories.d.ts +9 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.stories.js +72 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.test.d.ts +1 -0
- package/dist/components/MagnifyingIcon/MagnifyingIcon.test.js +101 -0
- package/dist/components/MagnifyingIcon/index.d.ts +2 -0
- package/dist/components/MagnifyingIcon/index.js +2 -0
- package/dist/components/MagnifyingIcon/types.d.ts +20 -0
- package/dist/components/MagnifyingIcon/types.js +2 -0
- package/dist/components/MultiSelect/MultiSelect.d.ts +4 -0
- package/dist/components/MultiSelect/MultiSelect.js +30 -0
- package/dist/components/MultiSelect/MultiSelect.stories.d.ts +10 -0
- package/dist/components/MultiSelect/MultiSelect.stories.js +162 -0
- package/dist/components/MultiSelect/MultiSelect.test.d.ts +1 -0
- package/dist/components/MultiSelect/MultiSelect.test.js +107 -0
- package/dist/components/MultiSelect/MultiSelect.types.d.ts +28 -0
- package/dist/components/MultiSelect/MultiSelect.types.js +1 -0
- package/dist/components/Page/ViewPageTemplate.stories.js +2 -3
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.d.ts +3 -0
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.js +72 -0
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.stories.d.ts +4 -0
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.stories.js +99 -0
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.test.d.ts +1 -0
- package/dist/components/PrimaryTableHeader/PrimaryTableHeader.test.js +124 -0
- package/dist/components/PrimaryTableHeader/index.d.ts +0 -0
- package/dist/components/PrimaryTableHeader/index.js +0 -0
- package/dist/components/PrimaryTableHeader/types.d.ts +35 -0
- package/dist/components/PrimaryTableHeader/types.js +2 -0
- package/dist/components/SearchInput/SearchInput.d.ts +1 -2
- package/dist/components/SearchInput/SearchInput.js +61 -11
- package/dist/components/SearchInput/SearchInput.stories.d.ts +2 -4
- package/dist/components/SearchInput/SearchInput.stories.js +80 -93
- package/dist/components/SearchInput/SearchInput.types.d.ts +37 -24
- package/dist/components/SearchInput/SearchNumberInput.d.ts +31 -0
- package/dist/components/SearchInput/SearchNumberInput.js +60 -0
- package/dist/components/SearchInput/SearchTextInput.d.ts +24 -0
- package/dist/components/SearchInput/SearchTextInput.js +65 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.d.ts +4 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.js +12 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.stories.d.ts +17 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.stories.js +77 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.test.d.ts +1 -0
- package/dist/components/SortArrowIcon/SortArrowIcon.test.js +44 -0
- package/dist/components/SortArrowIcon/index.d.ts +2 -0
- package/dist/components/SortArrowIcon/index.js +2 -0
- package/dist/components/SortArrowIcon/types.d.ts +15 -0
- package/dist/components/SortArrowIcon/types.js +1 -0
- package/dist/components/SortArrows/SortArrows.d.ts +3 -0
- package/dist/components/SortArrows/SortArrows.js +33 -0
- package/dist/components/SortArrows/SortArrows.stories.d.ts +7 -0
- package/dist/components/SortArrows/SortArrows.stories.js +41 -0
- package/dist/components/SortArrows/SortArrows.test.d.ts +1 -0
- package/dist/components/SortArrows/SortArrows.test.js +150 -0
- package/dist/components/SortArrows/index.d.ts +2 -0
- package/dist/components/SortArrows/index.js +2 -0
- package/dist/components/SortArrows/types.d.ts +21 -0
- package/dist/components/SortArrows/types.js +1 -0
- package/dist/components/SortArrows/useSortArrowsViewModel.d.ts +30 -0
- package/dist/components/SortArrows/useSortArrowsViewModel.js +114 -0
- package/dist/components/SortArrows/useSortArrowsViewModel.test.d.ts +1 -0
- package/dist/components/SortArrows/useSortArrowsViewModel.test.js +100 -0
- package/dist/components/TableCell/TableCell.d.ts +3 -0
- package/dist/components/TableCell/TableCell.js +13 -0
- package/dist/components/TableCell/TableCell.stories.d.ts +16 -0
- package/dist/components/TableCell/TableCell.stories.js +99 -0
- package/dist/components/TableCell/TableCell.test.d.ts +1 -0
- package/dist/components/TableCell/TableCell.test.js +84 -0
- package/dist/components/TableCell/index.d.ts +2 -0
- package/dist/components/TableCell/index.js +2 -0
- package/dist/components/TableCell/types.d.ts +12 -0
- package/dist/components/TableCell/types.js +1 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.d.ts +3 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.js +5 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.stories.d.ts +6 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.stories.js +62 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.test.d.ts +1 -0
- package/dist/components/TableHeaderContent/TableHeaderContent.test.js +41 -0
- package/dist/components/TableHeaderContent/index.d.ts +0 -0
- package/dist/components/TableHeaderContent/index.js +0 -0
- package/dist/components/TableHeaderContent/types.d.ts +5 -0
- package/dist/components/TableHeaderContent/types.js +1 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.d.ts +3 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.js +80 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.stories.d.ts +10 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.stories.js +82 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.test.d.ts +1 -0
- package/dist/components/TableHeaderInput/TableHeaderInput.test.js +84 -0
- package/dist/components/TableHeaderInput/index.d.ts +1 -0
- package/dist/components/TableHeaderInput/index.js +1 -0
- package/dist/components/TableHeaderInput/types.d.ts +30 -0
- package/dist/components/TableHeaderInput/types.js +1 -0
- package/dist/components/TableRow/TableRow.d.ts +15 -0
- package/dist/components/TableRow/TableRow.js +21 -0
- package/dist/components/TableRow/TableRow.stories.d.ts +9 -0
- package/dist/components/TableRow/TableRow.stories.js +195 -0
- package/dist/components/TableRow/TableRow.test.d.ts +1 -0
- package/dist/components/TableRow/TableRow.test.js +44 -0
- package/dist/components/TableRow/index.d.ts +2 -0
- package/dist/components/TableRow/index.js +2 -0
- package/dist/components/TableRow/types.d.ts +11 -0
- package/dist/components/TableRow/types.js +1 -0
- package/dist/components/ToggleButton/ToggleButton.d.ts +4 -0
- package/dist/components/ToggleButton/ToggleButton.js +41 -0
- package/dist/components/ToggleButton/ToggleButton.stories.d.ts +11 -0
- package/dist/components/ToggleButton/ToggleButton.stories.js +111 -0
- package/dist/components/ToggleButton/ToggleButton.test.d.ts +1 -0
- package/dist/components/ToggleButton/ToggleButton.test.js +106 -0
- package/dist/components/ToggleButton/ToggleButton.types.d.ts +22 -0
- package/dist/components/ToggleButton/ToggleButton.types.js +1 -0
- 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,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,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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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.
|
|
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.
|
|
52
|
-
"@testing-library/react": "^
|
|
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
|
}
|