tc-dazzle-ui 1.11.2 → 1.11.4

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.
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import './TableGrid.css';
3
+ export interface TableColumn {
4
+ id: string;
5
+ header: string;
6
+ accessor: string;
7
+ width?: number | string;
8
+ sortable?: boolean;
9
+ filterable?: boolean;
10
+ filterType?: 'text' | 'dropdown';
11
+ filterPlaceholder?: string;
12
+ isLink?: boolean;
13
+ }
14
+ export interface TableRow {
15
+ id: string;
16
+ [key: string]: any;
17
+ }
18
+ export interface TableGridProps {
19
+ columns: TableColumn[];
20
+ data: TableRow[];
21
+ totalCount?: number;
22
+ currentPage?: number;
23
+ rowsPerPage?: number;
24
+ rowsPerPageOptions?: number[];
25
+ onRowClick?: (row: TableRow) => void;
26
+ onCellClick?: (row: TableRow, column: TableColumn) => void;
27
+ onEditClick?: (row: TableRow) => void;
28
+ onSort?: (columnId: string, direction: 'asc' | 'desc') => void;
29
+ onFilter?: (columnId: string, value: string) => void;
30
+ onSearch?: (value: string) => void;
31
+ onResetColumns?: () => void;
32
+ onClearFilters?: () => void;
33
+ onRowsPerPageChange?: (rowsPerPage: number) => void;
34
+ onPageChange?: (page: number) => void;
35
+ showEditColumn?: boolean;
36
+ showSearch?: boolean;
37
+ showResetColumns?: boolean;
38
+ showClearFilters?: boolean;
39
+ showPagination?: boolean;
40
+ entityName?: string;
41
+ className?: string;
42
+ }
43
+ export declare const TableGrid: React.FC<TableGridProps>;
44
+ export default TableGrid;
@@ -0,0 +1,2 @@
1
+ export { TableGrid } from './TableGrid';
2
+ export type { TableGridProps, TableColumn, TableRow } from './TableGrid';
@@ -10,3 +10,5 @@ export { Footer } from './Footer';
10
10
  export type { FooterProps, FooterLink } from './Footer';
11
11
  export { RightPanel } from './RightPanel';
12
12
  export type { RightPanelProps } from './RightPanel';
