@agilant/toga-blox 1.0.32 → 1.0.34

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 +11 -4
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ import { DropdownProps } from "./Dropdown.types";
3
+ declare const Dropdown: React.FC<DropdownProps>;
4
+ export default Dropdown;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { AnimatePresence, motion } from "framer-motion";
4
+ import { getFontAwesomeIcon } from "../../utils/getFontAwesomeIcon";
5
+ const Dropdown = ({ options, selectedOption, onOptionSelect, optionClasses = "flex items-center cursor-pointer px-4 py-1 text-sm text-white transition duration-200", menuClasses = "absolute top-10 right-0 bg-white shadow-md rounded-lg w-40 z-10", dropdownClasses = "", icon = {
6
+ name: "chevronDown",
7
+ weight: "solid",
8
+ iconClasses: "text-navy-400",
9
+ }, selectedOptionBgColor = "bg-gray-50", optionHoverBgColor = "hover:bg-gray-50", }) => {
10
+ const [showMenu, setShowMenu] = useState(false);
11
+ const toggleMenu = () => setShowMenu(!showMenu);
12
+ return (_jsxs("div", { className: `flex items-center justify-between relative min-w-32 border-2 ${dropdownClasses}`, children: [_jsxs("div", { onClick: toggleMenu, className: `flex cursor-pointer items-center group h-full `, children: [_jsx("div", { className: `font-bold ${optionClasses}`, children: selectedOption }), _jsx("div", { className: `transform transition-transform duration-200 mx-1 px-1 rounded-full relative ${icon.iconClasses} ${showMenu ? "rotate-180" : "rotate-0"}`, children: _jsx("span", { children: getFontAwesomeIcon(icon.name, icon.weight) }) })] }), showMenu && (_jsx(AnimatePresence, { children: showMenu && (_jsx(motion.div, { initial: { opacity: 0, y: -10 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -10 }, className: `absolute top-0 z-10 right-0 left-0 ${menuClasses}`, children: _jsx("ul", { children: options.map((action) => (_jsxs("li", { className: `text-left px-4 py-2 cursor-pointer border-b ${action === selectedOption
13
+ ? `{${selectedOptionBgColor} font-semibold}`
14
+ : `${optionHoverBgColor} text-black`}`, onClick: () => {
15
+ onOptionSelect(action);
16
+ setShowMenu(false); // Close the menu
17
+ }, children: [selectedOption === action &&
18
+ getFontAwesomeIcon("check", "solid"), _jsx("span", { className: "pl-2", children: action })] }, action))) }) })) }))] }));
19
+ };
20
+ export default Dropdown;
@@ -0,0 +1,8 @@
1
+ import Dropdown from "./Dropdown";
2
+ import { Meta } from "@storybook/react";
3
+ declare const _default: Meta<typeof Dropdown>;
4
+ export default _default;
5
+ export declare const Default: any;
6
+ export declare const GreenTheme: any;
7
+ export declare const CustomIcon: any;
8
+ export declare const LargeDropdown: any;
@@ -0,0 +1,110 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import Dropdown from "./Dropdown";
4
+ export default {
5
+ title: "Components/Dropdown",
6
+ component: Dropdown,
7
+ argTypes: {
8
+ options: {
9
+ control: "array",
10
+ description: "List of options available in the dropdown.",
11
+ },
12
+ selectedOption: {
13
+ control: "text",
14
+ description: "Currently selected option.",
15
+ },
16
+ onOptionSelect: {
17
+ action: "selected",
18
+ description: "Callback function triggered when an option is selected.",
19
+ },
20
+ optionClasses: {
21
+ control: "text",
22
+ description: "Tailwind classes for dropdown options.",
23
+ },
24
+ menuClasses: {
25
+ control: "text",
26
+ description: "Tailwind classes for the dropdown menu container.",
27
+ },
28
+ dropdownClasses: {
29
+ control: "text",
30
+ description: "Tailwind classes for the dropdown container.",
31
+ },
32
+ icon: {
33
+ control: "object",
34
+ description: "name - FontAwesome icon name. weight - FontAwesome icon style (solid, regular, etc.). iconClasses - Tailwind classes for the dropdown icon.",
35
+ },
36
+ selectedOptionBgColor: {
37
+ control: "text",
38
+ description: "Tailwind classes for the dropdown menu option background color.",
39
+ },
40
+ optionHoverBgColor: {
41
+ control: "text",
42
+ description: "Tailwind classes for the dropdown menu option hover background color.",
43
+ },
44
+ },
45
+ tags: ["autodocs"],
46
+ parameters: {
47
+ layout: "centered",
48
+ },
49
+ };
50
+ const Template = (args) => {
51
+ const [selectedOption, setSelectedOption] = useState(args.selectedOption);
52
+ return (_jsx(Dropdown, { ...args, selectedOption: selectedOption, onOptionSelect: (option) => setSelectedOption(option) }));
53
+ };
54
+ export const Default = Template.bind({});
55
+ Default.args = {
56
+ options: ["Option 1", "Option 2", "Option 3"],
57
+ selectedOption: "Option 1",
58
+ optionClasses: "flex items-center cursor-pointer px-4 py-1 text-md text-black transition duration-200",
59
+ menuClasses: "absolute top-10 right-0 bg-white shadow-md rounded-lg w-40 z-10",
60
+ icon: {
61
+ name: "chevronDown",
62
+ weight: "solid",
63
+ iconClasses: "text-navy-400",
64
+ },
65
+ };
66
+ export const GreenTheme = Template.bind({});
67
+ GreenTheme.args = {
68
+ options: ["Green Option 1", "Green Option 2", "Green Option 3"],
69
+ selectedOption: "Green Option 1",
70
+ optionClasses: "flex items-center cursor-pointer px-4 py-1 text-md text-white transition duration-200 bg-green-500 hover:bg-green-600",
71
+ menuClasses: "absolute top-10 right-0 bg-green-200 shadow-md rounded-lg w-44 z-10",
72
+ icon: {
73
+ name: "chevronDown",
74
+ weight: "solid",
75
+ iconClasses: "text-green-800 text-white",
76
+ },
77
+ dropdownClasses: "bg-green-700 border-none",
78
+ };
79
+ export const CustomIcon = Template.bind({});
80
+ CustomIcon.args = {
81
+ options: ["Custom Option 1", "Custom Option 2", "Custom Option 3"],
82
+ selectedOption: "Custom Option 1",
83
+ optionClasses: "flex items-center cursor-pointer px-4 py-1 text-md text-black transition duration-200 hover:bg-red-200",
84
+ menuClasses: "absolute top-10 right-0 shadow-md rounded-lg w-40 z-10",
85
+ dropdownClasses: "text-black border-2 border-red-500",
86
+ icon: {
87
+ name: "arrowDown",
88
+ weight: "regular",
89
+ iconClasses: "text-red-700 hover:bg-red-200",
90
+ },
91
+ };
92
+ export const LargeDropdown = Template.bind({});
93
+ LargeDropdown.args = {
94
+ options: [
95
+ "Large Option 1",
96
+ "Large Option 2",
97
+ "Large Option 3",
98
+ "Large Option 4",
99
+ "Large Option 5",
100
+ ],
101
+ selectedOption: "Large Option 1",
102
+ optionClasses: "flex items-center cursor-pointer px-4 py-3 text-lg text-black transition duration-200 ",
103
+ menuClasses: "absolute top-10 right-0 shadow-md rounded-lg w-56 z-10",
104
+ icon: {
105
+ name: "chevronDown",
106
+ weight: "solid",
107
+ iconClasses: "text-black",
108
+ },
109
+ dropdownClasses: "",
110
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render, screen, fireEvent } from "@testing-library/react";
3
+ import { describe, expect, test, vi } from "vitest";
4
+ import Dropdown from "./Dropdown";
5
+ const mockOnOptionSelect = vi.fn();
6
+ const options = ["Option 1", "Option 2", "Option 3"];
7
+ describe("Dropdown Component", () => {
8
+ test("renders the dropdown with the selected option", () => {
9
+ render(_jsx(Dropdown, { options: options, selectedOption: options[0], onOptionSelect: mockOnOptionSelect }));
10
+ expect(screen.getByText("Option 1")).toBeInTheDocument();
11
+ });
12
+ test("opens the dropdown menu when clicked", () => {
13
+ render(_jsx(Dropdown, { options: options, selectedOption: options[0], onOptionSelect: mockOnOptionSelect }));
14
+ const dropdownButton = screen.getByText("Option 1");
15
+ fireEvent.click(dropdownButton);
16
+ expect(screen.getByText("Option 2")).toBeInTheDocument();
17
+ expect(screen.getByText("Option 3")).toBeInTheDocument();
18
+ });
19
+ test("selects an option and calls onOptionSelect", () => {
20
+ render(_jsx(Dropdown, { options: options, selectedOption: options[0], onOptionSelect: mockOnOptionSelect }));
21
+ const dropdownButton = screen.getByText("Option 1");
22
+ fireEvent.click(dropdownButton);
23
+ const optionToSelect = screen.getByText("Option 2");
24
+ fireEvent.click(optionToSelect);
25
+ expect(mockOnOptionSelect).toHaveBeenCalledWith("Option 2");
26
+ });
27
+ test("closes the dropdown menu when an option is selected", () => {
28
+ render(_jsx(Dropdown, { options: options, selectedOption: options[0], onOptionSelect: mockOnOptionSelect }));
29
+ const dropdownButton = screen.getByText("Option 1");
30
+ fireEvent.click(dropdownButton);
31
+ const optionToSelect = screen.getByText("Option 2");
32
+ fireEvent.click(optionToSelect);
33
+ expect(screen.queryByText("Option 2")).not.toBeInTheDocument();
34
+ });
35
+ test("toggles the dropdown menu visibility when clicked", () => {
36
+ render(_jsx(Dropdown, { options: options, selectedOption: options[0], onOptionSelect: mockOnOptionSelect }));
37
+ const dropdownButton = screen.getByText("Option 1");
38
+ fireEvent.click(dropdownButton);
39
+ expect(screen.getByText("Option 2")).toBeInTheDocument();
40
+ fireEvent.click(dropdownButton);
41
+ expect(screen.queryByText("Option 2")).not.toBeInTheDocument();
42
+ });
43
+ });
@@ -0,0 +1,15 @@
1
+ export type DropdownProps = {
2
+ options: string[];
3
+ selectedOption: string;
4
+ onOptionSelect: (action: string) => void;
5
+ optionClasses?: string;
6
+ menuClasses?: string;
7
+ dropdownClasses?: string;
8
+ icon?: {
9
+ name: string;
10
+ weight: "solid" | "regular" | "light" | "duotone" | "brands";
11
+ iconClasses?: string;
12
+ };
13
+ selectedOptionBgColor?: string;
14
+ optionHoverBgColor?: string;
15
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,16 +1,3 @@
1
- type GenericData = {
2
- id: string;
3
- [key: string]: any;
4
- };
5
- export type GenericListTypes<T> = {
6
- data: T[];
7
- renderItem: (item: T) => JSX.Element;
8
- itemHeight?: number;
9
- containerHeight?: number;
10
- containerClasses?: string;
11
- listDirection?: "horizontal" | "vertical";
12
- hasVirtualization?: boolean;
13
- listType: "ordered" | "unordered" | "none";
14
- };
15
- declare const GenericList: <T extends GenericData>({ data, renderItem, itemHeight, containerHeight, containerClasses, listDirection, hasVirtualization, listType, }: GenericListTypes<T>) => import("react/jsx-runtime").JSX.Element;
1
+ import { GenericData, GenericListTypes } from "./types";
2
+ declare const GenericList: <T extends GenericData>({ data, renderItem, itemHeight, containerHeight, containerClasses, listDirection, hasVirtualization, listType, parentRef, isVirtualizer, }: GenericListTypes<T>) => import("react/jsx-runtime").JSX.Element;
16
3
  export default GenericList;
@@ -1,59 +1,72 @@
1
- import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- import React, { useEffect, useState } from "react";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useCallback, useRef, forwardRef } from "react";
3
3
  import { useVirtualizer } from "@tanstack/react-virtual";
