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