UNPKG

@furystack/shades-common-components

Version:

Common UI components for FuryStack Shades

85 lines 4.64 kB
import { createComponent, Shade } from '@furystack/shades'; import { cssVariableTheme } from '../../services/css-variable-theme.js'; import { DataGridBody } from './body.js'; import { DataGridFooter } from './footer.js'; import { DataGridHeader } from './header.js'; let nextDataGridId = 0; export const DataGrid = Shade({ customElementName: 'shade-data-grid', css: { display: 'block', fontFamily: cssVariableTheme.typography.fontFamily, width: '100%', height: '100%', overflow: 'auto', zIndex: '1', '& table': { width: '100%', maxHeight: 'calc(100% - 4em)', position: 'relative', borderCollapse: 'collapse', }, '& th': { backdropFilter: 'blur(12px) saturate(180%)', background: cssVariableTheme.action.activeBackground, color: cssVariableTheme.text.secondary, height: '36px', padding: '0 0.6em', alignItems: 'center', top: '0', position: 'sticky', fontSize: '0.75rem', fontWeight: cssVariableTheme.typography.fontWeight.semibold, letterSpacing: '0.03em', textAlign: 'left', zIndex: '1', borderBottom: `1px solid ${cssVariableTheme.action.subtleBorder}`, borderRight: `1px solid ${cssVariableTheme.action.subtleBorder}`, }, }, render: ({ props, useDisposable, useRef, useHostProps, useState }) => { const wrapperRef = useRef('gridWrapper'); const [navSectionId] = useState('navSectionId', String(nextDataGridId++)); const headerFindOptions = props.findOptions; const handleHeaderChange = props.onFindOptionsChange; useDisposable('keydown-handler', () => { const listener = (ev) => props.collectionService.handleKeyDown(ev); window.addEventListener('keydown', listener, true); return { [Symbol.dispose]: () => window.removeEventListener('keydown', listener, true) }; }); useDisposable('focus-coordination', () => { const handleFocusOut = (ev) => { const wrapper = wrapperRef.current; if (wrapper && (!ev.relatedTarget || !wrapper.contains(ev.relatedTarget))) { props.collectionService.hasFocus.setValue(false); } }; queueMicrotask(() => { const wrapper = wrapperRef.current; if (wrapper) { wrapper.addEventListener('focusout', handleFocusOut); } }); return { [Symbol.dispose]: () => { const wrapper = wrapperRef.current; if (wrapper) { wrapper.removeEventListener('focusout', handleFocusOut); } }, }; }); if (props.styles?.wrapper) { useHostProps({ style: props.styles.wrapper }); } return (createComponent("div", { ref: wrapperRef, className: "shade-grid-wrapper", "data-nav-section": props.navSection ?? `data-grid-${navSectionId}`, ariaMultiSelectable: "true" }, createComponent("table", null, createComponent("thead", null, createComponent("tr", null, props.columns.map((column) => { return (createComponent("th", { style: props.styles?.header }, props.headerComponents?.[column]?.(column) || props.headerComponents?.default?.(column) || (createComponent(DataGridHeader, { field: column, findOptions: headerFindOptions, onFindOptionsChange: handleHeaderChange, filterConfig: props.columnFilters?.[column] })))); }))), createComponent(DataGridBody, { columns: props.columns, service: props.collectionService, rowComponents: props.rowComponents, onRowClick: (entry, ev) => props.collectionService.handleRowClick(entry, ev), onRowDoubleClick: (entry) => props.collectionService.handleRowDoubleClick(entry), style: props.styles?.cell, focusedRowStyle: props.focusedRowStyle, selectedRowStyle: props.selectedRowStyle, unfocusedRowStyle: props.unfocusedRowStyle, unselectedRowStyle: props.unselectedRowStyle, emptyComponent: props.emptyComponent, loaderComponent: props.loaderComponent })), createComponent(DataGridFooter, { service: props.collectionService, findOptions: props.findOptions, onFindOptionsChange: props.onFindOptionsChange, paginationOptions: props.paginationOptions }))); }, }); //# sourceMappingURL=data-grid.js.map