pixelize-design-library 2.3.17 → 2.3.19

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 (27) hide show
  1. package/.cursor/modules/inputs-date-file/MODULE.md +1 -0
  2. package/dist/Assets/defaultLogo.tsx +30 -0
  3. package/dist/Components/DatePicker/SingleDatePicker.d.ts.map +1 -1
  4. package/dist/Components/DatePicker/SingleDatePicker.js +30 -2
  5. package/dist/Components/Input/textInputIconSize.test.d.ts +1 -0
  6. package/dist/Components/Input/textInputIconSize.test.js +27 -0
  7. package/dist/Components/KanbanBoard/AccountCard.test.d.ts +1 -0
  8. package/dist/Components/KanbanBoard/AccountCard.test.js +68 -0
  9. package/dist/Components/KanbanBoard/KanbanActions/KanbanActions.test.d.ts +1 -0
  10. package/dist/Components/KanbanBoard/KanbanActions/KanbanActions.test.js +49 -0
  11. package/dist/Components/KanbanBoard/KanbanBoard.test.d.ts +1 -0
  12. package/dist/Components/KanbanBoard/KanbanBoard.test.js +185 -0
  13. package/dist/Components/SearchSelect/searchSelectSize.test.d.ts +1 -0
  14. package/dist/Components/SearchSelect/searchSelectSize.test.js +22 -0
  15. package/dist/Components/SideBar/components/OtherApps.test.d.ts +1 -0
  16. package/dist/Components/SideBar/components/OtherApps.test.js +111 -0
  17. package/dist/Components/Table/components/TableBody.virtualize.test.d.ts +1 -0
  18. package/dist/Components/Table/components/TableBody.virtualize.test.js +93 -0
  19. package/dist/Components/Table/settings/ManageColumns.test.d.ts +1 -0
  20. package/dist/Components/Table/settings/ManageColumns.test.js +146 -0
  21. package/dist/Theme/buildBrandTokens.test.d.ts +1 -0
  22. package/dist/Theme/buildBrandTokens.test.js +31 -0
  23. package/dist/Theme/chartColorsFromTheme.test.d.ts +1 -0
  24. package/dist/Theme/chartColorsFromTheme.test.js +35 -0
  25. package/dist/Utils/tableNormalizeCellValue.test.d.ts +1 -0
  26. package/dist/Utils/tableNormalizeCellValue.test.js +41 -0
  27. package/package.json +1 -1