13
+ export { TableGrid } from './TableGrid';
14
+ export type { TableGridProps, TableColumn, TableRow } from './TableGrid';
package/dist/index.esm.js CHANGED
@@ -244,6 +244,8 @@ const ChevronUpIcon = (props) => (jsx(IconWrapper, { ...props, children: jsx("sv
244
244
  const CaretDownIcon = (props) => (jsx(IconWrapper, { ...props, children: jsx("svg", { viewBox: "0 0 10 6", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M5 6L0 0H10L5 6Z", fill: "currentColor" }) }) }));
245
245
  // Menu Icon (hamburger)
246
246
  const MenuIcon = (props) => (jsx(IconWrapper, { ...props, children: jsx("svg", { viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M3 18H21V16H3V18ZM3 13H21V11H3V13ZM3 6V8H21V6H3Z", fill: "currentColor" }) }) }));
247
+ // Edit Icon (pencil)
248
+ const EditIcon$1 = (props) => (jsx(IconWrapper, { ...props, children: jsx("svg", { viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M3 17.25V21H6.75L17.81 9.94L14.06 6.19L3 17.25ZM20.71 7.04C21.1 6.65 21.1 6.02 20.71 5.63L18.37 3.29C17.98 2.9 17.35 2.9 16.96 3.29L15.13 5.12L18.88 8.87L20.71 7.04Z", fill: "currentColor" }) }) }));
247
249
  // Settings Icon (gear)
248
250
  const SettingsIcon = (props) => (jsx(IconWrapper, { ...props, children: jsx("svg", { viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M19.14 12.94C19.18 12.64 19.2 12.33 19.2 12C19.2 11.68 19.18 11.36 19.13 11.06L21.16 9.48C21.34 9.34 21.39 9.07 21.28 8.87L19.36 5.55C19.24 5.33 18.99 5.26 18.77 5.33L16.38 6.29C15.88 5.91 15.35 5.59 14.76 5.35L14.4 2.81C14.36 2.57 14.16 2.4 13.92 2.4H10.08C9.84 2.4 9.65 2.57 9.61 2.81L9.25 5.35C8.66 5.59 8.12 5.92 7.63 6.29L5.24 5.33C5.02 5.25 4.77 5.33 4.65 5.55L2.74 8.87C2.62 9.08 2.66 9.34 2.86 9.48L4.89 11.06C4.84 11.36 4.8 11.69 4.8 12C4.8 12.31 4.82 12.64 4.87 12.94L2.84 14.52C2.66 14.66 2.61 14.93 2.72 15.13L4.64 18.45C4.76 18.67 5.01 18.74 5.23 18.67L7.62 17.71C8.12 18.09 8.65 18.41 9.24 18.65L9.6 21.19C9.65 21.43 9.84 21.6 10.08 21.6H13.92C14.16 21.6 14.36 21.43 14.39 21.19L14.75 18.65C15.34 18.41 15.88 18.09 16.37 17.71L18.76 18.67C18.98 18.75 19.23 18.67 19.35 18.45L21.27 15.13C21.39 14.91 21.34 14.66 21.15 14.52L19.14 12.94ZM12 15.6C10.02 15.6 8.4 13.98 8.4 12C8.4 10.02 10.02 8.4 12 8.4C13.98 8.4 15.6 10.02 15.6 12C15.6 13.98 13.98 15.6 12 15.6Z", fill: "currentColor" }) }) }));
249
251
 
@@ -445,10 +447,10 @@ const GlobalHeader = ({ tabs, activeTabId, onTabClick, onMenuClick, showMenuButt
445
447
  return (jsxs("header", { className: getHeaderClasses(), role: "navigation", children: [showMenuButton && (jsx(IconButton, { icon: jsx(MenuIcon, { size: "medium", color: "#ffffff" }), onClick: onMenuClick, ariaLabel: "Open menu", className: "tc-global-header__menu-button" })), jsx("nav", { className: "tc-global-header__tabs", role: "tablist", children: tabs.map((tab) => (jsx(Tab, { label: tab.label, isActive: activeTabId === tab.id, onClick: () => onTabClick === null || onTabClick === void 0 ? void 0 : onTabClick(tab) }, tab.id))) }), showPropertiesButton && (jsx("button", { className: `tc-global-header__properties-btn ${isPropertiesOpen ? 'tc-global-header__properties-btn--active' : ''}`, onClick: onPropertiesClick, "aria-label": "Toggle Properties Panel", children: "Properties" }))] }));
446
448
  };
447
449
 
448
- const MIN_WIDTH = 242;
449
- const MAX_WIDTH = 424;
450
- const DEFAULT_WIDTH = 242;
451
- const Sidebar = ({ sections, activeItemId, onItemClick, onSettingsClick, onExpandAllClick, onCollapseAllClick, onWidthChange, defaultWidth = DEFAULT_WIDTH, minWidth = MIN_WIDTH, maxWidth = MAX_WIDTH, className = '', }) => {
450
+ const MIN_WIDTH$1 = 242;
451
+ const MAX_WIDTH$1 = 424;
452
+ const DEFAULT_WIDTH$1 = 242;
453
+ const Sidebar = ({ sections, activeItemId, onItemClick, onSettingsClick, onExpandAllClick, onCollapseAllClick, onWidthChange, defaultWidth = DEFAULT_WIDTH$1, minWidth = MIN_WIDTH$1, maxWidth = MAX_WIDTH$1, className = '', }) => {
452
454
  const [expandedSections, setExpandedSections] = useState(() => {
453
455
  const initialExpanded = new Set();
454
456
  if (sections.length > 0) {
@@ -606,6 +608,129 @@ const Footer = ({ copyrightText = 'Copyright © 2024 Mitratech Holdings, Inc. Al
606
608
  return (jsxs("footer", { className: getFooterClasses(), children: [jsx("div", { className: "tc-footer__copyright", children: copyrightText }), jsxs("div", { className: "tc-footer__right", children: [links.length > 0 && (jsx("div", { className: "tc-footer__links", children: links.map(renderLink) })), showLogo && (jsx("div", { className: "tc-footer__logo", children: jsx(MitratechLogo, {}) }))] })] }));
607
609
  };
608
610
 
611
+ const MIN_WIDTH = 300;
612
+ const MAX_WIDTH = 600;
613
+ const DEFAULT_WIDTH = 400;
614
+ const RightPanel = ({ onWidthChange, onToggle, defaultWidth = DEFAULT_WIDTH, minWidth = MIN_WIDTH, maxWidth = MAX_WIDTH, defaultOpen = true, className = '', children, }) => {
615
+ const [isOpen, setIsOpen] = useState(defaultOpen);
616
+ const [panelWidth, setPanelWidth] = useState(defaultWidth);
617
+ const [isResizing, setIsResizing] = useState(false);
618
+ const panelRef = useRef(null);
619
+ const startXRef = useRef(0);
620
+ const startWidthRef = useRef(0);
621
+ const handleMouseDown = useCallback((e) => {
622
+ e.preventDefault();
623
+ setIsResizing(true);
624
+ startXRef.current = e.clientX;
625
+ startWidthRef.current = panelWidth;
626
+ }, [panelWidth]);
627
+ const handleMouseMove = useCallback((e) => {
628
+ if (!isResizing)
629
+ return;
630
+ // For right panel, dragging left increases width, dragging right decreases
631
+ const delta = startXRef.current - e.clientX;
632
+ let newWidth = startWidthRef.current + delta;
633
+ // Clamp to min/max
634
+ newWidth = Math.max(minWidth, Math.min(maxWidth, newWidth));
635
+ setPanelWidth(newWidth);
636
+ onWidthChange === null || onWidthChange === void 0 ? void 0 : onWidthChange(newWidth);
637
+ }, [isResizing, minWidth, maxWidth, onWidthChange]);
638
+ const handleMouseUp = useCallback(() => {
639
+ setIsResizing(false);
640
+ }, []);
641
+ useEffect(() => {
642
+ if (isResizing) {
643
+ document.addEventListener('mousemove', handleMouseMove);
644
+ document.addEventListener('mouseup', handleMouseUp);
645
+ document.body.style.cursor = 'col-resize';
646
+ document.body.style.userSelect = 'none';
647
+ }
648
+ return () => {
649
+ document.removeEventListener('mousemove', handleMouseMove);
650
+ document.removeEventListener('mouseup', handleMouseUp);
651
+ document.body.style.cursor = '';
652
+ document.body.style.userSelect = '';
653
+ };
654
+ }, [isResizing, handleMouseMove, handleMouseUp]);
655
+ const handleToggle = () => {
656
+ const newState = !isOpen;
657
+ setIsOpen(newState);
658
+ onToggle === null || onToggle === void 0 ? void 0 : onToggle(newState);
659
+ };
660
+ // Add/remove body class and set CSS variable for panel width
661
+ useEffect(() => {
662
+ if (isOpen) {
663
+ document.body.classList.add('tc-right-panel-open');
664
+ document.documentElement.style.setProperty('--tc-right-panel-width', `${panelWidth}px`);
665
+ }
666
+ else {
667
+ document.body.classList.remove('tc-right-panel-open');
668
+ document.documentElement.style.setProperty('--tc-right-panel-width', '0px');
669
+ }
670
+ return () => {
671
+ document.body.classList.remove('tc-right-panel-open');
672
+ document.documentElement.style.removeProperty('--tc-right-panel-width');
673
+ };
674
+ }, [isOpen, panelWidth]);
675
+ const getPanelClasses = () => {
676
+ const classes = ['tc-right-panel'];
677
+ if (className)
678
+ classes.push(className);
679
+ if (isResizing)
680
+ classes.push('tc-right-panel--resizing');
681
+ if (!isOpen)
682
+ classes.push('tc-right-panel--collapsed');
683
+ return classes.join(' ');
684
+ };
685
+ const panelStyle = {
686
+ width: panelWidth,
687
+ minWidth: minWidth,
688
+ maxWidth: maxWidth,
689
+ };
690
+ return (jsxs(Fragment, { children: [jsx("button", { type: "button", className: `tc-right-panel__toggle-btn ${isOpen ? 'tc-right-panel__toggle-btn--open' : ''}`, onClick: handleToggle, "aria-label": isOpen ? 'Close panel' : 'Open panel', "aria-expanded": isOpen, children: jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "tc-right-panel__toggle-icon", children: jsx("path", { d: isOpen ? "M10 12L6 8L10 4" : "M6 4L10 8L6 12", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), isOpen && (jsxs("aside", { ref: panelRef, className: getPanelClasses(), style: panelStyle, children: [jsx("div", { className: "tc-right-panel__resize-handle", onMouseDown: handleMouseDown, title: "Drag to resize" }), jsx("div", { className: "tc-right-panel__content", children: children })] }))] }));
691
+ };
692
+
693
+ const TableGrid = ({ columns, data, totalCount, currentPage = 1, rowsPerPage = 10, rowsPerPageOptions = [10, 25, 50, 100], onRowClick, onCellClick, onEditClick, onSort, onFilter, onSearch, onResetColumns, onClearFilters, onRowsPerPageChange, onPageChange, showEditColumn = true, showSearch = true, showResetColumns = true, showClearFilters = true, showPagination = true, entityName = 'Items', className = '', }) => {
694
+ const [searchValue, setSearchValue] = useState('');
695
+ const [filterValues, setFilterValues] = useState({});
696
+ const [sortColumn, setSortColumn] = useState(null);
697
+ const [sortDirection, setSortDirection] = useState('asc');
698
+ const [isRowsDropdownOpen, setIsRowsDropdownOpen] = useState(false);
699
+ const total = totalCount !== null && totalCount !== void 0 ? totalCount : data.length;
700
+ const startIndex = (currentPage - 1) * rowsPerPage + 1;
701
+ const endIndex = Math.min(currentPage * rowsPerPage, total);
702
+ const handleSearchChange = (e) => {
703
+ setSearchValue(e.target.value);
704
+ onSearch === null || onSearch === void 0 ? void 0 : onSearch(e.target.value);
705
+ };
706
+ const handleFilterChange = (columnId, value) => {
707
+ setFilterValues(prev => ({ ...prev, [columnId]: value }));
708
+ onFilter === null || onFilter === void 0 ? void 0 : onFilter(columnId, value);
709
+ };
710
+ const handleSort = (columnId) => {
711
+ const newDirection = sortColumn === columnId && sortDirection === 'asc' ? 'desc' : 'asc';
712
+ setSortColumn(columnId);
713
+ setSortDirection(newDirection);
714
+ onSort === null || onSort === void 0 ? void 0 : onSort(columnId, newDirection);
715
+ };
716
+ const handleRowsPerPageChange = (value) => {
717
+ setIsRowsDropdownOpen(false);
718
+ onRowsPerPageChange === null || onRowsPerPageChange === void 0 ? void 0 : onRowsPerPageChange(value);
719
+ };
720
+ const renderSortIcon = (columnId) => {
721
+ return (jsx("span", { className: "tc-table-grid__sort-icon", children: jsxs("svg", { width: "19", height: "19", viewBox: "0 0 19 19", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsx("path", { d: "M9.5 4L13 8H6L9.5 4Z", fill: sortColumn === columnId && sortDirection === 'asc' ? '#001a35' : '#999' }), jsx("path", { d: "M9.5 15L6 11H13L9.5 15Z", fill: sortColumn === columnId && sortDirection === 'desc' ? '#001a35' : '#999' })] }) }));
722
+ };
723
+ return (jsxs("div", { className: `tc-table-grid ${className}`.trim(), children: [jsxs("div", { className: "tc-table-grid__toolbar", children: [jsx("div", { className: "tc-table-grid__info", children: jsxs("span", { className: "tc-table-grid__count", children: [entityName, " ", startIndex, " - ", endIndex, " of ", total] }) }), jsxs("div", { className: "tc-table-grid__actions", children: [showSearch && (jsx("div", { className: "tc-table-grid__search", children: jsx("input", { type: "text", placeholder: "Search", value: searchValue, onChange: handleSearchChange, className: "tc-table-grid__search-input" }) })), showResetColumns && (jsx("button", { type: "button", className: "tc-table-grid__button", onClick: onResetColumns, children: "Reset Columns" })), showClearFilters && (jsx("button", { type: "button", className: "tc-table-grid__button", onClick: onClearFilters, children: "Clear All Filters" }))] })] }), jsx("div", { className: "tc-table-grid__table-wrapper", children: jsxs("table", { className: "tc-table-grid__table", children: [jsx("thead", { className: "tc-table-grid__header", children: jsxs("tr", { className: "tc-table-grid__header-row", children: [showEditColumn && (jsx("th", { className: "tc-table-grid__header-cell tc-table-grid__header-cell--edit", children: jsx("div", { className: "tc-table-grid__header-content", children: jsx("span", { className: "tc-table-grid__header-text", children: "Edit" }) }) })), columns.map((column) => (jsx("th", { className: "tc-table-grid__header-cell", style: column.width ? { width: column.width } : undefined, children: jsxs("div", { className: "tc-table-grid__header-content", children: [jsxs("div", { className: "tc-table-grid__header-title", onClick: () => column.sortable !== false && handleSort(column.id), children: [jsx("span", { className: "tc-table-grid__header-text", children: column.header }), column.sortable !== false && renderSortIcon(column.id)] }), column.filterable !== false && (jsx("div", { className: "tc-table-grid__filter", children: column.filterType === 'dropdown' ? (jsx("div", { className: "tc-table-grid__filter-dropdown", children: jsx("select", { value: filterValues[column.id] || '', onChange: (e) => handleFilterChange(column.id, e.target.value), className: "tc-table-grid__filter-select", children: jsx("option", { value: "", children: "All" }) }) })) : (jsx("input", { type: "text", placeholder: column.filterPlaceholder || `Search for ${column.header}`, value: filterValues[column.id] || '', onChange: (e) => handleFilterChange(column.id, e.target.value), className: "tc-table-grid__filter-input" })) }))] }) }, column.id)))] }) }), jsx("tbody", { className: "tc-table-grid__body", children: data.map((row) => (jsxs("tr", { className: "tc-table-grid__row", onClick: () => onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row), children: [showEditColumn && (jsx("td", { className: "tc-table-grid__cell tc-table-grid__cell--edit", children: jsx("button", { type: "button", className: "tc-table-grid__edit-button", onClick: (e) => {
724
+ e.stopPropagation();
725
+ onEditClick === null || onEditClick === void 0 ? void 0 : onEditClick(row);
726
+ }, "aria-label": "Edit row", children: jsx(EditIcon$1, { size: "small", color: "#0067d2" }) }) })), columns.map((column) => (jsx("td", { className: `tc-table-grid__cell ${column.isLink ? 'tc-table-grid__cell--link' : ''}`, onClick: (e) => {
727
+ if (column.isLink) {
728
+ e.stopPropagation();
729
+ onCellClick === null || onCellClick === void 0 ? void 0 : onCellClick(row, column);
730
+ }
731
+ }, children: row[column.accessor] }, column.id)))] }, row.id))) })] }) }), showPagination && (jsxs("div", { className: "tc-table-grid__pagination", children: [jsxs("span", { className: "tc-table-grid__pagination-info", children: [entityName, " ", startIndex, " - ", endIndex, " of ", total] }), jsxs("div", { className: "tc-table-grid__rows-per-page", children: [jsxs("div", { className: "tc-table-grid__rows-dropdown", children: [jsxs("button", { type: "button", className: "tc-table-grid__rows-button", onClick: () => setIsRowsDropdownOpen(!isRowsDropdownOpen), children: [jsx("span", { children: rowsPerPage }), jsx(ChevronDownIcon, { size: "small" })] }), isRowsDropdownOpen && (jsx("ul", { className: "tc-table-grid__rows-menu", children: rowsPerPageOptions.map((option) => (jsx("li", { children: jsx("button", { type: "button", className: "tc-table-grid__rows-option", onClick: () => handleRowsPerPageChange(option), children: option }) }, option))) }))] }), jsx("span", { className: "tc-table-grid__rows-label", children: "rows per page" })] })] }))] }));
732
+ };
733
+
609
734
  const Layout = ({ header, sidebar, main, footer, actions, rightPanel, showSidebar = true, sidebarPosition = 'left', sidebarWidth = 280, rightPanelWidth = 320, maxContentWidth = '100%', className = '', }) => {
610
735
  const headerRef = useRef(null);
611
736
  const [headerHeight, setHeaderHeight] = useState(0);
@@ -848,5 +973,5 @@ function registerWebComponents() {
848
973
  // Auto-register when loaded in browser
849
974
  registerWebComponents();
850
975
 
851
- export { Button, CaretDownIcon, ChevronDownIcon, ChevronUpIcon, DropdownMenu, FilterDropdown, Footer, GlobalHeader, GlobalSearch, HeaderMenu, IconButton, InfoIcon, Input, Layout, Logo, MainHeader, PageHeader, SearchIcon, Sidebar, TCButton, TCInput, Tab, defaultIcons, registerWebComponents };
976
+ export { Button, CaretDownIcon, ChevronDownIcon, ChevronUpIcon, DropdownMenu, FilterDropdown, Footer, GlobalHeader, GlobalSearch, HeaderMenu, IconButton, InfoIcon, Input, Layout, Logo, MainHeader, PageHeader, RightPanel, SearchIcon, Sidebar, TCButton, TCInput, Tab, TableGrid, defaultIcons, registerWebComponents };
852
977
  //# sourceMappingURL=index.esm.js.map