all-purpose-table 1.0.11 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
- import { useState, useRef, useMemo, useEffect, Fragment as Fragment$1 } from 'react';
1
+ import { useState, useRef, useMemo, useEffect, useLayoutEffect, Fragment as Fragment$1 } from 'react';
2
+ import { createPortal } from 'react-dom';
2
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
4
 
4
5
  // #style-inject:#style-inject
@@ -24,7 +25,239 @@ function styleInject(css, { insertAt } = {}) {
24
25
  }
25
26
 
26
27
  // src/styles.css
27
- styleInject(":root {\n --apt-color-primary: #371f1f;\n --apt-color-border: #d1d5db;\n --apt-color-bg: white;\n --apt-color-bg-secondary: #e5e7eb;\n --apt-color-bg-hover: #f3f4f6;\n --apt-color-text: #1f2937;\n --apt-color-text-muted: #6b7280;\n --apt-color-text-muted-light: #9ca3af;\n --apt-color-accent: #9333ea;\n --apt-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);\n --apt-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);\n --apt-resizer-color: #bbb;\n --apt-resizer-hover-color: #888;\n --apt-th-sortable-hover: #d1d5db;\n --apt-btn-bg: white;\n --apt-btn-hover-bg: #d1d5db;\n}\n@media (prefers-color-scheme: dark) {\n :root {\n --apt-color-primary: #eee;\n --apt-color-border: #333;\n --apt-color-bg: #1e1e1e;\n --apt-color-bg-secondary: #333;\n --apt-color-bg-hover: rgba(126, 126, 126, 0.15);\n --apt-color-text: #eee;\n --apt-color-text-muted: #d1d5db;\n --apt-color-text-muted-light: #444;\n --apt-color-accent: #a855f7;\n --apt-resizer-color: #666;\n --apt-resizer-hover-color: #999;\n --apt-th-sortable-hover: #444;\n --apt-btn-bg: #444;\n --apt-btn-hover-bg: #555;\n }\n}\nhtml.dark,\n.dark,\n:root.dark {\n --apt-color-primary: #eee;\n --apt-color-border: #333;\n --apt-color-bg: #1e1e1e;\n --apt-color-bg-secondary: #333;\n --apt-color-bg-hover: rgba(126, 126, 126, 0.15);\n --apt-color-text: #eee;\n --apt-color-text-muted: #d1d5db;\n --apt-color-text-muted-light: #444;\n --apt-color-accent: #a855f7;\n --apt-resizer-color: #666;\n --apt-resizer-hover-color: #999;\n --apt-th-sortable-hover: #444;\n --apt-btn-bg: #444;\n --apt-btn-hover-bg: #555;\n}\nhtml.light,\n.light,\n:root.light {\n --apt-color-primary: #371f1f;\n --apt-color-border: #d1d5db;\n --apt-color-bg: white;\n --apt-color-bg-secondary: #e5e7eb;\n --apt-color-bg-hover: #f3f4f6;\n --apt-color-text: #1f2937;\n --apt-color-text-muted: #6b7280;\n --apt-color-text-muted-light: #9ca3af;\n --apt-color-accent: #9333ea;\n --apt-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);\n --apt-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);\n --apt-resizer-color: #bbb;\n --apt-resizer-hover-color: #888;\n --apt-th-sortable-hover: #d1d5db;\n --apt-btn-bg: white;\n --apt-btn-hover-bg: #d1d5db;\n}\n.apt-table-container {\n color: var(--apt-color-text);\n border-radius: 6px;\n margin: 0;\n padding: 0;\n border: 1px solid var(--apt-color-border);\n background-color: var(--apt-color-bg);\n box-shadow: var(--apt-shadow);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.apt-empty-state {\n flex-grow: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 48px 0;\n color: var(--apt-color-text-muted-light);\n}\n.apt-scroll-area {\n flex-grow: 1;\n overflow: auto;\n}\n.apt-table {\n width: 100%;\n text-align: left;\n font-size: 0.75rem;\n table-layout: fixed;\n border-collapse: collapse;\n border-spacing: 0;\n margin: 0;\n padding: 0;\n}\n.apt-thead {\n position: sticky;\n top: 0;\n background-color: var(--apt-color-bg-secondary);\n z-index: 10;\n}\n.apt-th {\n position: relative;\n padding: 12px 8px;\n border: none;\n}\n.apt-th-sortable {\n cursor: pointer;\n}\n.apt-th-sortable:hover {\n background-color: var(--apt-th-sortable-hover);\n}\n.apt-th-content {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.apt-resizer {\n position: absolute;\n right: 0;\n top: 4px;\n height: 80%;\n width: 3px;\n border-radius: 2px;\n cursor: col-resize;\n user-select: none;\n touch-action: none;\n background-color: var(--apt-resizer-color);\n}\n.apt-resizer:hover,\n.apt-th:hover .apt-resizer {\n background-color: var(--apt-resizer-hover-color);\n}\n.apt-tbody {\n border: none;\n}\n.apt-tbody tr {\n border: none;\n}\n.apt-row {\n transition: background-color 0.15s;\n}\n.apt-row:hover {\n background-color: var(--apt-color-bg-hover);\n}\n.apt-row-expanded {\n background-color: var(--apt-color-bg-hover);\n}\n.apt-td {\n padding: 4px 8px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border: none;\n}\n.apt-td-actions {\n padding: 4px 8px;\n border: none;\n}\n.apt-footer {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n align-items: center;\n padding: 8px;\n background-color: var(--apt-color-bg-secondary);\n}\n.apt-footer-left {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.apt-footer-center {\n justify-self: center;\n font-size: 0.875rem;\n color: var(--apt-color-text);\n}\n.apt-footer-right {\n justify-self: end;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.apt-rows-label {\n font-size: 0.75rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--apt-color-text-muted);\n}\n.apt-rows-select {\n padding: 4px 8px;\n font-size: 0.875rem;\n border-radius: 4px;\n background-color: var(--apt-btn-bg);\n color: var(--apt-color-text);\n border: 1px solid var(--apt-color-border);\n}\n.apt-btn {\n padding: 4px 12px;\n font-size: 0.875rem;\n border-radius: 4px;\n background-color: var(--apt-btn-bg);\n color: var(--apt-color-text);\n border: 0;\n cursor: pointer;\n transition: background-color 0.15s;\n}\n.apt-btn:hover:not(:disabled) {\n background-color: var(--apt-btn-hover-bg);\n}\n.apt-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.apt-sort-icon {\n display: inline-block;\n margin-left: 4px;\n width: 14px;\n height: 14px;\n opacity: 0.3;\n}\n.apt-sort-icon-active {\n opacity: 1;\n}\n.apt-column-toggle-container {\n position: relative;\n}\n.apt-column-toggle-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n border-radius: 8px;\n border: 1px solid var(--apt-color-border);\n background-color: var(--apt-color-bg-hover);\n padding: 8px 12px;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--apt-color-primary);\n box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);\n cursor: pointer;\n transition: background-color 0.15s;\n}\n.apt-column-toggle-btn:hover {\n background-color: var(--apt-color-bg-secondary);\n}\n.apt-column-toggle-btn:focus {\n outline: none;\n}\n.apt-column-toggle-icon {\n font-size: 1.125rem;\n}\n.apt-column-toggle-count {\n font-size: 0.75rem;\n opacity: 0.7;\n}\n.apt-column-toggle-menu {\n position: absolute;\n right: 0;\n margin-top: 8px;\n width: 288px;\n border-radius: 8px;\n border: 1px solid var(--apt-color-border);\n background-color: var(--apt-color-bg);\n box-shadow: var(--apt-shadow-lg);\n z-index: 50;\n max-height: 384px;\n overflow-y: auto;\n}\n.apt-column-toggle-menu-inner {\n padding: 12px;\n}\n.apt-column-toggle-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n border-bottom: 1px solid var(--apt-color-border);\n padding-bottom: 8px;\n}\n.apt-column-toggle-title {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--apt-color-primary);\n}\n.apt-column-toggle-select-all {\n font-size: 0.75rem;\n color: var(--apt-color-accent);\n background: none;\n border: none;\n cursor: pointer;\n text-decoration: none;\n}\n.apt-column-toggle-select-all:hover {\n text-decoration: underline;\n}\n.apt-column-toggle-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.apt-column-toggle-item {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n padding: 6px 8px;\n border-radius: 4px;\n transition: background-color 0.15s;\n}\n.apt-column-toggle-item:hover {\n background-color: var(--apt-color-bg-hover);\n}\n.apt-column-toggle-checkbox {\n width: 16px;\n height: 16px;\n color: var(--apt-color-accent);\n border-radius: 12px;\n cursor: pointer;\n accent-color: var(--apt-color-accent);\n}\n.apt-column-toggle-label {\n font-size: 0.875rem;\n color: var(--apt-color-primary);\n flex: 1;\n}\n.apt-flex {\n display: flex;\n}\n.apt-items-center {\n align-items: center;\n}\n.apt-gap-2 {\n gap: 8px;\n}\n");
28
+ styleInject(':root {\n --apt-color-primary: #371f1f;\n --apt-color-border: #d1d5db;\n --apt-color-border-subtle: #eceff3;\n --apt-color-bg: white;\n --apt-color-bg-secondary: #e5e7eb;\n --apt-color-bg-hover: #f3f4f6;\n --apt-color-row-stripe: #f9fafb;\n --apt-color-text: #1f2937;\n --apt-color-text-muted: #6b7280;\n --apt-color-text-muted-light: #9ca3af;\n --apt-color-accent: #9333ea;\n --apt-color-accent-soft: rgba(147, 51, 234, 0.12);\n --apt-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);\n --apt-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);\n --apt-resizer-color: #bbb;\n --apt-resizer-hover-color: #888;\n --apt-th-sortable-hover: #d1d5db;\n --apt-btn-bg: white;\n --apt-btn-hover-bg: #d1d5db;\n}\n@media (prefers-color-scheme: dark) {\n :root {\n --apt-color-primary: #eee;\n --apt-color-border: #333;\n --apt-color-border-subtle: #2a2a2a;\n --apt-color-bg: #1e1e1e;\n --apt-color-bg-secondary: #333;\n --apt-color-bg-hover: rgba(126, 126, 126, 0.15);\n --apt-color-row-stripe: rgba(255, 255, 255, 0.03);\n --apt-color-text: #eee;\n --apt-color-text-muted: #d1d5db;\n --apt-color-text-muted-light: #444;\n --apt-color-accent: #a855f7;\n --apt-color-accent-soft: rgba(168, 85, 247, 0.2);\n --apt-resizer-color: #666;\n --apt-resizer-hover-color: #999;\n --apt-th-sortable-hover: #444;\n --apt-btn-bg: #444;\n --apt-btn-hover-bg: #555;\n }\n}\nhtml.dark,\n.dark,\n:root.dark {\n --apt-color-primary: #eee;\n --apt-color-border: #333;\n --apt-color-border-subtle: #2a2a2a;\n --apt-color-bg: #1e1e1e;\n --apt-color-bg-secondary: #333;\n --apt-color-bg-hover: rgba(126, 126, 126, 0.15);\n --apt-color-row-stripe: rgba(255, 255, 255, 0.03);\n --apt-color-text: #eee;\n --apt-color-text-muted: #d1d5db;\n --apt-color-text-muted-light: #444;\n --apt-color-accent: #a855f7;\n --apt-color-accent-soft: rgba(168, 85, 247, 0.2);\n --apt-resizer-color: #666;\n --apt-resizer-hover-color: #999;\n --apt-th-sortable-hover: #444;\n --apt-btn-bg: #444;\n --apt-btn-hover-bg: #555;\n}\nhtml.light,\n.light,\n:root.light {\n --apt-color-primary: #371f1f;\n --apt-color-border: #d1d5db;\n --apt-color-border-subtle: #eceff3;\n --apt-color-bg: white;\n --apt-color-bg-secondary: #e5e7eb;\n --apt-color-bg-hover: #f3f4f6;\n --apt-color-row-stripe: #f9fafb;\n --apt-color-text: #1f2937;\n --apt-color-text-muted: #6b7280;\n --apt-color-text-muted-light: #9ca3af;\n --apt-color-accent: #9333ea;\n --apt-color-accent-soft: rgba(147, 51, 234, 0.12);\n --apt-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);\n --apt-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);\n --apt-resizer-color: #bbb;\n --apt-resizer-hover-color: #888;\n --apt-th-sortable-hover: #d1d5db;\n --apt-btn-bg: white;\n --apt-btn-hover-bg: #d1d5db;\n}\n.apt-table-container {\n color: var(--apt-color-text);\n border-radius: 6px;\n margin: 0;\n padding: 0;\n border: 1px solid var(--apt-color-border);\n background-color: var(--apt-color-bg);\n box-shadow: var(--apt-shadow);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.apt-empty-state {\n flex-grow: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 48px 0;\n color: var(--apt-color-text-muted-light);\n}\n.apt-scroll-area {\n flex-grow: 1;\n overflow: auto;\n}\n.apt-no-matches {\n text-align: center;\n padding: 32px 8px;\n color: var(--apt-color-text-muted-light);\n white-space: normal;\n}\n.apt-table {\n width: 100%;\n text-align: left;\n font-size: 0.75rem;\n table-layout: fixed;\n border-collapse: collapse;\n border-spacing: 0;\n margin: 0;\n padding: 0;\n}\n.apt-thead {\n position: sticky;\n top: 0;\n background-color: var(--apt-color-bg-secondary);\n z-index: 10;\n}\n.apt-th {\n position: relative;\n padding: 10px 12px;\n border: none;\n border-bottom: 2px solid var(--apt-color-border);\n font-weight: 600;\n font-size: 0.7rem;\n letter-spacing: 0.03em;\n text-transform: uppercase;\n color: var(--apt-color-text-muted);\n user-select: none;\n}\n.apt-th-sortable {\n cursor: pointer;\n}\n.apt-th-sortable:hover {\n background-color: var(--apt-th-sortable-hover);\n}\n.apt-th-content {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n gap: 2px;\n}\n.apt-th-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.apt-resizer {\n position: absolute;\n right: -3px;\n top: 0;\n height: 100%;\n width: 7px;\n cursor: col-resize;\n user-select: none;\n touch-action: none;\n z-index: 2;\n background-color: transparent;\n}\n.apt-resizer::after {\n content: "";\n position: absolute;\n right: 3px;\n top: 20%;\n height: 60%;\n width: 2px;\n border-radius: 2px;\n background-color: transparent;\n transition: background-color 0.15s;\n}\n.apt-th:hover .apt-resizer::after {\n background-color: var(--apt-resizer-color);\n}\n.apt-resizer:hover::after {\n background-color: var(--apt-color-accent);\n}\n.apt-th-spacer,\n.apt-td-spacer {\n padding: 0;\n border: none;\n}\n.apt-tbody {\n border: none;\n}\n.apt-tbody tr {\n border: none;\n}\n.apt-row {\n transition: background-color 0.15s;\n}\n.apt-row:hover {\n background-color: var(--apt-color-bg-hover);\n}\n.apt-row-expanded {\n background-color: var(--apt-color-bg-hover);\n}\n.apt-td {\n padding: 6px 12px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border: none;\n}\n.apt-td-actions {\n padding: 6px 12px;\n border: none;\n}\n.apt-footer {\n display: grid;\n grid-template-columns: 1fr 1fr 1fr;\n align-items: center;\n padding: 8px;\n background-color: var(--apt-color-bg-secondary);\n}\n.apt-footer-left {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.apt-footer-center {\n justify-self: center;\n font-size: 0.875rem;\n color: var(--apt-color-text);\n}\n.apt-footer-right {\n justify-self: end;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.apt-rows-label {\n font-size: 0.75rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--apt-color-text-muted);\n}\n.apt-rows-select {\n padding: 4px 8px;\n font-size: 0.875rem;\n border-radius: 4px;\n background-color: var(--apt-btn-bg);\n color: var(--apt-color-text);\n border: 1px solid var(--apt-color-border);\n}\n.apt-btn {\n padding: 4px 12px;\n font-size: 0.875rem;\n border-radius: 4px;\n background-color: var(--apt-btn-bg);\n color: var(--apt-color-text);\n border: 0;\n cursor: pointer;\n transition: background-color 0.15s;\n}\n.apt-btn:hover:not(:disabled) {\n background-color: var(--apt-btn-hover-bg);\n}\n.apt-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.apt-sort-icon {\n display: inline-block;\n margin-left: 4px;\n width: 14px;\n height: 14px;\n opacity: 0.3;\n}\n.apt-sort-icon-active {\n opacity: 1;\n}\n.apt-column-toggle-container {\n position: relative;\n}\n.apt-column-toggle-btn {\n display: flex;\n align-items: center;\n gap: 8px;\n border-radius: 8px;\n border: 1px solid var(--apt-color-border);\n background-color: var(--apt-color-bg-hover);\n padding: 8px 12px;\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--apt-color-primary);\n box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);\n cursor: pointer;\n transition: background-color 0.15s;\n}\n.apt-column-toggle-btn:hover {\n background-color: var(--apt-color-bg-secondary);\n}\n.apt-column-toggle-btn:focus {\n outline: none;\n}\n.apt-column-toggle-icon {\n font-size: 1.125rem;\n}\n.apt-column-toggle-count {\n font-size: 0.75rem;\n opacity: 0.7;\n}\n.apt-column-toggle-menu {\n position: absolute;\n right: 0;\n margin-top: 8px;\n width: 288px;\n border-radius: 8px;\n border: 1px solid var(--apt-color-border);\n background-color: var(--apt-color-bg);\n box-shadow: var(--apt-shadow-lg);\n z-index: 50;\n max-height: 384px;\n overflow-y: auto;\n}\n.apt-column-toggle-menu-inner {\n padding: 12px;\n}\n.apt-column-toggle-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 12px;\n border-bottom: 1px solid var(--apt-color-border);\n padding-bottom: 8px;\n}\n.apt-column-toggle-title {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--apt-color-primary);\n}\n.apt-column-toggle-select-all {\n font-size: 0.75rem;\n color: var(--apt-color-accent);\n background: none;\n border: none;\n cursor: pointer;\n text-decoration: none;\n}\n.apt-column-toggle-select-all:hover {\n text-decoration: underline;\n}\n.apt-column-toggle-list {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.apt-column-toggle-item {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n padding: 6px 8px;\n border-radius: 4px;\n transition: background-color 0.15s;\n}\n.apt-column-toggle-item:hover {\n background-color: var(--apt-color-bg-hover);\n}\n.apt-column-toggle-checkbox {\n width: 16px;\n height: 16px;\n color: var(--apt-color-accent);\n border-radius: 12px;\n cursor: pointer;\n accent-color: var(--apt-color-accent);\n}\n.apt-column-toggle-label {\n font-size: 0.875rem;\n color: var(--apt-color-primary);\n flex: 1;\n}\n.apt-striped .apt-row.apt-row-alt {\n background-color: var(--apt-color-row-stripe);\n}\n.apt-dividers .apt-tbody .apt-row > td {\n border-bottom: 1px solid var(--apt-color-border-subtle);\n}\n.apt-bordered .apt-th:not(.apt-th-spacer),\n.apt-bordered .apt-td:not(.apt-td-spacer) {\n border-right: 1px solid var(--apt-color-border-subtle);\n}\n.apt-bordered .apt-th:not(.apt-th-spacer) {\n border-right-color: var(--apt-color-border);\n}\n.apt-compact .apt-th {\n padding: 6px 8px;\n}\n.apt-compact .apt-td,\n.apt-compact .apt-td-actions {\n padding: 2px 8px;\n}\n.apt-row:hover,\n.apt-striped .apt-row.apt-row-alt:hover {\n background-color: var(--apt-color-bg-hover);\n}\n.apt-filter-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-left: auto;\n padding: 2px;\n width: 18px;\n height: 18px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--apt-color-text-muted-light);\n cursor: pointer;\n opacity: 0.6;\n transition:\n background-color 0.15s,\n color 0.15s,\n opacity 0.15s;\n}\n.apt-th:hover .apt-filter-btn {\n opacity: 1;\n}\n.apt-filter-btn:hover {\n background-color: var(--apt-color-accent-soft);\n color: var(--apt-color-accent);\n}\n.apt-filter-btn-active {\n opacity: 1;\n color: var(--apt-color-accent);\n background-color: var(--apt-color-accent-soft);\n}\n.apt-filter-icon {\n display: block;\n width: 12px;\n height: 12px;\n}\n.apt-filter-popover {\n position: fixed;\n z-index: 1000;\n display: flex;\n flex-direction: column;\n border: 1px solid var(--apt-color-border);\n border-radius: 8px;\n background-color: var(--apt-color-bg);\n color: var(--apt-color-text);\n box-shadow: var(--apt-shadow-lg);\n padding: 8px;\n font-size: 0.8125rem;\n text-transform: none;\n letter-spacing: normal;\n font-weight: 400;\n}\n.apt-filter-sort-row {\n display: flex;\n gap: 6px;\n margin-bottom: 8px;\n}\n.apt-filter-sort-btn {\n flex: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 4px;\n padding: 5px 8px;\n border: 1px solid var(--apt-color-border);\n border-radius: 6px;\n background-color: var(--apt-btn-bg);\n color: var(--apt-color-text);\n font-size: 0.75rem;\n cursor: pointer;\n transition: background-color 0.15s, border-color 0.15s;\n}\n.apt-filter-sort-btn:hover {\n background-color: var(--apt-color-bg-hover);\n}\n.apt-filter-sort-btn-active {\n border-color: var(--apt-color-accent);\n color: var(--apt-color-accent);\n background-color: var(--apt-color-accent-soft);\n}\n.apt-filter-sort-icon {\n width: 11px;\n height: 11px;\n}\n.apt-filter-search-wrap {\n margin-bottom: 6px;\n}\n.apt-filter-search {\n width: 100%;\n box-sizing: border-box;\n padding: 6px 8px;\n border: 1px solid var(--apt-color-border);\n border-radius: 6px;\n background-color: var(--apt-color-bg);\n color: var(--apt-color-text);\n font-size: 0.8125rem;\n outline: none;\n}\n.apt-filter-search:focus {\n border-color: var(--apt-color-accent);\n box-shadow: 0 0 0 2px var(--apt-color-accent-soft);\n}\n.apt-filter-list {\n max-height: 200px;\n overflow-y: auto;\n margin: 2px 0;\n}\n.apt-filter-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 6px;\n border-radius: 4px;\n cursor: pointer;\n}\n.apt-filter-item:hover {\n background-color: var(--apt-color-bg-hover);\n}\n.apt-filter-item-all {\n border-bottom: 1px solid var(--apt-color-border-subtle);\n border-radius: 0;\n margin-bottom: 2px;\n padding-bottom: 6px;\n font-weight: 600;\n}\n.apt-filter-checkbox {\n width: 15px;\n height: 15px;\n flex-shrink: 0;\n cursor: pointer;\n accent-color: var(--apt-color-accent);\n}\n.apt-filter-item-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.apt-filter-empty {\n padding: 12px 6px;\n text-align: center;\n color: var(--apt-color-text-muted);\n font-size: 0.75rem;\n}\n.apt-filter-footer {\n display: flex;\n justify-content: space-between;\n gap: 6px;\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--apt-color-border-subtle);\n}\n.apt-filter-clear {\n padding: 5px 10px;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: var(--apt-color-accent);\n font-size: 0.75rem;\n cursor: pointer;\n}\n.apt-filter-clear:hover:not(:disabled) {\n text-decoration: underline;\n}\n.apt-filter-clear:disabled {\n color: var(--apt-color-text-muted-light);\n cursor: not-allowed;\n}\n.apt-filter-done {\n padding: 5px 14px;\n border: none;\n border-radius: 6px;\n background-color: var(--apt-color-accent);\n color: #fff;\n font-size: 0.75rem;\n cursor: pointer;\n transition: opacity 0.15s;\n}\n.apt-filter-done:hover {\n opacity: 0.9;\n}\n.apt-flex {\n display: flex;\n}\n.apt-items-center {\n align-items: center;\n}\n.apt-gap-2 {\n gap: 8px;\n}\n');
29
+ var FilterIcon = ({ className }) => /* @__PURE__ */ jsx(
30
+ "svg",
31
+ {
32
+ className,
33
+ width: "12",
34
+ height: "12",
35
+ viewBox: "0 0 12 12",
36
+ fill: "currentColor",
37
+ children: /* @__PURE__ */ jsx("path", { d: "M1 2h10L7 6.5V11L5 9.5V6.5L1 2z" })
38
+ }
39
+ );
40
+ var SortAscIcon = ({ className }) => /* @__PURE__ */ jsx(
41
+ "svg",
42
+ {
43
+ className,
44
+ width: "12",
45
+ height: "12",
46
+ viewBox: "0 0 12 12",
47
+ fill: "currentColor",
48
+ children: /* @__PURE__ */ jsx("path", { d: "M6 2L2 7h8L6 2z" })
49
+ }
50
+ );
51
+ var SortDescIcon = ({ className }) => /* @__PURE__ */ jsx(
52
+ "svg",
53
+ {
54
+ className,
55
+ width: "12",
56
+ height: "12",
57
+ viewBox: "0 0 12 12",
58
+ fill: "currentColor",
59
+ children: /* @__PURE__ */ jsx("path", { d: "M6 10l4-5H2l4 5z" })
60
+ }
61
+ );
62
+ var POPOVER_WIDTH = 240;
63
+ var ColumnFilter = ({
64
+ columnKey,
65
+ label,
66
+ distinctValues,
67
+ search,
68
+ excluded,
69
+ sortConfig,
70
+ isSortable = true,
71
+ onSort,
72
+ onSearchChange,
73
+ onExcludedChange,
74
+ onClear
75
+ }) => {
76
+ const [open, setOpen] = useState(false);
77
+ const [pos, setPos] = useState(null);
78
+ const buttonRef = useRef(null);
79
+ const popoverRef = useRef(null);
80
+ const masterRef = useRef(null);
81
+ const isActive = search.trim() !== "" || excluded.size > 0;
82
+ const sortDir = sortConfig && sortConfig.key === columnKey ? sortConfig.direction : null;
83
+ const visibleValues = useMemo(() => {
84
+ const q = search.trim().toLowerCase();
85
+ if (!q) return distinctValues;
86
+ return distinctValues.filter((v) => v.toLowerCase().includes(q));
87
+ }, [distinctValues, search]);
88
+ const allVisibleSelected = visibleValues.length > 0 && visibleValues.every((v) => !excluded.has(v));
89
+ const someVisibleSelected = visibleValues.some((v) => !excluded.has(v));
90
+ useLayoutEffect(() => {
91
+ if (!open || !buttonRef.current) return;
92
+ const rect = buttonRef.current.getBoundingClientRect();
93
+ let left = rect.right - POPOVER_WIDTH;
94
+ const maxLeft = window.innerWidth - POPOVER_WIDTH - 8;
95
+ if (left > maxLeft) left = maxLeft;
96
+ if (left < 8) left = 8;
97
+ setPos({ top: rect.bottom + 6, left });
98
+ }, [open]);
99
+ useEffect(() => {
100
+ if (masterRef.current) {
101
+ masterRef.current.indeterminate = someVisibleSelected && !allVisibleSelected;
102
+ }
103
+ }, [someVisibleSelected, allVisibleSelected, open]);
104
+ useEffect(() => {
105
+ if (!open) return void 0;
106
+ const onDown = (e) => {
107
+ const target = e.target;
108
+ if (popoverRef.current?.contains(target)) return;
109
+ if (buttonRef.current?.contains(target)) return;
110
+ setOpen(false);
111
+ };
112
+ const onKey = (e) => {
113
+ if (e.key === "Escape") setOpen(false);
114
+ };
115
+ const onScroll = () => setOpen(false);
116
+ document.addEventListener("mousedown", onDown);
117
+ document.addEventListener("keydown", onKey);
118
+ window.addEventListener("scroll", onScroll, true);
119
+ window.addEventListener("resize", onScroll);
120
+ return () => {
121
+ document.removeEventListener("mousedown", onDown);
122
+ document.removeEventListener("keydown", onKey);
123
+ window.removeEventListener("scroll", onScroll, true);
124
+ window.removeEventListener("resize", onScroll);
125
+ };
126
+ }, [open]);
127
+ const toggleValue = (value) => {
128
+ const next = new Set(excluded);
129
+ if (next.has(value)) next.delete(value);
130
+ else next.add(value);
131
+ onExcludedChange(next);
132
+ };
133
+ const toggleAllVisible = () => {
134
+ const next = new Set(excluded);
135
+ if (allVisibleSelected) {
136
+ visibleValues.forEach((v) => next.add(v));
137
+ } else {
138
+ visibleValues.forEach((v) => next.delete(v));
139
+ }
140
+ onExcludedChange(next);
141
+ };
142
+ const handleClear = () => {
143
+ onClear();
144
+ };
145
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
146
+ /* @__PURE__ */ jsx(
147
+ "button",
148
+ {
149
+ ref: buttonRef,
150
+ type: "button",
151
+ className: `apt-filter-btn ${isActive ? "apt-filter-btn-active" : ""}`,
152
+ "aria-label": `Filter ${label}`,
153
+ "aria-expanded": open,
154
+ onClick: (e) => {
155
+ e.stopPropagation();
156
+ setOpen((v) => !v);
157
+ },
158
+ children: /* @__PURE__ */ jsx(FilterIcon, { className: "apt-filter-icon" })
159
+ }
160
+ ),
161
+ open && pos && typeof document !== "undefined" && createPortal(
162
+ /* @__PURE__ */ jsxs(
163
+ "div",
164
+ {
165
+ ref: popoverRef,
166
+ className: "apt-filter-popover",
167
+ style: { top: pos.top, left: pos.left, width: POPOVER_WIDTH },
168
+ onClick: (e) => e.stopPropagation(),
169
+ children: [
170
+ isSortable && /* @__PURE__ */ jsxs("div", { className: "apt-filter-sort-row", children: [
171
+ /* @__PURE__ */ jsxs(
172
+ "button",
173
+ {
174
+ type: "button",
175
+ className: `apt-filter-sort-btn ${sortDir === "asc" ? "apt-filter-sort-btn-active" : ""}`,
176
+ onClick: () => onSort("asc"),
177
+ children: [
178
+ /* @__PURE__ */ jsx(SortAscIcon, { className: "apt-filter-sort-icon" }),
179
+ /* @__PURE__ */ jsx("span", { children: "Asc" })
180
+ ]
181
+ }
182
+ ),
183
+ /* @__PURE__ */ jsxs(
184
+ "button",
185
+ {
186
+ type: "button",
187
+ className: `apt-filter-sort-btn ${sortDir === "desc" ? "apt-filter-sort-btn-active" : ""}`,
188
+ onClick: () => onSort("desc"),
189
+ children: [
190
+ /* @__PURE__ */ jsx(SortDescIcon, { className: "apt-filter-sort-icon" }),
191
+ /* @__PURE__ */ jsx("span", { children: "Desc" })
192
+ ]
193
+ }
194
+ )
195
+ ] }),
196
+ /* @__PURE__ */ jsx("div", { className: "apt-filter-search-wrap", children: /* @__PURE__ */ jsx(
197
+ "input",
198
+ {
199
+ type: "text",
200
+ className: "apt-filter-search",
201
+ placeholder: "Search\u2026",
202
+ value: search,
203
+ autoFocus: true,
204
+ onChange: (e) => onSearchChange(e.target.value)
205
+ }
206
+ ) }),
207
+ /* @__PURE__ */ jsxs("label", { className: "apt-filter-item apt-filter-item-all", children: [
208
+ /* @__PURE__ */ jsx(
209
+ "input",
210
+ {
211
+ ref: masterRef,
212
+ type: "checkbox",
213
+ className: "apt-filter-checkbox",
214
+ checked: allVisibleSelected,
215
+ onChange: toggleAllVisible
216
+ }
217
+ ),
218
+ /* @__PURE__ */ jsx("span", { className: "apt-filter-item-label", children: search.trim() ? "Select all (filtered)" : "Select all" })
219
+ ] }),
220
+ /* @__PURE__ */ jsx("div", { className: "apt-filter-list", children: visibleValues.length === 0 ? /* @__PURE__ */ jsx("div", { className: "apt-filter-empty", children: "No matches" }) : visibleValues.map((value) => /* @__PURE__ */ jsxs("label", { className: "apt-filter-item", children: [
221
+ /* @__PURE__ */ jsx(
222
+ "input",
223
+ {
224
+ type: "checkbox",
225
+ className: "apt-filter-checkbox",
226
+ checked: !excluded.has(value),
227
+ onChange: () => toggleValue(value)
228
+ }
229
+ ),
230
+ /* @__PURE__ */ jsx("span", { className: "apt-filter-item-label", title: value, children: value === "" ? "(Blanks)" : value })
231
+ ] }, value)) }),
232
+ /* @__PURE__ */ jsxs("div", { className: "apt-filter-footer", children: [
233
+ /* @__PURE__ */ jsx(
234
+ "button",
235
+ {
236
+ type: "button",
237
+ className: "apt-filter-clear",
238
+ onClick: handleClear,
239
+ disabled: !isActive,
240
+ children: "Clear filter"
241
+ }
242
+ ),
243
+ /* @__PURE__ */ jsx(
244
+ "button",
245
+ {
246
+ type: "button",
247
+ className: "apt-filter-done",
248
+ onClick: () => setOpen(false),
249
+ children: "Done"
250
+ }
251
+ )
252
+ ] })
253
+ ]
254
+ }
255
+ ),
256
+ document.body
257
+ )
258
+ ] });
259
+ };
260
+ var ColumnFilter_default = ColumnFilter;
28
261
  var SortIcon = ({ className }) => /* @__PURE__ */ jsx(
29
262
  "svg",
30
263
  {
@@ -58,21 +291,31 @@ var SortDownIcon = ({ className }) => /* @__PURE__ */ jsx(
58
291
  children: /* @__PURE__ */ jsx("path", { d: "M6 10l4-5H2l4 5z" })
59
292
  }
60
293
  );
294
+ function parseNumericWidth(value) {
295
+ if (typeof value === "number" && !Number.isNaN(value)) return value;
296
+ if (typeof value === "string") {
297
+ const parsed = parseFloat(value);
298
+ if (!Number.isNaN(parsed)) return parsed;
299
+ }
300
+ return null;
301
+ }
61
302
  function loadStoredColumnWidths(columnWidthsStorageKey, fallback) {
62
- if (!columnWidthsStorageKey || typeof window === "undefined") return fallback;
303
+ if (!columnWidthsStorageKey || typeof window === "undefined")
304
+ return { widths: fallback, hadStored: false };
63
305
  try {
64
306
  const raw = window.localStorage.getItem(columnWidthsStorageKey);
65
- if (!raw) return fallback;
307
+ if (!raw) return { widths: fallback, hadStored: false };
66
308
  const parsed = JSON.parse(raw);
67
- if (!parsed || typeof parsed !== "object") return fallback;
309
+ if (!parsed || typeof parsed !== "object")
310
+ return { widths: fallback, hadStored: false };
68
311
  const next = { ...fallback };
69
- Object.keys(next).forEach((key) => {
70
- const val = parsed[key];
71
- if (typeof val === "number" || typeof val === "string") next[key] = val;
312
+ Object.keys(parsed).forEach((key) => {
313
+ const num = parseNumericWidth(parsed[key]);
314
+ if (num !== null) next[key] = num;
72
315
  });
73
- return next;
316
+ return { widths: next, hadStored: true };
74
317
  } catch {
75
- return fallback;
318
+ return { widths: fallback, hadStored: false };
76
319
  }
77
320
  }
78
321
  var Table = ({
@@ -93,13 +336,20 @@ var Table = ({
93
336
  onRowsPerPageChange,
94
337
  expandedRowId,
95
338
  renderExpandedRow,
96
- renderFullRow
339
+ renderFullRow,
340
+ filterable = false,
341
+ striped = false,
342
+ dividers = false,
343
+ bordered = false,
344
+ density = "default"
97
345
  }) => {
98
346
  const [sortConfig, setSortConfig] = useState(
99
347
  initialSort || null
100
348
  );
101
349
  const [currentPage, setCurrentPage] = useState(1);
102
350
  const [columnWidths, setColumnWidths] = useState({});
351
+ const [columnsFrozen, setColumnsFrozen] = useState(false);
352
+ const [columnFilters, setColumnFilters] = useState({});
103
353
  const [expandedColumns, setExpandedColumns] = useState(
104
354
  () => /* @__PURE__ */ new Set()
105
355
  );
@@ -115,15 +365,34 @@ var Table = ({
115
365
  useEffect(() => {
116
366
  const initialWidths = {};
117
367
  headers.forEach((header) => {
118
- initialWidths[header.accessor] = header.width;
368
+ const w = parseNumericWidth(header.width);
369
+ if (w !== null) initialWidths[header.accessor] = w;
119
370
  });
120
371
  initialColumnWidthsRef.current = initialWidths;
121
- setColumnWidths(
122
- loadStoredColumnWidths(columnWidthsStorageKey, initialWidths)
372
+ const { widths, hadStored } = loadStoredColumnWidths(
373
+ columnWidthsStorageKey,
374
+ initialWidths
123
375
  );
376
+ setColumnWidths(widths);
377
+ setColumnsFrozen(hadStored);
124
378
  setExpandedColumns(/* @__PURE__ */ new Set());
379
+ setColumnFilters({});
125
380
  setCurrentPage(1);
126
381
  }, [headers, columnWidthsStorageKey]);
382
+ useLayoutEffect(() => {
383
+ if (!columnsFrozen || !tableRef.current) return;
384
+ const missing = headers.some((h) => columnWidths[h.accessor] == null);
385
+ if (!missing) return;
386
+ const cells = tableRef.current.tHead?.rows?.[0]?.cells;
387
+ const next = { ...columnWidths };
388
+ headers.forEach((header, idx) => {
389
+ if (next[header.accessor] == null) {
390
+ const cell = cells?.[idx];
391
+ if (cell) next[header.accessor] = cell.offsetWidth;
392
+ }
393
+ });
394
+ setColumnWidths(next);
395
+ }, [columnsFrozen, headers, columnWidths]);
127
396
  useEffect(() => {
128
397
  if (!columnWidthsStorageKey || typeof window === "undefined") return;
129
398
  if (Object.keys(columnWidths).length === 0) return;
@@ -152,14 +421,6 @@ var Table = ({
152
421
  })();
153
422
  return ctx ? ctx.measureText(String(text ?? "")).width : 0;
154
423
  };
155
- const parseWidthValue = (value, fallback) => {
156
- if (typeof value === "number" && !Number.isNaN(value)) return value;
157
- if (typeof value === "string") {
158
- const parsed = parseFloat(value);
159
- if (!Number.isNaN(parsed)) return parsed;
160
- }
161
- return fallback;
162
- };
163
424
  const rows = useMemo(() => {
164
425
  if (!Array.isArray(manualRowData)) return [];
165
426
  const src = manualRowData.filter(Boolean).filter((r) => typeof r === "object");
@@ -187,11 +448,43 @@ var Table = ({
187
448
  return base;
188
449
  });
189
450
  }, [manualRowData, headers]);
451
+ const distinctValuesByColumn = useMemo(() => {
452
+ const map = {};
453
+ const anyFilterable = headers.some((h) => h.isFilterable ?? filterable);
454
+ if (!anyFilterable) return map;
455
+ headers.forEach((header) => {
456
+ if (!(header.isFilterable ?? filterable)) return;
457
+ const set = /* @__PURE__ */ new Set();
458
+ rows.forEach((r) => set.add(String(r[header.accessor] ?? "")));
459
+ const arr = Array.from(set);
460
+ arr.sort(
461
+ (a, b) => a.localeCompare(b, void 0, { numeric: true, sensitivity: "base" })
462
+ );
463
+ map[header.accessor] = arr;
464
+ });
465
+ return map;
466
+ }, [rows, headers, filterable]);
467
+ const filteredRows = useMemo(() => {
468
+ const active = Object.entries(columnFilters).filter(
469
+ ([, f]) => f.search.trim() !== "" || f.excluded.size > 0
470
+ );
471
+ if (active.length === 0) return rows;
472
+ return rows.filter(
473
+ (row) => active.every(([accessor, filter]) => {
474
+ const val = String(row[accessor] ?? "");
475
+ if (filter.search.trim() !== "" && !val.toLowerCase().includes(filter.search.trim().toLowerCase())) {
476
+ return false;
477
+ }
478
+ if (filter.excluded.size > 0 && filter.excluded.has(val)) return false;
479
+ return true;
480
+ })
481
+ );
482
+ }, [rows, columnFilters]);
190
483
  const sortedRows = useMemo(() => {
191
484
  if (!sortConfig || !sortConfig.key) {
192
- return rows;
485
+ return filteredRows;
193
486
  }
194
- const sortableRows = [...rows];
487
+ const sortableRows = [...filteredRows];
195
488
  sortableRows.sort((a, b) => {
196
489
  const aVal = a[sortConfig.key];
197
490
  const bVal = b[sortConfig.key];
@@ -204,7 +497,7 @@ var Table = ({
204
497
  return 0;
205
498
  });
206
499
  return sortableRows;
207
- }, [rows, sortConfig]);
500
+ }, [filteredRows, sortConfig]);
208
501
  const effectiveShouldPaginate = shouldPaginate && sortedRows.length > rowsPerPage;
209
502
  const totalPages = effectiveShouldPaginate ? Math.ceil(sortedRows.length / rowsPerPage) : 1;
210
503
  const safePage = totalPages > 0 ? Math.min(currentPage, totalPages) : 1;
@@ -222,6 +515,50 @@ var Table = ({
222
515
  setSortConfig({ key, direction });
223
516
  setCurrentPage(1);
224
517
  };
518
+ const setColumnSearch = (accessor, value) => {
519
+ setColumnFilters((prev) => ({
520
+ ...prev,
521
+ [accessor]: {
522
+ search: value,
523
+ excluded: prev[accessor]?.excluded ?? /* @__PURE__ */ new Set()
524
+ }
525
+ }));
526
+ setCurrentPage(1);
527
+ };
528
+ const setColumnExcluded = (accessor, next) => {
529
+ setColumnFilters((prev) => ({
530
+ ...prev,
531
+ [accessor]: {
532
+ search: prev[accessor]?.search ?? "",
533
+ excluded: next
534
+ }
535
+ }));
536
+ setCurrentPage(1);
537
+ };
538
+ const clearColumnFilter = (accessor) => {
539
+ setColumnFilters((prev) => {
540
+ if (!prev[accessor]) return prev;
541
+ const next = { ...prev };
542
+ delete next[accessor];
543
+ return next;
544
+ });
545
+ setCurrentPage(1);
546
+ };
547
+ const setColumnSort = (accessor, direction) => {
548
+ setSortConfig({ key: accessor, direction });
549
+ setCurrentPage(1);
550
+ };
551
+ const freezeCurrentWidths = () => {
552
+ const next = { ...columnWidths };
553
+ const cells = tableRef.current?.tHead?.rows?.[0]?.cells;
554
+ headers.forEach((header, idx) => {
555
+ if (next[header.accessor] == null) {
556
+ const cell = cells?.[idx];
557
+ if (cell) next[header.accessor] = cell.offsetWidth;
558
+ }
559
+ });
560
+ return next;
561
+ };
225
562
  const autoSizeColumn = (colIndex, header) => {
226
563
  if (!tableRef.current) return;
227
564
  const tableEl = tableRef.current;
@@ -245,15 +582,11 @@ var Table = ({
245
582
  Math.ceil(measureTextWidth(r[header.accessor]))
246
583
  );
247
584
  });
248
- const minWidthPx = parseWidthValue(
249
- header?.minWidth,
250
- parseWidthValue(minColWidth, 50)
251
- );
585
+ const minWidthPx = parseNumericWidth(header?.minWidth) ?? minColWidth;
252
586
  const finalWidth = Math.max(maxWidth + 12, minWidthPx);
253
- setColumnWidths((prev) => ({
254
- ...prev,
255
- [header.accessor]: `${finalWidth}px`
256
- }));
587
+ const frozen = freezeCurrentWidths();
588
+ setColumnsFrozen(true);
589
+ setColumnWidths({ ...frozen, [header.accessor]: finalWidth });
257
590
  };
258
591
  const resetColumnWidth = (accessor) => {
259
592
  const regularWidth = initialColumnWidthsRef.current[accessor];
@@ -306,8 +639,11 @@ var Table = ({
306
639
  const th = e.target.closest("th");
307
640
  if (!th) return;
308
641
  const header = headers.find((h) => h.accessor === accessor);
309
- const minResizeWidth = parseWidthValue(header?.minWidth, minColWidth);
310
- const startWidth = th.offsetWidth;
642
+ const minResizeWidth = parseNumericWidth(header?.minWidth) ?? minColWidth;
643
+ const frozen = freezeCurrentWidths();
644
+ const startWidth = frozen[accessor] ?? th.offsetWidth;
645
+ setColumnsFrozen(true);
646
+ setColumnWidths(frozen);
311
647
  document.body.style.cursor = "col-resize";
312
648
  document.body.style.userSelect = "none";
313
649
  const handleMouseMove = (moveEvent) => {
@@ -316,7 +652,7 @@ var Table = ({
316
652
  const finalWidth = Math.max(newWidth, minResizeWidth);
317
653
  setColumnWidths((prev) => ({
318
654
  ...prev,
319
- [accessor]: `${finalWidth}px`
655
+ [accessor]: finalWidth
320
656
  }));
321
657
  };
322
658
  const handleMouseUp = () => {
@@ -331,103 +667,140 @@ var Table = ({
331
667
  document.addEventListener("mousemove", handleMouseMove);
332
668
  document.addEventListener("mouseup", handleMouseUp);
333
669
  };
670
+ const containerClassName = [
671
+ "apt-table-container",
672
+ striped && "apt-striped",
673
+ dividers && "apt-dividers",
674
+ bordered && "apt-bordered",
675
+ density === "compact" && "apt-compact"
676
+ ].filter(Boolean).join(" ");
677
+ const noData = rows.length === 0;
678
+ const noMatches = !noData && sortedRows.length === 0;
334
679
  const containerStyle = {
335
- height: sortedRows.length === 0 ? height : !effectiveShouldPaginate ? "auto" : height,
680
+ height: noData ? height : !effectiveShouldPaginate ? "auto" : height,
336
681
  maxHeight: !effectiveShouldPaginate ? height : void 0
337
682
  };
338
- return /* @__PURE__ */ jsx("div", { className: "apt-table-container", style: containerStyle, children: sortedRows.length === 0 ? /* @__PURE__ */ jsx("div", { className: "apt-empty-state", children: "No rows to display." }) : /* @__PURE__ */ jsxs(Fragment, { children: [
683
+ const spanCount = headers.length + (columnsFrozen ? 1 : 0);
684
+ return /* @__PURE__ */ jsx("div", { className: containerClassName, style: containerStyle, children: noData ? /* @__PURE__ */ jsx("div", { className: "apt-empty-state", children: "No rows to display." }) : /* @__PURE__ */ jsxs(Fragment, { children: [
339
685
  /* @__PURE__ */ jsx("div", { className: "apt-scroll-area", children: /* @__PURE__ */ jsxs("table", { className: "apt-table", ref: tableRef, children: [
340
- /* @__PURE__ */ jsx("colgroup", { children: headers.map((header) => /* @__PURE__ */ jsx(
341
- "col",
342
- {
343
- style: {
344
- width: columnWidths[header.accessor],
345
- minWidth: `${parseWidthValue(
346
- header.minWidth,
347
- minColWidth
348
- )}px`
349
- }
350
- },
351
- `col-${header.accessor}`
352
- )) }),
353
- /* @__PURE__ */ jsx("thead", { className: "apt-thead", children: /* @__PURE__ */ jsx("tr", { children: headers.map((header, idx) => {
354
- const isHeaderClickable = mobileAutoSizeOnHeaderClick && isMobile || header.isSortable;
355
- return /* @__PURE__ */ jsxs(
356
- "th",
686
+ /* @__PURE__ */ jsxs("colgroup", { children: [
687
+ headers.map((header) => /* @__PURE__ */ jsx(
688
+ "col",
357
689
  {
358
- onClick: () => handleHeaderClick(header, idx),
359
- className: `apt-th ${isHeaderClickable ? "apt-th-sortable" : ""}`,
360
- children: [
361
- /* @__PURE__ */ jsxs("div", { className: "apt-th-content", children: [
362
- header.label,
363
- header.isSortable && !(mobileAutoSizeOnHeaderClick && isMobile) && getSortIcon(header.accessor)
364
- ] }),
365
- /* @__PURE__ */ jsx(
366
- "div",
367
- {
368
- className: "apt-resizer",
369
- onMouseDown: (e) => {
370
- e.stopPropagation();
371
- handleMouseDown(e, header.accessor);
372
- },
373
- onClick: (e) => e.stopPropagation()
374
- }
375
- )
376
- ]
377
- },
378
- header.accessor
379
- );
380
- }) }) }),
381
- /* @__PURE__ */ jsx("tbody", { className: "apt-tbody", children: paginatedRows.map((row) => {
382
- const isExpanded = expandedRowId === row.id;
383
- const isFullRow = typeof renderFullRow === "function" && row?._meta?.fullRow;
384
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
385
- isFullRow ? /* @__PURE__ */ jsx(
386
- "tr",
387
- {
388
- className: `apt-row ${rowClassName ? rowClassName(row) : ""}`,
389
- onClick: () => onRowClick && onRowClick(row),
390
- children: /* @__PURE__ */ jsx(
391
- "td",
392
- {
393
- colSpan: headers.length,
394
- className: "apt-td",
395
- style: { padding: 0 },
396
- children: renderFullRow(row)
397
- }
398
- )
690
+ style: {
691
+ width: columnWidths[header.accessor] != null ? `${columnWidths[header.accessor]}px` : void 0,
692
+ minWidth: `${parseNumericWidth(header.minWidth) ?? minColWidth}px`
399
693
  }
400
- ) : /* @__PURE__ */ jsx(
401
- "tr",
694
+ },
695
+ `col-${header.accessor}`
696
+ )),
697
+ columnsFrozen && /* @__PURE__ */ jsx("col", { className: "apt-col-spacer" })
698
+ ] }),
699
+ /* @__PURE__ */ jsx("thead", { className: "apt-thead", children: /* @__PURE__ */ jsxs("tr", { children: [
700
+ headers.map((header, idx) => {
701
+ const columnFilterable = header.isFilterable ?? filterable;
702
+ const isHeaderClickable = mobileAutoSizeOnHeaderClick && isMobile || header.isSortable;
703
+ return /* @__PURE__ */ jsxs(
704
+ "th",
402
705
  {
403
- className: `apt-row ${rowClassName ? rowClassName(row) : ""}`,
404
- onClick: () => onRowClick && onRowClick(row),
405
- style: { height: `${rowHeight}px` },
406
- children: headers.map((header) => {
407
- const value = row[header.accessor];
408
- const cellContent = header.cellRenderer ? header.cellRenderer({ row, value }) : value;
409
- return /* @__PURE__ */ jsx(
706
+ onClick: () => handleHeaderClick(header, idx),
707
+ className: `apt-th ${isHeaderClickable ? "apt-th-sortable" : ""}`,
708
+ children: [
709
+ /* @__PURE__ */ jsxs("div", { className: "apt-th-content", children: [
710
+ /* @__PURE__ */ jsx("span", { className: "apt-th-label", children: header.label }),
711
+ header.isSortable && !(mobileAutoSizeOnHeaderClick && isMobile) && getSortIcon(header.accessor),
712
+ columnFilterable && /* @__PURE__ */ jsx(
713
+ ColumnFilter_default,
714
+ {
715
+ columnKey: header.accessor,
716
+ label: header.label,
717
+ distinctValues: distinctValuesByColumn[header.accessor] || [],
718
+ search: columnFilters[header.accessor]?.search ?? "",
719
+ excluded: columnFilters[header.accessor]?.excluded ?? /* @__PURE__ */ new Set(),
720
+ sortConfig,
721
+ isSortable: header.isSortable,
722
+ onSort: (dir) => setColumnSort(header.accessor, dir),
723
+ onSearchChange: (value) => setColumnSearch(header.accessor, value),
724
+ onExcludedChange: (next) => setColumnExcluded(header.accessor, next),
725
+ onClear: () => clearColumnFilter(header.accessor)
726
+ }
727
+ )
728
+ ] }),
729
+ /* @__PURE__ */ jsx(
730
+ "div",
731
+ {
732
+ className: "apt-resizer",
733
+ onMouseDown: (e) => {
734
+ e.stopPropagation();
735
+ handleMouseDown(e, header.accessor);
736
+ },
737
+ onClick: (e) => e.stopPropagation()
738
+ }
739
+ )
740
+ ]
741
+ },
742
+ header.accessor
743
+ );
744
+ }),
745
+ columnsFrozen && /* @__PURE__ */ jsx("th", { className: "apt-th apt-th-spacer", "aria-hidden": "true" })
746
+ ] }) }),
747
+ /* @__PURE__ */ jsxs("tbody", { className: "apt-tbody", children: [
748
+ noMatches && /* @__PURE__ */ jsx("tr", { className: "apt-row", children: /* @__PURE__ */ jsx("td", { colSpan: spanCount, className: "apt-td apt-no-matches", children: "No rows match the current filters." }) }),
749
+ paginatedRows.map((row, rowIdx) => {
750
+ const isExpanded = expandedRowId === row.id;
751
+ const isFullRow = typeof renderFullRow === "function" && row?._meta?.fullRow;
752
+ const altClass = rowIdx % 2 === 1 ? "apt-row-alt" : "";
753
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
754
+ isFullRow ? /* @__PURE__ */ jsx(
755
+ "tr",
756
+ {
757
+ className: `apt-row ${altClass} ${rowClassName ? rowClassName(row) : ""}`,
758
+ onClick: () => onRowClick && onRowClick(row),
759
+ children: /* @__PURE__ */ jsx(
410
760
  "td",
411
761
  {
412
- className: header.accessor === "actions" ? "apt-td-actions" : "apt-td",
413
- children: header.accessor === "actions" ? /* @__PURE__ */ jsx("div", { onClick: (e) => e.stopPropagation(), children: cellContent }) : cellContent
414
- },
415
- `${row.id}-${header.accessor}`
416
- );
417
- })
418
- }
419
- ),
420
- isExpanded && typeof renderExpandedRow === "function" && /* @__PURE__ */ jsx("tr", { className: "apt-row-expanded", children: /* @__PURE__ */ jsx(
421
- "td",
422
- {
423
- colSpan: headers.length,
424
- className: "apt-td",
425
- style: { padding: 0 },
426
- children: renderExpandedRow(row)
427
- }
428
- ) })
429
- ] }, row.id);
430
- }) })
762
+ colSpan: spanCount,
763
+ className: "apt-td",
764
+ style: { padding: 0 },
765
+ children: renderFullRow(row)
766
+ }
767
+ )
768
+ }
769
+ ) : /* @__PURE__ */ jsxs(
770
+ "tr",
771
+ {
772
+ className: `apt-row ${altClass} ${rowClassName ? rowClassName(row) : ""}`,
773
+ onClick: () => onRowClick && onRowClick(row),
774
+ style: { height: `${rowHeight}px` },
775
+ children: [
776
+ headers.map((header) => {
777
+ const value = row[header.accessor];
778
+ const cellContent = header.cellRenderer ? header.cellRenderer({ row, value }) : value;
779
+ return /* @__PURE__ */ jsx(
780
+ "td",
781
+ {
782
+ className: header.accessor === "actions" ? "apt-td-actions" : "apt-td",
783
+ children: header.accessor === "actions" ? /* @__PURE__ */ jsx("div", { onClick: (e) => e.stopPropagation(), children: cellContent }) : cellContent
784
+ },
785
+ `${row.id}-${header.accessor}`
786
+ );
787
+ }),
788
+ columnsFrozen && /* @__PURE__ */ jsx("td", { className: "apt-td apt-td-spacer", "aria-hidden": "true" })
789
+ ]
790
+ }
791
+ ),
792
+ isExpanded && typeof renderExpandedRow === "function" && /* @__PURE__ */ jsx("tr", { className: "apt-row-expanded", children: /* @__PURE__ */ jsx(
793
+ "td",
794
+ {
795
+ colSpan: spanCount,
796
+ className: "apt-td",
797
+ style: { padding: 0 },
798
+ children: renderExpandedRow(row)
799
+ }
800
+ ) })
801
+ ] }, row.id);
802
+ })
803
+ ] })
431
804
  ] }) }),
432
805
  shouldPaginate && totalPages > 1 || Array.isArray(rowsPerPageOptions) && rowsPerPageOptions.length > 0 && onRowsPerPageChange ? /* @__PURE__ */ jsxs("div", { className: "apt-footer", children: [
433
806
  /* @__PURE__ */ jsx("div", { className: "apt-footer-left", children: Array.isArray(rowsPerPageOptions) && rowsPerPageOptions.length > 0 && onRowsPerPageChange && /* @__PURE__ */ jsxs(Fragment, { children: [