4
- import { useCallback } from "react";
5
- const GenericList = ({ data, renderItem, itemHeight, containerHeight, containerClasses = "", listDirection = "vertical", hasVirtualization = false, listType = "none", }) => {
6
- const listClasses = listDirection === "horizontal" ? "flex flex-row" : "flex flex-col";
7
- const parentRef = React.createRef();
8
- const [virtualItems, setVirtualItems] = useState([]);
9
- const [nonVirtualItems, setNonVirtualItems] = useState([]);
10
- const estimateSize = useCallback(() => (itemHeight ? itemHeight : 0), [itemHeight]);
4
+ // New wrapper component for proper list semantics
5
+ const ListWrapper = forwardRef(({ listType, className, style, children }, ref) => {
6
+ const combinedClassName = `${className} ${listType !== "none" ? "list-none p-0 m-0" : ""}`.trim();
7
+ if (listType === "ordered") {
8
+ return (_jsx("ol", { ref: ref, className: combinedClassName, style: style, children: children }));
9
+ }
10
+ if (listType === "unordered") {
11
+ return (_jsx("ul", { ref: ref, className: combinedClassName, style: style, children: children }));
12
+ }
13
+ return (_jsx("div", { ref: ref, className: className, style: style, children: children }));
14
+ });
15
+ const getListDirectionClasses = (listDirection) => {
16
+ if (listDirection === "horizontal") {
17
+ return "flex overflow-x-auto";
18
+ }
19
+ if (listDirection === "vertical") {
20
+ return "flex flex-col";
21
+ }
22
+ return "";
23
+ };
24
+ // Improved virtualization positioning
25
+ const getVirtualItemPosition = (listDirection, start) => {
26
+ if (listDirection === "horizontal") {
27
+ return { left: start, top: 0 };
28
+ }
29
+ return { top: start, left: 0 };
30
+ };
31
+ const GenericList = ({ data, renderItem, itemHeight = 35, containerHeight, containerClasses = "", listDirection, hasVirtualization = false, listType = "none", parentRef, isVirtualizer = false, }) => {
32
+ const listClasses = getListDirectionClasses(listDirection);
33
+ const internalRef = useRef(null);
34
+ const scrollContainerRef = parentRef || internalRef;
11
35
  const count = data.length;
36
+ const estimateSize = useCallback(() => itemHeight, [itemHeight]);
37
+ // Virtualization logic
12
38
  const virtualizer = useVirtualizer({
13
39
  count,
14
40
  estimateSize,
15
- overscan: count,
16
- getScrollElement: () => parentRef.current,
41
+ overscan: 5,
42
+ getScrollElement: () => scrollContainerRef.current,
43
+ horizontal: listDirection === "horizontal",
17
44
  });
18
- useEffect(() => {
19
- if (hasVirtualization) {
20
- setVirtualItems(virtualizer.getVirtualItems());
21
- }
22
- else {
23
- setNonVirtualItems(data);
24
- }
25
- }, [hasVirtualization, virtualizer, data]);
26
- return (_jsx(_Fragment, { children: (() => {
27
- switch (listType) {
28
- case "ordered":
29
- return (_jsx("ol", { ref: parentRef, style: hasVirtualization
30
- ? {
31
- height: containerHeight,
32
- overflow: "scroll",
33
- }
34
- : {}, className: `${listClasses} ${containerClasses}`, children: hasVirtualization
35
- ? virtualItems.map((virtualItem) => (_jsx("li", { style: { height: itemHeight }, children: renderItem(data[virtualItem.index]) }, virtualItem.index)))
36
- : nonVirtualItems.map((item) => (_jsx("li", { children: renderItem(item) }, item.id))) }));
37
- case "unordered":
38
- return (_jsx("ul", { ref: parentRef, style: hasVirtualization
39
- ? {
40
- height: containerHeight,
41
- overflow: "scroll",
42
- }
43
- : {}, className: `${listClasses} ${containerClasses}`, children: hasVirtualization
44
- ? virtualItems.map((virtualItem) => (_jsx("li", { style: { height: itemHeight }, children: renderItem(data[virtualItem.index]) }, virtualItem.index)))
45
- : nonVirtualItems.map((item) => (_jsx("li", { children: renderItem(item) }, item.id))) }));
46
- case "none":
47
- default:
48
- return (_jsx("div", { ref: parentRef, style: hasVirtualization
49
- ? {
50
- height: containerHeight,
51
- overflow: "scroll",
52
- }
53
- : {}, className: `${listClasses} ${containerClasses}`, children: hasVirtualization
54
- ? virtualItems.map((virtualItem) => (_jsx("div", { style: { height: itemHeight }, children: renderItem(data[virtualItem.index]) }, virtualItem.index)))
55
- : nonVirtualItems.map((item) => (_jsx("div", { children: renderItem(item) }, item.id))) }));
56
- }
57
- })() }));
45
+ const totalSize = virtualizer.getTotalSize();
46
+ const virtualItems = virtualizer.getVirtualItems();
47
+ // Shared container props
48
+ const containerProps = {
49
+ ref: scrollContainerRef,
50
+ style: {
51
+ height: containerHeight,
52
+ overflow: "auto",
53
+ position: "relative",
54
+ },
55
+ className: `${listClasses} ${containerClasses}`.trim(),
56
+ };
57
+ return (_jsx(ListWrapper, { listType: listType, ...containerProps, children: !hasVirtualization || isVirtualizer ? (
58
+ // Non-virtualized render
59
+ data.map((item, index) => (_jsx("div", { children: renderItem(item, index) }, `${item.id}-${index}`)))) : (
60
+ // Virtualized render
61
+ _jsx("div", { style: {
62
+ height: listDirection === "vertical" ? totalSize : "100%",
63
+ width: listDirection === "horizontal" ? totalSize : "100%",
64
+ position: "relative",
65
+ }, children: virtualItems.map((virtualItem) => (_jsx("div", { style: {
66
+ position: "absolute",
67
+ width: "100%",
68
+ height: itemHeight,
69
+ ...getVirtualItemPosition(listDirection, virtualItem.start),
70
+ }, children: renderItem(data[virtualItem.index], virtualItem.index) }, virtualItem.key))) })) }));
58
71
  };
59
72
  export default GenericList;
@@ -1,35 +1,8 @@
1
- import { Meta } from "@storybook/react";
2
- import { TagName } from "../Text";
3
- export type IconButtonsListProps = {
4
- id: string;
5
- iconColor?: string;
6
- iconLabel?: string;
7
- backgroundColor?: string;
8
- size?: "xs" | "sm" | "md" | "lg" | string;
9
- icon: string;
10
- hoverBorder?: "border" | "none" | string;
11
- limitCharacters?: (text: string) => string;
12
- indicatorSize?: "sm" | "md" | "lg" | string;
13
- iconBorder?: "border" | "none" | string;
14
- hoverBackground: string;
15
- hoverColor: string;
16
- limitIndicator: boolean;
17
- indicatorNumber: string;
18
- additionalContainerClasses: string;
19
- onClick?: () => void;
20
- text: {
21
- size: string;
22
- color: string;
23
- text: string;
24
- fontFamily: string;
25
- tag: TagName;
26
- additionalClasses: string;
27
- };
28
- to?: string;
29
- href?: string;
30
- };
31
- declare const _default: Meta;
32
- export default _default;
33
- export declare const Default: any;
34
- export declare const VerticalList: any;
35
- export declare const LargeDataSet: any;
1
+ import { Meta, StoryObj } from "@storybook/react";
2
+ import GenericList from "./GenericList";
3
+ declare const meta: Meta<typeof GenericList>;
4
+ export default meta;
5
+ export declare const HoverList: StoryObj<typeof GenericList>;
6
+ export declare const ClickableList: StoryObj<typeof GenericList>;
7
+ export declare const ActionListExample: StoryObj<typeof GenericList>;
8
+ export declare const HorizontalClickable: StoryObj<typeof GenericList>;
@@ -1,87 +1,55 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import GenericList from "./GenericList";
3
- import DUMMYICONDATA from "../Header/DUMMYICONDATA.json";
4
- import DUMMYLISTDATA from "./DUMMYLISTDATA.json";
5
- import TreeList from "./templates/DummyDataList";
6
- export default {
3
+ const sampleData = Array.from({ length: 1000 }, (_, i) => ({
4
+ id: `item-${i}`,
5
+ name: `Item ${i}`,
6
+ value: i,
7
+ }));
8
+ const meta = {
7
9
  title: "Components/GenericList",
8
10
  component: GenericList,
9
- argTypes: {
10
- listDirection: {
11
- control: "select",
12
- options: ["horizontal", "vertical"],
13
- description: "Whether the list is horizontal or vertical",
14
- },
15
- listType: {
16
- table: {
17
- disable: true,
18
- },
19
- },
20
- hasVirtualization: {
21
- table: {
22
- disable: true,
23
- },
24
- },
25
- containerClasses: {
26
- table: {
27
- disable: true,
28
- },
29
- },
30
- itemHeight: {
31
- table: {
32
- disable: true,
33
- },
34
- },
35
- containerHeight: {
36
- table: {
37
- disable: true,
38
- },
39
- },
40
- renderItem: {
41
- table: {
42
- disable: true,
43
- },
44
- },
45
- data: {
46
- table: {
47
- disable: true,
48
- },
49
- },
50
- },
51
11
  tags: ["autodocs"],
52
- parameters: {
53
- layout: "centered",
12
+ };
13
+ export default meta;
14
+ // ... existing stories ...
15
+ // Hover state story
16
+ export const HoverList = {
17
+ args: {
18
+ data: sampleData.slice(0, 10),
19
+ renderItem: (item) => (_jsx("div", { className: "p-2 border-b hover:bg-gray-100 transition-colors duration-200", children: item.name })),
20
+ containerHeight: 300,
21
+ listType: "unordered",
54
22
  },
55
23
  };
56
- const Template = (args) => (_jsx(GenericList, { ...args }));
57
- export const Default = Template.bind({});
58
- Default.args = {
59
- containerClasses: "flex justify-center w-96 bg-slate-100",
60
- data: DUMMYICONDATA.DUMMYICONCOMPASSDATA,
61
- itemHeight: 20,
62
- containerHeight: 72,
63
- hasVirtualization: true,
64
- listDirection: "horizontal",
65
- listType: "none",
24
+ // Clickable rows story
25
+ export const ClickableList = {
26
+ args: {
27
+ data: sampleData.slice(0, 10),
28
+ renderItem: (item) => (_jsx("div", { className: "p-2 border-b hover:bg-blue-50 cursor-pointer transition-colors", onClick: () => alert(`Clicked: ${item.name}`), children: item.name })),
29
+ containerHeight: 300,
30
+ },
66
31
  };
67
- export const VerticalList = Template.bind({});
68
- VerticalList.args = {
69
- containerClasses: "w-96 bg-slate-100",
70
- data: DUMMYICONDATA.DUMMYICONCOMPASSDATA,
71
- itemHeight: 150,
72
- containerHeight: 300,
73
- hasVirtualization: true,
74
- listDirection: "vertical",
75
- listType: "none",
32
+ // Interactive list with both hover and click (like ActionList example)
33
+ export const ActionListExample = {
34
+ args: {
35
+ data: sampleData.slice(0, 5).map((item) => ({
36
+ ...item,
37
+ icon: "faUser",
38
+ color: "blue-500",
39
+ setActionModal: () => console.log(`Action for ${item.name}`),
40
+ })),
41
+ renderItem: (item) => (_jsxs("div", { className: "flex items-center p-2 hover:bg-gray-100 cursor-pointer group", onClick: () => alert(`Action triggered for: ${item.name}`), children: [_jsx("span", { className: `text-${item.color} w-6 text-center`, children: "\u26A1" }), _jsx("span", { className: "ml-2 group-hover:text-blue-600 transition-colors", children: item.name })] })),
42
+ containerClasses: "border rounded-lg w-64",
43
+ listType: "unordered",
44
+ },
76
45
  };
77
- export const LargeDataSet = Template.bind({});
78
- LargeDataSet.args = {
79
- containerClasses: "bg-slate-100 w-120 h-120 p-8",
80
- data: DUMMYLISTDATA.trees.flatMap((tree) => [tree, tree]),
81
- itemHeight: 50,
82
- containerHeight: 300,
83
- hasVirtualization: true,
84
- renderItem: (item) => _jsx(TreeList, { item: item }),
85
- listDirection: "vertical",
86
- listType: "unordered",
46
+ // Horizontal clickable items
47
+ export const HorizontalClickable = {
48
+ args: {
49
+ data: sampleData.slice(0, 10),
50
+ renderItem: (item) => (_jsx("div", { className: "p-4 border-r hover:bg-orange-50 cursor-pointer h-full flex items-center", onClick: () => alert(`Selected: ${item.name}`), children: _jsx("span", { className: "hover:scale-105 transition-transform", children: item.name }) })),
51
+ listDirection: "horizontal",
52
+ containerHeight: 80,
53
+ containerClasses: "w-full border-y",
54
+ },
87
55
  };
@@ -1 +1 @@
1
- export {};
1
+ import "@testing-library/jest-dom";