@eml-payments/ui-kit 1.3.2 → 1.4.3

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 (90) hide show
  1. package/dist/index.css +1 -1
  2. package/dist/src/components/Alert/Alert.js +9 -5
  3. package/dist/src/components/Button/Button.js +1 -1
  4. package/dist/src/components/Button/Button.stories.d.ts +2 -0
  5. package/dist/src/components/Button/Button.stories.js +7 -1
  6. package/dist/src/components/Button/Button.types.d.ts +1 -1
  7. package/dist/src/components/Button/ButtonVariants.js +9 -9
  8. package/dist/src/components/DatePicker/DatePicker.js +7 -3
  9. package/dist/src/components/Dialog/DialogContainer.stories.js +5 -4
  10. package/dist/src/components/Dropdown/Dropdown.stories.js +11 -9
  11. package/dist/src/components/DropdownWrapper/DropdownWrapper.stories.js +20 -18
  12. package/dist/src/components/Table/BaseTable/BaseTable.d.ts +2 -0
  13. package/dist/src/components/Table/BaseTable/BaseTable.js +8 -0
  14. package/dist/src/components/Table/BaseTable/BaseTable.stories.d.ts +7 -0
  15. package/dist/src/components/Table/BaseTable/BaseTable.stories.js +42 -0
  16. package/dist/src/components/Table/BaseTable/BaseTable.types.d.ts +0 -0
  17. package/dist/src/components/Table/BaseTable/BaseTable.types.js +1 -0
  18. package/dist/src/components/Table/BaseTable/TableHeader.d.ts +7 -0
  19. package/dist/src/components/Table/BaseTable/TableHeader.js +15 -0
  20. package/dist/src/components/Table/BaseTable/index.d.ts +1 -0
  21. package/dist/src/components/Table/BaseTable/index.js +1 -0
  22. package/dist/src/components/Table/InfiniteTable/InfiniteTable.d.ts +4 -0
  23. package/dist/src/components/Table/InfiniteTable/InfiniteTable.js +49 -0
  24. package/dist/src/components/Table/InfiniteTable/InfiniteTable.props.d.ts +32 -0
  25. package/dist/src/components/Table/InfiniteTable/InfiniteTable.props.js +1 -0
  26. package/dist/src/components/Table/InfiniteTable/InfiniteTable.stories.d.ts +8 -0
  27. package/dist/src/components/Table/InfiniteTable/InfiniteTable.stories.js +109 -0
  28. package/dist/src/components/Table/InfiniteTable/index.d.ts +2 -0
  29. package/dist/src/components/Table/InfiniteTable/index.js +1 -0
  30. package/dist/src/components/Table/InfiniteTable/useInfiniteScrollTrigger.d.ts +12 -0
  31. package/dist/src/components/Table/InfiniteTable/useInfiniteScrollTrigger.js +31 -0
  32. package/dist/src/components/Table/InfiniteTable/useInfiniteScrolling.d.ts +29 -0
  33. package/dist/src/components/Table/InfiniteTable/useInfiniteScrolling.js +103 -0
  34. package/dist/src/components/Table/InfiniteTable/useInfiniteTableController.d.ts +14 -0
  35. package/dist/src/components/Table/InfiniteTable/useInfiniteTableController.js +76 -0
  36. package/dist/src/components/Table/Pagination/PageSizeSelector.d.ts +2 -0
  37. package/dist/src/components/Table/Pagination/PageSizeSelector.js +9 -0
  38. package/dist/src/components/Table/Pagination/Pagination.types.d.ts +21 -0
  39. package/dist/src/components/Table/Pagination/Pagination.types.js +1 -0
  40. package/dist/src/components/Table/Pagination/PaginationFooter.d.ts +2 -0
  41. package/dist/src/components/Table/Pagination/PaginationFooter.js +10 -0
  42. package/dist/src/components/Table/Pagination/index.d.ts +3 -2
  43. package/dist/src/components/Table/Pagination/index.js +3 -2
  44. package/dist/src/components/Table/Pagination/usePaginationController.d.ts +16 -0
  45. package/dist/src/components/Table/Pagination/usePaginationController.js +33 -0
  46. package/dist/src/components/Table/StandardTable/StandardTable.d.ts +4 -0
  47. package/dist/src/components/Table/StandardTable/StandardTable.js +47 -0
  48. package/dist/src/components/Table/StandardTable/StandardTable.stories.d.ts +25 -0
  49. package/dist/src/components/Table/StandardTable/StandardTable.stories.js +268 -0
  50. package/dist/src/components/Table/StandardTable/StandardTable.types.d.ts +4 -0
  51. package/dist/src/components/Table/StandardTable/StandardTable.types.js +1 -0
  52. package/dist/src/components/Table/StandardTable/index.d.ts +2 -0
  53. package/dist/src/components/Table/StandardTable/index.js +1 -0
  54. package/dist/src/components/Table/StandardTable/useStandardTableController.d.ts +22 -0
  55. package/dist/src/components/Table/StandardTable/useStandardTableController.js +100 -0
  56. package/dist/src/components/Table/Table.types.d.ts +72 -29
  57. package/dist/src/components/Table/body/Body.types.d.ts +0 -0
  58. package/dist/src/components/Table/body/Body.types.js +1 -0
  59. package/dist/src/components/Table/body/renderGroupRow.d.ts +13 -0
  60. package/dist/src/components/Table/body/renderGroupRow.js +14 -0
  61. package/dist/src/components/Table/body/renderLeafRow.d.ts +11 -0
  62. package/dist/src/components/Table/body/renderLeafRow.js +17 -0
  63. package/dist/src/components/Table/body/renderTableBody.d.ts +22 -0
  64. package/dist/src/components/Table/body/renderTableBody.js +21 -0
  65. package/dist/src/components/Table/body/utils/getColSpan.d.ts +2 -0
  66. package/dist/src/components/Table/body/utils/getColSpan.js +4 -0
  67. package/dist/src/components/Table/body/utils/getTableBodyState.d.ts +16 -0
  68. package/dist/src/components/Table/body/utils/getTableBodyState.js +9 -0
  69. package/dist/src/components/Table/body/utils/index.d.ts +2 -0
  70. package/dist/src/components/Table/body/utils/index.js +2 -0
  71. package/dist/src/components/Table/hooks/useTableColumns.d.ts +2 -0
  72. package/dist/src/components/Table/hooks/useTableColumns.js +5 -0
  73. package/dist/src/components/Table/hooks/useTableLayout.d.ts +5 -0
  74. package/dist/src/components/Table/hooks/useTableLayout.js +21 -0
  75. package/dist/src/components/Table/hooks/useTableSorting.d.ts +5 -0
  76. package/dist/src/components/Table/hooks/useTableSorting.js +14 -0
  77. package/dist/src/components/Table/hooks/useUrlPaginationSync.d.ts +4 -5
  78. package/dist/src/components/Table/hooks/useUrlPaginationSync.js +23 -9
  79. package/dist/src/components/Table/index.d.ts +5 -2
  80. package/dist/src/components/Table/index.js +2 -2
  81. package/dist/src/components/Table/render-rows/renderTableRows.d.ts +22 -0
  82. package/dist/src/components/Table/render-rows/renderTableRows.js +31 -0
  83. package/dist/src/components/Table/table.helpers.d.ts +5 -2
  84. package/dist/src/components/Table/table.helpers.js +13 -7
  85. package/dist/src/components/UICreditCard/UICreditCard.d.ts +1 -1
  86. package/dist/src/components/UICreditCard/UICreditCard.js +4 -2
  87. package/dist/src/components/UICreditCard/UICreditCard.stories.d.ts +1 -0
  88. package/dist/src/components/UICreditCard/UICreditCard.stories.js +12 -4
  89. package/dist/src/components/UICreditCard/UICreditCard.types.d.ts +3 -0
  90. package/package.json +3 -3
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from '../../Button';
3
+ import { DropdownWrapper } from '../../DropdownWrapper';
4
+ import { classNames } from '../../../utils';
5
+ import { flexRender } from '@tanstack/react-table';
6
+ import { FiMoreHorizontal } from 'react-icons/fi';
7
+ import { getRowInteractivity } from '../table.helpers';
8
+ export function renderLeafRow({ row, onRowClick, isRowClickable, hasActions, tableActionsDropdown, }) {
9
+ var _a, _b;
10
+ const original = row.original;
11
+ const { clickable, disabled } = getRowInteractivity(original, onRowClick, isRowClickable);
12
+ return (_jsxs("tr", { className: classNames('border-t transition-colors', clickable && 'cursor-pointer hover:bg-gray-50', disabled && 'bg-muted/40 text-muted-foreground cursor-not-allowed'), onClick: clickable ? () => onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(original) : undefined, children: [row.getVisibleCells().map((cell) => {
13
+ const width = cell.column.getSize();
14
+ const isSelect = cell.column.id === 'select';
15
+ return (_jsx("td", { style: { width }, className: isSelect ? 'p-1' : 'px-4 py-3', children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id));
16
+ }), hasActions && tableActionsDropdown && (_jsx("td", { className: "w-[40px] px-2 py-2 text-right", children: _jsx(DropdownWrapper, { options: tableActionsDropdown.getOptions(original), menuAlignment: tableActionsDropdown.menuAlignment, isTriggerElementDisabled: disabled, triggerElement: (_b = (_a = tableActionsDropdown.renderCustomTrigger) === null || _a === void 0 ? void 0 : _a.call(tableActionsDropdown, original)) !== null && _b !== void 0 ? _b : (_jsx(Button, { size: "icon", variant: "ghost", className: "p-1", disabled: disabled, children: _jsx(FiMoreHorizontal, { size: 16 }) })) }) }))] }, row.id));
17
+ }
@@ -0,0 +1,22 @@
1
+ import type { Table } from '@tanstack/react-table';
2
+ import type { ITableActionsDropdownProps } from '../Table.types';
3
+ import type { TableBodyState } from './utils';
4
+ interface RenderTableBodyProps<T extends {
5
+ id: string;
6
+ }> {
7
+ table: Table<T>;
8
+ state: TableBodyState<T>;
9
+ colSpan: number;
10
+ onRowClick?: (row: T) => void;
11
+ isRowClickable?: (row: T) => boolean;
12
+ onGroupRowClick?: (args: {
13
+ columnId: string;
14
+ value: unknown;
15
+ rows: T[];
16
+ }) => void;
17
+ tableActionsDropdown?: ITableActionsDropdownProps<T>;
18
+ }
19
+ export declare function renderTableBody<T extends {
20
+ id: string;
21
+ }>({ table, state, colSpan, onRowClick, isRowClickable, onGroupRowClick, tableActionsDropdown, }: RenderTableBodyProps<T>): React.ReactNode;
22
+ export {};
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { renderTableRows } from '../render-rows/renderTableRows';
3
+ export function renderTableBody({ table, state, colSpan, onRowClick, isRowClickable, onGroupRowClick, tableActionsDropdown, }) {
4
+ var _a;
5
+ switch (state.type) {
6
+ case 'loading':
7
+ return null; // spinner handled by BaseTable
8
+ case 'empty':
9
+ return (_jsx("tr", { children: _jsx("td", { colSpan: colSpan, className: "px-4 py-8 text-center text-muted-foreground", children: state.message }) }));
10
+ case 'rows':
11
+ return renderTableRows({
12
+ table,
13
+ rows: state.rows,
14
+ hasActions: Boolean((_a = table.options.meta) === null || _a === void 0 ? void 0 : _a.hasActions),
15
+ onRowClick,
16
+ isRowClickable,
17
+ onGroupRowClick,
18
+ tableActionsDropdown,
19
+ });
20
+ }
21
+ }
@@ -0,0 +1,2 @@
1
+ import type { Table } from '@tanstack/react-table';
2
+ export declare function getColSpan<T>(table: Table<T>): number;
@@ -0,0 +1,4 @@
1
+ export function getColSpan(table) {
2
+ var _a;
3
+ return table.getVisibleLeafColumns().length + (((_a = table.options.meta) === null || _a === void 0 ? void 0 : _a.hasActions) ? 1 : 0);
4
+ }
@@ -0,0 +1,16 @@
1
+ import type { Row } from '@tanstack/react-table';
2
+ import type { ReactNode } from 'react';
3
+ export type TableBodyState<T> = {
4
+ type: 'loading';
5
+ } | {
6
+ type: 'empty';
7
+ message: ReactNode;
8
+ } | {
9
+ type: 'rows';
10
+ rows: Row<T>[];
11
+ };
12
+ export declare function getTableBodyState<T>({ rows, isLoading, noResultsMessage, }: {
13
+ rows: Row<T>[];
14
+ isLoading?: boolean;
15
+ noResultsMessage: ReactNode;
16
+ }): TableBodyState<T>;
@@ -0,0 +1,9 @@
1
+ export function getTableBodyState({ rows, isLoading, noResultsMessage, }) {
2
+ if (isLoading) {
3
+ return { type: 'loading' };
4
+ }
5
+ if (rows.length === 0) {
6
+ return { type: 'empty', message: noResultsMessage };
7
+ }
8
+ return { type: 'rows', rows };
9
+ }
@@ -0,0 +1,2 @@
1
+ export * from './getTableBodyState';
2
+ export * from './getColSpan';
@@ -0,0 +1,2 @@
1
+ export * from './getTableBodyState';
2
+ export * from './getColSpan';
@@ -0,0 +1,2 @@
1
+ import type { FlexColumnDef } from '../Table.types';
2
+ export declare function useTableColumns<T>(columns: FlexColumnDef<T>[], containerWidth: number, virtualizationEnabled: boolean): import("../table.helpers").VirtualFlexColumnDef<T>[];
@@ -0,0 +1,5 @@
1
+ import { useMemo } from 'react';
2
+ import { applyFlexSizes } from '../table.helpers';
3
+ export function useTableColumns(columns, containerWidth, virtualizationEnabled) {
4
+ return useMemo(() => applyFlexSizes(columns, containerWidth, virtualizationEnabled), [columns, containerWidth, virtualizationEnabled]);
5
+ }
@@ -0,0 +1,5 @@
1
+ export declare function useTableLayout(): {
2
+ parentScrollRef: import("react").MutableRefObject<HTMLDivElement | null>;
3
+ loaderRef: import("react").MutableRefObject<HTMLTableRowElement | null>;
4
+ containerWidth: number;
5
+ };
@@ -0,0 +1,21 @@
1
+ import { useLayoutEffect, useRef, useState } from 'react';
2
+ export function useTableLayout() {
3
+ const parentScrollRef = useRef(null);
4
+ const loaderRef = useRef(null);
5
+ const [containerWidth, setContainerWidth] = useState(0);
6
+ useLayoutEffect(() => {
7
+ if (!parentScrollRef.current) {
8
+ return;
9
+ }
10
+ const ro = new ResizeObserver(([entry]) => {
11
+ setContainerWidth(entry.contentRect.width);
12
+ });
13
+ ro.observe(parentScrollRef.current);
14
+ return () => ro.disconnect();
15
+ }, []);
16
+ return {
17
+ parentScrollRef,
18
+ loaderRef,
19
+ containerWidth,
20
+ };
21
+ }
@@ -0,0 +1,5 @@
1
+ import type { SortingState } from '@tanstack/react-table';
2
+ export declare function useTableSorting(controlledSorting?: SortingState, onSortingChange?: (s: SortingState) => void): {
3
+ sorting: SortingState;
4
+ onSortingChange: (updater: SortingState | ((prev: SortingState) => SortingState)) => void;
5
+ };
@@ -0,0 +1,14 @@
1
+ import { useState } from 'react';
2
+ export function useTableSorting(controlledSorting, onSortingChange) {
3
+ const [internalSorting, setInternalSorting] = useState(controlledSorting !== null && controlledSorting !== void 0 ? controlledSorting : []);
4
+ const sorting = controlledSorting !== null && controlledSorting !== void 0 ? controlledSorting : internalSorting;
5
+ const handleSortingChange = (updater) => {
6
+ const next = typeof updater === 'function' ? updater(sorting) : updater;
7
+ setInternalSorting(next);
8
+ onSortingChange === null || onSortingChange === void 0 ? void 0 : onSortingChange(next);
9
+ };
10
+ return {
11
+ sorting,
12
+ onSortingChange: handleSortingChange,
13
+ };
14
+ }
@@ -1,6 +1,5 @@
1
- export declare function useUrlPaginationSync(rowsPerPage: number, tableId: string): {
2
- pageIndex: number;
3
- setPageIndex: import("react").Dispatch<import("react").SetStateAction<number>>;
4
- pageSize: number;
5
- setPageSize: import("react").Dispatch<import("react").SetStateAction<number>>;
1
+ export declare function useUrlPaginationSync(tableId: string, defaultPageSize: number): {
2
+ initialPageIndex: number;
3
+ initialPageSize: number;
4
+ syncToUrl: (pageIndex: number, pageSize: number) => void;
6
5
  };
@@ -1,12 +1,26 @@
1
- import { useState } from 'react';
1
+ import { useCallback, useState } from 'react';
2
2
  import { useSearchParams } from 'react-router-dom';
3
- export function useUrlPaginationSync(rowsPerPage, tableId) {
4
- const [searchParams] = useSearchParams();
5
- const pageSizeKey = `${tableId}_pageSize`;
3
+ export function useUrlPaginationSync(tableId, defaultPageSize) {
4
+ const [searchParams, setSearchParams] = useSearchParams();
6
5
  const pageNoKey = `${tableId}_pageNo`;
7
- const initialPageIndex = Math.max(parseInt(searchParams.get(pageNoKey) || '1') - 1, 0);
8
- const initialPageSize = Math.max(parseInt(searchParams.get(pageSizeKey) || String(rowsPerPage !== null && rowsPerPage !== void 0 ? rowsPerPage : 10)), 1);
9
- const [pageIndex, setPageIndex] = useState(initialPageIndex);
10
- const [pageSize, setPageSize] = useState(initialPageSize);
11
- return { pageIndex, setPageIndex, pageSize, setPageSize };
6
+ const pageSizeKey = `${tableId}_pageSize`;
7
+ const [initialPageIndex] = useState(() => {
8
+ const raw = Number(searchParams.get(pageNoKey));
9
+ return Number.isFinite(raw) && raw > 0 ? raw - 1 : 0;
10
+ });
11
+ const [initialPageSize] = useState(() => {
12
+ const raw = Number(searchParams.get(pageSizeKey));
13
+ return Number.isFinite(raw) && raw > 0 ? raw : defaultPageSize;
14
+ });
15
+ const syncToUrl = useCallback((pageIndex, pageSize) => {
16
+ const next = new URLSearchParams(searchParams);
17
+ next.set(pageNoKey, String(pageIndex + 1)); // 1-based
18
+ next.set(pageSizeKey, String(pageSize));
19
+ setSearchParams(next, { replace: true });
20
+ }, [pageNoKey, pageSizeKey, searchParams, setSearchParams]);
21
+ return {
22
+ initialPageIndex,
23
+ initialPageSize,
24
+ syncToUrl,
25
+ };
12
26
  }
@@ -1,2 +1,5 @@
1
- export * from './Table';
2
- export * from './Table.types';
1
+ export { StandardTable } from './StandardTable';
2
+ export { InfiniteTable } from './InfiniteTable';
3
+ export type { StandardTableProps } from './StandardTable/StandardTable.types';
4
+ export type { InfiniteTableProps } from './InfiniteTable/InfiniteTable.props';
5
+ export type { FlexColumnDef, TableInputProps, ITableActionsDropdownProps, GroupRowClickHandler, StandardPaginationProps, ClientPaginationProps, ServerPaginationProps, InfiniteScrollOptions, VirtualizationOptions, InfiniteScrollTableProps, } from './Table.types';
@@ -1,2 +1,2 @@
1
- export * from './Table';
2
- export * from './Table.types';
1
+ export { StandardTable } from './StandardTable';
2
+ export { InfiniteTable } from './InfiniteTable';
@@ -0,0 +1,22 @@
1
+ import type React from 'react';
2
+ import { type Row, type Table } from '@tanstack/react-table';
3
+ import type { ITableActionsDropdownProps } from '../Table.types';
4
+ interface RenderTableRowsProps<T extends {
5
+ id: string;
6
+ }> {
7
+ table: Table<T>;
8
+ rows: Row<T>[];
9
+ hasActions: boolean;
10
+ onRowClick?: (row: T) => void;
11
+ isRowClickable?: (row: T) => boolean;
12
+ onGroupRowClick?: (args: {
13
+ columnId: string;
14
+ value: unknown;
15
+ rows: T[];
16
+ }) => void;
17
+ tableActionsDropdown?: ITableActionsDropdownProps<T>;
18
+ }
19
+ export declare function renderTableRows<T extends {
20
+ id: string;
21
+ }>({ table, rows, onRowClick, isRowClickable, onGroupRowClick, tableActionsDropdown, hasActions, }: RenderTableRowsProps<T>): React.ReactNode[];
22
+ export {};
@@ -0,0 +1,31 @@
1
+ import { renderGroupRow } from '../body/renderGroupRow';
2
+ import { renderLeafRow } from '../body/renderLeafRow';
3
+ export function renderTableRows({ table, rows, onRowClick, isRowClickable, onGroupRowClick, tableActionsDropdown, hasActions, }) {
4
+ const result = [];
5
+ for (const row of rows) {
6
+ if (row.getIsGrouped() && row.groupingColumnId) {
7
+ const groupedRow = row;
8
+ result.push(renderGroupRow({
9
+ row: groupedRow,
10
+ onGroupRowClick,
11
+ }), ...renderTableRows({
12
+ table,
13
+ rows: row.subRows,
14
+ hasActions,
15
+ onRowClick,
16
+ isRowClickable,
17
+ onGroupRowClick,
18
+ tableActionsDropdown,
19
+ }));
20
+ continue;
21
+ }
22
+ result.push(renderLeafRow({
23
+ row,
24
+ onRowClick,
25
+ isRowClickable,
26
+ hasActions,
27
+ tableActionsDropdown,
28
+ }));
29
+ }
30
+ return result;
31
+ }
@@ -1,8 +1,11 @@
1
- import type { Table } from '@tanstack/react-table';
2
1
  import type { FlexColumnDef } from './Table.types';
3
- export declare function getCheckboxSelectionColumn<T>(table: Table<T>): FlexColumnDef<T>;
2
+ export declare function getCheckboxSelectionColumn<T>(): FlexColumnDef<T>;
4
3
  export type VirtualFlexColumnDef<T> = FlexColumnDef<T> & {
5
4
  size?: number;
6
5
  _virtualLocked?: boolean;
7
6
  };
8
7
  export declare function applyFlexSizes<T>(columns?: FlexColumnDef<T>[], containerWidth?: number, virtualizationEnabled?: boolean): VirtualFlexColumnDef<T>[];
8
+ export declare function getRowInteractivity<T>(row: T, onRowClick?: (row: T) => void, isRowClickable?: (row: T) => boolean): {
9
+ clickable: boolean;
10
+ disabled: boolean;
11
+ };
@@ -1,21 +1,19 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Checkbox } from '../Checkbox';
3
- export function getCheckboxSelectionColumn(table) {
3
+ export function getCheckboxSelectionColumn() {
4
4
  return {
5
5
  id: 'select',
6
6
  size: 24,
7
- header: () => {
7
+ header: ({ table }) => {
8
8
  if (!table.options.enableMultiRowSelection) {
9
9
  return null;
10
10
  }
11
11
  const hasSelectableRows = table.getRowModel().rows.some((row) => row.getCanSelect());
12
- return (_jsx("div", { className: "flex justify-center items-center h-full", children: _jsx(Checkbox, { checked: table.getIsAllPageRowsSelected(),
13
- // indeterminate={table.getIsSomeRowsSelected()} TODO: Implement indeterminate state
14
- disabled: !hasSelectableRows, onCheckedChange: (checked) => {
12
+ return (_jsx("div", { className: "flex h-full items-center justify-center", children: _jsx(Checkbox, { checked: table.getIsAllPageRowsSelected(), disabled: !hasSelectableRows, onCheckedChange: (checked) => {
15
13
  table.toggleAllPageRowsSelected(Boolean(checked));
16
14
  } }) }));
17
15
  },
18
- cell: ({ row }) => (_jsx("div", { className: "flex justify-center items-center h-full", children: _jsx(Checkbox, { checked: row.getIsSelected(), disabled: !row.getCanSelect(), onCheckedChange: (checked) => {
16
+ cell: ({ row }) => (_jsx("div", { className: "flex h-full items-center justify-center", children: _jsx(Checkbox, { checked: row.getIsSelected(), disabled: !row.getCanSelect(), onCheckedChange: (checked) => {
19
17
  row.toggleSelected(Boolean(checked));
20
18
  } }) })),
21
19
  enableSorting: false,
@@ -24,8 +22,9 @@ export function getCheckboxSelectionColumn(table) {
24
22
  };
25
23
  }
26
24
  export function applyFlexSizes(columns, containerWidth = 0, virtualizationEnabled = false) {
27
- if (!columns)
25
+ if (!columns) {
28
26
  return [];
27
+ }
29
28
  if (!virtualizationEnabled || containerWidth === 0) {
30
29
  return columns;
31
30
  }
@@ -40,3 +39,10 @@ export function applyFlexSizes(columns, containerWidth = 0, virtualizationEnable
40
39
  };
41
40
  });
42
41
  }
42
+ export function getRowInteractivity(row, onRowClick, isRowClickable) {
43
+ const allowed = isRowClickable ? isRowClickable(row) : true;
44
+ return {
45
+ clickable: Boolean(onRowClick) && allowed,
46
+ disabled: !allowed,
47
+ };
48
+ }
@@ -1,3 +1,3 @@
1
1
  import { type JSX } from 'react';
2
2
  import type { UICreditCardProps } from './UICreditCard.types';
3
- export declare const UICreditCard: ({ cvv, cvvLabel, cardNumber, cardNumberLabel, expiryDate, expiryDateLabel, enableCopy, classNames, backImageUrl, frontImageUrl, cardholderName, cardholderNameLabel, isFlipped, customBackContent, customFrontContent, aspectRatio, }: UICreditCardProps) => JSX.Element;
3
+ export declare const UICreditCard: ({ cvv, cvvLabel, cardNumber, cardNumberLabel, expiryDate, expiryDateLabel, enableCopy, classNames, backImageUrl, frontImageUrl, cardholderName, cardholderNameLabel, isFlipped, customBackContent, customFrontContent, aspectRatio, isBlocked, blockedImageUrlOverlay, }: UICreditCardProps) => JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { CopyButton } from '../CopyButton/CopyButton';
3
- export const UICreditCard = ({ cvv, cvvLabel = 'CVV', cardNumber, cardNumberLabel = 'Card number', expiryDate, expiryDateLabel = 'Expiry', enableCopy, classNames, backImageUrl, frontImageUrl, cardholderName, cardholderNameLabel = 'Cardholder name', isFlipped = false, customBackContent, customFrontContent, aspectRatio = 3 / 2, }) => {
3
+ export const UICreditCard = ({ cvv, cvvLabel = 'CVV', cardNumber, cardNumberLabel = 'Card number', expiryDate, expiryDateLabel = 'Expiry', enableCopy, classNames, backImageUrl, frontImageUrl, cardholderName, cardholderNameLabel = 'Cardholder name', isFlipped = false, customBackContent, customFrontContent, aspectRatio = 3 / 2, isBlocked = false, blockedImageUrlOverlay, }) => {
4
4
  return (_jsx("div", { className: "relative mx-auto group", style: { aspectRatio, width: '100%', perspective: '500px' }, children: _jsxs("div", { className: `absolute w-full h-full transition-transform duration-700 ease-in-out top-0 ${classNames === null || classNames === void 0 ? void 0 : classNames.container}`, style: {
5
5
  transformStyle: 'preserve-3d',
6
6
  transform: isFlipped ? 'rotateY(180deg)' : 'rotateY(0deg)',
@@ -11,5 +11,7 @@ export const UICreditCard = ({ cvv, cvvLabel = 'CVV', cardNumber, cardNumberLabe
11
11
  backfaceVisibility: 'hidden',
12
12
  transform: 'rotateY(180deg)',
13
13
  backgroundImage: `url(${backImageUrl})`,
14
- }, children: customBackContent !== null && customBackContent !== void 0 ? customBackContent : (_jsxs("div", { className: "flex flex-col justify-end flex-1 gap-2", children: [_jsx("div", { children: _jsxs("div", { className: "flex flex-col items-start", children: [_jsx("div", { className: `text-xs text-(--uikit-textSecondary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldLabel}`, children: cardholderNameLabel }), _jsx("div", { className: `text-base text-(--uikit-textPrimary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldValue}`, children: cardholderName })] }) }), _jsxs("div", { className: "flex flex-col items-start", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: `text-xs text-(--uikit-textSecondary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldLabel}`, children: cardNumberLabel }), enableCopy && _jsx(CopyButton, { value: cardNumber, className: classNames === null || classNames === void 0 ? void 0 : classNames.copyIcon })] }), _jsx("div", { className: `text-base text-(--uikit-textPrimary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldValue}`, children: cardNumber })] }), _jsxs("div", { className: "flex items-start gap-10", children: [expiryDate && (_jsxs("div", { className: "flex flex-col items-start", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-xs text-(--uikit-textSecondary)", children: expiryDateLabel }), enableCopy && (_jsx(CopyButton, { value: expiryDate, className: classNames === null || classNames === void 0 ? void 0 : classNames.copyIcon }))] }), _jsx("div", { className: `text-base text-(--uikit-textPrimary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldValue}`, children: expiryDate })] })), cvv && (_jsxs("div", { className: "flex flex-col items-start", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-xs text-(--uikit-textSecondary)", children: cvvLabel }), enableCopy && _jsx(CopyButton, { value: cvv, className: classNames === null || classNames === void 0 ? void 0 : classNames.copyIcon })] }), _jsx("div", { className: `text-base text-(--uikit-textPrimary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldValue}`, children: cvv })] }))] })] })) })] }) }));
14
+ }, children: customBackContent !== null && customBackContent !== void 0 ? customBackContent : (_jsxs("div", { className: "flex flex-col justify-end flex-1 gap-2", children: [_jsx("div", { children: _jsxs("div", { className: "flex flex-col items-start", children: [_jsx("div", { className: `text-xs text-(--uikit-textSecondary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldLabel}`, children: cardholderNameLabel }), _jsx("div", { className: `text-base text-(--uikit-textPrimary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldValue}`, children: cardholderName })] }) }), _jsxs("div", { className: "flex flex-col items-start", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: `text-xs text-(--uikit-textSecondary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldLabel}`, children: cardNumberLabel }), enableCopy && _jsx(CopyButton, { value: cardNumber, className: classNames === null || classNames === void 0 ? void 0 : classNames.copyIcon })] }), _jsx("div", { className: `text-base text-(--uikit-textPrimary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldValue}`, children: cardNumber })] }), _jsxs("div", { className: "flex items-start gap-10", children: [expiryDate && (_jsxs("div", { className: "flex flex-col items-start", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-xs text-(--uikit-textSecondary)", children: expiryDateLabel }), enableCopy && (_jsx(CopyButton, { value: expiryDate, className: classNames === null || classNames === void 0 ? void 0 : classNames.copyIcon }))] }), _jsx("div", { className: `text-base text-(--uikit-textPrimary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldValue}`, children: expiryDate })] })), cvv && (_jsxs("div", { className: "flex flex-col items-start", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-xs text-(--uikit-textSecondary)", children: cvvLabel }), enableCopy && _jsx(CopyButton, { value: cvv, className: classNames === null || classNames === void 0 ? void 0 : classNames.copyIcon })] }), _jsx("div", { className: `text-base text-(--uikit-textPrimary) ${classNames === null || classNames === void 0 ? void 0 : classNames.fieldValue}`, children: cvv })] }))] })] })) }), isBlocked && (_jsx("div", { className: `absolute inset-0 h-full w-full opacity-50 ${classNames === null || classNames === void 0 ? void 0 : classNames.blockedOverlay}`, style: {
15
+ zIndex: 10,
16
+ }, children: _jsx("img", { src: blockedImageUrlOverlay, alt: "Card blocked", className: "h-full w-full object-cover rounded-(--uikit-radius)" }) }))] }) }));
15
17
  };