@@ -12,6 +12,7 @@ ThemeDatePicker (Single/Range/Time variants), FileUpload, FileUploader, Editor (
12
12
  ## Key rules
13
13
 
14
14
  - DatePicker themed for brand tokens
15
+ - Masked-input blur must not discard a valid value. `isMaskComplete()` only recognises numeric/`a` tokens, so text month formats (e.g. `MMM d, yyyy`) never look "complete" — `handleInputBlur`/`handleInputFocus` therefore keep any value that `parseValidatedValue()` can parse to a valid date, and only `requestClose(null)` (clear) on empty/unparseable input. The Clear button and emptied-mask paths remain the explicit ways to clear. Regression: `SingleDatePicker.blur.test.tsx`.
15
16
 
16
17
  ## Migration notes
17
18
 
@@ -0,0 +1,30 @@
1
+ import { useCustomTheme } from "../Theme/useCustomTheme";
2
+
3
+ const DefaultLogo = () => {
4
+ const theme = useCustomTheme();
5
+ return (
6
+ <svg
7
+ width="12.09"
8
+ height="15.95"
9
+ viewBox="0 0 31 29"
10
+ fill="none"
11
+ xmlns="http://www.w3.org/2000/svg"
12
+ >
13
+ <path
14
+ d="M30.4999 6.26137V7.81058H15.9761H14.8787V22.8508V28.8862H12.5226C9.6824 28.8862 7.32632 26.4656 7.06812 23.3995C7.06812 23.2381 7.06812 23.0444 7.06812 22.8508V18.3323C7.06812 18.2677 7.06812 18.2032 7.06812 18.1063V15.5889V6.2291C7.06812 2.80793 9.84378 -5.72205e-06 13.2972 -5.72205e-06H24.8517C28.0147 0.355021 30.4676 3.00158 30.4676 6.2291L30.4999 6.26137Z"
15
+ fill={theme.colors.black}
16
+ />
17
+ <path
18
+ d="M7.10053 23.3672H7.03598C5.16402 23.2381 3.48571 22.4635 2.25926 21.3338C0.871428 20.0428 0 18.2677 0 16.3312V15.6211H7.06825V18.1386C7.06825 18.2032 7.06825 18.2677 7.06825 18.3645V22.883C7.06825 23.0767 7.06825 23.2381 7.06825 23.4317L7.10053 23.3672Z"
19
+ fill={theme.colors.black}
20
+ />
21
+ <path
22
+ d="M30.4678 12.0063V15.6211V17.1703C30.4678 20.6238 26.272 23.3994 21.0757 23.3994H14.8789V22.8508V15.6211H22.6572V7.81056C22.6895 7.81056 30.5001 7.81056 30.5001 7.81056V11.5868C30.5001 11.7159 30.5001 11.8772 30.5001 12.0063H30.4678Z"
23
+ fill={theme.colors.black}
24
+ />
25
+ </svg>
26
+
27
+ )
28
+ };
29
+
30
+ export default DefaultLogo;
@@ -1 +1 @@
1
- {"version":3,"file":"SingleDatePicker.d.ts","sourceRoot":"","sources":["../../../src/Components/DatePicker/SingleDatePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6E,MAAM,OAAO,CAAC;AA6BlG,OAAO,EAAE,qBAAqB,EAAc,MAAM,mBAAmB,CAAC;AA2OtE,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA+7B5D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"SingleDatePicker.d.ts","sourceRoot":"","sources":["../../../src/Components/DatePicker/SingleDatePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6E,MAAM,OAAO,CAAC;AA6BlG,OAAO,EAAE,qBAAqB,EAAc,MAAM,mBAAmB,CAAC;AA2OtE,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA09B5D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -435,7 +435,13 @@ const SingleDatePicker = (props) => {
435
435
  if (enableMask && isMaskActive) {
436
436
  setIsMaskActive(false);
437
437
  segmentInputBufferRef.current = "";
438
- if (!value || !value.trim() || !isMaskComplete(value)) {
438
+ // isMaskComplete() can't recognise text month tokens (e.g. "MMM"), so a
439
+ // valid, externally-set value like "Jun 10, 2026" is judged "incomplete"
440
+ // and was being cleared on blur (data loss). Only clear when the value is
441
+ // empty or genuinely can't be parsed into a valid date; otherwise fall
442
+ // through and let the parse path below commit it.
443
+ const hasParsableDate = parseValidatedValue(value) !== null;
444
+ if (!value || !value.trim() || (!isMaskComplete(value) && !hasParsableDate)) {
439
445
  setInputValue("");
440
446
  setTempDate(null);
441
447
  setIsTyping(false);
@@ -635,6 +641,24 @@ const SingleDatePicker = (props) => {
635
641
  }
636
642
  return finalDate;
637
643
  };
644
+ // Returns the validated Date for a fully-typed value, or null when the value
645
+ // is empty / not a parseable, in-range date. Used by blur handling so an
646
+ // already-valid value is never discarded just because the mask-completeness
647
+ // heuristic doesn't understand text month tokens.
648
+ const parseValidatedValue = (value) => {
649
+ if (!value || !value.trim())
650
+ return null;
651
+ try {
652
+ const parsed = (0, date_fns_1.parse)(value, resolvedDateFormat, new Date());
653
+ if ((0, date_fns_1.isValid)(parsed)) {
654
+ return computeFinalDate(parsed);
655
+ }
656
+ }
657
+ catch (error) {
658
+ console.error("Error parsing input:", error);
659
+ }
660
+ return null;
661
+ };
638
662
  const updateTempDateFromMask = (value) => {
639
663
  if (!isMaskComplete(value)) {
640
664
  return;
@@ -662,7 +686,11 @@ const SingleDatePicker = (props) => {
662
686
  return;
663
687
  setIsMaskActive(true);
664
688
  setIsTyping(true);
665
- if (!inputValue || inputValue.length !== maskPlaceholder.length) {
689
+ // Never blank an already-valid value on focus. The mask placeholder is built
690
+ // with padded tokens (e.g. "MMM dd, yyyy"), so a valid but shorter value such
691
+ // as "Jun 5, 2026" would otherwise be replaced by the empty mask and lost.
692
+ const hasValidValue = parseValidatedValue(inputValue) !== null;
693
+ if (!hasValidValue && (!inputValue || inputValue.length !== maskPlaceholder.length)) {
666
694
  setInputValue(maskPlaceholder);
667
695
  maskInsertedRef.current = true;
668
696
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var textInputIconSize_1 = require("./textInputIconSize");
4
+ describe("getTextInputIconSizePx", function () {
5
+ it("maps Chakra input sizes to increasing pixel values", function () {
6
+ var xs = (0, textInputIconSize_1.getTextInputIconSizePx)("xs");
7
+ var sm = (0, textInputIconSize_1.getTextInputIconSizePx)("sm");
8
+ var md = (0, textInputIconSize_1.getTextInputIconSizePx)("md");
9
+ var lg = (0, textInputIconSize_1.getTextInputIconSizePx)("lg");
10
+ expect(xs).toBeLessThan(sm);
11
+ expect(sm).toBeLessThan(md);
12
+ expect(md).toBeLessThan(lg);
13
+ });
14
+ it("defaults to md for missing or unknown size", function () {
15
+ expect((0, textInputIconSize_1.getTextInputIconSizePx)(undefined)).toBe(18);
16
+ expect((0, textInputIconSize_1.getTextInputIconSizePx)("nope")).toBe(18);
17
+ });
18
+ });
19
+ describe("getTextInputIconWrapperSx", function () {
20
+ it("includes the resolved pixel size in svg rules for xs", function () {
21
+ var sx = (0, textInputIconSize_1.getTextInputIconWrapperSx)("xs");
22
+ var svg = sx["& > svg, & > * svg, & svg"];
23
+ expect(svg).toBeDefined();
24
+ expect(svg === null || svg === void 0 ? void 0 : svg.width).toContain("14");
25
+ expect(svg === null || svg === void 0 ? void 0 : svg.height).toContain("14");
26
+ });
27
+ });
@@ -0,0 +1 @@
1
+ import "@testing-library/jest-dom";
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ var react_1 = __importDefault(require("react"));
18
+ var react_2 = require("@testing-library/react");
19
+ require("@testing-library/jest-dom");
20
+ var react_3 = require("@chakra-ui/react");
21
+ var AccountCard_1 = __importDefault(require("./AccountCard"));
22
+ jest.mock("../../Theme/useCustomTheme", function () { return ({
23
+ useCustomTheme: function () { return ({
24
+ colors: {
25
+ background: { 50: "#fafafa", 100: "#f5f5f5", 500: "#fff" },
26
+ boxborder: { 300: "#e2e8f0" },
27
+ gray: { 200: "#eee", 700: "#333" },
28
+ primary: { 300: "#90cdf4", 500: "#3182ce" },
29
+ red: { 600: "#e53e3e" },
30
+ blue: { 600: "#3182ce" },
31
+ text: {},
32
+ },
33
+ }); },
34
+ }); });
35
+ var mockAccount = {
36
+ id: "1",
37
+ name: "Test Account",
38
+ email: "test@example.com",
39
+ };
40
+ var defaultProps = {
41
+ account: mockAccount,
42
+ index: 0,
43
+ onDelete: jest.fn(),
44
+ onOpen: jest.fn(),
45
+ };
46
+ var renderCard = function (ui) {
47
+ return (0, react_2.render)(react_1.default.createElement(react_3.ChakraProvider, null, ui));
48
+ };
49
+ describe("AccountCard – permissions", function () {
50
+ it("renders the delete icon when isDeletable is true (default)", function () {
51
+ renderCard(react_1.default.createElement(AccountCard_1.default, __assign({}, defaultProps)));
52
+ expect(react_2.screen.getByLabelText("Delete")).toBeInTheDocument();
53
+ });
54
+ it("hides the delete icon when isDeletable is false", function () {
55
+ renderCard(react_1.default.createElement(AccountCard_1.default, __assign({}, defaultProps, { isDeletable: false })));
56
+ expect(react_2.screen.queryByLabelText("Delete")).not.toBeInTheDocument();
57
+ });
58
+ it("renders the open (ExternalLink) icon regardless of isDeletable", function () {
59
+ renderCard(react_1.default.createElement(AccountCard_1.default, __assign({}, defaultProps, { isDeletable: false })));
60
+ expect(react_2.screen.getByLabelText("Open")).toBeInTheDocument();
61
+ });
62
+ it("calls onDelete when delete icon is clicked and isDeletable is true", function () {
63
+ var onDelete = jest.fn();
64
+ renderCard(react_1.default.createElement(AccountCard_1.default, __assign({}, defaultProps, { onDelete: onDelete, isDeletable: true })));
65
+ react_2.fireEvent.click(react_2.screen.getByLabelText("Delete"));
66
+ expect(onDelete).toHaveBeenCalledWith(mockAccount);
67
+ });
68
+ });
@@ -0,0 +1 @@
1
+ import "@testing-library/jest-dom";
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var react_1 = __importDefault(require("react"));
7
+ var react_2 = require("@testing-library/react");
8
+ require("@testing-library/jest-dom");
9
+ var react_3 = require("@chakra-ui/react");
10
+ var KanbanActions_1 = __importDefault(require("./KanbanActions"));
11
+ jest.mock("../../../Theme/useCustomTheme", function () { return ({
12
+ useCustomTheme: function () { return ({
13
+ colors: {
14
+ text: { 500: "#555" },
15
+ primary: { 500: "#3182ce" },
16
+ },
17
+ }); },
18
+ }); });
19
+ jest.mock("../../Select/Select", function () { return ({
20
+ __esModule: true,
21
+ default: function (_a) {
22
+ var placeholder = _a.placeholder;
23
+ return react_1.default.createElement("div", { "data-testid": "mock-select" }, placeholder);
24
+ },
25
+ }); });
26
+ jest.mock("../../Divider/Divider", function () { return ({
27
+ __esModule: true,
28
+ default: function () { return react_1.default.createElement("div", { "data-testid": "mock-divider" }); },
29
+ }); });
30
+ var options = [{ id: "1", label: "Open" }];
31
+ var renderActions = function (ui) {
32
+ return (0, react_2.render)(react_1.default.createElement(react_3.ChakraProvider, null, ui));
33
+ };
34
+ describe("KanbanActions", function () {
35
+ it("renders Edit Layout and Create New as buttons", function () {
36
+ renderActions(react_1.default.createElement(KanbanActions_1.default, { options: options, onEdit: jest.fn(), onCreate: jest.fn() }));
37
+ expect(react_2.screen.getByRole("button", { name: /edit layout/i })).toBeInTheDocument();
38
+ expect(react_2.screen.getByRole("button", { name: /create new/i })).toBeInTheDocument();
39
+ });
40
+ it("invokes onEdit and onCreate when buttons are clicked", function () {
41
+ var onEdit = jest.fn();
42
+ var onCreate = jest.fn();
43
+ renderActions(react_1.default.createElement(KanbanActions_1.default, { options: options, onEdit: onEdit, onCreate: onCreate }));
44
+ react_2.fireEvent.click(react_2.screen.getByRole("button", { name: /edit layout/i }));
45
+ react_2.fireEvent.click(react_2.screen.getByRole("button", { name: /create new/i }));
46
+ expect(onEdit).toHaveBeenCalledTimes(1);
47
+ expect(onCreate).toHaveBeenCalledTimes(1);
48
+ });
49
+ });
@@ -0,0 +1 @@
1
+ import "@testing-library/jest-dom";
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ var react_1 = __importDefault(require("react"));
18
+ var react_2 = require("@testing-library/react");
19
+ require("@testing-library/jest-dom");
20
+ var react_3 = require("@chakra-ui/react");
21
+ var KanbanBoard_1 = __importDefault(require("./KanbanBoard"));
22
+ jest.mock("../../Theme/useCustomTheme", function () { return ({
23
+ useCustomTheme: function () { return ({
24
+ colors: {
25
+ background: { 100: "#f9f9f9", 500: "#fff" },
26
+ gray: { 100: "#f0f0f0", 200: "#eee", 300: "#ddd", 400: "#ccc", 500: "#bbb", 700: "#333" },
27
+ primary: { 500: "#3182ce" },
28
+ blue: { 50: "#ebf8ff", 500: "#3182ce", 600: "#3182ce" },
29
+ red: { 600: "#e53e3e" },
30
+ text: { 500: "#555", 600: "#444", 700: "#333" },
31
+ secondary: { 500: "#805ad5" },
32
+ },
33
+ }); },
34
+ }); });
35
+ jest.mock("@hello-pangea/dnd", function () { return ({
36
+ DragDropContext: function (_a) {
37
+ var children = _a.children;
38
+ return react_1.default.createElement("div", null, children);
39
+ },
40
+ Droppable: function (_a) {
41
+ var children = _a.children;
42
+ return children({ innerRef: function () { }, droppableProps: {}, placeholder: null }, { isDraggingOver: false });
43
+ },
44
+ Draggable: function (_a) {
45
+ var children = _a.children, isDragDisabled = _a.isDragDisabled;
46
+ var provided = {
47
+ innerRef: function () { },
48
+ draggableProps: { "data-drag-disabled": isDragDisabled },
49
+ dragHandleProps: {},
50
+ };
51
+ return children(provided, { isDragging: false });
52
+ },
53
+ }); });
54
+ jest.mock("react-window", function () { return ({
55
+ VariableSizeList: function () { return null; },
56
+ }); });
57
+ beforeAll(function () {
58
+ global.ResizeObserver = /** @class */ (function () {
59
+ function class_1() {
60
+ }
61
+ class_1.prototype.observe = function () { };
62
+ class_1.prototype.unobserve = function () { };
63
+ class_1.prototype.disconnect = function () { };
64
+ return class_1;
65
+ }());
66
+ Object.defineProperty(window, "matchMedia", {
67
+ writable: true,
68
+ configurable: true,
69
+ value: jest.fn().mockImplementation(function (query) { return ({
70
+ matches: false,
71
+ media: query,
72
+ onchange: null,
73
+ addListener: jest.fn(),
74
+ removeListener: jest.fn(),
75
+ addEventListener: jest.fn(),
76
+ removeEventListener: jest.fn(),
77
+ dispatchEvent: jest.fn(),
78
+ }); }),
79
+ });
80
+ });
81
+ var renderWithChakra = function (ui) {
82
+ return (0, react_2.render)(react_1.default.createElement(react_3.ChakraProvider, null, ui));
83
+ };
84
+ var sampleData = {
85
+ col1: {
86
+ id: "col1",
87
+ title: "To Do",
88
+ color: "#3182ce",
89
+ items: [
90
+ { id: "1", name: "Account A", email: "a@example.com" },
91
+ { id: "2", name: "Account B", email: "b@example.com" },
92
+ ],
93
+ },
94
+ };
95
+ describe("KanbanBoard – permissions", function () {
96
+ describe("isDeletable", function () {
97
+ it("shows card delete icons when permissions.isDeletable is true", function () {
98
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, permissions: { isDeletable: true } }));
99
+ expect(react_2.screen.getAllByLabelText("Delete").length).toBeGreaterThan(0);
100
+ });
101
+ it("hides card delete icons when permissions.isDeletable is false", function () {
102
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, permissions: { isDeletable: false } }));
103
+ expect(react_2.screen.queryByLabelText("Delete")).not.toBeInTheDocument();
104
+ });
105
+ it("shows card delete icons when permissions prop is omitted (default allow)", function () {
106
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData }));
107
+ expect(react_2.screen.getAllByLabelText("Delete").length).toBeGreaterThan(0);
108
+ });
109
+ });
110
+ describe("isCreatable", function () {
111
+ var kanbanCreate = { isCreatable: true, label: "Create New" };
112
+ it("shows the create button when permissions.isCreatable is true", function () {
113
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, kanbanCreate: kanbanCreate, permissions: { isCreatable: true } }));
114
+ expect(react_2.screen.getByText("Create New")).toBeInTheDocument();
115
+ });
116
+ it("hides the create button when permissions.isCreatable is false", function () {
117
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, kanbanCreate: kanbanCreate, permissions: { isCreatable: false } }));
118
+ expect(react_2.screen.queryByText("Create New")).not.toBeInTheDocument();
119
+ });
120
+ });
121
+ describe("isEditable", function () {
122
+ var kanbanEdit = { isEditable: true, label: "Edit Layout" };
123
+ it("shows the edit button when permissions.isEditable is true", function () {
124
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, kanbanEdit: kanbanEdit, permissions: { isEditable: true } }));
125
+ expect(react_2.screen.getByText("Edit Layout")).toBeInTheDocument();
126
+ });
127
+ it("hides the edit button when permissions.isEditable is false", function () {
128
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, kanbanEdit: kanbanEdit, permissions: { isEditable: false } }));
129
+ expect(react_2.screen.queryByText("Edit Layout")).not.toBeInTheDocument();
130
+ });
131
+ it("sets isDragDisabled on cards when permissions.isEditable is false", function () {
132
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, permissions: { isEditable: false } }));
133
+ var disabledDraggables = react_2.screen
134
+ .getAllByRole("generic")
135
+ .filter(function (el) { return el.getAttribute("data-drag-disabled") === "true"; });
136
+ expect(disabledDraggables.length).toBeGreaterThan(0);
137
+ });
138
+ });
139
+ describe("column collapse", function () {
140
+ it("shows a collapse control per column when enableColumnCollapse is true", function () {
141
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, enableColumnCollapse: true }));
142
+ expect(react_2.screen.getAllByLabelText("Collapse column").length).toBeGreaterThan(0);
143
+ });
144
+ it("hides cards when a column is collapsed", function () {
145
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, enableColumnCollapse: true }));
146
+ expect(react_2.screen.getAllByLabelText("Delete").length).toBeGreaterThan(0);
147
+ react_2.fireEvent.click(react_2.screen.getAllByLabelText("Collapse column")[0]);
148
+ expect(react_2.screen.queryByLabelText("Delete")).not.toBeInTheDocument();
149
+ expect(react_2.screen.getByLabelText("Expand column")).toBeInTheDocument();
150
+ });
151
+ it("still shows column customNode when horizontally collapsed", function () {
152
+ var dataWithCustom = {
153
+ col1: __assign(__assign({}, sampleData.col1), { customNode: function () { return react_1.default.createElement("span", null, "Column summary line"); } }),
154
+ };
155
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: dataWithCustom, enableColumnCollapse: true }));
156
+ expect(react_2.screen.getByText("Column summary line")).toBeInTheDocument();
157
+ react_2.fireEvent.click(react_2.screen.getByLabelText("Collapse column"));
158
+ expect(react_2.screen.queryByLabelText("Delete")).not.toBeInTheDocument();
159
+ expect(react_2.screen.getByText("Column summary line")).toBeInTheDocument();
160
+ });
161
+ it("starts with columns collapsed when collapsedColumns is set", function () {
162
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, enableColumnCollapse: true, collapsedColumns: { col1: true } }));
163
+ expect(react_2.screen.queryByLabelText("Delete")).not.toBeInTheDocument();
164
+ expect(react_2.screen.getByLabelText("Expand column")).toBeInTheDocument();
165
+ });
166
+ it("calls onColumnCollapseChange when collapsing and expanding", function () {
167
+ var onColumnCollapseChange = jest.fn();
168
+ renderWithChakra(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, enableColumnCollapse: true, onColumnCollapseChange: onColumnCollapseChange }));
169
+ react_2.fireEvent.click(react_2.screen.getAllByLabelText("Collapse column")[0]);
170
+ expect(onColumnCollapseChange).toHaveBeenCalledTimes(1);
171
+ expect(onColumnCollapseChange).toHaveBeenLastCalledWith({
172
+ colId: "col1",
173
+ collapsed: true,
174
+ collapsedColumns: { col1: true },
175
+ });
176
+ react_2.fireEvent.click(react_2.screen.getByLabelText("Expand column"));
177
+ expect(onColumnCollapseChange).toHaveBeenCalledTimes(2);
178
+ expect(onColumnCollapseChange).toHaveBeenLastCalledWith({
179
+ colId: "col1",
180
+ collapsed: false,
181
+ collapsedColumns: { col1: false },
182
+ });
183
+ });
184
+ });
185
+ });
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var searchSelectSize_1 = require("./searchSelectSize");
4
+ describe("getSearchSelectSizeStyles", function () {
5
+ it.each(["xs", "sm", "md", "lg"])("returns minH for %s", function (sz) {
6
+ var t = (0, searchSelectSize_1.getSearchSelectSizeStyles)(sz);
7
+ expect(t.minH).toMatch(/rem$/);
8
+ expect(t.insideSelectDefaultHeight).toMatch(/rem$/);
9
+ });
10
+ it("xs is more compact than lg", function () {
11
+ var xs = (0, searchSelectSize_1.getSearchSelectSizeStyles)("xs");
12
+ var lg = (0, searchSelectSize_1.getSearchSelectSizeStyles)("lg");
13
+ var parse = function (h) { return parseFloat(h); };
14
+ expect(parse(xs.minH)).toBeLessThan(parse(lg.minH));
15
+ expect(parse(xs.insideSelectDefaultHeight)).toBeLessThan(parse(lg.insideSelectDefaultHeight));
16
+ });
17
+ it("uses md as fallback for unknown size keys (runtime map lookup)", function () {
18
+ var t = (0, searchSelectSize_1.getSearchSelectSizeStyles)("unknown");
19
+ var md = (0, searchSelectSize_1.getSearchSelectSizeStyles)("md");
20
+ expect(t).toEqual(md);
21
+ });
22
+ });
@@ -0,0 +1 @@
1
+ import "@testing-library/jest-dom";
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ var react_1 = __importDefault(require("react"));
43
+ var react_2 = require("@testing-library/react");
44
+ var user_event_1 = __importDefault(require("@testing-library/user-event"));
45
+ require("@testing-library/jest-dom");
46
+ var react_3 = require("@chakra-ui/react");
47
+ var OtherApps_1 = __importDefault(require("./OtherApps"));
48
+ jest.mock("../../../Theme/useCustomTheme", function () { return ({
49
+ useCustomTheme: function () { return ({
50
+ colors: {
51
+ white: "#fff",
52
+ gray: { 400: "#a0aec0" },
53
+ primary: { 500: "#3182ce", 700: "#2c5282" },
54
+ sidebar: {
55
+ background: {
56
+ 200: "#2d3748",
57
+ 500: "#1a202c",
58
+ },
59
+ },
60
+ },
61
+ }); },
62
+ }); });
63
+ var sampleApps = [
64
+ {
65
+ name: "Billing",
66
+ color: "#3182ce",
67
+ description: "Billing app",
68
+ onClick: jest.fn(),
69
+ },
70
+ {
71
+ name: "Tickets",
72
+ color: "#38a169",
73
+ onClick: jest.fn(),
74
+ },
75
+ ];
76
+ var renderWithChakra = function (ui) { return (0, react_2.render)(react_1.default.createElement(react_3.ChakraProvider, null, ui)); };
77
+ describe("OtherApps", function () {
78
+ beforeEach(function () {
79
+ jest.clearAllMocks();
80
+ });
81
+ it("does not render flyout copy when expanded", function () {
82
+ renderWithChakra(react_1.default.createElement(OtherApps_1.default, { toggle: false, otherApps: sampleApps }));
83
+ expect(react_2.screen.getByText("Other Apps")).toBeInTheDocument();
84
+ expect(react_2.screen.getByText("Billing")).toBeInTheDocument();
85
+ expect(react_2.screen.queryAllByRole("tooltip")).toHaveLength(0);
86
+ });
87
+ it("shows flyout with Open label on hover when collapsed", function () { return __awaiter(void 0, void 0, void 0, function () {
88
+ var buttons, _a;
89
+ return __generator(this, function (_b) {
90
+ switch (_b.label) {
91
+ case 0:
92
+ renderWithChakra(react_1.default.createElement(OtherApps_1.default, { toggle: true, otherApps: sampleApps }));
93
+ buttons = react_2.screen.getAllByRole("button");
94
+ expect(buttons).toHaveLength(2);
95
+ return [4 /*yield*/, user_event_1.default.hover(buttons[0])];
96
+ case 1:
97
+ _b.sent();
98
+ _a = expect;
99
+ return [4 /*yield*/, react_2.screen.findByText("Billing app")];
100
+ case 2:
101
+ _a.apply(void 0, [_b.sent()]).toBeInTheDocument();
102
+ return [2 /*return*/];
103
+ }
104
+ });
105
+ }); });
106
+ it("renders no app rows when otherApps is empty", function () {
107
+ renderWithChakra(react_1.default.createElement(OtherApps_1.default, { toggle: true, otherApps: [] }));
108
+ expect(react_2.screen.queryByRole("button")).not.toBeInTheDocument();
109
+ expect(react_2.screen.queryByText("Billing")).not.toBeInTheDocument();
110
+ });
111
+ });
@@ -0,0 +1 @@
1
+ import "@testing-library/jest-dom";
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var react_1 = __importStar(require("react"));
40
+ var react_2 = require("@testing-library/react");
41
+ require("@testing-library/jest-dom");
42
+ var react_3 = require("@chakra-ui/react");
43
+ var TableBody_1 = __importDefault(require("./TableBody"));
44
+ jest.mock("../../../Theme/useCustomTheme", function () { return ({
45
+ useCustomTheme: function () { return ({
46
+ colors: {
47
+ background: { 50: "#fff", 100: "#f9f9f9" },
48
+ backgroundColor: { light: "#fafafa", secondary: "#eee", muted: "#f3f3f3" },
49
+ disabled: { 100: "#eee" },
50
+ gray: { 100: "#f0f0f0", 200: "#eee", 300: "#ddd", 400: "#ccc", 500: "#bbb", 600: "#666" },
51
+ border: { 500: "#ddd" },
52
+ primary: { 500: "#3182ce" },
53
+ text: { 500: "#555" },
54
+ secondary: { opacity: { 4: "rgba(0,0,0,0.04)" } },
55
+ white: "#fff",
56
+ },
57
+ shadows: { lg: "0 0 0" },
58
+ }); },
59
+ }); });
60
+ var columns = [{ id: "name", label: "Name" }];
61
+ var makeData = function (n) {
62
+ return Array.from({ length: n }, function (_, i) { return ({ id: i, name: "Row ".concat(i) }); });
63
+ };
64
+ var Harness = function (_a) {
65
+ var count = _a.count;
66
+ var ref = (0, react_1.useRef)(null);
67
+ return (react_1.default.createElement(react_3.ChakraProvider, null,
68
+ react_1.default.createElement("div", { ref: ref },
69
+ react_1.default.createElement(react_3.Table, null,
70
+ react_1.default.createElement(react_3.Tbody, null,
71
+ react_1.default.createElement(TableBody_1.default, { data: makeData(count), columns: columns, startRow: 0, endRow: count, columnWidths: [120], isCheckbox: false, isContent: false, isLink: false, isActionFreeze: false, noBorders: false, selections: [], handleCheckbox: function () { }, scrollContainerRef: ref }))))));
72
+ };
73
+ describe("TableBody virtualization", function () {
74
+ it("windows large pages and reserves height with spacer rows", function () {
75
+ var _a = (0, react_2.render)(react_1.default.createElement(Harness, { count: 100 })), container = _a.container, queryByText = _a.queryByText;
76
+ // jsdom clientHeight=0 -> 500px fallback -> ceil(500/45)+12 = 24 rows
77
+ expect(queryByText("Row 0")).toBeInTheDocument();
78
+ expect(queryByText("Row 23")).toBeInTheDocument();
79
+ // Rows beyond the window are not mounted.
80
+ expect(queryByText("Row 50")).not.toBeInTheDocument();
81
+ expect(queryByText("Row 99")).not.toBeInTheDocument();
82
+ // A trailing spacer reserves the height of the unrendered rows.
83
+ var spacers = container.querySelectorAll('tr[aria-hidden="true"]');
84
+ expect(spacers.length).toBe(1);
85
+ expect(spacers[0]).toHaveStyle({ height: "".concat((100 - 24) * 45, "px") });
86
+ });
87
+ it("renders every row and no spacers below the threshold", function () {
88
+ var _a = (0, react_2.render)(react_1.default.createElement(Harness, { count: 30 })), container = _a.container, queryByText = _a.queryByText;
89
+ expect(queryByText("Row 0")).toBeInTheDocument();
90
+ expect(queryByText("Row 29")).toBeInTheDocument();
91
+ expect(container.querySelectorAll('tr[aria-hidden="true"]').length).toBe(0);
92
+ });
93
+ });
@@ -0,0 +1 @@
1
+ import "@testing-library/jest-dom";
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ var __generator = (this && this.__generator) || function (thisArg, body) {
45
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
46
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
47
+ function verb(n) { return function (v) { return step([n, v]); }; }
48
+ function step(op) {
49
+ if (f) throw new TypeError("Generator is already executing.");
50
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
51
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
52
+ if (y = 0, t) op = [op[0] & 2, t.value];
53
+ switch (op[0]) {
54
+ case 0: case 1: t = op; break;
55
+ case 4: _.label++; return { value: op[1], done: false };
56
+ case 5: _.label++; y = op[1]; op = [0]; continue;
57
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
58
+ default:
59
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
60
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
61
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
62
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
63
+ if (t[2]) _.ops.pop();
64
+ _.trys.pop(); continue;
65
+ }
66
+ op = body.call(thisArg, _);
67
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
68
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
69
+ }
70
+ };
71
+ var __importDefault = (this && this.__importDefault) || function (mod) {
72
+ return (mod && mod.__esModule) ? mod : { "default": mod };
73
+ };
74
+ Object.defineProperty(exports, "__esModule", { value: true });
75
+ var react_1 = __importStar(require("react"));
76
+ var react_2 = require("@testing-library/react");
77
+ require("@testing-library/jest-dom");
78
+ var react_3 = require("@chakra-ui/react");
79
+ var ManageColumns_1 = __importDefault(require("./ManageColumns"));
80
+ jest.mock("../../../Theme/useCustomTheme", function () { return ({
81
+ useCustomTheme: function () { return ({
82
+ colors: {
83
+ gray: {
84
+ 50: "#fafafa",
85
+ 100: "#f5f5f5",
86
+ 200: "#eee",
87
+ 400: "#ccc",
88
+ 500: "#999",
89
+ 600: "#666",
90
+ },
91
+ primary: {
92
+ 50: "#eef",
93
+ 100: "#ddf",
94
+ 300: "#99c",
95
+ 400: "#66a",
96
+ 500: "#338",
97
+ },
98
+ red: { 50: "#fee", 200: "#fcc", 600: "#c00" },
99
+ border: { 200: "#e2e8f0" },
100
+ white: "#fff",
101
+ },
102
+ shadows: { sm: "0 1px 2px rgba(0,0,0,0.05)" },
103
+ }); },
104
+ }); });
105
+ var renderWithChakra = function (ui) {
106
+ return (0, react_2.render)(react_1.default.createElement(react_3.ChakraProvider, null, ui));
107
+ };
108
+ function ManageColumnsHarness(_a) {
109
+ var columns = _a.columns, childRef = _a.childRef;
110
+ var _b = (0, react_1.useState)(columns), items = _b[0], setItems = _b[1];
111
+ return (react_1.default.createElement(ManageColumns_1.default, { columns: columns, items: items, setItems: setItems, childInputMethodsRef: childRef }));
112
+ }
113
+ describe("ManageColumns", function () {
114
+ it("syncs local column state when the columns prop changes", function () { return __awaiter(void 0, void 0, void 0, function () {
115
+ var childRef, columnsA, columnsB, rerender;
116
+ var _a, _b;
117
+ return __generator(this, function (_c) {
118
+ switch (_c.label) {
119
+ case 0:
120
+ childRef = (0, react_1.createRef)();
121
+ columnsA = [
122
+ { id: "a", label: "Alpha", isHidden: false },
123
+ { id: "b", label: "Beta", isHidden: true },
124
+ ];
125
+ columnsB = [
126
+ { id: "a", label: "Alpha", isHidden: true },
127
+ { id: "b", label: "Beta", isHidden: false },
128
+ ];
129
+ rerender = renderWithChakra(react_1.default.createElement(ManageColumnsHarness, { columns: columnsA, childRef: childRef })).rerender;
130
+ expect(react_2.screen.getByRole("checkbox", { name: "Alpha" })).toBeChecked();
131
+ expect(react_2.screen.getByRole("checkbox", { name: "Beta" })).not.toBeChecked();
132
+ expect((_a = childRef.current) === null || _a === void 0 ? void 0 : _a.getManageColumnsData()).toEqual(columnsA);
133
+ rerender(react_1.default.createElement(react_3.ChakraProvider, null,
134
+ react_1.default.createElement(ManageColumnsHarness, { columns: columnsB, childRef: childRef })));
135
+ return [4 /*yield*/, (0, react_2.waitFor)(function () {
136
+ expect(react_2.screen.getByRole("checkbox", { name: "Alpha" })).not.toBeChecked();
137
+ expect(react_2.screen.getByRole("checkbox", { name: "Beta" })).toBeChecked();
138
+ })];
139
+ case 1:
140
+ _c.sent();
141
+ expect((_b = childRef.current) === null || _b === void 0 ? void 0 : _b.getManageColumnsData()).toEqual(columnsB);
142
+ return [2 /*return*/];
143
+ }
144
+ });
145
+ }); });
146
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var buildBrandTokens_1 = require("./buildBrandTokens");
4
+ describe("normalizeHex", function () {
5
+ it("adds hash and lowercases", function () {
6
+ expect((0, buildBrandTokens_1.normalizeHex)("9A4FE5")).toBe("#9a4fe5");
7
+ expect((0, buildBrandTokens_1.normalizeHex)("#2CAA3D")).toBe("#2caa3d");
8
+ });
9
+ it("rejects invalid hex", function () {
10
+ expect(function () { return (0, buildBrandTokens_1.normalizeHex)("gggggg"); }).toThrow(/Invalid hex/);
11
+ expect(function () { return (0, buildBrandTokens_1.normalizeHex)("#fff"); }).toThrow(/Invalid hex/);
12
+ });
13
+ });
14
+ describe("buildPrimaryOpacity", function () {
15
+ it("appends alpha steps to brand hex", function () {
16
+ expect((0, buildBrandTokens_1.buildPrimaryOpacity)("#2caa3d")).toEqual({
17
+ 4: "#2caa3d0a",
18
+ 8: "#2caa3d14",
19
+ 16: "#2caa3d29",
20
+ 24: "#2caa3d3d",
21
+ 32: "#2caa3d52",
22
+ 40: "#2caa3d66",
23
+ 48: "#2caa3d7a",
24
+ });
25
+ });
26
+ });
27
+ describe("buildPrimaryShadowTint", function () {
28
+ it("returns 8-digit hex with shadow alpha", function () {
29
+ expect((0, buildBrandTokens_1.buildPrimaryShadowTint)("#0088cc")).toBe("#0088cc47");
30
+ });
31
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var chartColorsFromTheme_1 = require("./chartColorsFromTheme");
4
+ var mockColors = {
5
+ primary: { 500: "#111111" },
6
+ semantic: {
7
+ error: { 500: "#222222" },
8
+ success: { 500: "#333333" },
9
+ },
10
+ orange: { 500: "#444444" },
11
+ gray: { 700: "#555555" },
12
+ white: "#ffffff",
13
+ };
14
+ describe("chartColorsFromTheme", function () {
15
+ it("getDefaultSeriesColors returns four theme hues", function () {
16
+ expect((0, chartColorsFromTheme_1.getDefaultSeriesColors)(mockColors)).toEqual([
17
+ "#111111",
18
+ "#222222",
19
+ "#333333",
20
+ "#444444",
21
+ ]);
22
+ });
23
+ it("mergeChartTitleStyle applies primary then overrides", function () {
24
+ expect((0, chartColorsFromTheme_1.mergeChartTitleStyle)(mockColors, { fontSize: "20px" })).toMatchObject({
25
+ color: "#111111",
26
+ fontSize: "20px",
27
+ fontWeight: 600,
28
+ fontFamily: "Arial",
29
+ });
30
+ expect((0, chartColorsFromTheme_1.mergeChartTitleStyle)(mockColors, { color: "#999999" }).color).toBe("#999999");
31
+ });
32
+ it("chartAxisLabelColor reads gray scale", function () {
33
+ expect((0, chartColorsFromTheme_1.chartAxisLabelColor)(mockColors)).toBe("#555555");
34
+ });
35
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var react_1 = __importDefault(require("react"));
7
+ var table_1 = require("./table");
8
+ describe("normalizeTableCellValue", function () {
9
+ it("returns primitives as-is (string/number/boolean)", function () {
10
+ expect((0, table_1.normalizeTableCellValue)("x")).toBe("x");
11
+ expect((0, table_1.normalizeTableCellValue)(42)).toBe(42);
12
+ expect((0, table_1.normalizeTableCellValue)(false)).toBe(false);
13
+ });
14
+ it("returns empty string for null and undefined", function () {
15
+ expect((0, table_1.normalizeTableCellValue)(null)).toBe("");
16
+ expect((0, table_1.normalizeTableCellValue)(undefined)).toBe("");
17
+ });
18
+ it("returns React elements unchanged", function () {
19
+ var el = react_1.default.createElement("span", null, "hi");
20
+ expect((0, table_1.normalizeTableCellValue)(el)).toBe(el);
21
+ });
22
+ it("uses label or name on plain objects (relation fields)", function () {
23
+ expect((0, table_1.normalizeTableCellValue)({
24
+ id: 1,
25
+ label: "Owner Name",
26
+ email: "a@b.com",
27
+ role: "admin",
28
+ company_name: "Acme",
29
+ })).toBe("Owner Name");
30
+ expect((0, table_1.normalizeTableCellValue)({ id: 2, name: "Jane", email: "j@b.com" })).toBe("Jane");
31
+ });
32
+ it("returns company_name when label/name missing", function () {
33
+ expect((0, table_1.normalizeTableCellValue)({
34
+ id: 3,
35
+ company_name: "Solo Co",
36
+ })).toBe("Solo Co");
37
+ });
38
+ it("returns empty string for unrecognized objects", function () {
39
+ expect((0, table_1.normalizeTableCellValue)({ a: 1, b: 2 })).toBe("");
40
+ });
41
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelize-design-library",
3
- "version": "2.3.17",
3
+ "version": "2.3.19",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",