@@ -8,3 +8,4 @@ export declare const WithCustomContent: Story;
8
8
  export declare const WithDefaultFlipState: Story;
9
9
  export declare const CopyDisabled: Story;
10
10
  export declare const ControlledFlipToggle: Story;
11
+ export declare const BlockedCard: Story;
@@ -31,9 +31,17 @@ export const WithDefaultFlipState = {
31
31
  export const CopyDisabled = {
32
32
  render: () => (_jsx("div", { style: { maxWidth: '450px', margin: '0 auto' }, children: _jsx(UICreditCard, { isFlipped: true, enableCopy: false, cardholderName: "No Copy", cardNumber: "4444 5555 6666 7777", expiryDate: "11/29", cvv: "000", frontImageUrl: "https://fastly.picsum.photos/id/349/200/300.jpg?hmac=gEjHZbjuKtdD2GOM-qQtuaA95TCvDUs6iVvKraQ94nU", backImageUrl: "https://fastly.picsum.photos/id/349/200/300.jpg?hmac=gEjHZbjuKtdD2GOM-qQtuaA95TCvDUs6iVvKraQ94nU" }) })),
33
33
  };
34
+ function ControlledFlipToggleExample() {
35
+ const [flipped, setFlipped] = useState(false);
36
+ return (_jsx("div", { style: { maxWidth: '450px', margin: '0 auto' }, children: _jsxs("div", { className: "flex flex-col items-center gap-4", children: [_jsx("button", { className: "px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition", onClick: () => setFlipped((prev) => !prev), children: flipped ? 'Show Front' : 'Show Back' }), _jsx(UICreditCard, { isFlipped: flipped, cardholderName: "Toggle Flip", cardNumber: "8888 9999 0000 1111", expiryDate: "08/28", cvv: "456", enableCopy: true, frontImageUrl: "https://fastly.picsum.photos/id/349/200/300.jpg?hmac=gEjHZbjuKtdD2GOM-qQtuaA95TCvDUs6iVvKraQ94nU", backImageUrl: "https://fastly.picsum.photos/id/349/200/300.jpg?hmac=gEjHZbjuKtdD2GOM-qQtuaA95TCvDUs6iVvKraQ94nU" })] }) }));
37
+ }
34
38
  export const ControlledFlipToggle = {
35
- render: () => {
36
- const [flipped, setFlipped] = useState(false);
37
- return (_jsx("div", { style: { maxWidth: '450px', margin: '0 auto' }, children: _jsxs("div", { className: "flex flex-col items-center gap-4", children: [_jsx("button", { className: "px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition", onClick: () => setFlipped((prev) => !prev), children: flipped ? 'Show Front' : 'Show Back' }), _jsx(UICreditCard, { isFlipped: flipped, cardholderName: "Toggle Flip", cardNumber: "8888 9999 0000 1111", expiryDate: "08/28", cvv: "456", enableCopy: true, frontImageUrl: "https://fastly.picsum.photos/id/349/200/300.jpg?hmac=gEjHZbjuKtdD2GOM-qQtuaA95TCvDUs6iVvKraQ94nU", backImageUrl: "https://fastly.picsum.photos/id/349/200/300.jpg?hmac=gEjHZbjuKtdD2GOM-qQtuaA95TCvDUs6iVvKraQ94nU" })] }) }));
38
- },
39
+ render: () => _jsx(ControlledFlipToggleExample, {}),
40
+ };
41
+ function BlockedCardExample() {
42
+ const [flipped, setFlipped] = useState(false);
43
+ return (_jsx("div", { style: { maxWidth: '450px', margin: '0 auto' }, children: _jsxs("div", { className: "flex flex-col items-center gap-4", children: [_jsx("button", { className: "px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition", onClick: () => setFlipped((prev) => !prev), children: flipped ? 'Show Front' : 'Show Back' }), _jsx(UICreditCard, { isFlipped: flipped, isBlocked: true, blockedImageUrlOverlay: "https://thumbs.dreamstime.com/b/frozen-background-12857463.jpg", cardholderName: "Blocked Card", cardNumber: "5555 6666 7777 8888", expiryDate: "10/27", cvv: "321", enableCopy: false, frontImageUrl: "https://fastly.picsum.photos/id/349/200/300.jpg?hmac=gEjHZbjuKtdD2GOM-qQtuaA95TCvDUs6iVvKraQ94nU", backImageUrl: "https://fastly.picsum.photos/id/349/200/300.jpg?hmac=gEjHZbjuKtdD2GOM-qQtuaA95TCvDUs6iVvKraQ94nU" })] }) }));
44
+ }
45
+ export const BlockedCard = {
46
+ render: () => _jsx(BlockedCardExample, {}),
39
47
  };
@@ -5,6 +5,8 @@ export interface UICreditCardProps {
5
5
  cardNumberLabel?: string;
6
6
  frontImageUrl: string;
7
7
  backImageUrl: string;
8
+ isBlocked?: boolean;
9
+ blockedImageUrlOverlay?: string;
8
10
  cvv?: string;
9
11
  cvvLabel?: string;
10
12
  expiryDate?: string;
@@ -17,6 +19,7 @@ export interface UICreditCardProps {
17
19
  fieldLabel?: string;
18
20
  fieldValue?: string;
19
21
  copyIcon?: string;
22
+ blockedOverlay?: string;
20
23
  };
21
24
  customFrontContent?: React.ReactNode;
22
25
  customBackContent?: React.ReactNode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eml-payments/ui-kit",
3
- "version": "1.3.2",
3
+ "version": "1.4.3",
4
4
  "private": false,
5
5
  "description": "ARLO UIKit",
6
6
  "homepage": "https://github.com/EML-Payments/arlo.npm.uikit#readme",
@@ -67,7 +67,7 @@
67
67
  "class-variance-authority": "^0.7.1",
68
68
  "clsx": "^2.1.1",
69
69
  "dayjs": "^1.11.19",
70
- "lucide-react": "^0.562.0",
70
+ "lucide-react": "^0.575.0",
71
71
  "prettier": "^3.6.2",
72
72
  "react": ">=18.0.0",
73
73
  "react-day-picker": "^9.13.0",
@@ -94,7 +94,7 @@
94
94
  "eslint-plugin-prettier": "^5.5.1",
95
95
  "eslint-plugin-react": "^7.37.5",
96
96
  "eslint-plugin-react-hooks": "^7.0.0",
97
- "eslint-plugin-react-refresh": "^0.4.20",
97
+ "eslint-plugin-react-refresh": "^0.5.0",
98
98
  "eslint-plugin-storybook": "^10.0.6",
99
99
  "husky": "^9.1.7",
100
100
  "lint-staged": "^16.1.2",