@skygraph/react 0.6.4 → 0.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +70 -70
  2. package/dist/{Table-CMKo6Pc3.d.cts → Table-Bhlshbs2.d.cts} +39 -0
  3. package/dist/{Table-CAay8MmA.d.ts → Table-DOGK_njf.d.ts} +39 -0
  4. package/dist/{chunk-Y6XZ5TLD.js → chunk-B6BK5B64.js} +3 -3
  5. package/dist/chunk-B6BK5B64.js.map +1 -0
  6. package/dist/{chunk-PEX2UTNG.js → chunk-EA2J67A4.js} +2 -2
  7. package/dist/chunk-EA2J67A4.js.map +1 -0
  8. package/dist/{chunk-BNMJSYI2.js → chunk-EWUB2QCP.js} +2 -2
  9. package/dist/chunk-EWUB2QCP.js.map +1 -0
  10. package/dist/{chunk-7AA2JPZB.js → chunk-G4MRXKGC.js} +21 -14
  11. package/dist/chunk-G4MRXKGC.js.map +1 -0
  12. package/dist/{chunk-EFDB2ENB.js → chunk-MTHPDCO3.js} +8 -6
  13. package/dist/chunk-MTHPDCO3.js.map +1 -0
  14. package/dist/{chunk-KGFFQGCM.js → chunk-N4S66XHX.js} +8 -4
  15. package/dist/chunk-N4S66XHX.js.map +1 -0
  16. package/dist/{chunk-SEQI65CF.js → chunk-U7BXGUMC.js} +1 -1
  17. package/dist/chunk-U7BXGUMC.js.map +1 -0
  18. package/dist/{chunk-45YW5VSP.js → chunk-UCCGEZPJ.js} +2 -2
  19. package/dist/chunk-UCCGEZPJ.js.map +1 -0
  20. package/dist/{chunk-VLRLCHEL.js → chunk-YJZKXU5O.js} +1 -1
  21. package/dist/chunk-YJZKXU5O.js.map +1 -0
  22. package/dist/{chunk-ZJC2QUWA.js → chunk-YWCL3MUL.js} +1 -1
  23. package/dist/chunk-YWCL3MUL.js.map +1 -0
  24. package/dist/datagrid.cjs +3 -4
  25. package/dist/datagrid.cjs.map +1 -1
  26. package/dist/datagrid.js +4 -4
  27. package/dist/devtools.cjs.map +1 -1
  28. package/dist/devtools.js +1 -1
  29. package/dist/form.cjs.map +1 -1
  30. package/dist/form.js +3 -3
  31. package/dist/index.cjs +1239 -255
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +16 -4
  34. package/dist/index.d.ts +16 -4
  35. package/dist/index.js +1113 -150
  36. package/dist/index.js.map +1 -1
  37. package/dist/table.cjs +17 -10
  38. package/dist/table.cjs.map +1 -1
  39. package/dist/table.d.cts +1 -1
  40. package/dist/table.d.ts +1 -1
  41. package/dist/table.js +4 -4
  42. package/dist/tree.cjs +11 -7
  43. package/dist/tree.cjs.map +1 -1
  44. package/dist/tree.js +3 -3
  45. package/dist/virtual.cjs.map +1 -1
  46. package/dist/virtual.js +2 -2
  47. package/package.json +2 -2
  48. package/dist/chunk-45YW5VSP.js.map +0 -1
  49. package/dist/chunk-7AA2JPZB.js.map +0 -1
  50. package/dist/chunk-BNMJSYI2.js.map +0 -1
  51. package/dist/chunk-EFDB2ENB.js.map +0 -1
  52. package/dist/chunk-KGFFQGCM.js.map +0 -1
  53. package/dist/chunk-PEX2UTNG.js.map +0 -1
  54. package/dist/chunk-SEQI65CF.js.map +0 -1
  55. package/dist/chunk-VLRLCHEL.js.map +0 -1
  56. package/dist/chunk-Y6XZ5TLD.js.map +0 -1
  57. package/dist/chunk-ZJC2QUWA.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/Pagination.tsx","../src/components/ui/Select.tsx","../src/components/complex/Table/export.ts","../src/hooks/useTable.ts","../src/utils/print/printElement.ts","../src/components/complex/Table/Table.tsx","../src/components/complex/Table/FilterDropdown.tsx","../src/components/complex/Table/TableHeader.tsx","../src/components/complex/Table/TableBody.tsx","../src/components/complex/Table/TableGroupRow.tsx","../src/components/complex/Table/VirtualTableBody.tsx","../src/components/complex/Table/ContextMenu.tsx","../src/components/complex/Table/useTableState.ts","../src/components/complex/Table/helpers.ts","../src/components/complex/Table/defaultIcons.tsx","../src/components/complex/Table/types.ts","../src/types/slots.ts"],"sourcesContent":["import { useState } from 'react'\r\nimport { useConfig } from '../ConfigProvider'\r\nimport type { BaseComponentProps } from '../../types'\r\nimport type React from 'react'\r\n\r\n/** Props for page navigation, optional total text, page size, and quick jump. */\r\nexport interface PaginationProps extends BaseComponentProps {\r\n /** Current page number (1-based). */\r\n current: number\r\n /** Total number of records across all pages. */\r\n total: number\r\n /** Number of items per page. @default 10 */\r\n pageSize?: number\r\n /** Called when the user selects a different page. */\r\n onChange?: (page: number) => void\r\n /** Called when the user picks a new value from the size changer. */\r\n onPageSizeChange?: (size: number) => void\r\n /** Renders total count text, or a custom node from total and visible range. */\r\n showTotal?: boolean | ((total: number, range: [number, number]) => React.ReactNode)\r\n /** Disables all controls; falls back to ConfigProvider when omitted. */\r\n disabled?: boolean\r\n /** Renders prev/next with current/total only, hiding page numbers. */\r\n simple?: boolean\r\n /** Shows a select to change `pageSize`. */\r\n showSizeChanger?: boolean\r\n /** Options for the page size select. @default [10, 20, 50, 100] */\r\n pageSizeOptions?: number[]\r\n /** Shows an input to jump to a page by number. */\r\n showQuickJumper?: boolean\r\n}\r\n\r\n/**\r\n * Page controls with numbered pages, ellipsis folding, and optional size changer and jumper.\r\n * Clamps the current page into valid range for the given total and page size.\r\n */\r\nexport function Pagination({\r\n current,\r\n total,\r\n pageSize = 10,\r\n onChange,\r\n onPageSizeChange,\r\n showTotal,\r\n disabled: disabledProp,\r\n simple,\r\n showSizeChanger,\r\n pageSizeOptions = [10, 20, 50, 100],\r\n showQuickJumper,\r\n className,\r\n style,\r\n unstyled,\r\n}: PaginationProps) {\r\n const config = useConfig()\r\n const disabled = disabledProp ?? config.disabled ?? false\r\n const locale = config.locale?.pagination\r\n const totalPrefix = locale?.totalPrefix ?? 'Total'\r\n const itemsPerPageLabel = locale?.itemsPerPage ?? '/ page'\r\n const jumpLabel = locale?.jump ?? 'Go to'\r\n const ariaLabel = locale?.ariaLabel ?? 'Pagination'\r\n const [jumpValue, setJumpValue] = useState('')\r\n\r\n const totalPages = Math.max(1, Math.ceil(total / pageSize))\r\n const safeCurrentPage = Math.min(Math.max(1, current), totalPages)\r\n const rangeStart = (safeCurrentPage - 1) * pageSize + 1\r\n const rangeEnd = Math.min(safeCurrentPage * pageSize, total)\r\n\r\n const go = (page: number) => {\r\n if (disabled || page < 1 || page > totalPages || page === safeCurrentPage) return\r\n onChange?.(page)\r\n }\r\n\r\n const handleJump = () => {\r\n const num = parseInt(jumpValue, 10)\r\n if (!isNaN(num)) {\r\n go(num)\r\n }\r\n setJumpValue('')\r\n }\r\n\r\n // Keyboard paging: ← / → step one page, Home / End jump to the edges.\r\n // Skipped while focus sits in the size-changer <select> or quick-jumper\r\n // <input> so arrow keys there keep their native behaviour.\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {\r\n if (disabled) return\r\n const tag = (e.target as HTMLElement).tagName\r\n if (tag === 'INPUT' || tag === 'SELECT') return\r\n switch (e.key) {\r\n case 'ArrowLeft':\r\n e.preventDefault()\r\n go(safeCurrentPage - 1)\r\n break\r\n case 'ArrowRight':\r\n e.preventDefault()\r\n go(safeCurrentPage + 1)\r\n break\r\n case 'Home':\r\n e.preventDefault()\r\n go(1)\r\n break\r\n case 'End':\r\n e.preventDefault()\r\n go(totalPages)\r\n break\r\n }\r\n }\r\n\r\n const pages = buildPages(safeCurrentPage, totalPages)\r\n\r\n const renderTotal = () => {\r\n if (!showTotal) return null\r\n if (typeof showTotal === 'function') {\r\n return <span className=\"sg-pagination-total\">{showTotal(total, [rangeStart, rangeEnd])}</span>\r\n }\r\n return (\r\n <span className=\"sg-pagination-total\">\r\n {totalPrefix} {total}\r\n </span>\r\n )\r\n }\r\n\r\n const renderSizeChanger = () => {\r\n if (!showSizeChanger) return null\r\n return (\r\n <select\r\n className=\"sg-pagination-size-changer\"\r\n value={pageSize}\r\n onChange={(e) => onPageSizeChange?.(Number(e.target.value))}\r\n disabled={disabled}\r\n >\r\n {pageSizeOptions.map((opt) => (\r\n <option key={opt} value={opt}>\r\n {opt} {itemsPerPageLabel}\r\n </option>\r\n ))}\r\n </select>\r\n )\r\n }\r\n\r\n const renderQuickJumper = () => {\r\n if (!showQuickJumper) return null\r\n return (\r\n <span className=\"sg-pagination-quick-jumper\">\r\n {jumpLabel}\r\n <input\r\n type=\"text\"\r\n value={jumpValue}\r\n onChange={(e) => setJumpValue(e.target.value)}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') handleJump()\r\n }}\r\n onBlur={handleJump}\r\n disabled={disabled}\r\n className=\"sg-pagination-jumper-input\"\r\n />\r\n </span>\r\n )\r\n }\r\n\r\n if (unstyled) {\r\n return (\r\n <nav className={className} style={style} aria-label={ariaLabel} onKeyDown={handleKeyDown}>\r\n <button\r\n type=\"button\"\r\n disabled={safeCurrentPage <= 1}\r\n onClick={() => go(safeCurrentPage - 1)}\r\n >\r\n ‹\r\n </button>\r\n {pages.map((p, i) =>\r\n p === '...' ? (\r\n <span key={`e${i}`}>…</span>\r\n ) : (\r\n <button\r\n key={p}\r\n type=\"button\"\r\n onClick={() => go(p as number)}\r\n aria-current={p === safeCurrentPage ? 'page' : undefined}\r\n >\r\n {p}\r\n </button>\r\n ),\r\n )}\r\n <button\r\n type=\"button\"\r\n disabled={safeCurrentPage >= totalPages}\r\n onClick={() => go(safeCurrentPage + 1)}\r\n >\r\n ›\r\n </button>\r\n </nav>\r\n )\r\n }\r\n\r\n if (simple) {\r\n return (\r\n <nav\r\n className={[\r\n 'sg-pagination sg-pagination-simple',\r\n disabled ? 'sg-pagination-disabled' : '',\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={style}\r\n aria-label={ariaLabel}\r\n onKeyDown={handleKeyDown}\r\n >\r\n <button\r\n type=\"button\"\r\n className=\"sg-pagination-item sg-pagination-prev\"\r\n disabled={safeCurrentPage <= 1}\r\n onClick={() => go(safeCurrentPage - 1)}\r\n >\r\n ‹\r\n </button>\r\n <span className=\"sg-pagination-simple-pager\">\r\n {safeCurrentPage} / {totalPages}\r\n </span>\r\n <button\r\n type=\"button\"\r\n className=\"sg-pagination-item sg-pagination-next\"\r\n disabled={safeCurrentPage >= totalPages}\r\n onClick={() => go(safeCurrentPage + 1)}\r\n >\r\n ›\r\n </button>\r\n </nav>\r\n )\r\n }\r\n\r\n return (\r\n <nav\r\n className={['sg-pagination', disabled ? 'sg-pagination-disabled' : '', className]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={style}\r\n aria-label={ariaLabel}\r\n onKeyDown={handleKeyDown}\r\n >\r\n {renderTotal()}\r\n <button\r\n type=\"button\"\r\n className=\"sg-pagination-item sg-pagination-prev\"\r\n disabled={safeCurrentPage <= 1}\r\n onClick={() => go(safeCurrentPage - 1)}\r\n >\r\n ‹\r\n </button>\r\n {pages.map((p, i) =>\r\n p === '...' ? (\r\n <span key={`e${i}`} className=\"sg-pagination-ellipsis\">\r\n …\r\n </span>\r\n ) : (\r\n <button\r\n key={p}\r\n type=\"button\"\r\n className={`sg-pagination-item${p === safeCurrentPage ? ' sg-pagination-item-active' : ''}`}\r\n onClick={() => go(p as number)}\r\n aria-current={p === safeCurrentPage ? 'page' : undefined}\r\n >\r\n {p}\r\n </button>\r\n ),\r\n )}\r\n <button\r\n type=\"button\"\r\n className=\"sg-pagination-item sg-pagination-next\"\r\n disabled={safeCurrentPage >= totalPages}\r\n onClick={() => go(safeCurrentPage + 1)}\r\n >\r\n ›\r\n </button>\r\n {renderSizeChanger()}\r\n {renderQuickJumper()}\r\n </nav>\r\n )\r\n}\r\n\r\n/**\r\n * Build a 7-slot page strip so the control width stays stable when the\r\n * user jumps between pages. Layouts:\r\n * • near start: [1] [2] [3] [4] [5] [...] [N]\r\n * • middle: [1] [...] [c-1] [c] [c+1] [...] [N]\r\n * • near end: [1] [...] [N-4] [N-3] [N-2] [N-1] [N]\r\n * Totals < 8 are rendered as a contiguous range — the strip is already\r\n * narrow enough that prev/next jumps cannot shift the surrounding layout.\r\n */\r\nfunction buildPages(current: number, total: number): (number | '...')[] {\r\n if (total <= 7) {\r\n return Array.from({ length: total }, (_, i) => i + 1)\r\n }\r\n if (current <= 4) {\r\n return [1, 2, 3, 4, 5, '...', total]\r\n }\r\n if (current >= total - 3) {\r\n return [1, '...', total - 4, total - 3, total - 2, total - 1, total]\r\n }\r\n return [1, '...', current - 1, current, current + 1, '...', total]\r\n}\r\n","import { useState, useRef, useEffect, useId } from 'react'\nimport { useConfig } from '../ConfigProvider'\nimport { Transition } from './Transition'\nimport type { BaseComponentProps, InteractiveProps, SizableProps } from '../../types'\nimport { Spin } from './Spin'\n\n/** Single selectable entry in a Select dropdown or native option list. */\nexport interface SelectOption {\n /** Display text for the option. */\n label: string\n /** Value submitted with the form and returned by onChange. */\n value: string | number\n /** When true, the option cannot be selected. */\n disabled?: boolean\n /** When true, shows a loading state for the option. */\n loading?: boolean\n}\n\n/** Props shared by single and multiple modes. */\ninterface SelectPropsBase extends BaseComponentProps, InteractiveProps, SizableProps {\n /** Options shown in the dropdown or native select. */\n options: SelectOption[]\n /** Text shown when nothing is selected. */\n placeholder?: string\n /** Called when the control loses focus. */\n onBlur?: () => void\n /**\n * Accessible name for the control. Required for the styled (non-`unstyled`)\n * variant when there is no surrounding `<label htmlFor=...>` — the styled\n * trigger is a `<div role=\"combobox\">` and a parent `<label>` cannot\n * associate. WCAG 4.1.2 expects a name for every interactive control;\n * provide either `'aria-label'` or `'aria-labelledby'`.\n *\n * In the `unstyled` variant the underlying native `<select>` is fully\n * labelable, so this prop is purely informational there.\n */\n 'aria-label'?: string\n /** Id(s) of the element(s) that describe this control. Mirrors `aria-label`. */\n 'aria-labelledby'?: string\n}\n\n/** Single-select variant. `value` is one option value. */\nexport interface SelectPropsSingle extends SelectPropsBase {\n /** When false/omitted, the component is single-select. */\n multiple?: false\n /** Controlled selected value. */\n value?: string | number\n /** Initial value when uncontrolled. */\n defaultValue?: string | number\n /** Called when the selection changes. */\n onChange?: (value: string | number) => void\n}\n\n/**\n * Multiple-select variant. `value` is an array. Selecting an option\n * toggles its presence in the array; the dropdown stays open while picking.\n */\nexport interface SelectPropsMultiple extends SelectPropsBase {\n /** Enables multi-select mode. Render shows chips per selected option. */\n multiple: true\n /** Controlled selected values. */\n value?: (string | number)[]\n /** Initial selection when uncontrolled. */\n defaultValue?: (string | number)[]\n /** Called when the selection set changes. */\n onChange?: (values: (string | number)[]) => void\n}\n\n/** Props for the Select combobox; supports styled or native unstyled rendering. */\nexport type SelectProps = SelectPropsSingle | SelectPropsMultiple\n\n/**\n * Dropdown or native select for choosing one option (default) or many\n * options when `multiple` is set. Keyboard and click-outside behavior apply\n * in the styled (non-unstyled) mode.\n *\n * @default placeholder - `'Select...'`\n */\nexport function Select(props: SelectProps) {\n const {\n options,\n placeholder = 'Select...',\n disabled: disabledProp,\n loading,\n size: sizeProp,\n onBlur,\n className,\n style,\n unstyled,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n } = props\n\n const isMultiple = props.multiple === true\n const config = useConfig()\n const size = sizeProp ?? config.size ?? 'middle'\n const disabled = disabledProp ?? config.disabled ?? false\n\n const initialSingle = isMultiple\n ? undefined\n : (props.value ?? props.defaultValue)\n const initialMultiple: (string | number)[] = isMultiple\n ? (props.value ?? props.defaultValue ?? [])\n : []\n\n const [internalSingle, setInternalSingle] = useState<string | number | undefined>(initialSingle)\n const [internalMultiple, setInternalMultiple] = useState<(string | number)[]>(initialMultiple)\n const [open, setOpen] = useState(false)\n const [focusedIndex, setFocusedIndex] = useState(-1)\n const ref = useRef<HTMLDivElement>(null)\n const listboxId = useId()\n\n const currentSingle = isMultiple\n ? undefined\n : ((props.value ?? internalSingle) as string | number | undefined)\n const currentMultiple: (string | number)[] = isMultiple\n ? ((props.value ?? internalMultiple) as (string | number)[])\n : []\n\n const selectedOption = isMultiple\n ? undefined\n : options.find((o) => o.value === currentSingle)\n const selectedOptions = isMultiple\n ? options.filter((o) => currentMultiple.includes(o.value))\n : []\n\n useEffect(() => {\n const handleClickOutside = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setOpen(false)\n }\n }\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }, [])\n\n useEffect(() => {\n if (!open) setFocusedIndex(-1)\n }, [open])\n\n const emitSingle = (val: string | number) => {\n setInternalSingle(val)\n if (!isMultiple) props.onChange?.(val)\n }\n\n const emitMultiple = (vals: (string | number)[]) => {\n setInternalMultiple(vals)\n if (isMultiple) props.onChange?.(vals)\n }\n\n const handleSelect = (opt: SelectOption) => {\n if (opt.disabled || opt.loading) return\n if (isMultiple) {\n const exists = currentMultiple.includes(opt.value)\n const next = exists\n ? currentMultiple.filter((v) => v !== opt.value)\n : [...currentMultiple, opt.value]\n emitMultiple(next)\n } else {\n emitSingle(opt.value)\n setOpen(false)\n }\n }\n\n const handleRemoveTag = (val: string | number, e: React.MouseEvent) => {\n e.stopPropagation()\n if (disabled || loading) return\n emitMultiple(currentMultiple.filter((v) => v !== val))\n }\n\n if (unstyled) {\n if (isMultiple) {\n return (\n <select\n className={className}\n style={style}\n multiple\n value={currentMultiple.map(String)}\n disabled={disabled || loading}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n onChange={(e) => {\n const picked = Array.from(e.target.selectedOptions).map((o) => {\n const v = o.value\n const numVal = Number(v)\n return options.some((opt) => opt.value === numVal) ? numVal : v\n })\n emitMultiple(picked)\n }}\n onBlur={onBlur}\n >\n {options.map((opt) => (\n <option key={opt.value} value={opt.value} disabled={opt.disabled}>\n {opt.label}\n </option>\n ))}\n </select>\n )\n }\n return (\n <select\n className={className}\n style={style}\n value={currentSingle as string}\n disabled={disabled || loading}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n onChange={(e) => {\n const v = e.target.value\n const numVal = Number(v)\n const finalVal = options.some((o) => o.value === numVal) ? numVal : v\n emitSingle(finalVal)\n }}\n onBlur={onBlur}\n >\n {!selectedOption && <option value=\"\">{placeholder}</option>}\n {options.map((opt) => (\n <option key={opt.value} value={opt.value} disabled={opt.disabled}>\n {opt.label}\n </option>\n ))}\n </select>\n )\n }\n\n const wrapperClass = [\n 'sg-select',\n `sg-select-${size}`,\n isMultiple ? 'sg-select-multiple' : '',\n open ? 'sg-select-open' : '',\n disabled || loading ? 'sg-select-disabled' : '',\n loading ? 'sg-select-loading' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const isOptionSelected = (opt: SelectOption) =>\n isMultiple ? currentMultiple.includes(opt.value) : opt.value === currentSingle\n\n const renderTrigger = () => {\n if (isMultiple) {\n if (selectedOptions.length === 0) {\n return <span className=\"sg-select-placeholder\">{placeholder}</span>\n }\n return (\n <span className=\"sg-select-tags\">\n {selectedOptions.map((opt) => (\n <span key={opt.value} className=\"sg-select-tag\">\n <span className=\"sg-select-tag-label\">{opt.label}</span>\n <button\n type=\"button\"\n className=\"sg-select-tag-remove\"\n aria-label={`Remove ${opt.label}`}\n tabIndex={-1}\n onClick={(e) => handleRemoveTag(opt.value, e)}\n >\n ×\n </button>\n </span>\n ))}\n </span>\n )\n }\n return (\n <span\n className={\n selectedOption ? 'sg-select-selection-item' : 'sg-select-placeholder'\n }\n >\n {selectedOption?.label ?? placeholder}\n </span>\n )\n }\n\n return (\n <div className={wrapperClass} ref={ref} style={style} onBlur={onBlur}>\n <div\n className=\"sg-select-selector\"\n role=\"combobox\"\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={listboxId}\n aria-multiselectable={isMultiple || undefined}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-disabled={disabled || loading || undefined}\n tabIndex={disabled || loading ? -1 : 0}\n onClick={() => !disabled && !loading && setOpen(!open)}\n onKeyDown={(e) => {\n if (disabled || loading) return\n switch (e.key) {\n case 'Enter':\n case ' ':\n e.preventDefault()\n if (open && focusedIndex >= 0) {\n handleSelect(options[focusedIndex])\n } else {\n setOpen(!open)\n }\n break\n case 'Escape':\n e.preventDefault()\n setOpen(false)\n break\n case 'ArrowDown':\n e.preventDefault()\n if (!open) setOpen(true)\n else setFocusedIndex((i) => (i + 1) % options.length)\n break\n case 'ArrowUp':\n e.preventDefault()\n if (!open) setOpen(true)\n else\n setFocusedIndex(\n (i) => (i - 1 + options.length) % options.length,\n )\n break\n case 'Backspace':\n if (isMultiple && currentMultiple.length > 0) {\n emitMultiple(currentMultiple.slice(0, -1))\n }\n break\n }\n }}\n >\n {renderTrigger()}\n {loading ? (\n <Spin size=\"small\" unstyled={unstyled} />\n ) : (\n <span className=\"sg-select-arrow\">{open ? '\\u25B2' : '\\u25BC'}</span>\n )}\n </div>\n <Transition visible={open} name=\"sg-slide-up\" unmountOnExit>\n <div className=\"sg-select-dropdown\" role=\"listbox\" id={listboxId} aria-multiselectable={isMultiple || undefined}>\n {options.map((opt, idx) => (\n <div\n key={opt.value}\n role=\"option\"\n aria-selected={isOptionSelected(opt)}\n className={[\n 'sg-select-option',\n isOptionSelected(opt) ? 'sg-select-option-selected' : '',\n idx === focusedIndex ? 'sg-select-option-focused' : '',\n opt.disabled || opt.loading ? 'sg-select-option-disabled' : '',\n opt.loading ? 'sg-select-option-loading' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={() => handleSelect(opt)}\n >\n <span>{opt.label}</span>\n {opt.loading && <Spin size=\"small\" unstyled={unstyled} />}\n </div>\n ))}\n </div>\n </Transition>\n </div>\n )\n}\n","/** Serializes a 2D string matrix to CSV with RFC-style quoting. */\r\nexport function toCSVString(data: string[][]): string {\r\n return data\r\n .map((row) =>\r\n row\r\n .map((cell) => {\r\n if (cell.includes(',') || cell.includes('\"') || cell.includes('\\n')) {\r\n return `\"${cell.replace(/\"/g, '\"\"')}\"`\r\n }\r\n return cell\r\n })\r\n .join(','),\r\n )\r\n .join('\\n')\r\n}\r\n\r\n/** Serializes a 2D string matrix to tab-separated lines. */\r\nexport function toTSVString(data: string[][]): string {\r\n return data.map((row) => row.join('\\t')).join('\\n')\r\n}\r\n\r\n/**\r\n * Builds a JSON array of row objects using string headers as keys.\r\n * @param pretty - Pretty-print with indentation when true.\r\n * @default true\r\n */\r\nexport function toJSONString(\r\n headers: string[],\r\n rows: string[][],\r\n pretty = true,\r\n): string {\r\n const objects = rows.map((row) => {\r\n const obj: Record<string, string> = {}\r\n headers.forEach((h, i) => {\r\n obj[h] = row[i] ?? ''\r\n })\r\n return obj\r\n })\r\n return pretty ? JSON.stringify(objects, null, 2) : JSON.stringify(objects)\r\n}\r\n\r\n/**\r\n * Triggers a CSV file download in the browser.\r\n * @default filename `'export.csv'`\r\n */\r\nexport function downloadCSV(content: string, filename = 'export.csv'): void {\r\n const blob = new Blob([content], { type: 'text/csv;charset=utf-8;' })\r\n const url = URL.createObjectURL(blob)\r\n const a = document.createElement('a')\r\n a.href = url\r\n a.download = filename\r\n a.click()\r\n URL.revokeObjectURL(url)\r\n}\r\n\r\n/**\r\n * Triggers a JSON file download in the browser.\r\n * @default filename `'export.json'`\r\n */\r\nexport function downloadJSON(content: string, filename = 'export.json'): void {\r\n const blob = new Blob([content], { type: 'application/json;charset=utf-8;' })\r\n const url = URL.createObjectURL(blob)\r\n const a = document.createElement('a')\r\n a.href = url\r\n a.download = filename\r\n a.click()\r\n URL.revokeObjectURL(url)\r\n}\r\n\r\n/** Copies text using the Clipboard API when available. */\r\nexport async function copyToClipboard(text: string): Promise<void> {\r\n if (navigator.clipboard) {\r\n await navigator.clipboard.writeText(text)\r\n }\r\n}\r\n\r\n/** Opens a print dialog with the table DOM and current document styles. */\r\nexport function printTable(tableEl: HTMLElement | null): void {\r\n if (!tableEl) return\r\n const printWindow = window.open('', '_blank')\r\n if (!printWindow) return\r\n\r\n const styles = Array.from(document.querySelectorAll('style, link[rel=\"stylesheet\"]'))\r\n .map((el) => el.outerHTML)\r\n .join('\\n')\r\n\r\n printWindow.document.write(`<!DOCTYPE html><html><head>${styles}\r\n <style>\r\n body { padding: 20px; }\r\n .sg-table-toolbar, .sg-table-pagination, .sg-table-selection-bar { display: none !important; }\r\n .sg-table-wrapper { overflow: visible !important; }\r\n .sg-table-scroll { overflow: visible !important; max-height: none !important; }\r\n @media print { @page { size: landscape; margin: 1cm; } }\r\n </style>\r\n </head><body>${tableEl.outerHTML}</body></html>`)\r\n printWindow.document.close()\r\n printWindow.focus()\r\n setTimeout(() => {\r\n printWindow.print()\r\n printWindow.close()\r\n }, 300)\r\n}\r\n","import { useState, useCallback, useMemo, useEffect, useRef } from 'react'\r\nimport { createCore, createTable } from '@skygraph/core'\r\nimport type {\r\n Core,\r\n TableEngine,\r\n TableState,\r\n TableOptions,\r\n RowId,\r\n SortDirection,\r\n SortConfig,\r\n ColumnFilter,\r\n} from '@skygraph/core'\r\n\r\nexport interface UseTableOptions extends TableOptions {\r\n data?: Array<{ id: RowId; data: Record<string, unknown> }>\r\n}\r\n\r\nexport type FilterFn = (row: Record<string, unknown>) => boolean\r\n\r\nexport interface UseTableReturn {\r\n core: Core\r\n table: TableEngine\r\n visibleRows: Array<{ id: RowId; data: Record<string, unknown> }>\r\n tableState: TableState\r\n /** Snapshot of pinned columns; refreshes after `pinColumn` / `clearPinned`. */\r\n pinnedColumns: { left: string[]; right: string[] }\r\n /** Snapshot of persisted column widths; refreshes after `setColumnWidth` /\r\n * `clearColumnWidths`. */\r\n columnWidths: Record<string, number>\r\n setSort: (column: string, direction: SortDirection) => void\r\n setSorts: (sorts: SortConfig[]) => void\r\n clearSort: () => void\r\n addFilter: (filter: ColumnFilter) => void\r\n removeFilter: (column: string) => void\r\n clearFilters: () => void\r\n setFilterFn: (fn: FilterFn | null) => void\r\n setPage: (page: number) => void\r\n nextPage: () => void\r\n prevPage: () => void\r\n pinColumn: (column: string, side: 'left' | 'right' | null) => void\r\n clearPinned: () => void\r\n setColumnWidth: (column: string, width: number) => void\r\n clearColumnWidths: () => void\r\n refresh: () => void\r\n}\r\n\r\nexport function useTable(options?: UseTableOptions): UseTableReturn {\r\n const [{ core, table }] = useState(() => {\r\n const c = createCore()\r\n const t = createTable(c, options)\r\n if (options?.data) {\r\n t.addRows(options.data)\r\n }\r\n return { core: c, table: t }\r\n })\r\n\r\n const [visibleRows, setVisibleRows] = useState(() => table.getVisibleRows())\r\n const [tableState, setTableState] = useState(() => table.getTableState())\r\n const [pinnedColumns, setPinnedColumns] = useState(() => table.getPinnedColumns())\r\n const [columnWidths, setColumnWidthsState] = useState<Record<string, number>>(\r\n () => table.getColumnWidths(),\r\n )\r\n\r\n const prevDataRef = useRef(options?.data)\r\n useEffect(() => {\r\n const newData = options?.data\r\n if (newData === prevDataRef.current) return\r\n prevDataRef.current = newData\r\n\r\n table.reset()\r\n if (newData) {\r\n table.addRows(newData)\r\n }\r\n setVisibleRows(table.getVisibleRows())\r\n setTableState(table.getTableState())\r\n }, [options?.data, table])\r\n\r\n const refresh = useCallback(() => {\r\n setVisibleRows(table.getVisibleRows())\r\n setTableState(table.getTableState())\r\n setPinnedColumns(table.getPinnedColumns())\r\n setColumnWidthsState(table.getColumnWidths())\r\n }, [table])\r\n\r\n const pinColumn = useCallback(\r\n (column: string, side: 'left' | 'right' | null) => {\r\n table.pinColumn(column, side)\r\n setPinnedColumns(table.getPinnedColumns())\r\n },\r\n [table],\r\n )\r\n\r\n const clearPinned = useCallback(() => {\r\n table.clearPinned()\r\n setPinnedColumns(table.getPinnedColumns())\r\n }, [table])\r\n\r\n const setColumnWidth = useCallback(\r\n (column: string, width: number) => {\r\n table.setColumnWidth(column, width)\r\n setColumnWidthsState(table.getColumnWidths())\r\n },\r\n [table],\r\n )\r\n\r\n const clearColumnWidths = useCallback(() => {\r\n table.clearColumnWidths()\r\n setColumnWidthsState(table.getColumnWidths())\r\n }, [table])\r\n\r\n const setSort = useCallback(\r\n (column: string, direction: SortDirection) => {\r\n table.setSort(column, direction)\r\n refresh()\r\n },\r\n [table, refresh]\r\n )\r\n\r\n const setSorts = useCallback(\r\n (sorts: SortConfig[]) => {\r\n table.setSorts(sorts)\r\n refresh()\r\n },\r\n [table, refresh]\r\n )\r\n\r\n const clearSort = useCallback(() => {\r\n table.clearSort()\r\n refresh()\r\n }, [table, refresh])\r\n\r\n const addFilter = useCallback(\r\n (filter: ColumnFilter) => {\r\n table.addFilter(filter)\r\n refresh()\r\n },\r\n [table, refresh]\r\n )\r\n\r\n const removeFilter = useCallback(\r\n (column: string) => {\r\n table.removeFilter(column)\r\n refresh()\r\n },\r\n [table, refresh]\r\n )\r\n\r\n const clearFilters = useCallback(() => {\r\n table.clearFilters()\r\n refresh()\r\n }, [table, refresh])\r\n\r\n const setFilterFn = useCallback(\r\n (fn: FilterFn | null) => {\r\n table.setFilterFn(fn)\r\n refresh()\r\n },\r\n [table, refresh]\r\n )\r\n\r\n const setPage = useCallback(\r\n (page: number) => {\r\n table.setPage(page)\r\n refresh()\r\n },\r\n [table, refresh]\r\n )\r\n\r\n const nextPage = useCallback(() => {\r\n table.nextPage()\r\n refresh()\r\n }, [table, refresh])\r\n\r\n const prevPage = useCallback(() => {\r\n table.prevPage()\r\n refresh()\r\n }, [table, refresh])\r\n\r\n return useMemo(\r\n () => ({\r\n core,\r\n table,\r\n visibleRows,\r\n tableState,\r\n pinnedColumns,\r\n columnWidths,\r\n setSort,\r\n setSorts,\r\n clearSort,\r\n addFilter,\r\n removeFilter,\r\n clearFilters,\r\n setFilterFn,\r\n setPage,\r\n nextPage,\r\n prevPage,\r\n pinColumn,\r\n clearPinned,\r\n setColumnWidth,\r\n clearColumnWidths,\r\n refresh,\r\n }),\r\n [\r\n core,\r\n table,\r\n visibleRows,\r\n tableState,\r\n pinnedColumns,\r\n columnWidths,\r\n setSort,\r\n setSorts,\r\n clearSort,\r\n addFilter,\r\n removeFilter,\r\n clearFilters,\r\n setFilterFn,\r\n setPage,\r\n nextPage,\r\n prevPage,\r\n pinColumn,\r\n clearPinned,\r\n setColumnWidth,\r\n clearColumnWidths,\r\n refresh,\r\n ]\r\n )\r\n}\r\n","import type { PrintOptions } from './types'\r\n\r\n/**\r\n * Вычисляет CSS `@page` блок для popup-страницы по `PrintOptions`. Вынесено\r\n * в отдельную функцию ради тестируемости (snapshot-тест без `window.open`).\r\n */\r\nexport function buildPageRule(opts: PrintOptions = {}): string {\r\n const orientation = opts.orientation ?? 'portrait'\r\n const pageSize = opts.pageSize ?? 'A4'\r\n const margins = opts.margins ?? '1cm'\r\n return `@page { size: ${pageSize} ${orientation}; margin: ${margins}; }`\r\n}\r\n\r\n/**\r\n * Собирает HTML-документ popup-страницы. Используется `printElement` и\r\n * напрямую тестами — поэтому никаких `window.*` побочных эффектов.\r\n *\r\n * Стратегия:\r\n * 1. Клонируем `<style>` и `<link rel=\"stylesheet\">` из текущего\r\n * документа, чтобы popup увидел SkyGraph-стили (включая `print.css`).\r\n * 2. Дописываем нашу `@page`-секцию + `body` reset.\r\n * 3. Опциональный `transform: scale(...)` на обёртке.\r\n * 4. Подставляем `outerHTML` исходного `node`.\r\n * 5. Триггерим `print()` после `load`-события, чтобы шрифты и стили\r\n * успели приехать в popup.\r\n */\r\nexport function buildPrintHtml(\r\n fragment: string,\r\n opts: PrintOptions = {},\r\n documentRef: Document | null = typeof document !== 'undefined' ? document : null,\r\n): string {\r\n const styles =\r\n documentRef === null\r\n ? ''\r\n : Array.from(documentRef.querySelectorAll('style, link[rel=\"stylesheet\"]'))\r\n .map((el) => el.outerHTML)\r\n .join('\\n')\r\n\r\n const pageRule = buildPageRule(opts)\r\n const scale = opts.scale && opts.scale !== 1 ? opts.scale : null\r\n const title = escapeHtml(opts.fileName ?? 'SkyGraph print')\r\n const customStyles = opts.customStyles ?? ''\r\n\r\n const wrapperOpen = scale\r\n ? `<div class=\"sg-print-root\" style=\"transform: scale(${scale}); transform-origin: 0 0;\">`\r\n : `<div class=\"sg-print-root\">`\r\n\r\n return `<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<meta charset=\"utf-8\" />\r\n<title>${title}</title>\r\n${styles}\r\n<style>\r\n ${pageRule}\r\n html, body { margin: 0; padding: 0; background: #fff; }\r\n body { padding: 0; }\r\n .sg-print-root { width: 100%; }\r\n ${customStyles}\r\n</style>\r\n</head>\r\n<body>\r\n${wrapperOpen}\r\n${fragment}\r\n</div>\r\n</body>\r\n</html>`\r\n}\r\n\r\nfunction escapeHtml(s: string): string {\r\n return s\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#39;')\r\n}\r\n\r\n/**\r\n * Открывает popup-окно, инжектирует SkyGraph-стили + `outerHTML` `node`-а,\r\n * и вызывает `window.print()`. Возвращает popup-окно или `null`, если\r\n * браузер заблокировал открытие нового окна.\r\n *\r\n * Пример:\r\n * ```ts\r\n * const ref = useRef<HTMLDivElement>(null)\r\n * <button onClick={() => printElement(ref.current, { fileName: 'report.pdf' })}>\r\n * Print\r\n * </button>\r\n * ```\r\n *\r\n * Никаких runtime-зависимостей: всё на штатном `window.open` + CSS\r\n * `@media print`. PDF получается через системный диалог печати → \"Save as PDF\".\r\n */\r\nexport function printElement(\r\n node: Element | null,\r\n opts: PrintOptions = {},\r\n): Window | null {\r\n if (!node) return null\r\n if (typeof window === 'undefined') return null\r\n\r\n const popup = window.open('', '_blank')\r\n if (!popup) return null\r\n\r\n const html = buildPrintHtml(node.outerHTML, opts)\r\n popup.document.open()\r\n popup.document.write(html)\r\n popup.document.close()\r\n popup.focus()\r\n\r\n if (opts.skipPrint) return popup\r\n\r\n // Дать браузеру время подгрузить linked-stylesheet'ы. `setTimeout(0)`\r\n // достаточно для inline `<style>` блоков; для `<link>` лучше ждать `load`.\r\n const trigger = () => {\r\n try {\r\n popup.print()\r\n } catch {\r\n // Печать может быть заблокирована; popup всё равно остаётся открытым,\r\n // пользователь может вызвать \"печать\" из меню браузера вручную.\r\n }\r\n if (!opts.keepOpen) {\r\n try {\r\n popup.close()\r\n } catch {\r\n // Closed by user already / blocked — игнорируем.\r\n }\r\n }\r\n }\r\n\r\n // `load` срабатывает после линковки стилей. Если popup уже `complete`,\r\n // запускаем сразу. Минимальный fallback на `setTimeout` — на случай\r\n // окружений (jsdom), где `load` не диспатчится.\r\n if (popup.document.readyState === 'complete') {\r\n setTimeout(trigger, 0)\r\n } else {\r\n popup.addEventListener('load', () => setTimeout(trigger, 0), { once: true })\r\n setTimeout(trigger, 300)\r\n }\r\n\r\n return popup\r\n}\r\n","import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useRef } from 'react'\r\nimport { Input } from '../../ui/Input'\r\nimport { Pagination } from '../../ui/Pagination'\r\nimport { Spin } from '../../ui/Spin'\r\nimport { Checkbox } from '../../ui/Checkbox'\r\nimport { TableHeader } from './TableHeader'\r\nimport { TableBody } from './TableBody'\r\nimport { VirtualTableBody } from './VirtualTableBody'\r\nimport { ContextMenu } from './ContextMenu'\r\nimport { useTableState } from './useTableState'\r\nimport { useConfig } from '../../ConfigProvider'\r\nimport {\r\n toCSVString,\r\n downloadCSV,\r\n toTSVString,\r\n toJSONString,\r\n downloadJSON,\r\n copyToClipboard,\r\n} from './export'\r\nimport { printElement } from '../../../utils/print'\r\nimport type { PrintOptions } from '../../../utils/print'\r\nimport { slotClass, slotStyle } from '../../../types'\r\nimport type { TableProps, TableClassNames, TableStyles } from './types'\r\n\r\n/**\r\n * Императивный API таблицы для ref.print() и других ref-методов.\r\n */\r\nexport interface TableRef {\r\n /**\r\n * Открыть popup и вызвать window.print() для текущей DOM-области таблицы.\r\n * Опции мерджатся с теми, что заданы через prop `printable`\r\n * (на уровне prop приоритетен `fileName`).\r\n */\r\n print: (opts?: PrintOptions) => void\r\n}\r\n\r\nconst DRAG_HANDLE_WIDTH = '32px'\r\nconst ROW_NUMBER_WIDTH = '48px'\r\n\r\n/**\r\n * Data table with sorting, filtering, selection, grouping, virtualization, and export tools.\r\n * Layout and behavior are driven by `TableProps` and internal `useTableState`.\r\n */\r\nfunction TableInner(props: TableProps, forwardedRef: React.ForwardedRef<TableRef>) {\r\n const {\r\n rowSelection,\r\n expandable,\r\n sticky,\r\n draggable,\r\n searchable,\r\n showPagination = true,\r\n bordered: borderedProp,\r\n size: sizeProp,\r\n scroll,\r\n summary,\r\n onRowClick,\r\n onCellEdit,\r\n loading: loadingProp,\r\n rowClassName,\r\n className,\r\n style,\r\n unstyled,\r\n rowDraggable,\r\n onRowOrderChange,\r\n headerContextMenu,\r\n cellContextMenu,\r\n columnVisibility,\r\n virtual: virtualProp,\r\n exportable,\r\n onExport,\r\n selectionSummary,\r\n selectionActions,\r\n striped,\r\n showSizeChanger,\r\n pageSizeOptions,\r\n showQuickJumper,\r\n showTotal,\r\n onPageSizeChange,\r\n showRowNumber,\r\n footer,\r\n fullscreenable,\r\n densityToggle,\r\n groupBy,\r\n groupByOptions,\r\n onGroupByChange,\r\n keyboardNavigation,\r\n emptyContent,\r\n printable,\r\n exportJSON,\r\n highlightOnHover,\r\n columnAutoResize,\r\n columnPinning,\r\n classNames: slotCls,\r\n styles: slotSty,\r\n } = props\r\n\r\n const sCls: TableClassNames = slotCls ?? {}\r\n const sSty: TableStyles = slotSty ?? {}\r\n\r\n const config = useConfig()\r\n const sizeFromProp = sizeProp ?? config.size ?? 'middle'\r\n const bordered = borderedProp ?? config.bordered ?? false\r\n const loading = loadingProp ?? false\r\n\r\n const state = useTableState(props)\r\n const tableRef = useRef<HTMLDivElement>(null)\r\n const scrollRef = useRef<HTMLDivElement>(null)\r\n\r\n const effectiveSize = densityToggle ? state.density : sizeFromProp\r\n\r\n // Memoised so the empty `{}` literal stays referentially stable across\r\n // renders — otherwise `useMemo(gridTemplate, [rowNumConfig, ...])` below\r\n // would invalidate every render whenever `showRowNumber === true`.\r\n const rowNumConfig = useMemo(\r\n () => (showRowNumber ? (typeof showRowNumber === 'object' ? showRowNumber : {}) : null),\r\n [showRowNumber],\r\n )\r\n\r\n const getExportData = useCallback(() => {\r\n const cols = state.columns.map((c) => c.key)\r\n const headers = state.columns.map((c) => (typeof c.title === 'string' ? c.title : c.key))\r\n const rows = state.flatRows\r\n .filter((r) => !r.__groupRow)\r\n .map((row) =>\r\n cols.map((k) => {\r\n const v = row.data[k]\r\n return v == null ? '' : String(v)\r\n }),\r\n )\r\n return { cols, headers, rows }\r\n }, [state.columns, state.flatRows])\r\n\r\n const handleExportCSV = useCallback(() => {\r\n const { headers, rows } = getExportData()\r\n const data = [headers, ...rows]\r\n if (onExport) {\r\n onExport(data)\r\n } else {\r\n downloadCSV(toCSVString(data))\r\n }\r\n }, [getExportData, onExport])\r\n\r\n const handleExportJSON = useCallback(() => {\r\n const { headers, rows } = getExportData()\r\n downloadJSON(toJSONString(headers, rows))\r\n }, [getExportData])\r\n\r\n const handleCopy = useCallback(async () => {\r\n const { headers, rows } = getExportData()\r\n await copyToClipboard(toTSVString([headers, ...rows]))\r\n }, [getExportData])\r\n\r\n const printOptionsFromProp: PrintOptions = useMemo(() => {\r\n if (typeof printable === 'object' && printable !== null) {\r\n return { fileName: printable.fileName }\r\n }\r\n return {}\r\n }, [printable])\r\n\r\n const doPrint = useCallback(\r\n (opts?: PrintOptions) => {\r\n printElement(tableRef.current, { ...printOptionsFromProp, ...(opts ?? {}) })\r\n },\r\n [printOptionsFromProp],\r\n )\r\n\r\n const handlePrint = useCallback(() => {\r\n doPrint()\r\n }, [doPrint])\r\n\r\n useImperativeHandle(forwardedRef, () => ({ print: doPrint }), [doPrint])\r\n\r\n // Grid template\r\n const gridTemplate = useMemo(() => {\r\n const parts: string[] = []\r\n if (rowDraggable) parts.push(DRAG_HANDLE_WIDTH)\r\n if (rowNumConfig) parts.push(rowNumConfig.width ? `${rowNumConfig.width}px` : ROW_NUMBER_WIDTH)\r\n parts.push(state.gridTemplate)\r\n return parts.join(' ')\r\n }, [rowDraggable, rowNumConfig, state.gridTemplate])\r\n\r\n const totalCols = state.totalCols + (rowDraggable ? 1 : 0) + (rowNumConfig ? 1 : 0)\r\n\r\n const virtualConfig = virtualProp\r\n ? {\r\n rowHeight: typeof virtualProp === 'object' ? (virtualProp.rowHeight ?? 40) : 40,\r\n estimateRowHeight:\r\n typeof virtualProp === 'object' ? virtualProp.estimateRowHeight : undefined,\r\n overscan: typeof virtualProp === 'object' ? (virtualProp.overscan ?? 5) : 5,\r\n height: typeof virtualProp === 'object' ? virtualProp.height : undefined,\r\n }\r\n : null\r\n\r\n // Fixed-height fast path: number `rowHeight` + no measurement estimate.\r\n // We pin every visible cell to that height via CSS so the rendered DOM's\r\n // `scrollHeight` matches the engine's `totalHeight` exactly — without\r\n // this, natural cell padding makes the two drift apart by a few pixels\r\n // per row and the scrollbar thumb lags behind the cursor while dragged.\r\n const virtualFixedRowHeight =\r\n virtualConfig &&\r\n typeof virtualConfig.rowHeight === 'number' &&\r\n virtualConfig.estimateRowHeight == null\r\n ? virtualConfig.rowHeight\r\n : null\r\n\r\n // Unstyled\r\n if (unstyled) {\r\n return (\r\n <div className={className} style={style} role=\"table\">\r\n <div role=\"rowgroup\">\r\n <div role=\"row\">\r\n {state.columns.map((col) => (\r\n <span\r\n key={col.key}\r\n role=\"columnheader\"\r\n onClick={(e) => state.handleSort(col, e.shiftKey)}\r\n >\r\n {col.title}\r\n </span>\r\n ))}\r\n </div>\r\n </div>\r\n <div role=\"rowgroup\">\r\n {state.flatRows.map((row) => (\r\n <div key={row.id} role=\"row\">\r\n {state.columns.map((col) => (\r\n <span key={col.key} role=\"cell\">\r\n {col.render\r\n ? col.render(row.data[col.key], row.data, row.id)\r\n : String(row.data[col.key] ?? '')}\r\n </span>\r\n ))}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )\r\n }\r\n\r\n const hasToolbar =\r\n searchable ||\r\n columnVisibility ||\r\n exportable ||\r\n exportJSON ||\r\n fullscreenable ||\r\n densityToggle ||\r\n printable ||\r\n groupBy ||\r\n (groupByOptions && groupByOptions.length > 0)\r\n\r\n const wrapperCls = [\r\n 'sg-table-wrapper',\r\n `sg-table-${effectiveSize}`,\r\n bordered ? 'sg-table-bordered' : '',\r\n sticky || virtualConfig ? 'sg-table-sticky' : '',\r\n loading ? 'sg-table-loading' : '',\r\n striped ? 'sg-table-striped' : '',\r\n state.isFullscreen ? 'sg-table-fullscreen' : '',\r\n highlightOnHover === false ? '' : 'sg-table-hoverable',\r\n sCls.root,\r\n className,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')\r\n\r\n const scrollStyle: React.CSSProperties = {}\r\n if (scroll?.x) scrollStyle.overflowX = 'auto'\r\n if (virtualConfig) {\r\n // Virtualization needs an owned vertical scroll so it can observe the\r\n // viewport. `virtual.height` wins over `scroll.y` for the body window.\r\n scrollStyle.overflowY = 'auto'\r\n scrollStyle.height = virtualConfig.height ?? scroll?.y ?? 400\r\n } else if (scroll?.y) {\r\n scrollStyle.overflowY = 'auto'\r\n scrollStyle.maxHeight = scroll.y\r\n }\r\n\r\n const selectedCount = rowSelection?.selectedKeys.length ?? 0\r\n\r\n return (\r\n <div\r\n className={wrapperCls}\r\n style={slotStyle(sSty.root, style)}\r\n ref={(el) => {\r\n ;(tableRef as React.MutableRefObject<HTMLDivElement | null>).current = el\r\n ;(state.wrapperRef as React.MutableRefObject<HTMLDivElement | null>).current = el\r\n }}\r\n onKeyDown={keyboardNavigation ? state.handleKeyNav : undefined}\r\n tabIndex={keyboardNavigation ? 0 : undefined}\r\n >\r\n {/* Toolbar */}\r\n {hasToolbar && (\r\n <div className={slotClass('sg-table-toolbar', sCls.toolbar)} style={sSty.toolbar}>\r\n {searchable && (\r\n <Input\r\n placeholder={state.t.searchPlaceholder}\r\n size=\"small\"\r\n value={state.searchText}\r\n onChange={state.setSearchText}\r\n style={{ maxWidth: 240 }}\r\n />\r\n )}\r\n <div className=\"sg-table-toolbar-right\">\r\n {groupByOptions && groupByOptions.length > 0 && (\r\n <GroupByDropdown\r\n value={groupBy ?? null}\r\n options={groupByOptions}\r\n onChange={onGroupByChange ?? (() => {})}\r\n t={state.t}\r\n />\r\n )}\r\n {groupBy && (\r\n <div className=\"sg-table-toolbar-group\">\r\n <button className=\"sg-table-toolbar-btn\" onClick={state.expandAllGroups}>\r\n {state.t.groupExpand}\r\n </button>\r\n <button className=\"sg-table-toolbar-btn\" onClick={state.collapseAllGroups}>\r\n {state.t.groupCollapse}\r\n </button>\r\n </div>\r\n )}\r\n {densityToggle && (\r\n <DensityDropdown value={state.density} onChange={state.setDensity} t={state.t} />\r\n )}\r\n {columnVisibility && (\r\n <ColumnVisibilityDropdown\r\n leafColumns={state.leafColumns}\r\n hiddenSet={state.hiddenSet}\r\n onToggle={state.toggleColumnVisibility}\r\n label={state.t.showColumns}\r\n />\r\n )}\r\n {exportable && (\r\n <>\r\n <button className=\"sg-table-toolbar-btn\" onClick={handleExportCSV}>\r\n {state.t.exportCSV}\r\n </button>\r\n <button className=\"sg-table-toolbar-btn\" onClick={handleCopy}>\r\n {state.t.copyTable}\r\n </button>\r\n </>\r\n )}\r\n {exportJSON && (\r\n <button className=\"sg-table-toolbar-btn\" onClick={handleExportJSON}>\r\n {state.t.exportJSON}\r\n </button>\r\n )}\r\n {printable && (\r\n <button className=\"sg-table-toolbar-btn\" onClick={handlePrint}>\r\n {state.t.print}\r\n </button>\r\n )}\r\n {fullscreenable && (\r\n <button className=\"sg-table-toolbar-btn\" onClick={state.toggleFullscreen}>\r\n {state.isFullscreen ? state.t.exitFullscreen : state.t.fullscreen}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Selection Summary Bar */}\r\n {selectionSummary && selectedCount > 0 && (\r\n <div className=\"sg-table-selection-bar\">\r\n <span className=\"sg-table-selection-count\">{state.t.selectedRows(selectedCount)}</span>\r\n {selectionActions?.map((action) => (\r\n <button\r\n key={action.key}\r\n className={`sg-table-selection-action${action.danger ? ' sg-table-selection-action-danger' : ''}`}\r\n onClick={() =>\r\n action.onClick(\r\n rowSelection!.selectedKeys,\r\n state.visibleRows\r\n .filter((r) => rowSelection!.selectedKeys.includes(r.id))\r\n .map((r) => r.data),\r\n )\r\n }\r\n >\r\n {action.label}\r\n </button>\r\n ))}\r\n <button\r\n className=\"sg-table-selection-clear\"\r\n onClick={() => rowSelection?.onChange([], [])}\r\n >\r\n ✕\r\n </button>\r\n </div>\r\n )}\r\n\r\n <div\r\n ref={scrollRef}\r\n className={slotClass('sg-table-scroll', scroll?.x ? 'sg-table-scroll-x' : '', sCls.scroll)}\r\n style={slotStyle(\r\n Object.keys(scrollStyle).length > 0 ? scrollStyle : undefined,\r\n sSty.scroll,\r\n )}\r\n >\r\n {/* Pinned top rows */}\r\n {state.pinnedTop.length > 0 && (\r\n <div\r\n className=\"sg-table-pinned-top\"\r\n style={{ gridTemplateColumns: gridTemplate, minWidth: scroll?.x }}\r\n >\r\n <TableBody\r\n columns={state.columns}\r\n flatRows={state.pinnedTop}\r\n rowSelection={rowSelection}\r\n expandable={expandable}\r\n isTreeMode={state.isTreeMode}\r\n indentSize={state.indentSize}\r\n treeExpanded={state.treeExpanded}\r\n expandedKeys={state.expandedKeys}\r\n totalCols={totalCols}\r\n spanMap={state.spanMap}\r\n hiddenCells={state.hiddenCells}\r\n t={state.t}\r\n rowClassName={rowClassName}\r\n fixedStyle={state.fixedStyle}\r\n onRowClick={onRowClick}\r\n onCellEdit={onCellEdit}\r\n onSelectRow={state.handleSelectRow}\r\n onToggleExpand={state.handleToggleExpand}\r\n onToggleTreeExpand={state.handleToggleTreeExpand}\r\n onContextMenu={state.setContextMenu}\r\n striped={false}\r\n isPinnedSection\r\n slotClassNames={sCls}\r\n slotStyles={sSty}\r\n />\r\n </div>\r\n )}\r\n\r\n <div\r\n className={slotClass(\r\n 'sg-table-grid',\r\n virtualFixedRowHeight != null ? 'sg-table-grid-virtual-fixed' : '',\r\n sCls.grid,\r\n )}\r\n style={slotStyle(\r\n {\r\n gridTemplateColumns: gridTemplate,\r\n minWidth: scroll?.x,\r\n ...(virtualFixedRowHeight != null\r\n ? ({\r\n ['--sg-virtual-row-height' as string]: `${virtualFixedRowHeight}px`,\r\n } as React.CSSProperties)\r\n : null),\r\n },\r\n sSty.grid,\r\n )}\r\n role=\"table\"\r\n >\r\n <TableHeader\r\n columns={state.columns}\r\n headerRows={state.headerRows}\r\n hasColumnGroups={state.hasColumnGroups}\r\n rowSelection={rowSelection}\r\n expandable={expandable}\r\n draggable={draggable}\r\n allSelected={state.allSelected}\r\n someSelected={state.someSelected}\r\n dragOver={state.dragOver}\r\n t={state.t}\r\n fixedStyle={state.fixedStyle}\r\n onSort={state.handleSort}\r\n onSelectAll={state.handleSelectAll}\r\n onDragStart={state.handleDragStart}\r\n onDragOver={state.handleDragOver}\r\n onDragLeave={state.setDragOver}\r\n onDrop={state.handleDrop}\r\n onDragEnd={state.handleDragEnd}\r\n onResizeStart={state.handleResizeStart}\r\n filterState={state.filterState}\r\n filterActions={state.filterActions}\r\n filterRef={state.filterRef}\r\n sorts={state.sorts}\r\n getSortIndex={state.getSortIndex}\r\n getSortDirection={state.getSortDirection}\r\n headerContextMenu={headerContextMenu}\r\n onContextMenu={state.setContextMenu}\r\n showRowNumber={!!rowNumConfig}\r\n rowDraggable={rowDraggable}\r\n columnPinning={columnPinning}\r\n onPinColumn={state.handlePinColumn}\r\n onAutoResize={columnAutoResize ? state.handleAutoResize : undefined}\r\n slotClassNames={sCls}\r\n slotStyles={sSty}\r\n />\r\n\r\n {virtualConfig ? (\r\n <VirtualTableBody\r\n columns={state.columns}\r\n flatRows={state.flatRows}\r\n rowHeight={virtualConfig.rowHeight}\r\n estimateRowHeight={virtualConfig.estimateRowHeight}\r\n overscan={virtualConfig.overscan}\r\n scrollContainerRef={scrollRef}\r\n rowSelection={rowSelection}\r\n expandable={expandable}\r\n isTreeMode={state.isTreeMode}\r\n indentSize={state.indentSize}\r\n treeExpanded={state.treeExpanded}\r\n expandedKeys={state.expandedKeys}\r\n totalCols={totalCols}\r\n spanMap={state.spanMap}\r\n hiddenCells={state.hiddenCells}\r\n t={state.t}\r\n rowClassName={rowClassName}\r\n fixedStyle={state.fixedStyle}\r\n onRowClick={onRowClick}\r\n onCellEdit={onCellEdit}\r\n onSelectRow={state.handleSelectRow}\r\n onToggleExpand={state.handleToggleExpand}\r\n onToggleTreeExpand={state.handleToggleTreeExpand}\r\n rowDraggable={rowDraggable}\r\n showRowNumber={!!rowNumConfig}\r\n cellContextMenu={cellContextMenu}\r\n onContextMenu={state.setContextMenu}\r\n striped={striped}\r\n groupBy={groupBy}\r\n onToggleGroup={state.toggleGroupExpand}\r\n focusedCell={state.focusedCell}\r\n onFocusCell={state.setFocusedCell}\r\n keyboardNavigation={keyboardNavigation}\r\n emptyContent={emptyContent}\r\n slotClassNames={sCls}\r\n slotStyles={sSty}\r\n />\r\n ) : (\r\n <TableBody\r\n columns={state.columns}\r\n flatRows={state.flatRows}\r\n rowSelection={rowSelection}\r\n expandable={expandable}\r\n isTreeMode={state.isTreeMode}\r\n indentSize={state.indentSize}\r\n treeExpanded={state.treeExpanded}\r\n expandedKeys={state.expandedKeys}\r\n totalCols={totalCols}\r\n spanMap={state.spanMap}\r\n hiddenCells={state.hiddenCells}\r\n t={state.t}\r\n rowClassName={rowClassName}\r\n fixedStyle={state.fixedStyle}\r\n onRowClick={onRowClick}\r\n onCellEdit={onCellEdit}\r\n onSelectRow={state.handleSelectRow}\r\n onToggleExpand={state.handleToggleExpand}\r\n onToggleTreeExpand={state.handleToggleTreeExpand}\r\n rowDraggable={rowDraggable}\r\n onRowOrderChange={onRowOrderChange}\r\n cellContextMenu={cellContextMenu}\r\n onContextMenu={state.setContextMenu}\r\n striped={striped}\r\n showRowNumber={!!rowNumConfig}\r\n groupBy={groupBy}\r\n onToggleGroup={state.toggleGroupExpand}\r\n focusedCell={state.focusedCell}\r\n onFocusCell={state.setFocusedCell}\r\n keyboardNavigation={keyboardNavigation}\r\n emptyContent={emptyContent}\r\n slotClassNames={sCls}\r\n slotStyles={sSty}\r\n />\r\n )}\r\n\r\n {/* Aggregation footer */}\r\n {footer && state.aggregates && (\r\n <div\r\n className={['sg-table-footer-row', sCls.footer].filter(Boolean).join(' ')}\r\n role=\"row\"\r\n style={{ display: 'contents', ...sSty.footer }}\r\n >\r\n {rowDraggable && <div className=\"sg-table-td sg-table-footer-cell\" role=\"cell\" />}\r\n {rowNumConfig && <div className=\"sg-table-td sg-table-footer-cell\" role=\"cell\" />}\r\n {rowSelection && <div className=\"sg-table-td sg-table-footer-cell\" role=\"cell\" />}\r\n {expandable && <div className=\"sg-table-td sg-table-footer-cell\" role=\"cell\" />}\r\n {state.columns.map((col) => (\r\n <div\r\n key={col.key}\r\n className=\"sg-table-td sg-table-footer-cell\"\r\n role=\"cell\"\r\n style={state.fixedStyle(col)}\r\n >\r\n {state.aggregates![col.key] != null ? (\r\n <span className=\"sg-table-aggregate-value\">\r\n <span className=\"sg-table-aggregate-label\">\r\n {typeof col.aggregate === 'string' ? state.t[col.aggregate] : ''}\r\n </span>{' '}\r\n {String(state.aggregates![col.key])}\r\n </span>\r\n ) : null}\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Summary rows (custom) */}\r\n {summary &&\r\n state.visibleRows &&\r\n summary(state.visibleRows).map((cells, ri) => (\r\n <div\r\n key={`sum-${ri}`}\r\n className=\"sg-table-summary-row\"\r\n role=\"row\"\r\n style={{ display: 'contents' }}\r\n >\r\n {cells.map((cell, ci) => (\r\n <div\r\n key={ci}\r\n className=\"sg-table-td sg-table-summary-cell\"\r\n role=\"cell\"\r\n style={{\r\n gridColumn: cell.colSpan ? `span ${cell.colSpan}` : undefined,\r\n textAlign: cell.align,\r\n }}\r\n >\r\n {cell.content}\r\n </div>\r\n ))}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Pinned bottom rows */}\r\n {state.pinnedBottom.length > 0 && (\r\n <div\r\n className=\"sg-table-pinned-bottom\"\r\n style={{ gridTemplateColumns: gridTemplate, minWidth: scroll?.x }}\r\n >\r\n <TableBody\r\n columns={state.columns}\r\n flatRows={state.pinnedBottom}\r\n rowSelection={rowSelection}\r\n expandable={expandable}\r\n isTreeMode={state.isTreeMode}\r\n indentSize={state.indentSize}\r\n treeExpanded={state.treeExpanded}\r\n expandedKeys={state.expandedKeys}\r\n totalCols={totalCols}\r\n spanMap={state.spanMap}\r\n hiddenCells={state.hiddenCells}\r\n t={state.t}\r\n rowClassName={rowClassName}\r\n fixedStyle={state.fixedStyle}\r\n onRowClick={onRowClick}\r\n onCellEdit={onCellEdit}\r\n onSelectRow={state.handleSelectRow}\r\n onToggleExpand={state.handleToggleExpand}\r\n onToggleTreeExpand={state.handleToggleTreeExpand}\r\n onContextMenu={state.setContextMenu}\r\n striped={false}\r\n isPinnedSection\r\n slotClassNames={sCls}\r\n slotStyles={sSty}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Context Menu */}\r\n <ContextMenu state={state.contextMenu} onClose={() => state.setContextMenu(null)} />\r\n\r\n {loading && (\r\n <div className=\"sg-table-loading-mask\">\r\n <Spin size=\"large\" />\r\n </div>\r\n )}\r\n\r\n {showPagination && state.tableState.totalPages > 1 && (\r\n <div className={slotClass('sg-table-pagination', sCls.pagination)} style={sSty.pagination}>\r\n <span className=\"sg-table-pagination-total\">\r\n {state.t.totalRows(state.tableState.filteredRows)}\r\n </span>\r\n <Pagination\r\n current={state.tableState.page}\r\n total={state.tableState.filteredRows}\r\n pageSize={state.tableState.pageSize}\r\n onChange={state.setPage}\r\n showSizeChanger={showSizeChanger}\r\n pageSizeOptions={pageSizeOptions}\r\n showQuickJumper={showQuickJumper}\r\n showTotal={showTotal}\r\n onPageSizeChange={onPageSizeChange}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\n/**\r\n * Data table — основная экспортная функция (forwardRef-обёртка над `TableInner`).\r\n * Ref-методы — см. `TableRef`.\r\n */\r\nexport const Table = forwardRef<TableRef, TableProps>(TableInner)\r\nTable.displayName = 'Table'\r\n\r\nfunction ColumnVisibilityDropdown({\r\n leafColumns,\r\n hiddenSet,\r\n onToggle,\r\n label,\r\n}: {\r\n leafColumns: { key: string; title: React.ReactNode }[]\r\n hiddenSet: Set<string>\r\n onToggle: (key: string) => void\r\n label: string\r\n}) {\r\n const [open, setOpen] = React.useState(false)\r\n const ref = React.useRef<HTMLDivElement>(null)\r\n\r\n React.useEffect(() => {\r\n if (!open) return\r\n const h = (e: MouseEvent) => {\r\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\r\n }\r\n document.addEventListener('mousedown', h)\r\n return () => document.removeEventListener('mousedown', h)\r\n }, [open])\r\n\r\n return (\r\n <div ref={ref} style={{ position: 'relative' }}>\r\n <button className=\"sg-table-toolbar-btn\" onClick={() => setOpen(!open)}>\r\n {label}\r\n </button>\r\n {open && (\r\n <div className=\"sg-table-col-visibility-dropdown\">\r\n {leafColumns.map((col) => (\r\n <label key={col.key} className=\"sg-table-col-visibility-item\">\r\n <Checkbox checked={!hiddenSet.has(col.key)} onChange={() => onToggle(col.key)} />\r\n <span>{typeof col.title === 'string' ? col.title : col.key}</span>\r\n </label>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nfunction GroupByDropdown({\r\n value,\r\n options,\r\n onChange,\r\n t,\r\n}: {\r\n value: string | null\r\n options: Array<{ key: string; label: React.ReactNode }>\r\n onChange: (field: string | null) => void\r\n t: { groupByLabel: string; groupByNone: string }\r\n}) {\r\n const [open, setOpen] = React.useState(false)\r\n const ref = React.useRef<HTMLDivElement>(null)\r\n\r\n React.useEffect(() => {\r\n if (!open) return\r\n const h = (e: MouseEvent) => {\r\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\r\n }\r\n document.addEventListener('mousedown', h)\r\n return () => document.removeEventListener('mousedown', h)\r\n }, [open])\r\n\r\n const current = value ? options.find((o) => o.key === value) : null\r\n\r\n return (\r\n <div ref={ref} style={{ position: 'relative' }}>\r\n <button className=\"sg-table-toolbar-btn\" onClick={() => setOpen(!open)}>\r\n {t.groupByLabel}\r\n {current ? `: ${typeof current.label === 'string' ? current.label : current.key}` : ''}\r\n </button>\r\n {open && (\r\n <div className=\"sg-table-group-by-dropdown\" role=\"menu\">\r\n <button\r\n type=\"button\"\r\n className={`sg-table-group-by-option${value === null ? ' sg-table-group-by-active' : ''}`}\r\n onClick={() => {\r\n onChange(null)\r\n setOpen(false)\r\n }}\r\n >\r\n {t.groupByNone}\r\n </button>\r\n {options.map((opt) => (\r\n <button\r\n key={opt.key}\r\n type=\"button\"\r\n className={`sg-table-group-by-option${value === opt.key ? ' sg-table-group-by-active' : ''}`}\r\n onClick={() => {\r\n onChange(opt.key)\r\n setOpen(false)\r\n }}\r\n >\r\n {opt.label}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nfunction DensityDropdown({\r\n value,\r\n onChange,\r\n t,\r\n}: {\r\n value: 'small' | 'middle' | 'large'\r\n onChange: (v: 'small' | 'middle' | 'large') => void\r\n t: { density: string; densitySmall: string; densityMiddle: string; densityLarge: string }\r\n}) {\r\n const [open, setOpen] = React.useState(false)\r\n const ref = React.useRef<HTMLDivElement>(null)\r\n\r\n React.useEffect(() => {\r\n if (!open) return\r\n const h = (e: MouseEvent) => {\r\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\r\n }\r\n document.addEventListener('mousedown', h)\r\n return () => document.removeEventListener('mousedown', h)\r\n }, [open])\r\n\r\n const options: Array<{ key: 'small' | 'middle' | 'large'; label: string }> = [\r\n { key: 'small', label: t.densitySmall },\r\n { key: 'middle', label: t.densityMiddle },\r\n { key: 'large', label: t.densityLarge },\r\n ]\r\n\r\n return (\r\n <div ref={ref} style={{ position: 'relative' }}>\r\n <button className=\"sg-table-toolbar-btn\" onClick={() => setOpen(!open)}>\r\n {t.density}\r\n </button>\r\n {open && (\r\n <div className=\"sg-table-density-dropdown\">\r\n {options.map((opt) => (\r\n <button\r\n key={opt.key}\r\n className={`sg-table-density-option${value === opt.key ? ' sg-table-density-active' : ''}`}\r\n onClick={() => {\r\n onChange(opt.key)\r\n setOpen(false)\r\n }}\r\n >\r\n {opt.label}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n","import React from 'react'\r\nimport { createPortal } from 'react-dom'\r\nimport { Checkbox } from '../../ui/Checkbox'\r\nimport { Input } from '../../ui/Input'\r\nimport { Button } from '../../ui/Button'\r\nimport { Select } from '../../ui/Select'\r\nimport type {\r\n AdvancedFilter,\r\n FilterDropdownProps,\r\n FilterOperator,\r\n TableColumn,\r\n TableLocale,\r\n} from './types'\r\n\r\n/** Column filter UI state from table state hook. */\r\ninterface FilterState {\r\n /** Selected filter values keyed by column. */\r\n activeFilters: Record<string, unknown[]>\r\n /** Filter-list search strings keyed by column. */\r\n filterSearchText: Record<string, string>\r\n /** Column key with an open filter popover. */\r\n openFilterDropdown: string | null\r\n /** Active advanced filters keyed by column. */\r\n advancedFilters: Record<string, AdvancedFilter>\r\n /** Anchor элемент (FilterTrigger), используется для позиционирования portal. */\r\n filterAnchor: HTMLElement | null\r\n}\r\n\r\n/** Callbacks that mutate filter UI state. */\r\ninterface FilterActions {\r\n /** Opens or closes a column filter popover. */\r\n setOpenFilterDropdown: (key: string | null) => void\r\n /** Сохраняет DOM-элемент-якорь для портального позиционирования popover'а. */\r\n setFilterAnchor: (el: HTMLElement | null) => void\r\n /** Toggles a preset filter value. */\r\n handleFilterToggle: (colKey: string, value: unknown, multiple: boolean) => void\r\n /** Confirms the current filter selection. */\r\n handleFilterConfirm: (colKey: string) => void\r\n /** Clears active filters for a column. */\r\n handleFilterReset: (colKey: string) => void\r\n /** Closes the filter popover. */\r\n handleFilterClose: (colKey: string) => void\r\n /** Updates search-mode filter text. */\r\n handleSearchFilterChange: (colKey: string, text: string) => void\r\n /** Updates filter list search text. */\r\n setFilterSearchText: React.Dispatch<React.SetStateAction<Record<string, string>>>\r\n /** Builds props for custom filter dropdown renderers. */\r\n getFilterDropdownProps: (col: TableColumn) => FilterDropdownProps\r\n /** Sets / clears the advanced filter for a column. */\r\n setAdvancedFilter: (colKey: string, filter: AdvancedFilter | null) => void\r\n}\r\n\r\n/** Shared props for filter trigger and dropdown content. */\r\ninterface FilterTriggerProps {\r\n /** Target column. */\r\n col: TableColumn\r\n /** Resolved table locale. */\r\n t: Required<TableLocale>\r\n /** Filter popover state. */\r\n state: FilterState\r\n /** Filter state mutators. */\r\n actions: FilterActions\r\n /**\r\n * Ref on the dropdown for outside-click detection. Typed as nullable so\r\n * `useRef<HTMLDivElement>(null)` callers compile under\r\n * `strictNullChecks` / `useDefineForClassFields` without `as` casts.\r\n */\r\n filterRef: React.RefObject<HTMLDivElement | null>\r\n}\r\n\r\n/** Default operators offered for textual columns. */\r\nconst TEXT_OPS: FilterOperator[] = [\r\n 'eq',\r\n 'neq',\r\n 'contains',\r\n 'startsWith',\r\n 'endsWith',\r\n 'in',\r\n 'notIn',\r\n 'isEmpty',\r\n 'isNotEmpty',\r\n]\r\n\r\n/** Default operators offered for numeric columns. */\r\nconst NUMBER_OPS: FilterOperator[] = [\r\n 'eq',\r\n 'neq',\r\n 'lt',\r\n 'lte',\r\n 'gt',\r\n 'gte',\r\n 'between',\r\n 'in',\r\n 'notIn',\r\n 'isEmpty',\r\n 'isNotEmpty',\r\n]\r\n\r\n/** Operators that don't need a value input. */\r\nconst NO_VALUE_OPS = new Set<FilterOperator>(['isEmpty', 'isNotEmpty'])\r\n\r\n/** Filter icon in the header; toggles the column filter popover. */\r\nexport function FilterTrigger({ col, t, state, actions }: FilterTriggerProps) {\r\n const hasFilter =\r\n col.filterDropdown ||\r\n col.filterMode === 'search' ||\r\n col.filterMode === 'advanced' ||\r\n (col.filters && col.filters.length > 0)\r\n if (!hasFilter) return null\r\n\r\n const filtered =\r\n col.filterMode === 'advanced'\r\n ? state.advancedFilters[col.key] != null\r\n : (state.activeFilters[col.key]?.length ?? 0) > 0\r\n const iconNode = col.filterIcon\r\n ? typeof col.filterIcon === 'function'\r\n ? col.filterIcon(filtered)\r\n : col.filterIcon\r\n : col.filterMode === 'search'\r\n ? t.searchIcon\r\n : t.filterIcon\r\n\r\n return (\r\n <span\r\n className={`sg-table-filter-trigger${filtered ? ' sg-table-filter-active' : ''}`}\r\n onClick={(e) => {\r\n e.stopPropagation()\r\n const isOpen = state.openFilterDropdown === col.key\r\n if (isOpen) {\r\n actions.setOpenFilterDropdown(null)\r\n actions.setFilterAnchor(null)\r\n } else {\r\n actions.setFilterAnchor(e.currentTarget)\r\n actions.setOpenFilterDropdown(col.key)\r\n }\r\n }}\r\n >\r\n {iconNode}\r\n </span>\r\n )\r\n}\r\n\r\n/**\r\n * Обёртка над `createPortal`, которая позиционирует children как `position: fixed`\r\n * у нижнего края `anchor`. Пересчитывает координаты на scroll/resize.\r\n * Без портала advanced-фильтр клипается scroll-контейнером таблицы.\r\n */\r\nfunction FilterPortal({\r\n anchor,\r\n children,\r\n}: {\r\n anchor: HTMLElement | null\r\n children: React.ReactNode\r\n}) {\r\n const [coords, setCoords] = React.useState<{ top: number; left: number } | null>(null)\r\n\r\n React.useLayoutEffect(() => {\r\n if (!anchor) return\r\n const update = () => {\r\n const r = anchor.getBoundingClientRect()\r\n setCoords({ top: r.bottom + 4, left: r.left })\r\n }\r\n update()\r\n window.addEventListener('scroll', update, true)\r\n window.addEventListener('resize', update)\r\n return () => {\r\n window.removeEventListener('scroll', update, true)\r\n window.removeEventListener('resize', update)\r\n }\r\n }, [anchor])\r\n\r\n if (!anchor || !coords || typeof document === 'undefined') return null\r\n\r\n return createPortal(\r\n <div\r\n className=\"sg-table-filter-portal\"\r\n style={{ position: 'fixed', top: coords.top, left: coords.left, zIndex: 1100 }}\r\n >\r\n {children}\r\n </div>,\r\n document.body,\r\n )\r\n}\r\n\r\n/** Filter popover body: custom dropdown, search field, advanced builder, or preset checklist. */\r\nexport function FilterDropdownContent({ col, t, state, actions, filterRef }: FilterTriggerProps) {\r\n if (state.openFilterDropdown !== col.key) return null\r\n\r\n if (col.filterDropdown) {\r\n const props = actions.getFilterDropdownProps(col)\r\n const content =\r\n typeof col.filterDropdown === 'function' ? col.filterDropdown(props) : col.filterDropdown\r\n return (\r\n <FilterPortal anchor={state.filterAnchor}>\r\n <div\r\n className=\"sg-table-filter-dropdown\"\r\n ref={filterRef}\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n {content}\r\n </div>\r\n </FilterPortal>\r\n )\r\n }\r\n\r\n if (col.filterMode === 'advanced') {\r\n return (\r\n <FilterPortal anchor={state.filterAnchor}>\r\n <AdvancedFilterPanel\r\n col={col}\r\n t={t}\r\n state={state}\r\n actions={actions}\r\n filterRef={filterRef}\r\n />\r\n </FilterPortal>\r\n )\r\n }\r\n\r\n if (col.filterMode === 'search') {\r\n const searchVal = (state.activeFilters[col.key]?.[0] as string) ?? ''\r\n return (\r\n <FilterPortal anchor={state.filterAnchor}>\r\n <div\r\n className=\"sg-table-filter-dropdown sg-table-filter-search-mode\"\r\n ref={filterRef}\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n <Input\r\n placeholder={`${t.searchPlaceholder.replace('...', '')} ${typeof col.title === 'string' ? col.title : ''}...`}\r\n size=\"small\"\r\n value={searchVal}\r\n onChange={(v) => actions.handleSearchFilterChange(col.key, v)}\r\n />\r\n <div className=\"sg-table-filter-actions\">\r\n <Button\r\n size=\"small\"\r\n onClick={() => {\r\n actions.handleFilterReset(col.key)\r\n actions.handleFilterClose(col.key)\r\n }}\r\n >\r\n {t.filterReset}\r\n </Button>\r\n <Button\r\n size=\"small\"\r\n type=\"primary\"\r\n onClick={() => actions.handleFilterConfirm(col.key)}\r\n >\r\n {t.filterConfirm}\r\n </Button>\r\n </div>\r\n </div>\r\n </FilterPortal>\r\n )\r\n }\r\n\r\n if (!col.filters || col.filters.length === 0) return null\r\n\r\n const multiple = col.filterMultiple !== false\r\n const currentVals = state.activeFilters[col.key] ?? []\r\n const searchTxt = state.filterSearchText[col.key] ?? ''\r\n\r\n let visibleFilters = col.filters\r\n if (col.filterSearch && searchTxt) {\r\n visibleFilters = col.filters.filter((f) => {\r\n if (typeof col.filterSearch === 'function') {\r\n return col.filterSearch(searchTxt, f)\r\n }\r\n return f.text.toLowerCase().includes(searchTxt.toLowerCase())\r\n })\r\n }\r\n\r\n return (\r\n <FilterPortal anchor={state.filterAnchor}>\r\n <div\r\n className=\"sg-table-filter-dropdown\"\r\n ref={filterRef}\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n {col.filterSearch !== undefined && col.filterSearch !== false && (\r\n <div className=\"sg-table-filter-search\">\r\n <Input\r\n placeholder={t.filterSearchPlaceholder}\r\n size=\"small\"\r\n value={searchTxt}\r\n onChange={(v) => actions.setFilterSearchText((prev) => ({ ...prev, [col.key]: v }))}\r\n />\r\n </div>\r\n )}\r\n <div className=\"sg-table-filter-list\">\r\n {visibleFilters.map((f) => {\r\n const checked = currentVals.includes(f.value)\r\n return (\r\n <label key={String(f.value)} className=\"sg-table-filter-item\">\r\n {multiple ? (\r\n <Checkbox\r\n checked={checked}\r\n onChange={() => actions.handleFilterToggle(col.key, f.value, true)}\r\n />\r\n ) : (\r\n <input\r\n type=\"radio\"\r\n checked={checked}\r\n onChange={() => actions.handleFilterToggle(col.key, f.value, false)}\r\n />\r\n )}\r\n <span>{f.text}</span>\r\n </label>\r\n )\r\n })}\r\n {visibleFilters.length === 0 && (\r\n <div className=\"sg-table-filter-empty\">{t.filterEmptyText}</div>\r\n )}\r\n </div>\r\n <div className=\"sg-table-filter-actions\">\r\n <Button\r\n size=\"small\"\r\n onClick={() => {\r\n actions.handleFilterReset(col.key)\r\n actions.handleFilterClose(col.key)\r\n }}\r\n >\r\n {t.filterReset}\r\n </Button>\r\n <Button size=\"small\" type=\"primary\" onClick={() => actions.handleFilterConfirm(col.key)}>\r\n {t.filterConfirm}\r\n </Button>\r\n </div>\r\n </div>\r\n </FilterPortal>\r\n )\r\n}\r\n\r\n/**\r\n * Расширенный фильтр: пользователь выбирает оператор и значение.\r\n * Управляет локальным черновиком (`draftOp`/`draftValue`) и применяет\r\n * результат через `actions.setAdvancedFilter` по нажатию на «OK».\r\n */\r\nfunction AdvancedFilterPanel({ col, t, state, actions, filterRef }: FilterTriggerProps) {\r\n const isNumeric = col.advancedFilterType === 'number'\r\n const defaultOps = isNumeric ? NUMBER_OPS : TEXT_OPS\r\n const ops = col.advancedFilterOperators ?? defaultOps\r\n\r\n const current = state.advancedFilters[col.key]\r\n const [draftOp, setDraftOp] = React.useState<FilterOperator>(current?.op ?? ops[0])\r\n const [draftValue, setDraftValue] = React.useState<string>(() => formatDraftValue(current?.value))\r\n const [draftValue2, setDraftValue2] = React.useState<string>(() => {\r\n const v = current?.value\r\n if (Array.isArray(v) && v.length === 2) return String(v[1] ?? '')\r\n return ''\r\n })\r\n\r\n React.useEffect(() => {\r\n if (current) {\r\n setDraftOp(current.op)\r\n setDraftValue(formatDraftValue(current.value))\r\n if (Array.isArray(current.value) && current.value.length === 2) {\r\n setDraftValue2(String(current.value[1] ?? ''))\r\n }\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [state.openFilterDropdown])\r\n\r\n const reset = () => {\r\n setDraftOp(ops[0])\r\n setDraftValue('')\r\n setDraftValue2('')\r\n actions.setAdvancedFilter(col.key, null)\r\n actions.handleFilterClose(col.key)\r\n }\r\n\r\n const confirm = () => {\r\n if (NO_VALUE_OPS.has(draftOp)) {\r\n actions.setAdvancedFilter(col.key, { op: draftOp })\r\n } else if (draftOp === 'between') {\r\n const a = parseValue(draftValue, isNumeric)\r\n const b = parseValue(draftValue2, isNumeric)\r\n actions.setAdvancedFilter(col.key, { op: 'between', value: [a, b] })\r\n } else if (draftOp === 'in' || draftOp === 'notIn') {\r\n const list = draftValue\r\n .split(',')\r\n .map((s) => s.trim())\r\n .filter((s) => s.length > 0)\r\n .map((s) => parseValue(s, isNumeric))\r\n actions.setAdvancedFilter(col.key, { op: draftOp, value: list })\r\n } else {\r\n actions.setAdvancedFilter(col.key, {\r\n op: draftOp,\r\n value: parseValue(draftValue, isNumeric),\r\n })\r\n }\r\n actions.setOpenFilterDropdown(null)\r\n }\r\n\r\n const showValueInput = !NO_VALUE_OPS.has(draftOp)\r\n const showSecondInput = draftOp === 'between'\r\n const isValueRequired = showValueInput\r\n const valueIsEmpty = isValueRequired && draftValue.trim() === ''\r\n const secondValueIsEmpty = showSecondInput && draftValue2.trim() === ''\r\n const confirmDisabled = valueIsEmpty || secondValueIsEmpty\r\n\r\n return (\r\n <div\r\n className=\"sg-table-filter-dropdown sg-table-filter-advanced-mode\"\r\n ref={filterRef}\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n <div className=\"sg-table-filter-advanced-row\">\r\n <Select\r\n size=\"small\"\r\n value={draftOp}\r\n onChange={(v) => setDraftOp(v as FilterOperator)}\r\n options={ops.map((op) => ({ label: operatorLabel(op, t), value: op }))}\r\n aria-label={t.filterOperatorAriaLabel}\r\n />\r\n </div>\r\n {showValueInput && (\r\n <div className=\"sg-table-filter-advanced-row\">\r\n <Input\r\n size=\"small\"\r\n type={\r\n isNumeric && draftOp !== 'in' && draftOp !== 'notIn' && draftOp !== 'between'\r\n ? 'number'\r\n : 'text'\r\n }\r\n value={draftValue}\r\n onChange={setDraftValue}\r\n placeholder={\r\n draftOp === 'in' || draftOp === 'notIn'\r\n ? t.filterAdvancedInPlaceholder\r\n : t.filterAdvancedValuePlaceholder\r\n }\r\n />\r\n </div>\r\n )}\r\n {showSecondInput && (\r\n <div className=\"sg-table-filter-advanced-row\">\r\n <Input\r\n size=\"small\"\r\n type={isNumeric ? 'number' : 'text'}\r\n value={draftValue2}\r\n onChange={setDraftValue2}\r\n placeholder={t.filterAdvancedBetweenMaxPlaceholder}\r\n />\r\n </div>\r\n )}\r\n <div className=\"sg-table-filter-actions\">\r\n <Button size=\"small\" onClick={reset}>\r\n {t.filterReset}\r\n </Button>\r\n <Button size=\"small\" type=\"primary\" disabled={confirmDisabled} onClick={confirm}>\r\n {t.filterConfirm}\r\n </Button>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nfunction formatDraftValue(value: unknown): string {\r\n if (value == null) return ''\r\n if (Array.isArray(value)) return value.map((v) => String(v ?? '')).join(', ')\r\n return String(value)\r\n}\r\n\r\nfunction parseValue(raw: string, numeric: boolean): unknown {\r\n const trimmed = raw.trim()\r\n if (trimmed === '') return ''\r\n if (numeric) {\r\n const n = Number(trimmed)\r\n return Number.isNaN(n) ? trimmed : n\r\n }\r\n return trimmed\r\n}\r\n\r\nfunction operatorLabel(op: FilterOperator, t: Required<TableLocale>): string {\r\n const map: Record<FilterOperator, string> = {\r\n eq: t.filterOpEq,\r\n neq: t.filterOpNeq,\r\n lt: t.filterOpLt,\r\n lte: t.filterOpLte,\r\n gt: t.filterOpGt,\r\n gte: t.filterOpGte,\r\n between: t.filterOpBetween,\r\n in: t.filterOpIn,\r\n notIn: t.filterOpNotIn,\r\n contains: t.filterOpContains,\r\n startsWith: t.filterOpStartsWith,\r\n endsWith: t.filterOpEndsWith,\r\n isEmpty: t.filterOpIsEmpty,\r\n isNotEmpty: t.filterOpIsNotEmpty,\r\n }\r\n return map[op]\r\n}\r\n","import React from 'react'\r\nimport { Checkbox } from '../../ui/Checkbox'\r\nimport { FilterTrigger, FilterDropdownContent } from './FilterDropdown'\r\nimport type {\r\n AdvancedFilter,\r\n TableColumn,\r\n HeaderCell,\r\n RowSelectionConfig,\r\n ExpandableConfig,\r\n TableLocale,\r\n SortDirection,\r\n SortConfig,\r\n FilterDropdownProps,\r\n TableClassNames,\r\n TableStyles,\r\n} from './types'\r\nimport type { ContextMenuItem, ContextMenuState } from './ContextMenu'\r\n\r\n/** Internal props for the table header row(s). */\r\ninterface HeaderProps {\r\n /** Visible leaf columns in flat header mode. */\r\n columns: TableColumn[]\r\n /** Multi-row header grid when columns are grouped. */\r\n headerRows: HeaderCell[][] | null\r\n /** Whether grouped header rows are used. */\r\n hasColumnGroups: boolean\r\n /** Selection column state when enabled. */\r\n rowSelection?: RowSelectionConfig\r\n /** Expand column spacer when enabled. */\r\n expandable?: ExpandableConfig\r\n /** Enables column drag reorder. */\r\n draggable?: boolean\r\n /** All visible rows are selected. */\r\n allSelected: boolean\r\n /** Some but not all visible rows are selected. */\r\n someSelected: boolean\r\n /** Column key currently highlighted as drag target. */\r\n dragOver: string | null\r\n /** Resolved locale strings. */\r\n t: Required<TableLocale>\r\n /** Sticky/fixed styles for header cells. */\r\n fixedStyle: (col: TableColumn, isHeader?: boolean) => React.CSSProperties\r\n /** Sort click handler (supports multi-sort via shift). */\r\n onSort: (col: TableColumn, shiftKey?: boolean) => void\r\n /** Select-all checkbox toggle. */\r\n onSelectAll: () => void\r\n /** Column drag start. */\r\n onDragStart: (e: React.DragEvent, key: string) => void\r\n /** Column drag over. */\r\n onDragOver: (e: React.DragEvent, key: string) => void\r\n /** Clears drag-over highlight. */\r\n onDragLeave: () => void\r\n /** Column drop to reorder. */\r\n onDrop: (e: React.DragEvent, key: string) => void\r\n /** Column drag end cleanup. */\r\n onDragEnd: () => void\r\n /** Begins column resize drag. */\r\n onResizeStart: (e: React.MouseEvent, colKey: string) => void\r\n /** Filter dropdown UI state. */\r\n filterState: {\r\n /** Active filter values per column key. */\r\n activeFilters: Record<string, unknown[]>\r\n /** Per-column filter search box text. */\r\n filterSearchText: Record<string, string>\r\n /** Column key with open filter dropdown, if any. */\r\n openFilterDropdown: string | null\r\n /** Active advanced filters keyed by column. */\r\n advancedFilters: Record<string, AdvancedFilter>\r\n /** Anchor элемент для портального позиционирования popover'а. */\r\n filterAnchor: HTMLElement | null\r\n }\r\n /** Filter dropdown callbacks and helpers. */\r\n filterActions: {\r\n /** Opens or closes a column filter popover. */\r\n setOpenFilterDropdown: (key: string | null) => void\r\n /** Сохраняет DOM-якорь для позиционирования portal'нутого popover'а. */\r\n setFilterAnchor: (el: HTMLElement | null) => void\r\n /** Toggles a value in multi-select filters. */\r\n handleFilterToggle: (colKey: string, value: unknown, multiple: boolean) => void\r\n /** Applies filters and closes the dropdown. */\r\n handleFilterConfirm: (colKey: string) => void\r\n /** Clears filters for a column. */\r\n handleFilterReset: (colKey: string) => void\r\n /** Closes the dropdown for a column. */\r\n handleFilterClose: (colKey: string) => void\r\n /** Updates search-mode filter text. */\r\n handleSearchFilterChange: (colKey: string, text: string) => void\r\n /** Updates filter list search text state. */\r\n setFilterSearchText: React.Dispatch<React.SetStateAction<Record<string, string>>>\r\n /** Builds props for custom `filterDropdown` renderers. */\r\n getFilterDropdownProps: (col: TableColumn) => FilterDropdownProps\r\n /** Sets / clears the advanced filter for a column. */\r\n setAdvancedFilter: (colKey: string, filter: AdvancedFilter | null) => void\r\n }\r\n /** Ref attached to the open filter panel for outside click. */\r\n filterRef: React.RefObject<HTMLDivElement | null>\r\n /** Active multi-sort configuration. */\r\n sorts: SortConfig[]\r\n /** 0-based sort priority index for a column, or -1. */\r\n getSortIndex: (colKey: string) => number\r\n /** Current sort direction for a column, if any. */\r\n getSortDirection: (colKey: string) => SortDirection | null\r\n /** Extra context menu items for a header cell. */\r\n headerContextMenu?: (column: TableColumn) => ContextMenuItem[]\r\n /** Opens the shared context menu. */\r\n onContextMenu: (state: ContextMenuState | null) => void\r\n /** Renders row number header cell. */\r\n showRowNumber?: boolean\r\n /** Spacer column for row drag handle. */\r\n rowDraggable?: boolean\r\n /** Enables pin/unpin items in the header menu. */\r\n columnPinning?: boolean\r\n /** Pins a column left, right, or unpins. */\r\n onPinColumn?: (key: string, fixed: 'left' | 'right' | undefined) => void\r\n /** Auto-fits column width to measured content. */\r\n onAutoResize?: (colKey: string) => void\r\n /** Публичные классы по слотам Table (передаются из Table.tsx). */\r\n slotClassNames?: TableClassNames\r\n /** Публичные стили по слотам Table. */\r\n slotStyles?: TableStyles\r\n}\r\n\r\nfunction SortIndicator({\r\n col,\r\n sorts,\r\n getSortIndex,\r\n getSortDirection,\r\n t,\r\n}: {\r\n col: TableColumn\r\n sorts: SortConfig[]\r\n getSortIndex: (colKey: string) => number\r\n getSortDirection: (colKey: string) => SortDirection | null\r\n t: Required<TableLocale>\r\n}) {\r\n if (!col.sortable) return null\r\n const dir = getSortDirection(col.key)\r\n const idx = getSortIndex(col.key)\r\n const isActive = dir !== null\r\n\r\n return (\r\n <span className={`sg-table-sort-arrows${isActive ? ' sg-table-sort-active' : ''}`}>\r\n <span className={`sg-table-sort-asc${dir === 'asc' ? ' sg-table-sort-current' : ''}`}>\r\n {t.sortAsc}\r\n </span>\r\n <span className={`sg-table-sort-desc${dir === 'desc' ? ' sg-table-sort-current' : ''}`}>\r\n {t.sortDesc}\r\n </span>\r\n {idx >= 0 && sorts.length > 1 && <span className=\"sg-table-sort-index\">{idx + 1}</span>}\r\n </span>\r\n )\r\n}\r\n\r\nfunction ColumnTooltip({ content }: { content: string | React.ReactNode }) {\r\n if (!content) return null\r\n return (\r\n <span className=\"sg-table-th-tooltip\" title={typeof content === 'string' ? content : undefined}>\r\n ⓘ\r\n </span>\r\n )\r\n}\r\n\r\n/** Renders flat or grouped header cells with sort, filter, resize, and drag handles. */\r\nexport function TableHeader(props: HeaderProps) {\r\n const {\r\n columns,\r\n headerRows,\r\n hasColumnGroups,\r\n rowSelection,\r\n expandable,\r\n draggable,\r\n allSelected,\r\n someSelected,\r\n dragOver,\r\n t,\r\n fixedStyle,\r\n onSort,\r\n onSelectAll,\r\n onDragStart,\r\n onDragOver,\r\n onDragLeave,\r\n onDrop,\r\n onDragEnd,\r\n onResizeStart,\r\n filterState,\r\n filterActions,\r\n filterRef,\r\n sorts,\r\n getSortIndex,\r\n getSortDirection,\r\n headerContextMenu,\r\n onContextMenu,\r\n showRowNumber,\r\n rowDraggable,\r\n columnPinning,\r\n onPinColumn,\r\n onAutoResize,\r\n slotClassNames,\r\n slotStyles,\r\n } = props\r\n\r\n const sCls = slotClassNames ?? {}\r\n const sSty = slotStyles ?? {}\r\n\r\n const filterProps = (col: TableColumn) => ({\r\n col,\r\n t,\r\n state: filterState,\r\n actions: filterActions,\r\n filterRef,\r\n })\r\n\r\n const sortProps = {\r\n sorts,\r\n getSortIndex,\r\n getSortDirection,\r\n t,\r\n }\r\n\r\n const buildContextMenu = (col: TableColumn, e: React.MouseEvent) => {\r\n e.preventDefault()\r\n const items: ContextMenuItem[] = []\r\n\r\n if (headerContextMenu) {\r\n items.push(...headerContextMenu(col))\r\n }\r\n\r\n if (columnPinning && onPinColumn) {\r\n if (items.length > 0) {\r\n items.push({ key: 'pin-divider', label: '', divider: true })\r\n }\r\n if (col.fixed !== 'left') {\r\n items.push({\r\n key: 'pin-left',\r\n label: t.pinLeft,\r\n onClick: () => onPinColumn(col.key, 'left'),\r\n })\r\n }\r\n if (col.fixed !== 'right') {\r\n items.push({\r\n key: 'pin-right',\r\n label: t.pinRight,\r\n onClick: () => onPinColumn(col.key, 'right'),\r\n })\r\n }\r\n if (col.fixed) {\r\n items.push({\r\n key: 'unpin',\r\n label: t.unpin,\r\n onClick: () => onPinColumn(col.key, undefined),\r\n })\r\n }\r\n }\r\n\r\n if (items.length > 0) {\r\n onContextMenu({ x: e.clientX, y: e.clientY, items })\r\n }\r\n }\r\n\r\n if (hasColumnGroups && headerRows) {\r\n return (\r\n <>\r\n {headerRows.map((row, ri) => (\r\n <div\r\n key={`hdr-${ri}`}\r\n className={['sg-table-header-row', sCls.headerRow].filter(Boolean).join(' ')}\r\n role=\"row\"\r\n style={{ display: 'contents', ...sSty.headerRow }}\r\n >\r\n {ri === 0 && rowDraggable && (\r\n <div\r\n className=\"sg-table-th\"\r\n role=\"columnheader\"\r\n style={{ gridRow: `span ${headerRows.length}` }}\r\n />\r\n )}\r\n {ri === 0 && showRowNumber && (\r\n <div\r\n className=\"sg-table-th sg-table-cell-row-number\"\r\n role=\"columnheader\"\r\n style={{ gridRow: `span ${headerRows.length}` }}\r\n >\r\n {t.rowNumber}\r\n </div>\r\n )}\r\n {ri === 0 && rowSelection && (\r\n <div\r\n className=\"sg-table-th sg-table-cell-selection\"\r\n role=\"columnheader\"\r\n style={{ gridRow: `span ${headerRows.length}` }}\r\n >\r\n {rowSelection.type !== 'radio' && (\r\n <Checkbox\r\n checked={allSelected}\r\n indeterminate={someSelected}\r\n onChange={onSelectAll}\r\n />\r\n )}\r\n </div>\r\n )}\r\n {ri === 0 && expandable && (\r\n <div\r\n className=\"sg-table-th sg-table-cell-expand\"\r\n role=\"columnheader\"\r\n style={{ gridRow: `span ${headerRows.length}` }}\r\n />\r\n )}\r\n {row.map((cell, ci) => {\r\n const isLeaf = !cell.col.children || cell.col.children.length === 0\r\n return (\r\n <div\r\n key={cell.col.key ?? `g-${ri}-${ci}`}\r\n className={[\r\n 'sg-table-th',\r\n isLeaf && cell.col.sortable ? 'sg-table-th-sortable' : '',\r\n cell.col.fixed ? 'sg-table-cell-fixed' : '',\r\n cell.col.fixed ? `sg-table-cell-fixed-${cell.col.fixed}` : '',\r\n cell.colSpan > 1 ? 'sg-table-th-group' : '',\r\n sCls.headerCell,\r\n cell.col.headerClassName,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={{\r\n ...(isLeaf ? fixedStyle(cell.col, true) : {}),\r\n gridColumn: cell.colSpan > 1 ? `span ${cell.colSpan}` : undefined,\r\n gridRow: cell.rowSpan > 1 ? `span ${cell.rowSpan}` : undefined,\r\n justifyContent: cell.colSpan > 1 ? 'center' : undefined,\r\n ...sSty.headerCell,\r\n }}\r\n role=\"columnheader\"\r\n onClick={isLeaf ? (e) => onSort(cell.col, e.shiftKey) : undefined}\r\n onContextMenu={isLeaf ? (e) => buildContextMenu(cell.col, e) : undefined}\r\n >\r\n <span\r\n className={['sg-table-th-content', sCls.headerCellContent]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={sSty.headerCellContent}\r\n >\r\n <span className=\"sg-table-th-title\">{cell.col.title}</span>\r\n {isLeaf && cell.col.tooltip && <ColumnTooltip content={cell.col.tooltip} />}\r\n {isLeaf && <SortIndicator col={cell.col} {...sortProps} />}\r\n </span>\r\n {isLeaf && <FilterTrigger {...filterProps(cell.col)} />}\r\n {isLeaf && <FilterDropdownContent {...filterProps(cell.col)} />}\r\n {isLeaf && cell.col.resizable && (\r\n <div\r\n className=\"sg-table-resize-handle\"\r\n onMouseDown={(e) => onResizeStart(e, cell.col.key)}\r\n onDoubleClick={\r\n onAutoResize\r\n ? (e) => {\r\n e.stopPropagation()\r\n onAutoResize(cell.col.key)\r\n }\r\n : undefined\r\n }\r\n />\r\n )}\r\n </div>\r\n )\r\n })}\r\n </div>\r\n ))}\r\n </>\r\n )\r\n }\r\n\r\n return (\r\n <div\r\n className={['sg-table-header-row', sCls.headerRow].filter(Boolean).join(' ')}\r\n role=\"row\"\r\n style={{ display: 'contents', ...sSty.headerRow }}\r\n >\r\n {rowDraggable && <div className=\"sg-table-th\" role=\"columnheader\" />}\r\n {showRowNumber && (\r\n <div className=\"sg-table-th sg-table-cell-row-number\" role=\"columnheader\">\r\n {t.rowNumber}\r\n </div>\r\n )}\r\n {rowSelection && (\r\n <div className=\"sg-table-th sg-table-cell-selection\" role=\"columnheader\">\r\n {rowSelection.type !== 'radio' && (\r\n <Checkbox checked={allSelected} indeterminate={someSelected} onChange={onSelectAll} />\r\n )}\r\n </div>\r\n )}\r\n {expandable && <div className=\"sg-table-th sg-table-cell-expand\" role=\"columnheader\" />}\r\n {columns.map((col) => (\r\n <div\r\n key={col.key}\r\n className={[\r\n 'sg-table-th',\r\n col.sortable ? 'sg-table-th-sortable' : '',\r\n dragOver === col.key ? 'sg-table-th-drag-over' : '',\r\n col.fixed ? 'sg-table-cell-fixed' : '',\r\n col.fixed ? `sg-table-cell-fixed-${col.fixed}` : '',\r\n sCls.headerCell,\r\n col.headerClassName,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={{ ...fixedStyle(col, true), ...sSty.headerCell }}\r\n role=\"columnheader\"\r\n onClick={(e) => onSort(col, e.shiftKey)}\r\n onContextMenu={(e) => buildContextMenu(col, e)}\r\n draggable={draggable && !col.fixed}\r\n onDragStart={draggable ? (e) => onDragStart(e, col.key) : undefined}\r\n onDragOver={draggable ? (e) => onDragOver(e, col.key) : undefined}\r\n onDragLeave={draggable ? () => onDragLeave() : undefined}\r\n onDrop={draggable ? (e) => onDrop(e, col.key) : undefined}\r\n onDragEnd={draggable ? () => onDragEnd() : undefined}\r\n >\r\n <span\r\n className={['sg-table-th-content', sCls.headerCellContent].filter(Boolean).join(' ')}\r\n style={sSty.headerCellContent}\r\n >\r\n <span className=\"sg-table-th-title\">{col.title}</span>\r\n {col.tooltip && <ColumnTooltip content={col.tooltip} />}\r\n <SortIndicator col={col} {...sortProps} />\r\n </span>\r\n <FilterTrigger {...filterProps(col)} />\r\n <FilterDropdownContent {...filterProps(col)} />\r\n {col.resizable && (\r\n <div\r\n className=\"sg-table-resize-handle\"\r\n onMouseDown={(e) => onResizeStart(e, col.key)}\r\n onDoubleClick={\r\n onAutoResize\r\n ? (e) => {\r\n e.stopPropagation()\r\n onAutoResize(col.key)\r\n }\r\n : undefined\r\n }\r\n />\r\n )}\r\n </div>\r\n ))}\r\n </div>\r\n )\r\n}\r\n","import React, { useRef, useState, useEffect, useCallback } from 'react'\r\nimport { Checkbox } from '../../ui/Checkbox'\r\nimport { copyToClipboard } from './export'\r\nimport { TableGroupRow } from './TableGroupRow'\r\nimport type {\r\n TableColumn,\r\n RowSelectionConfig,\r\n ExpandableConfig,\r\n FlatRow,\r\n CellSpan,\r\n RowId,\r\n TableLocale,\r\n TableClassNames,\r\n TableStyles,\r\n} from './types'\r\nimport type { ContextMenuItem, ContextMenuState } from './ContextMenu'\r\n\r\n/** Internal props for the non-virtual table body grid. */\r\nexport interface BodyProps {\r\n /** Visible columns in render order. */\r\n columns: TableColumn[]\r\n /** Flattened rows including group headers. */\r\n flatRows: FlatRow[]\r\n /** Row selection config when selection column is shown. */\r\n rowSelection?: RowSelectionConfig\r\n /** Expandable row config when expand column is shown. */\r\n expandable?: ExpandableConfig\r\n /** Renders first column with tree indent and toggles. */\r\n isTreeMode: boolean\r\n /** Pixels per tree nesting level. */\r\n indentSize: number\r\n /** Keys of expanded tree nodes. */\r\n treeExpanded: Set<RowId>\r\n /** Keys of expanded detail rows. */\r\n expandedKeys: Set<RowId>\r\n /** Total grid columns including leading utility cells. */\r\n totalCols: number\r\n /** Map of cell key to rowspan/colspan. */\r\n spanMap: Map<string, CellSpan>\r\n /** Keys of cells covered by spans and not rendered. */\r\n hiddenCells: Set<string>\r\n /** Resolved locale strings. */\r\n t: Required<TableLocale>\r\n /** Optional row class or resolver. */\r\n rowClassName?: string | ((row: Record<string, unknown>, id: RowId) => string)\r\n /** Sticky/fixed/ellipsis styles per column. */\r\n fixedStyle: (col: TableColumn) => React.CSSProperties\r\n /** Row click handler. */\r\n onRowClick?: (id: RowId, data: Record<string, unknown>) => void\r\n /** Inline edit commit handler. */\r\n onCellEdit?: (id: RowId, column: string, value: unknown) => void\r\n /** Toggles a row in the selection model. */\r\n onSelectRow: (id: RowId, row: Record<string, unknown>) => void\r\n /** Toggles expanded row content. */\r\n onToggleExpand: (id: RowId) => void\r\n /** Toggles tree node expansion. */\r\n onToggleTreeExpand: (id: RowId) => void\r\n /** Enables row drag reorder handle column. */\r\n rowDraggable?: boolean\r\n /** Called after a row drag reorder. */\r\n onRowOrderChange?: (fromIndex: number, toIndex: number) => void\r\n /** Builds cell context menu items. */\r\n cellContextMenu?: (id: RowId, column: string, data: Record<string, unknown>) => ContextMenuItem[]\r\n /** Opens or closes the shared context menu. */\r\n onContextMenu: (state: ContextMenuState | null) => void\r\n /** Zebra striping for data rows. */\r\n striped?: boolean\r\n /** Renders leading row number cells. */\r\n showRowNumber?: boolean\r\n /** Group-by field name for header label. */\r\n groupBy?: string\r\n /** Toggles a grouped section expanded state. */\r\n onToggleGroup?: (groupKey: string) => void\r\n /** Current keyboard-focused cell coordinates. */\r\n focusedCell?: { row: number; col: number } | null\r\n /** Updates keyboard-focused cell. */\r\n onFocusCell?: (cell: { row: number; col: number } | null) => void\r\n /** Enables focus outlines and cell focus moves. */\r\n keyboardNavigation?: boolean\r\n /** Custom empty state when no rows. */\r\n emptyContent?: React.ReactNode\r\n /** Renders pinned top/bottom sections without zebra. */\r\n isPinnedSection?: boolean\r\n /** Публичные классы по слотам Table. */\r\n slotClassNames?: TableClassNames\r\n /** Публичные стили по слотам Table. */\r\n slotStyles?: TableStyles\r\n /**\r\n * Сдвиг локальных индексов до абсолютных. Передаётся `VirtualTableBody`\r\n * для виртуализации с динамическими высотами — при наличии оффсета\r\n * каждая строка получает атрибут `data-sg-virtual-row-index`, который\r\n * читает `ResizeObserver` для отчёта обратно в движок.\r\n */\r\n rowIndexOffset?: number\r\n}\r\n\r\n/** Renders the main or pinned table body rows, cells, and expand regions. */\r\nexport function TableBody(props: BodyProps) {\r\n const {\r\n columns,\r\n flatRows,\r\n rowSelection,\r\n expandable,\r\n isTreeMode,\r\n indentSize,\r\n treeExpanded,\r\n expandedKeys,\r\n totalCols,\r\n spanMap,\r\n hiddenCells,\r\n t,\r\n rowClassName,\r\n fixedStyle,\r\n onRowClick,\r\n onCellEdit,\r\n onSelectRow,\r\n onToggleExpand,\r\n onToggleTreeExpand,\r\n rowDraggable,\r\n onRowOrderChange,\r\n cellContextMenu,\r\n onContextMenu,\r\n striped,\r\n showRowNumber,\r\n groupBy,\r\n onToggleGroup,\r\n focusedCell,\r\n onFocusCell,\r\n keyboardNavigation,\r\n emptyContent,\r\n slotClassNames,\r\n slotStyles,\r\n isPinnedSection,\r\n rowIndexOffset,\r\n } = props\r\n\r\n const sCls = slotClassNames ?? {}\r\n const sSty = slotStyles ?? {}\r\n\r\n const [editingCell, setEditingCell] = useState<{\r\n rowId: RowId\r\n col: string\r\n } | null>(null)\r\n const [editValue, setEditValue] = useState('')\r\n const editRef = useRef<HTMLInputElement>(null)\r\n\r\n const [dragRowIdx, setDragRowIdx] = useState<number | null>(null)\r\n const [dragOverRowIdx, setDragOverRowIdx] = useState<number | null>(null)\r\n\r\n const [copiedCell, setCopiedCell] = useState<string | null>(null)\r\n\r\n useEffect(() => {\r\n if (editingCell && editRef.current) editRef.current.focus()\r\n }, [editingCell])\r\n\r\n const handleEditStart = (rowId: RowId, col: string, val: unknown) => {\r\n setEditingCell({ rowId, col })\r\n setEditValue(String(val ?? ''))\r\n }\r\n\r\n const handleEditSave = () => {\r\n if (editingCell && onCellEdit) {\r\n onCellEdit(editingCell.rowId, editingCell.col, editValue)\r\n }\r\n setEditingCell(null)\r\n }\r\n\r\n const handleEditCancel = () => setEditingCell(null)\r\n\r\n const handleRowDragStart = (e: React.DragEvent, idx: number) => {\r\n setDragRowIdx(idx)\r\n e.dataTransfer.effectAllowed = 'move'\r\n e.dataTransfer.setData('text/plain', String(idx))\r\n }\r\n\r\n const handleRowDragOver = (e: React.DragEvent, idx: number) => {\r\n e.preventDefault()\r\n e.dataTransfer.dropEffect = 'move'\r\n setDragOverRowIdx(idx)\r\n }\r\n\r\n const handleRowDrop = (_e: React.DragEvent, toIdx: number) => {\r\n if (dragRowIdx !== null && dragRowIdx !== toIdx) {\r\n onRowOrderChange?.(dragRowIdx, toIdx)\r\n }\r\n setDragRowIdx(null)\r\n setDragOverRowIdx(null)\r\n }\r\n\r\n const handleRowDragEnd = () => {\r\n setDragRowIdx(null)\r\n setDragOverRowIdx(null)\r\n }\r\n\r\n const handleCellContext = (\r\n e: React.MouseEvent,\r\n id: RowId,\r\n colKey: string,\r\n data: Record<string, unknown>,\r\n ) => {\r\n if (!cellContextMenu) return\r\n e.preventDefault()\r\n const items = cellContextMenu(id, colKey, data)\r\n if (items.length > 0) {\r\n onContextMenu({ x: e.clientX, y: e.clientY, items })\r\n }\r\n }\r\n\r\n const handleCellCopy = useCallback(async (rowId: RowId, colKey: string, value: unknown) => {\r\n await copyToClipboard(String(value ?? ''))\r\n setCopiedCell(`${rowId}:${colKey}`)\r\n setTimeout(() => setCopiedCell(null), 1500)\r\n }, [])\r\n\r\n if (flatRows.length === 0) {\r\n return (\r\n <div\r\n className={['sg-table-empty', sCls.empty].filter(Boolean).join(' ')}\r\n style={{ gridColumn: `1 / ${totalCols + 1}`, ...sSty.empty }}\r\n role=\"row\"\r\n >\r\n <span role=\"cell\">{emptyContent ?? t.emptyText}</span>\r\n </div>\r\n )\r\n }\r\n\r\n let dataRowIndex = 0\r\n\r\n return (\r\n <>\r\n {flatRows.map((row, rowIdx) => {\r\n // Group row rendering\r\n if (row.__groupRow) {\r\n return (\r\n <TableGroupRow\r\n key={row.id}\r\n group={row.__groupRow}\r\n groupBy={groupBy}\r\n totalCols={totalCols}\r\n t={t}\r\n onToggle={onToggleGroup ?? (() => {})}\r\n />\r\n )\r\n }\r\n\r\n const currentDataIdx = dataRowIndex++\r\n const isExpanded = expandedKeys.has(row.id)\r\n const isSelected = rowSelection?.selectedKeys.includes(row.id)\r\n const canExpand = expandable?.rowExpandable\r\n ? expandable.rowExpandable(row.data)\r\n : !!expandable\r\n\r\n const rowCls =\r\n typeof rowClassName === 'function' ? rowClassName(row.data, row.id) : (rowClassName ?? '')\r\n\r\n const isZebra = striped && currentDataIdx % 2 === 1\r\n const isDragOver = dragOverRowIdx === rowIdx && dragRowIdx !== rowIdx\r\n const isPinned = isPinnedSection\r\n\r\n const virtualIndexAttr = rowIndexOffset !== undefined ? rowIndexOffset + rowIdx : undefined\r\n\r\n return (\r\n <React.Fragment key={row.id}>\r\n <div\r\n className={[\r\n 'sg-table-row',\r\n isSelected ? 'sg-table-row-selected' : '',\r\n onRowClick ? 'sg-table-row-clickable' : '',\r\n isZebra ? 'sg-table-row-striped' : '',\r\n isDragOver ? 'sg-table-row-drag-over' : '',\r\n isPinned ? 'sg-table-row-pinned' : '',\r\n sCls.row,\r\n rowCls,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n role=\"row\"\r\n style={{ display: 'contents', ...sSty.row }}\r\n data-sg-virtual-row-index={virtualIndexAttr}\r\n draggable={rowDraggable}\r\n onDragStart={rowDraggable ? (e) => handleRowDragStart(e, rowIdx) : undefined}\r\n onDragOver={rowDraggable ? (e) => handleRowDragOver(e, rowIdx) : undefined}\r\n onDrop={rowDraggable ? (e) => handleRowDrop(e, rowIdx) : undefined}\r\n onDragEnd={rowDraggable ? handleRowDragEnd : undefined}\r\n >\r\n {rowDraggable && (\r\n <div\r\n className=\"sg-table-td sg-table-cell-drag-handle\"\r\n role=\"cell\"\r\n style={{\r\n cursor: 'grab',\r\n userSelect: 'none',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n }}\r\n >\r\n ⠿\r\n </div>\r\n )}\r\n\r\n {showRowNumber && (\r\n <div className=\"sg-table-td sg-table-cell-row-number\" role=\"cell\">\r\n {currentDataIdx + 1}\r\n </div>\r\n )}\r\n\r\n {rowSelection && (\r\n <div\r\n className=\"sg-table-td sg-table-cell-selection\"\r\n role=\"cell\"\r\n onClick={(e) => {\r\n e.stopPropagation()\r\n // The control (checkbox/radio) toggles via its own\r\n // onChange. Clicking the surrounding padding still\r\n // selects, but only when the click lands on the cell\r\n // itself — otherwise a label-wrapped checkbox bubbles a\r\n // second synthetic click here and the toggle cancels out.\r\n if (e.target === e.currentTarget) {\r\n onSelectRow(row.id, row.data)\r\n }\r\n }}\r\n >\r\n {rowSelection.type === 'radio' ? (\r\n <input\r\n type=\"radio\"\r\n checked={!!isSelected}\r\n onChange={() => onSelectRow(row.id, row.data)}\r\n />\r\n ) : (\r\n <Checkbox\r\n checked={!!isSelected}\r\n onChange={() => onSelectRow(row.id, row.data)}\r\n />\r\n )}\r\n </div>\r\n )}\r\n\r\n {expandable && (\r\n <div className=\"sg-table-td sg-table-cell-expand\" role=\"cell\">\r\n {canExpand && (\r\n <button\r\n className={`sg-table-expand-btn${isExpanded ? ' sg-table-expand-open' : ''}`}\r\n onClick={(e) => {\r\n e.stopPropagation()\r\n onToggleExpand(row.id)\r\n }}\r\n >\r\n {t.expandIcon}\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n\r\n {columns.map((col, colIndex) => {\r\n const cellKey = `${row.id}:${col.key}`\r\n if (hiddenCells.has(cellKey)) return null\r\n\r\n const span = spanMap.get(cellKey)\r\n const val = row.data[col.key]\r\n const isEditing = editingCell?.rowId === row.id && editingCell?.col === col.key\r\n const isFocused =\r\n keyboardNavigation && focusedCell?.row === rowIdx && focusedCell?.col === colIndex\r\n const isCopied = copiedCell === cellKey\r\n\r\n const cellStyle: React.CSSProperties = { ...fixedStyle(col) }\r\n if (span?.colSpan && span.colSpan > 1) cellStyle.gridColumn = `span ${span.colSpan}`\r\n if (span?.rowSpan && span.rowSpan > 1) cellStyle.gridRow = `span ${span.rowSpan}`\r\n\r\n const isFirstCol = colIndex === 0\r\n const treeIndent = isTreeMode && isFirstCol ? row.depth * indentSize : 0\r\n\r\n const cellClsExtra =\r\n typeof col.cellClassName === 'function'\r\n ? col.cellClassName(val, row.data, row.id)\r\n : (col.cellClassName ?? '')\r\n\r\n return (\r\n <div\r\n key={col.key}\r\n className={[\r\n 'sg-table-td',\r\n col.fixed ? 'sg-table-cell-fixed' : '',\r\n col.fixed ? `sg-table-cell-fixed-${col.fixed}` : '',\r\n col.editable ? 'sg-table-td-editable' : '',\r\n isFocused ? 'sg-table-cell-focused' : '',\r\n isCopied ? 'sg-table-cell-copied' : '',\r\n col.copyable ? 'sg-table-cell-copyable' : '',\r\n sCls.bodyCell,\r\n cellClsExtra,\r\n ]\r\n .filter(Boolean)\r\n .join(' ')}\r\n style={{ ...cellStyle, ...sSty.bodyCell }}\r\n role=\"cell\"\r\n tabIndex={keyboardNavigation ? -1 : undefined}\r\n onClick={() => {\r\n onRowClick?.(row.id, row.data)\r\n if (keyboardNavigation) {\r\n onFocusCell?.({ row: rowIdx, col: colIndex })\r\n }\r\n }}\r\n onContextMenu={(e) => handleCellContext(e, row.id, col.key, row.data)}\r\n onDoubleClick={\r\n col.editable && onCellEdit\r\n ? (e) => {\r\n e.stopPropagation()\r\n handleEditStart(row.id, col.key, val)\r\n }\r\n : undefined\r\n }\r\n >\r\n {isTreeMode && isFirstCol && (\r\n <span\r\n style={{\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n minWidth: treeIndent + 20,\r\n flexShrink: 0,\r\n }}\r\n >\r\n <span style={{ width: treeIndent }} />\r\n {row.hasChildren ? (\r\n <button\r\n className={`sg-table-expand-btn${treeExpanded.has(row.id) ? ' sg-table-expand-open' : ''}`}\r\n onClick={(e) => {\r\n e.stopPropagation()\r\n onToggleTreeExpand(row.id)\r\n }}\r\n >\r\n {t.expandIcon}\r\n </button>\r\n ) : (\r\n <span style={{ width: 20 }} />\r\n )}\r\n </span>\r\n )}\r\n <span className=\"sg-table-cell-content\">\r\n {isEditing ? (\r\n <input\r\n ref={editRef}\r\n className=\"sg-table-edit-input\"\r\n value={editValue}\r\n onChange={(e) => setEditValue(e.target.value)}\r\n onBlur={handleEditSave}\r\n onKeyDown={(e) => {\r\n if (e.key === 'Enter') handleEditSave()\r\n if (e.key === 'Escape') handleEditCancel()\r\n }}\r\n />\r\n ) : col.render ? (\r\n col.render(val, row.data, row.id)\r\n ) : (\r\n String(val ?? '')\r\n )}\r\n </span>\r\n {col.copyable && !isEditing && (\r\n <button\r\n className=\"sg-table-copy-btn\"\r\n onClick={(e) => {\r\n e.stopPropagation()\r\n handleCellCopy(row.id, col.key, val)\r\n }}\r\n title=\"Copy\"\r\n >\r\n {isCopied ? '✓' : '⎘'}\r\n </button>\r\n )}\r\n </div>\r\n )\r\n })}\r\n </div>\r\n\r\n {expandable && isExpanded && (\r\n <div\r\n className=\"sg-table-expanded-row\"\r\n style={{ gridColumn: `1 / ${totalCols + 1}` }}\r\n role=\"row\"\r\n >\r\n <div role=\"cell\">{expandable.expandedRowRender(row.data, row.id)}</div>\r\n </div>\r\n )}\r\n </React.Fragment>\r\n )\r\n })}\r\n </>\r\n )\r\n}\r\n","import type { GroupRow, TableLocale } from './types'\r\n\r\n/** Props for the synthetic group header row. */\r\nexport interface TableGroupRowProps {\r\n /** Group metadata (key, value, count, aggregates). */\r\n group: GroupRow\r\n /** Field used to derive the group, displayed in the title. */\r\n groupBy?: string\r\n /** Number of grid columns the group row should span. */\r\n totalCols: number\r\n /** Resolved table locale strings. */\r\n t: Required<TableLocale>\r\n /** Toggle expand / collapse for this group key. */\r\n onToggle: (groupKey: string) => void\r\n}\r\n\r\n/**\r\n * Group header row rendered above each set of grouped data rows.\r\n * Spans the entire row, shows expand/collapse affordance, group title,\r\n * row count, and aggregate values when configured.\r\n */\r\nexport function TableGroupRow({ group, groupBy, totalCols, t, onToggle }: TableGroupRowProps) {\r\n return (\r\n <div\r\n className=\"sg-table-group-row\"\r\n role=\"row\"\r\n style={{ display: 'contents' }}\r\n >\r\n <div\r\n className=\"sg-table-td sg-table-group-cell\"\r\n role=\"cell\"\r\n style={{ gridColumn: `1 / ${totalCols + 1}` }}\r\n onClick={() => onToggle(group.groupKey)}\r\n >\r\n <button\r\n type=\"button\"\r\n className={`sg-table-expand-btn${group.expanded ? ' sg-table-expand-open' : ''}`}\r\n aria-label={group.expanded ? t.groupCollapse : t.groupExpand}\r\n aria-expanded={group.expanded}\r\n onClick={(e) => {\r\n e.stopPropagation()\r\n onToggle(group.groupKey)\r\n }}\r\n >\r\n {t.expandIcon}\r\n </button>\r\n <span className=\"sg-table-group-title\">\r\n {groupBy ? `${groupBy}: ` : null}\r\n <strong>{String(group.groupValue)}</strong>\r\n </span>\r\n <span className=\"sg-table-group-count\">({group.count})</span>\r\n {Object.keys(group.aggregates).length > 0 && (\r\n <span className=\"sg-table-group-aggregates\">\r\n {Object.entries(group.aggregates).map(([key, val]) => (\r\n <span key={key} className=\"sg-table-group-agg-item\">\r\n {key}: {String(val)}\r\n </span>\r\n ))}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n}\r\n","import React, { useEffect, useLayoutEffect, useMemo, useReducer, useRef, useState } from 'react'\r\nimport { createVirtual } from '@skygraph/core'\r\nimport type { VirtualEngine } from '@skygraph/core'\r\nimport { TableBody, type BodyProps } from './TableBody'\r\nimport type { FlatRow } from './types'\r\n\r\n/**\r\n * Сигнатура функций оценки/измерения высоты строки. Принимает данные строки\r\n * + её id (как в `TableEngine.getEstimatedRowHeight`).\r\n */\r\nexport type VirtualRowHeightFn = (row: Record<string, unknown>, id: string) => number\r\n\r\ninterface VirtualBodyProps extends BodyProps {\r\n /**\r\n * Высота строки.\r\n *\r\n * - `number` — фиксированная одинаковая высота для всех строк (быстрый\r\n * путь, CSS-локается на стороне `Table.tsx`).\r\n * - `function` — **декларативная** per-row высота: значение, которое\r\n * возвращает функция, трактуется как точная высота строки. Высота\r\n * жёстко локается в DOM через inline-style, чтобы `scrollHeight`\r\n * контейнера ВСЕГДА совпадал с `engine.totalHeight` (это убирает\r\n * дрейф ползунка при drag и тремор от посторонних reflow'ов).\r\n * ResizeObserver в этом режиме не используется — если контент\r\n * сильно выше декларируемой высоты, он будет обрезан\r\n * (`overflow: hidden`).\r\n */\r\n rowHeight: number | VirtualRowHeightFn\r\n /**\r\n * Эстимейт высоты для off-screen строк, когда `rowHeight` — число\r\n * (или не задан). Если задан вместе с `rowHeight`-функцией, функция\r\n * используется для видимых строк (как точная высота, см. выше),\r\n * а `estimateRowHeight` — для строк за пределами viewport.\r\n */\r\n estimateRowHeight?: VirtualRowHeightFn\r\n /** Сколько лишних строк рендерить выше / ниже viewport. */\r\n overscan: number\r\n /** Ref на родительский `.sg-table-scroll`, чей scroll-контекст мы наблюдаем. */\r\n scrollContainerRef: React.RefObject<HTMLDivElement | null>\r\n}\r\n\r\nconst DEFAULT_ROW_HEIGHT = 40\r\n\r\n/**\r\n * Резолвит эстимейт-функцию для `createVirtual`. Использует измеренную /\r\n * уже виденную ранее высоту, если она прокидывается извне; иначе вызывает\r\n * пользовательский callback.\r\n */\r\nfunction buildEstimate(\r\n rowHeight: number | VirtualRowHeightFn,\r\n estimate: VirtualRowHeightFn | undefined,\r\n flatRows: FlatRow[],\r\n): number | ((index: number) => number) {\r\n if (typeof rowHeight === 'number' && estimate == null) {\r\n return rowHeight\r\n }\r\n const fallback = typeof rowHeight === 'number' ? rowHeight : DEFAULT_ROW_HEIGHT\r\n const fn: VirtualRowHeightFn | undefined =\r\n estimate ?? (typeof rowHeight === 'function' ? rowHeight : undefined)\r\n if (!fn) return fallback\r\n return (index: number) => {\r\n const row = flatRows[index]\r\n if (!row) return fallback\r\n const v = fn(row.data, row.id)\r\n return Number.isFinite(v) && v >= 0 ? v : fallback\r\n }\r\n}\r\n\r\n/**\r\n * Виртуализированное тело таблицы. Живёт в той же CSS Grid, что и `TableHeader`,\r\n * поэтому ширины колонок остаются согласованными автоматически. Скролл\r\n * наблюдается на родительском `.sg-table-scroll` — мы не вводим вложенный\r\n * scrollbox.\r\n *\r\n * **Динамические высоты:** если `rowHeight` — функция, или передан\r\n * `estimateRowHeight`, движок переходит на путь с измерениями. Каждая\r\n * отрендеренная строка получает `data-sg-virtual-row-index` и наблюдается\r\n * через `ResizeObserver`. Префикс-сумма offsets пересобирается лениво при\r\n * первом запросе после `setMeasuredHeight`.\r\n */\r\nexport function VirtualTableBody(props: VirtualBodyProps) {\r\n const {\r\n rowHeight,\r\n estimateRowHeight,\r\n overscan,\r\n scrollContainerRef,\r\n flatRows,\r\n totalCols,\r\n ...bodyProps\r\n } = props\r\n\r\n const isDeclarative = typeof rowHeight === 'function'\r\n const isDynamic = isDeclarative || estimateRowHeight != null\r\n\r\n // VirtualEngine создаётся один раз и переиспользуется. setItemCount /\r\n // setItemHeight применяются в эффектах.\r\n const virtual = useMemo<VirtualEngine>(\r\n () =>\r\n createVirtual({\r\n itemCount: flatRows.length,\r\n itemHeight: buildEstimate(rowHeight, estimateRowHeight, flatRows),\r\n overscan,\r\n }),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [],\r\n )\r\n\r\n const [, forceUpdate] = useReducer((n: number) => n + 1, 0)\r\n\r\n // Подписка на инвалидации движка — единственный путь, по которому новый\r\n // measurement вызывает перерисовку. Эффект подключается один раз.\r\n //\r\n // В declarative-mode (rowHeight как функция) sync-prime в useLayoutEffect\r\n // выставляет engine-size до paint'а, а subscribe тут же триггерит\r\n // forceUpdate — React обработает его внутри того же task'а до paint'а,\r\n // так что DOM-расчёты (bottomPad, topPad) уезжают в одну итерацию,\r\n // synchronously, без лишних кадров. Это и обеспечивает совпадение\r\n // scrollHeight ↔ totalHeight на каждом кадре скролла.\r\n useEffect(() => virtual.subscribe(() => forceUpdate()), [virtual])\r\n\r\n useEffect(() => {\r\n virtual.setItemCount(flatRows.length)\r\n virtual.setItemHeight(buildEstimate(rowHeight, estimateRowHeight, flatRows))\r\n }, [virtual, flatRows, rowHeight, estimateRowHeight])\r\n\r\n // В declarative-mode пред-заполняем engine значениями rowHeight для ВСЕХ\r\n // строк, а не только видимых. Без этого totalHeight «доуточнялся»\r\n // постепенно при появлении новых строк в viewport, ergo scrollHeight\r\n // менялся прямо во время drag'а ползунка → курсор уезжал от него.\r\n // Стоимость: O(N) function-вызовов один раз на data change. Для 4000\r\n // строк это ~4000 setMeasuredHeight, событий движок отправит ровно\r\n // столько, сколько реально новых значений — последующие вызовы с тем\r\n // же h возвращают `false` без emit'а.\r\n useEffect(() => {\r\n if (!isDeclarative) return\r\n const fn = rowHeight as VirtualRowHeightFn\r\n for (let i = 0; i < flatRows.length; i++) {\r\n const row = flatRows[i]\r\n if (!row) continue\r\n const h = fn(row.data, row.id)\r\n if (Number.isFinite(h) && h >= 0) {\r\n virtual.setMeasuredHeight(i, Math.round(h))\r\n }\r\n }\r\n }, [virtual, flatRows, rowHeight, isDeclarative])\r\n\r\n const [scrollTop, setScrollTop] = useState(0)\r\n const [viewportHeight, setViewportHeight] = useState(0)\r\n\r\n useEffect(() => {\r\n const el = scrollContainerRef.current\r\n if (!el) return\r\n\r\n setViewportHeight(el.clientHeight)\r\n setScrollTop(el.scrollTop)\r\n\r\n // Synchronous scroll handler — when the user drags the scrollbar\r\n // thumb, the browser moves it in sync with the pointer. If we\r\n // defer the React state update to rAF, the DOM content (topPad /\r\n // bottomPad) updates a frame late, which causes the browser to\r\n // recalculate scroll position and the thumb drifts away from the\r\n // cursor. Using synchronous updates keeps scrollHeight stable on\r\n // the same frame the browser processes the scroll event.\r\n const onScroll = () => {\r\n setScrollTop(el.scrollTop)\r\n }\r\n el.addEventListener('scroll', onScroll, { passive: true })\r\n\r\n let ro: ResizeObserver | null = null\r\n if (typeof ResizeObserver !== 'undefined') {\r\n ro = new ResizeObserver(() => setViewportHeight(el.clientHeight))\r\n ro.observe(el)\r\n }\r\n\r\n return () => {\r\n el.removeEventListener('scroll', onScroll)\r\n ro?.disconnect()\r\n }\r\n }, [scrollContainerRef])\r\n\r\n const range = virtual.getRange(scrollTop, viewportHeight || 400)\r\n const visibleRows = flatRows.slice(range.startIndex, range.endIndex + 1)\r\n const totalHeight = range.totalHeight\r\n const topPad = range.offsetTop\r\n const visibleSize = visibleRows.reduce(\r\n (sum, _row, idx) => sum + virtual.getItemSize(range.startIndex + idx),\r\n 0,\r\n )\r\n const bottomPad = Math.max(0, totalHeight - topPad - visibleSize)\r\n\r\n // Чтобы измерения не входили в петлю из субпиксельного дребезга\r\n // (`getBoundingClientRect` периодически возвращает 47.5 ↔ 48.0 на одних\r\n // и тех же DOM-узлах), стабилизируем высоту до целых пикселей. Math.round\r\n // симметричен относительно 0.5 (устойчивее `Math.ceil`, которая ловила\r\n // дрожь 48.0 ↔ 48.001 как 48 ↔ 49).\r\n const normalizeHeight = (h: number) => Math.round(h)\r\n\r\n // Стабильный ResizeObserver. Нужен ТОЛЬКО в measurement-mode\r\n // (`rowHeight: number + estimateRowHeight: function`), где реальные\r\n // высоты неизвестны до layout'а. В declarative-mode (rowHeight как\r\n // функция) высоты декларируются пользователем напрямую → RO не нужен,\r\n // его наблюдение лишь будит цикл re-render'ов от субпиксельных\r\n // изменений во время неродственных reflow'ов (например, появление\r\n // page-scrollbar при прокрутке страницы пересчитывает ширину колонок\r\n // и высоту длинных строк — отсюда и был «тремор всего блока»).\r\n const roRef = useRef<ResizeObserver | null>(null)\r\n const observedCellsRef = useRef<Set<HTMLElement>>(new Set())\r\n\r\n useEffect(() => {\r\n if (!isDynamic) return\r\n if (isDeclarative) return\r\n if (typeof ResizeObserver === 'undefined') return\r\n\r\n const ro = new ResizeObserver((entries) => {\r\n for (const entry of entries) {\r\n const target = entry.target as HTMLElement\r\n const rowEl = target.closest('[data-sg-virtual-row-index]') as HTMLElement | null\r\n if (!rowEl) continue\r\n const idx = Number(rowEl.getAttribute('data-sg-virtual-row-index'))\r\n virtual.setMeasuredHeight(idx, normalizeHeight(entry.contentRect.height))\r\n }\r\n })\r\n roRef.current = ro\r\n return () => {\r\n ro.disconnect()\r\n roRef.current = null\r\n observedCellsRef.current.clear()\r\n }\r\n }, [isDynamic, isDeclarative, virtual])\r\n\r\n // На каждый ре-рендер:\r\n // 1) Sync-prime engine значениями для видимых строк:\r\n // - declarative: значение из `rowHeight(row.data, row.id)` — это\r\n // пользовательский контракт «вот точная высота строки».\r\n // - measurement: реальная высота первой ячейки через\r\n // `getBoundingClientRect`, только для НЕ-измеренных раньше строк.\r\n // 2) Inline-locking всех ячеек ряда к engine-размеру: устанавливаем\r\n // `style.height = ${size}px`. Это и есть ключевой ингредиент,\r\n // благодаря которому `DOM.scrollHeight ≡ engine.totalHeight` — без\r\n // этого замечательного равенства браузер при drag-е ползунка\r\n // мапит cursorY → scrollTop по «вранному» scrollHeight и ползунок\r\n // уезжает от курсора, а RO-callback'и от внешних layout-возмущений\r\n // дёргают bottomPad и провоцируют тремор.\r\n // 3) Diff observe/unobserve ячеек RO (только в measurement-mode).\r\n useLayoutEffect(() => {\r\n if (!isDynamic) return\r\n const grid = scrollContainerRef.current?.querySelector('.sg-table-grid')\r\n if (!grid) return\r\n\r\n const rowEls = grid.querySelectorAll<HTMLElement>('[data-sg-virtual-row-index]')\r\n const ro = roRef.current\r\n const currentCells = new Set<HTMLElement>()\r\n\r\n rowEls.forEach((rowEl) => {\r\n const firstCell = rowEl.firstElementChild as HTMLElement | null\r\n if (!firstCell) return\r\n const idx = Number(rowEl.getAttribute('data-sg-virtual-row-index'))\r\n currentCells.add(firstCell)\r\n\r\n // 1) sync-prime engine size\r\n if (isDeclarative) {\r\n const row = flatRows[idx]\r\n if (row) {\r\n const declared = (rowHeight as VirtualRowHeightFn)(row.data, row.id)\r\n if (Number.isFinite(declared) && declared >= 0) {\r\n virtual.setMeasuredHeight(idx, Math.round(declared))\r\n }\r\n }\r\n } else if (!virtual.hasMeasured(idx)) {\r\n virtual.setMeasuredHeight(idx, normalizeHeight(firstCell.getBoundingClientRect().height))\r\n }\r\n\r\n // 2) lock cell heights to engine size to keep DOM.scrollHeight in\r\n // sync with engine.totalHeight. Only applies once engine knows the\r\n // size — для впервые-видимых measurement-строк до RO-сheck размер\r\n // ещё estimate'ный, локать его смысла нет.\r\n if (isDeclarative || virtual.hasMeasured(idx)) {\r\n const h = virtual.getItemSize(idx)\r\n const px = `${h}px`\r\n const children = rowEl.children\r\n for (let c = 0; c < children.length; c++) {\r\n const cell = children[c] as HTMLElement\r\n if (cell.style.height !== px) cell.style.height = px\r\n if (cell.style.minHeight !== '0px') cell.style.minHeight = '0px'\r\n if (cell.style.overflow !== 'hidden') cell.style.overflow = 'hidden'\r\n }\r\n }\r\n\r\n // 3) RO observe (measurement-mode only)\r\n if (ro && !observedCellsRef.current.has(firstCell)) {\r\n ro.observe(firstCell)\r\n }\r\n })\r\n\r\n if (ro) {\r\n for (const cell of observedCellsRef.current) {\r\n if (!currentCells.has(cell)) ro.unobserve(cell)\r\n }\r\n }\r\n observedCellsRef.current = currentCells\r\n\r\n // Фоллбэк для jsdom / runtime без RO — одноразовое измерение, чтобы\r\n // initial-render тестов отчитался.\r\n if (!isDeclarative && typeof ResizeObserver === 'undefined') {\r\n rowEls.forEach((rowEl) => {\r\n const firstCell = rowEl.firstElementChild as HTMLElement | null\r\n if (!firstCell) return\r\n const idx = Number(rowEl.getAttribute('data-sg-virtual-row-index'))\r\n virtual.setMeasuredHeight(idx, normalizeHeight(firstCell.getBoundingClientRect().height))\r\n })\r\n }\r\n }, [isDynamic, isDeclarative, virtual, scrollContainerRef, visibleRows, flatRows, rowHeight])\r\n\r\n const spacerColumn = `1 / ${totalCols + 1}`\r\n\r\n return (\r\n <>\r\n {topPad > 0 && (\r\n <div style={{ gridColumn: spacerColumn, height: topPad }} role=\"presentation\" aria-hidden />\r\n )}\r\n <TableBody\r\n {...bodyProps}\r\n flatRows={visibleRows}\r\n totalCols={totalCols}\r\n rowIndexOffset={range.startIndex}\r\n />\r\n {bottomPad > 0 && (\r\n <div\r\n style={{ gridColumn: spacerColumn, height: bottomPad }}\r\n role=\"presentation\"\r\n aria-hidden\r\n />\r\n )}\r\n </>\r\n )\r\n}\r\n","import React, { useEffect, useRef, useState } from 'react'\r\n\r\n/** One entry in a table context menu. */\r\nexport interface ContextMenuItem {\r\n /** Unique key among siblings. */\r\n key: string\r\n /** Primary label. */\r\n label: React.ReactNode\r\n /** Optional leading icon. */\r\n icon?: React.ReactNode\r\n /** Destructive styling. */\r\n danger?: boolean\r\n /** Disables click handling. */\r\n disabled?: boolean\r\n /** Renders a separator instead of a row. */\r\n divider?: boolean\r\n /** Invoked on item activate. */\r\n onClick?: () => void\r\n /** Nested submenu items. */\r\n children?: ContextMenuItem[]\r\n}\r\n\r\n/** Open context menu position and items. */\r\nexport interface ContextMenuState {\r\n /** Viewport X in pixels. */\r\n x: number\r\n /** Viewport Y in pixels. */\r\n y: number\r\n /** Root menu items. */\r\n items: ContextMenuItem[]\r\n}\r\n\r\n/** Props for the floating context menu overlay. */\r\ninterface ContextMenuProps {\r\n /** Current menu state, or null when closed. */\r\n state: ContextMenuState | null\r\n /** Closes the menu on outside interaction. */\r\n onClose: () => void\r\n}\r\n\r\n/**\r\n * Fixed-position menu for header/cell context actions.\r\n * Closes on outside click, Escape, or window scroll.\r\n */\r\nexport function ContextMenu({ state, onClose }: ContextMenuProps) {\r\n const ref = useRef<HTMLDivElement>(null)\r\n const [subMenu, setSubMenu] = useState<{ key: string; x: number; y: number; items: ContextMenuItem[] } | null>(null)\r\n\r\n useEffect(() => {\r\n if (!state) return\r\n const handle = (e: MouseEvent) => {\r\n if (ref.current && !ref.current.contains(e.target as Node)) {\r\n onClose()\r\n }\r\n }\r\n const handleKey = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') onClose()\r\n }\r\n const handleScroll = () => onClose()\r\n\r\n document.addEventListener('mousedown', handle)\r\n document.addEventListener('keydown', handleKey)\r\n window.addEventListener('scroll', handleScroll, true)\r\n return () => {\r\n document.removeEventListener('mousedown', handle)\r\n document.removeEventListener('keydown', handleKey)\r\n window.removeEventListener('scroll', handleScroll, true)\r\n }\r\n }, [state, onClose])\r\n\r\n if (!state) return null\r\n\r\n // Runtime-only positioning: coordinates come from the click event and the\r\n // submenu hangs off the parent's right edge. Every other visual property\r\n // lives in `packages/styles/components/context-menu.css`.\r\n const rootStyle: React.CSSProperties = {\r\n position: 'fixed',\r\n top: state.y,\r\n left: state.x,\r\n }\r\n const submenuStyle: React.CSSProperties = {\r\n position: 'absolute',\r\n top: 0,\r\n left: '100%',\r\n }\r\n\r\n const itemClass = (item: ContextMenuItem) => {\r\n const classes = ['sg-context-menu-item']\r\n if (item.danger) classes.push('sg-context-menu-item--danger')\r\n if (item.disabled) classes.push('sg-context-menu-item--disabled')\r\n return classes.join(' ')\r\n }\r\n\r\n const renderItems = (items: ContextMenuItem[], isSubmenu = false) => (\r\n <div\r\n ref={isSubmenu ? undefined : ref}\r\n className=\"sg-context-menu\"\r\n style={isSubmenu ? submenuStyle : rootStyle}\r\n role=\"menu\"\r\n >\r\n {items.map((item) => {\r\n if (item.divider) {\r\n return <div key={item.key} className=\"sg-context-menu-divider\" />\r\n }\r\n\r\n return (\r\n <div\r\n key={item.key}\r\n className={itemClass(item)}\r\n role=\"menuitem\"\r\n onClick={() => {\r\n if (item.disabled) return\r\n item.onClick?.()\r\n if (!item.children) onClose()\r\n }}\r\n onMouseEnter={(e) => {\r\n if (item.children) {\r\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\r\n setSubMenu({ key: item.key, x: rect.right, y: rect.top, items: item.children })\r\n } else {\r\n setSubMenu(null)\r\n }\r\n }}\r\n >\r\n {item.icon && <span className=\"sg-context-menu-icon\">{item.icon}</span>}\r\n <span className=\"sg-context-menu-label\">{item.label}</span>\r\n {item.children && <span className=\"sg-context-menu-submenu-arrow\">›</span>}\r\n {subMenu?.key === item.key && item.children && renderItems(item.children, true)}\r\n </div>\r\n )\r\n })}\r\n </div>\r\n )\r\n\r\n return renderItems(state.items)\r\n}\r\n","import { useState, useRef, useEffect, useMemo, useCallback } from 'react'\r\nimport { useTable } from '../../../hooks/useTable'\r\nimport { useConfig } from '../../ConfigProvider'\r\nimport {\r\n flattenLeafColumns,\r\n buildHeaderRows,\r\n flattenTreeRows,\r\n collectAllTreeIds,\r\n computeSpanMap,\r\n computeHiddenCells,\r\n getFixedStyle,\r\n groupByColumn,\r\n separatePinnedRows,\r\n computeColumnAggregates,\r\n} from './helpers'\r\nimport type {\r\n AdvancedFilter,\r\n TableColumn,\r\n TableProps,\r\n FlatRow,\r\n HeaderCell,\r\n FilterDropdownProps,\r\n SortDirection,\r\n SortConfig,\r\n RowId,\r\n} from './types'\r\nimport { DEFAULT_COL_WIDTH, MIN_COL_WIDTH, SELECTION_COL_WIDTH, DEFAULT_LOCALE } from './types'\r\nimport type { ContextMenuState } from './ContextMenu'\r\n\r\n/**\r\n * Derives table UI state: columns, sorting, filters, selection, grouping, and layout helpers.\r\n * Bridges `useTable` engine data with header/body presentation props.\r\n */\r\nexport function useTableState(props: TableProps) {\r\n const {\r\n columns: columnsProp,\r\n rowSelection,\r\n expandable,\r\n tree,\r\n draggable: _draggable,\r\n searchable,\r\n locale,\r\n onColumnOrderChange,\r\n onCellEdit: _onCellEdit,\r\n multiSort,\r\n sorts: controlledSorts,\r\n onSortsChange,\r\n hiddenColumns: hiddenColumnsProp,\r\n onHiddenColumnsChange,\r\n onColumnPinChange,\r\n groupBy,\r\n defaultGroupExpanded,\r\n onGroupExpandChange,\r\n pinnedRows: pinnedRowsConfig,\r\n keyboardNavigation,\r\n scroll,\r\n footer: _footer,\r\n showRowNumber: _showRowNumber,\r\n fullscreenable: _fullscreenable,\r\n densityToggle: _densityToggle,\r\n emptyContent: _emptyContent,\r\n printable: _printable,\r\n exportJSON: _exportJSON,\r\n highlightOnHover: _highlightOnHover,\r\n columnAutoResize: _columnAutoResize,\r\n ...tableOptions\r\n } = props\r\n\r\n /** When `scroll.x` is set, the author opts into hard pixel columns with a\r\n * horizontal scrollbar. Otherwise the table flexes to fit its container. */\r\n const hasScrollX = scroll?.x != null\r\n\r\n const {\r\n table,\r\n visibleRows,\r\n tableState,\r\n columnWidths: persistedColWidths,\r\n setSort,\r\n setSorts,\r\n clearSort,\r\n setPage,\r\n setFilterFn,\r\n setColumnWidth: persistColumnWidth,\r\n refresh,\r\n } = useTable(tableOptions)\r\n\r\n // Источники locale в порядке возрастания приоритета:\r\n // 1. DEFAULT_LOCALE (hardcoded-fallback — работает и без ConfigProvider)\r\n // 2. config.locale.table (из ConfigProvider)\r\n // 3. props.locale (явный проп Table)\r\n const config = useConfig()\r\n const configTableLocale = config.locale?.table\r\n const t = useMemo(\r\n () => ({ ...DEFAULT_LOCALE, ...configTableLocale, ...locale }),\r\n [configTableLocale, locale],\r\n )\r\n\r\n const hasColumnGroups = columnsProp.some((c) => c.children && c.children.length > 0)\r\n const leafColumns = useMemo(() => flattenLeafColumns(columnsProp), [columnsProp])\r\n const headerRows = useMemo<HeaderCell[][] | null>(\r\n () => (hasColumnGroups ? buildHeaderRows(columnsProp) : null),\r\n [columnsProp, hasColumnGroups],\r\n )\r\n\r\n // Multi-sort state\r\n const [internalSorts, setInternalSorts] = useState<SortConfig[]>([])\r\n const sorts = controlledSorts ?? internalSorts\r\n\r\n // Initial widths come from three sources, in order of precedence:\r\n // 1. engine-persisted widths (`$table.<id>.state.columnWidths`)\r\n // 2. column defaults (`column.width`)\r\n // 3. global default (`DEFAULT_COL_WIDTH`)\r\n // A column with a persisted width is treated as user-resized so it\r\n // keeps its exact px under flex-layout (otherwise it would snap back\r\n // to the auto track).\r\n const [colWidths, setColWidths] = useState<Record<string, number>>(() => {\r\n const w: Record<string, number> = {}\r\n for (const c of leafColumns) {\r\n w[c.key] = persistedColWidths[c.key] ?? c.width ?? DEFAULT_COL_WIDTH\r\n }\r\n return w\r\n })\r\n /** Columns the user has drag/auto-resized. Pinned to exact px — wins over auto-layout. */\r\n const [userResizedCols, setUserResizedCols] = useState<Set<string>>(\r\n () => new Set(Object.keys(persistedColWidths)),\r\n )\r\n\r\n const [colOrder, setColOrder] = useState<string[]>(() => leafColumns.map((c) => c.key))\r\n const [dragCol, setDragCol] = useState<string | null>(null)\r\n const [dragOver, setDragOver] = useState<string | null>(null)\r\n\r\n // Hidden columns\r\n const [internalHidden, setInternalHidden] = useState<Set<string>>(\r\n () => new Set(hiddenColumnsProp ?? []),\r\n )\r\n const hiddenSet = useMemo(\r\n () => (hiddenColumnsProp ? new Set(hiddenColumnsProp) : internalHidden),\r\n [hiddenColumnsProp, internalHidden],\r\n )\r\n\r\n const toggleColumnVisibility = useCallback(\r\n (key: string) => {\r\n if (onHiddenColumnsChange) {\r\n const current = hiddenColumnsProp ?? []\r\n const next = current.includes(key) ? current.filter((k) => k !== key) : [...current, key]\r\n onHiddenColumnsChange(next)\r\n } else {\r\n setInternalHidden((prev) => {\r\n const next = new Set(prev)\r\n if (next.has(key)) {\r\n next.delete(key)\r\n } else {\r\n next.add(key)\r\n }\r\n return next\r\n })\r\n }\r\n },\r\n [hiddenColumnsProp, onHiddenColumnsChange],\r\n )\r\n\r\n const [internalExpanded, setInternalExpanded] = useState<Set<RowId>>(() => {\r\n if (tree?.defaultExpandAllRows) {\r\n const childrenKey = tree.childrenColumnName ?? 'children'\r\n return new Set(collectAllTreeIds(props.data ?? [], childrenKey))\r\n }\r\n return new Set(expandable?.defaultExpandedRowKeys ?? [])\r\n })\r\n const expandedKeys = expandable?.expandedKeys\r\n ? new Set(expandable.expandedKeys)\r\n : internalExpanded\r\n\r\n const [treeExpanded, setTreeExpanded] = useState<Set<RowId>>(() => {\r\n if (tree?.defaultExpandAllRows) {\r\n const childrenKey = tree.childrenColumnName ?? 'children'\r\n return new Set(collectAllTreeIds(props.data ?? [], childrenKey))\r\n }\r\n return new Set()\r\n })\r\n\r\n const [searchText, setSearchText] = useState('')\r\n\r\n const [activeFilters, setActiveFilters] = useState<Record<string, unknown[]>>(() => {\r\n const init: Record<string, unknown[]> = {}\r\n for (const col of leafColumns) {\r\n if (col.filteredValue) {\r\n init[col.key] = [...col.filteredValue]\r\n } else if (col.defaultFilteredValue) {\r\n init[col.key] = [...col.defaultFilteredValue]\r\n }\r\n }\r\n return init\r\n })\r\n const [filterSearchText, setFilterSearchText] = useState<Record<string, string>>({})\r\n const [openFilterDropdown, setOpenFilterDropdown] = useState<string | null>(null)\r\n const [advancedFilters, setAdvancedFiltersState] = useState<Record<string, AdvancedFilter>>({})\r\n const filterRef = useRef<HTMLDivElement>(null)\r\n // Anchor элемент (FilterTrigger span). Используется FilterDropdownContent\r\n // для расчёта координат при рендере popover'а через React Portal в\r\n // document.body — иначе scroll-контейнер таблицы клипает popover и dropdown\r\n // вложенного <Select>.\r\n const [filterAnchor, setFilterAnchor] = useState<HTMLElement | null>(null)\r\n\r\n /**\r\n * Apply / clear an advanced column filter through the engine and mirror\r\n * it into local state so the trigger lights up. Engine path takes\r\n * precedence over the legacy `customFilterFn` path because the engine\r\n * runs filters before sort and pagination.\r\n */\r\n const setAdvancedFilter = useCallback(\r\n (colKey: string, filter: AdvancedFilter | null) => {\r\n setAdvancedFiltersState((prev) => {\r\n const next = { ...prev }\r\n if (filter == null) delete next[colKey]\r\n else next[colKey] = filter\r\n return next\r\n })\r\n table.setColumnFilter(colKey, filter)\r\n // Engine.setColumnFilter пересчитывает filteredOrder, но React-стейт\r\n // visibleRows живёт в useTable и обновляется только через refresh().\r\n // Без него таблица не перерисуется, пока пользователь не сделает любое\r\n // другое действие, которое случайно дернёт refresh.\r\n refresh()\r\n },\r\n [table, refresh],\r\n )\r\n\r\n const resizeRef = useRef<{ col: string; startX: number; startW: number } | null>(null)\r\n const resizeCleanupRef = useRef<(() => void) | null>(null)\r\n\r\n useEffect(\r\n () => () => {\r\n resizeCleanupRef.current?.()\r\n },\r\n [],\r\n )\r\n\r\n // Context menu state\r\n const [contextMenu, setContextMenu] = useState<ContextMenuState | null>(null)\r\n\r\n const columns = useMemo(() => {\r\n const base = hasColumnGroups\r\n ? leafColumns\r\n : (() => {\r\n const map = new Map(leafColumns.map((c) => [c.key, c]))\r\n return colOrder.filter((k) => map.has(k)).map((k) => map.get(k)!)\r\n })()\r\n return base.filter((c) => !hiddenSet.has(c.key) && !c.hidden)\r\n }, [leafColumns, colOrder, hasColumnGroups, hiddenSet])\r\n\r\n useEffect(() => {\r\n const keys = leafColumns.map((c) => c.key)\r\n setColOrder((prev) => {\r\n const prevSet = new Set(prev)\r\n const added = keys.filter((k) => !prevSet.has(k))\r\n const valid = prev.filter((k) => keys.includes(k))\r\n return [...valid, ...added]\r\n })\r\n }, [leafColumns])\r\n\r\n useEffect(() => {\r\n for (const col of leafColumns) {\r\n if (col.filteredValue !== undefined) {\r\n setActiveFilters((prev) => {\r\n if (JSON.stringify(prev[col.key]) === JSON.stringify(col.filteredValue)) return prev\r\n return { ...prev, [col.key]: [...col.filteredValue!] }\r\n })\r\n }\r\n }\r\n }, [leafColumns])\r\n\r\n useEffect(() => {\r\n const colFilters = columns.filter((c) => c.onFilter && activeFilters[c.key]?.length)\r\n const hasSearch = searchable && searchText.length > 0\r\n\r\n if (colFilters.length === 0 && !hasSearch) {\r\n setFilterFn(null)\r\n return\r\n }\r\n\r\n const lower = hasSearch ? searchText.toLowerCase() : ''\r\n\r\n setFilterFn((row) => {\r\n for (const col of colFilters) {\r\n const vals = activeFilters[col.key]\r\n const fn = col.onFilter!\r\n if (!vals.some((v) => fn(v, row))) return false\r\n }\r\n if (hasSearch) {\r\n const match = Object.values(row).some(\r\n (v) => v != null && String(v).toLowerCase().includes(lower),\r\n )\r\n if (!match) return false\r\n }\r\n return true\r\n })\r\n }, [activeFilters, searchText, searchable, setFilterFn, columns])\r\n\r\n useEffect(() => {\r\n if (!openFilterDropdown) return\r\n const handle = (e: MouseEvent) => {\r\n if (filterRef.current && !filterRef.current.contains(e.target as Node)) {\r\n setOpenFilterDropdown(null)\r\n }\r\n }\r\n document.addEventListener('mousedown', handle)\r\n return () => document.removeEventListener('mousedown', handle)\r\n }, [openFilterDropdown])\r\n\r\n // ---- Sort handler (multi-sort aware) ----\r\n\r\n const handleSort = useCallback(\r\n (col: TableColumn, shiftKey?: boolean) => {\r\n if (!col.sortable) return\r\n\r\n if (multiSort && shiftKey) {\r\n const existing = sorts.find((s) => s.column === col.key)\r\n let next: SortConfig[]\r\n if (!existing) {\r\n next = [...sorts, { column: col.key, direction: 'asc' as SortDirection }]\r\n } else if (existing.direction === 'asc') {\r\n next = sorts.map((s) =>\r\n s.column === col.key ? { ...s, direction: 'desc' as SortDirection } : s,\r\n )\r\n } else {\r\n next = sorts.filter((s) => s.column !== col.key)\r\n }\r\n\r\n // `sorts` проп задан => controlled-режим, internal state не трогаем.\r\n // Иначе всегда обновляем internal state, а `onSortsChange` шлём как\r\n // уведомление (uncontrolled + callback должны работать вместе).\r\n onSortsChange?.(next)\r\n if (controlledSorts === undefined) {\r\n setInternalSorts(next)\r\n }\r\n\r\n if (next.length === 0) {\r\n clearSort()\r\n } else {\r\n setSorts(next)\r\n }\r\n } else {\r\n // Берём текущую сортировку именно этой колонки (а не `sorts[0]`),\r\n // чтобы при мультисорте клик без Shift по уже сортированной колонке\r\n // переключал направление asc→desc→none, а не сбрасывал всё.\r\n const current = sorts.find((s) => s.column === col.key) ?? null\r\n let next: SortConfig[]\r\n\r\n if (!current || current.column !== col.key) {\r\n next = [{ column: col.key, direction: 'asc' }]\r\n } else if (current.direction === 'asc') {\r\n next = [{ column: col.key, direction: 'desc' }]\r\n } else {\r\n next = []\r\n }\r\n\r\n onSortsChange?.(next)\r\n if (controlledSorts === undefined) {\r\n setInternalSorts(next)\r\n }\r\n\r\n if (next.length === 0) {\r\n clearSort()\r\n } else {\r\n setSort(next[0].column, next[0].direction)\r\n }\r\n }\r\n },\r\n [multiSort, sorts, controlledSorts, onSortsChange, setSort, setSorts, clearSort],\r\n )\r\n\r\n const getSortIndex = useCallback(\r\n (colKey: string): number => {\r\n if (!multiSort || sorts.length <= 1) return -1\r\n return sorts.findIndex((s) => s.column === colKey)\r\n },\r\n [multiSort, sorts],\r\n )\r\n\r\n const getSortDirection = useCallback(\r\n (colKey: string): SortDirection | null => {\r\n const found = sorts.find((s) => s.column === colKey)\r\n return found?.direction ?? null\r\n },\r\n [sorts],\r\n )\r\n\r\n // ---- Other handlers ----\r\n\r\n const handleToggleExpand = (id: RowId) => {\r\n const open = expandedKeys.has(id)\r\n // `onExpand` is a notification callback, not a controlled-mode signal.\r\n // Controlled mode is keyed off `expandable.expandedKeys` being provided;\r\n // otherwise we still own the expansion state internally even when the\r\n // host listens via `onExpand`.\r\n expandable?.onExpand?.(!open, id)\r\n if (expandable?.expandedKeys == null) {\r\n setInternalExpanded((prev) => {\r\n const next = new Set(prev)\r\n if (open) {\r\n next.delete(id)\r\n } else {\r\n next.add(id)\r\n }\r\n return next\r\n })\r\n }\r\n }\r\n\r\n const handleToggleTreeExpand = (id: RowId) => {\r\n setTreeExpanded((prev) => {\r\n const next = new Set(prev)\r\n if (next.has(id)) {\r\n next.delete(id)\r\n } else {\r\n next.add(id)\r\n }\r\n return next\r\n })\r\n }\r\n\r\n const handleSelectRow = (id: RowId, row: Record<string, unknown>) => {\r\n if (!rowSelection) return\r\n const { selectedKeys, onChange, type = 'checkbox' } = rowSelection\r\n if (type === 'radio') {\r\n onChange([id], [row])\r\n return\r\n }\r\n const next = selectedKeys.includes(id)\r\n ? selectedKeys.filter((k) => k !== id)\r\n : [...selectedKeys, id]\r\n onChange(\r\n next,\r\n visibleRows.filter((r) => next.includes(r.id)).map((r) => r.data),\r\n )\r\n }\r\n\r\n const handleSelectAll = () => {\r\n if (!rowSelection) return\r\n const ids = visibleRows.map((r) => r.id)\r\n const all = ids.every((id) => rowSelection.selectedKeys.includes(id))\r\n rowSelection.onChange(all ? [] : ids, all ? [] : visibleRows.map((r) => r.data))\r\n }\r\n\r\n const handleFilterToggle = (colKey: string, value: unknown, multiple: boolean) => {\r\n setActiveFilters((prev) => {\r\n const current = prev[colKey] ?? []\r\n if (!multiple) return { ...prev, [colKey]: [value] }\r\n const idx = current.indexOf(value)\r\n const next = idx >= 0 ? current.filter((_, i) => i !== idx) : [...current, value]\r\n return { ...prev, [colKey]: next }\r\n })\r\n }\r\n\r\n const handleFilterConfirm = (colKey: string) => {\r\n setOpenFilterDropdown(null)\r\n setFilterSearchText((prev) => ({ ...prev, [colKey]: '' }))\r\n }\r\n\r\n const handleFilterReset = (colKey: string) => {\r\n setActiveFilters((prev) => ({ ...prev, [colKey]: [] }))\r\n setFilterSearchText((prev) => ({ ...prev, [colKey]: '' }))\r\n }\r\n\r\n const handleFilterClose = (colKey: string) => {\r\n setOpenFilterDropdown(null)\r\n setFilterSearchText((prev) => ({ ...prev, [colKey]: '' }))\r\n }\r\n\r\n const handleSearchFilterChange = (colKey: string, text: string) => {\r\n setActiveFilters((prev) => ({ ...prev, [colKey]: text ? [text] : [] }))\r\n }\r\n\r\n const getFilterDropdownProps = (col: TableColumn): FilterDropdownProps => ({\r\n selectedKeys: activeFilters[col.key] ?? [],\r\n setSelectedKeys: (keys) => setActiveFilters((prev) => ({ ...prev, [col.key]: keys })),\r\n confirm: () => handleFilterConfirm(col.key),\r\n clearFilters: () => handleFilterReset(col.key),\r\n close: () => handleFilterClose(col.key),\r\n })\r\n\r\n const handleResizeStart = (e: React.MouseEvent, colKey: string) => {\r\n e.preventDefault()\r\n e.stopPropagation()\r\n resizeCleanupRef.current?.()\r\n\r\n // Реальная ширина колонки из DOM, а не из declared/persisted. При\r\n // flex/minmax-раскладке declared-ширина не совпадает с фактической →\r\n // на первом mousemove колонка скакала к declared. Измеряем th.\r\n const handle = e.currentTarget as HTMLElement\r\n const th = handle.closest('.sg-table-th') as HTMLElement | null\r\n const measuredW = th?.getBoundingClientRect().width\r\n const startW =\r\n measuredW && Number.isFinite(measuredW) ? measuredW : (colWidths[colKey] ?? DEFAULT_COL_WIDTH)\r\n\r\n resizeRef.current = {\r\n col: colKey,\r\n startX: e.clientX,\r\n startW,\r\n }\r\n\r\n const onMove = (ev: MouseEvent) => {\r\n const ref = resizeRef.current\r\n if (!ref) return\r\n const diff = ev.clientX - ref.startX\r\n const min = leafColumns.find((c) => c.key === ref.col)?.minWidth ?? MIN_COL_WIDTH\r\n const nextWidth = Math.max(min, ref.startW + diff)\r\n const col = ref.col\r\n setColWidths((prev) => ({\r\n ...prev,\r\n [col]: nextWidth,\r\n }))\r\n setUserResizedCols((prev) => (prev.has(col) ? prev : new Set(prev).add(col)))\r\n }\r\n const cleanup = () => {\r\n resizeRef.current = null\r\n document.removeEventListener('mousemove', onMove)\r\n document.removeEventListener('mouseup', onUp)\r\n resizeCleanupRef.current = null\r\n }\r\n const onUp = () => {\r\n const ref = resizeRef.current\r\n cleanup()\r\n if (!ref) return\r\n // Mirror the final user-resized width into the engine so it survives\r\n // remounts when the host persists `$table.<id>.state.columnWidths`.\r\n // Functional updater is used to avoid stale closure on `colWidths`.\r\n setColWidths((prev) => {\r\n const w = prev[ref.col]\r\n if (typeof w === 'number') persistColumnWidth(ref.col, w)\r\n return prev\r\n })\r\n }\r\n resizeCleanupRef.current = cleanup\r\n document.addEventListener('mousemove', onMove)\r\n document.addEventListener('mouseup', onUp)\r\n }\r\n\r\n const handleDragStart = (e: React.DragEvent, key: string) => {\r\n setDragCol(key)\r\n e.dataTransfer.effectAllowed = 'move'\r\n e.dataTransfer.setData('text/plain', key)\r\n }\r\n\r\n const handleDragOver = (e: React.DragEvent, key: string) => {\r\n e.preventDefault()\r\n e.dataTransfer.dropEffect = 'move'\r\n setDragOver(key)\r\n }\r\n\r\n const handleDrop = (e: React.DragEvent, targetKey: string) => {\r\n e.preventDefault()\r\n if (!dragCol || dragCol === targetKey) {\r\n setDragCol(null)\r\n setDragOver(null)\r\n return\r\n }\r\n // Compute the next order outside the state updater. Calling\r\n // `onColumnOrderChange` (a parent setState) from inside the updater runs\r\n // it during React's render phase and triggers the \"Cannot update a\r\n // component while rendering a different component\" warning.\r\n const next = colOrder.filter((k) => k !== dragCol)\r\n const idx = next.indexOf(targetKey)\r\n next.splice(idx, 0, dragCol)\r\n setColOrder(next)\r\n onColumnOrderChange?.(next)\r\n setDragCol(null)\r\n setDragOver(null)\r\n }\r\n\r\n const handleDragEnd = () => {\r\n setDragCol(null)\r\n setDragOver(null)\r\n }\r\n\r\n // Column pin\r\n const handlePinColumn = useCallback(\r\n (key: string, fixed: 'left' | 'right' | undefined) => {\r\n onColumnPinChange?.(key, fixed)\r\n },\r\n [onColumnPinChange],\r\n )\r\n\r\n // ---- Fullscreen ----\r\n const [isFullscreen, setIsFullscreen] = useState(false)\r\n const wrapperRef = useRef<HTMLDivElement>(null)\r\n\r\n const toggleFullscreen = useCallback(() => {\r\n setIsFullscreen((prev) => !prev)\r\n }, [])\r\n\r\n // ---- Density ----\r\n const [density, setDensity] = useState<'small' | 'middle' | 'large'>('middle')\r\n\r\n // ---- Group By ----\r\n // Engine-side grouping: keep core in sync so Core consumers (subscribers,\r\n // exports, snapshot) see the same `groupBy` field as the React UI.\r\n // Aggregates are passed through from `column.aggregate` when configured —\r\n // engine recomputes them after each filter / sort change.\r\n useEffect(() => {\r\n if (!groupBy) {\r\n table.clearGroupBy()\r\n return\r\n }\r\n const aggregates = leafColumns\r\n .filter((c) => c.aggregate)\r\n .map((c) => ({\r\n column: c.key,\r\n type:\r\n typeof c.aggregate === 'function'\r\n ? (c.aggregate as (vals: unknown[]) => unknown)\r\n : (c.aggregate as 'sum' | 'avg' | 'count' | 'min' | 'max'),\r\n }))\r\n table.groupBy(groupBy, aggregates)\r\n }, [groupBy, leafColumns, table])\r\n\r\n // Expanded groups are tracked as an explicit set of group keys. Earlier a\r\n // `'__all__'` sentinel was used for \"expand all\", but it made individual\r\n // collapse/expand a no-op while the sentinel was present (the default\r\n // `defaultGroupExpanded` state) — toggling one group could not override the\r\n // global flag. The set now always holds the real group keys; \"expand all\"\r\n // seeds every key (see `allGroupKeys` below).\r\n const [expandedGroups, setExpandedGroups] = useState<Set<string>>(() => new Set())\r\n // Holds the current group keys so the stable expand-all callback can seed\r\n // the set without depending on derived data computed further down.\r\n const allGroupKeysRef = useRef<string[]>([])\r\n // Tracks whether the default-expanded seeding has run for the active\r\n // `groupBy`; reset whenever the grouping field changes.\r\n const groupsSeededRef = useRef(false)\r\n\r\n const toggleGroupExpand = useCallback(\r\n (groupKey: string) => {\r\n const willExpand = !expandedGroups.has(groupKey)\r\n setExpandedGroups((prev) => {\r\n const next = new Set(prev)\r\n if (next.has(groupKey)) next.delete(groupKey)\r\n else next.add(groupKey)\r\n return next\r\n })\r\n // Notify outside the updater so a parent setState never runs during the\r\n // render phase.\r\n onGroupExpandChange?.(groupKey, willExpand)\r\n },\r\n [onGroupExpandChange, expandedGroups],\r\n )\r\n\r\n const expandAllGroups = useCallback(() => {\r\n setExpandedGroups(new Set(allGroupKeysRef.current))\r\n }, [])\r\n\r\n const collapseAllGroups = useCallback(() => {\r\n setExpandedGroups(new Set())\r\n }, [])\r\n\r\n // ---- Keyboard navigation ----\r\n const [focusedCell, setFocusedCell] = useState<{ row: number; col: number } | null>(null)\r\n\r\n const handleKeyNav = useCallback(\r\n (e: React.KeyboardEvent) => {\r\n if (!keyboardNavigation || !focusedCell) return\r\n const maxRow = visibleRows.length - 1\r\n const maxCol = columns.length - 1\r\n let { row, col } = focusedCell\r\n\r\n switch (e.key) {\r\n case 'ArrowUp':\r\n e.preventDefault()\r\n row = Math.max(0, row - 1)\r\n break\r\n case 'ArrowDown':\r\n e.preventDefault()\r\n row = Math.min(maxRow, row + 1)\r\n break\r\n case 'ArrowLeft':\r\n e.preventDefault()\r\n col = Math.max(0, col - 1)\r\n break\r\n case 'ArrowRight':\r\n e.preventDefault()\r\n col = Math.min(maxCol, col + 1)\r\n break\r\n case 'Tab':\r\n e.preventDefault()\r\n if (e.shiftKey) {\r\n col -= 1\r\n if (col < 0) {\r\n col = maxCol\r\n row = Math.max(0, row - 1)\r\n }\r\n } else {\r\n col += 1\r\n if (col > maxCol) {\r\n col = 0\r\n row = Math.min(maxRow, row + 1)\r\n }\r\n }\r\n break\r\n case 'Home':\r\n e.preventDefault()\r\n col = 0\r\n if (e.ctrlKey) row = 0\r\n break\r\n case 'End':\r\n e.preventDefault()\r\n col = maxCol\r\n if (e.ctrlKey) row = maxRow\r\n break\r\n default:\r\n return\r\n }\r\n setFocusedCell({ row, col })\r\n },\r\n [keyboardNavigation, focusedCell, visibleRows.length, columns.length],\r\n )\r\n\r\n // Column auto-resize: measure content and set optimal width\r\n const handleAutoResize = useCallback(\r\n (colKey: string) => {\r\n const maxLen = visibleRows.reduce((max, row) => {\r\n const val = String(row.data[colKey] ?? '')\r\n return Math.max(max, val.length)\r\n }, 0)\r\n const headerCol = leafColumns.find((c) => c.key === colKey)\r\n const headerLen = typeof headerCol?.title === 'string' ? headerCol.title.length : 6\r\n const charWidth = 8\r\n const padding = 32\r\n const min = headerCol?.minWidth ?? MIN_COL_WIDTH\r\n const optimal = Math.max(min, Math.max(maxLen, headerLen) * charWidth + padding)\r\n setColWidths((prev) => ({ ...prev, [colKey]: optimal }))\r\n setUserResizedCols((prev) => (prev.has(colKey) ? prev : new Set(prev).add(colKey)))\r\n },\r\n [visibleRows, leafColumns],\r\n )\r\n\r\n // ---- Tree data ----\r\n\r\n const isTreeMode = !!tree\r\n const childrenKey = tree?.childrenColumnName ?? 'children'\r\n const indentSize = tree?.indentSize ?? 20\r\n\r\n const baseFlatRows: FlatRow[] = useMemo(() => {\r\n if (!isTreeMode) {\r\n return visibleRows.map((r) => ({\r\n id: r.id,\r\n data: r.data,\r\n depth: 0,\r\n hasChildren: false,\r\n }))\r\n }\r\n return flattenTreeRows(visibleRows, childrenKey, treeExpanded)\r\n }, [visibleRows, isTreeMode, childrenKey, treeExpanded])\r\n\r\n // Distinct group keys for the active `groupBy`, in first-seen order. Used to\r\n // seed \"expand all\" and the `defaultGroupExpanded` initial state.\r\n const allGroupKeys = useMemo(() => {\r\n if (!groupBy) return [] as string[]\r\n const seen = new Set<string>()\r\n const keys: string[] = []\r\n for (const r of baseFlatRows) {\r\n const k = String(r.data[groupBy] ?? 'Other')\r\n if (!seen.has(k)) {\r\n seen.add(k)\r\n keys.push(k)\r\n }\r\n }\r\n return keys\r\n }, [baseFlatRows, groupBy])\r\n\r\n // Keep the ref in sync so the stable expand-all callback can read the\r\n // current keys without re-creating on every data change.\r\n allGroupKeysRef.current = allGroupKeys\r\n\r\n // Reset the \"seeded\" guard whenever the grouping field changes so a new\r\n // `groupBy` re-applies `defaultGroupExpanded`.\r\n useEffect(() => {\r\n groupsSeededRef.current = false\r\n }, [groupBy])\r\n\r\n // Seed all groups as expanded once per `groupBy` when `defaultGroupExpanded`\r\n // is set. Runs after the keys are known (covers async data that arrives\r\n // after mount).\r\n useEffect(() => {\r\n if (!groupBy || !defaultGroupExpanded) return\r\n if (groupsSeededRef.current || allGroupKeys.length === 0) return\r\n groupsSeededRef.current = true\r\n setExpandedGroups(new Set(allGroupKeys))\r\n }, [groupBy, defaultGroupExpanded, allGroupKeys])\r\n\r\n // Apply group-by if configured\r\n const groupedRows: FlatRow[] = useMemo(() => {\r\n if (!groupBy) return baseFlatRows\r\n return groupByColumn(baseFlatRows, groupBy, columns, expandedGroups)\r\n }, [baseFlatRows, groupBy, columns, expandedGroups])\r\n\r\n // Separate pinned rows\r\n const {\r\n top: pinnedTop,\r\n middle: middleRows,\r\n bottom: pinnedBottom,\r\n } = useMemo(\r\n () => separatePinnedRows(groupedRows, pinnedRowsConfig?.top, pinnedRowsConfig?.bottom),\r\n [groupedRows, pinnedRowsConfig],\r\n )\r\n\r\n const flatRows = groupedRows\r\n\r\n // Aggregation footer data\r\n const aggregates = useMemo(\r\n () => computeColumnAggregates(columns, baseFlatRows),\r\n [columns, baseFlatRows],\r\n )\r\n\r\n // ---- Grid ----\r\n\r\n const extraBefore: string[] = []\r\n if (rowSelection) extraBefore.push(SELECTION_COL_WIDTH)\r\n if (expandable) extraBefore.push(SELECTION_COL_WIDTH)\r\n\r\n // Grid-template rules:\r\n //\r\n // Mode A — `scroll.x` is SET (author wants a horizontal scrollbar):\r\n // • Widths are hard pixels by default — columns never shrink. Sticky\r\n // offsets for fixed columns stay stable, table punches out of the\r\n // container and the scroll handles overflow.\r\n // • If numeric `scroll.x` is wider than the declared tracks, regular\r\n // columns flex to absorb the remainder instead of leaving blank space.\r\n //\r\n // Mode B — `scroll.x` is NOT set (fluid layout):\r\n // • No `width` / not resized → `minmax(MIN, 1fr)` — flex column.\r\n // • Mixed explicit/auto widths → explicit widths stay px while auto\r\n // columns share the remaining space.\r\n // • All regular columns have widths → those widths become fr weights,\r\n // so the table fills the container without leaving a blank tail.\r\n // • Fixed/resized columns keep their exact px (sticky offsets / user\r\n // resize must not be disturbed by auto-layout).\r\n const hasAutoColumns = columns.some(\r\n (c) => !c.fixed && !userResizedCols.has(c.key) && c.width == null,\r\n )\r\n const shouldFlexExplicitWidths = !hasScrollX && !hasAutoColumns\r\n const scrollXMinWidth =\r\n typeof scroll?.x === 'number'\r\n ? scroll.x\r\n : typeof scroll?.x === 'string' && scroll.x.trim().endsWith('px')\r\n ? Number.parseFloat(scroll.x)\r\n : null\r\n const declaredGridWidth =\r\n extraBefore.reduce((sum, w) => sum + Number.parseFloat(w), 0) +\r\n columns.reduce((sum, c) => sum + (colWidths[c.key] ?? c.width ?? DEFAULT_COL_WIDTH), 0)\r\n const shouldFillScrollX =\r\n hasScrollX &&\r\n scrollXMinWidth !== null &&\r\n Number.isFinite(scrollXMinWidth) &&\r\n scrollXMinWidth > declaredGridWidth\r\n\r\n const colTemplates = columns.map((c) => {\r\n const resized = userResizedCols.has(c.key)\r\n const w = colWidths[c.key] ?? c.width ?? DEFAULT_COL_WIDTH\r\n\r\n if (hasScrollX) {\r\n if (c.fixed || resized) {\r\n return `${w}px`\r\n }\r\n return shouldFillScrollX ? `minmax(${w}px, ${w}fr)` : `${w}px`\r\n }\r\n\r\n if (c.fixed || resized) {\r\n return `${w}px`\r\n }\r\n if (c.width == null) {\r\n return `minmax(${MIN_COL_WIDTH}px, 1fr)`\r\n }\r\n if (shouldFlexExplicitWidths) {\r\n return `minmax(${MIN_COL_WIDTH}px, ${w}fr)`\r\n }\r\n return `minmax(${MIN_COL_WIDTH}px, ${w}px)`\r\n })\r\n const gridTemplate = [...extraBefore, ...colTemplates].join(' ')\r\n const totalCols = extraBefore.length + columns.length\r\n\r\n // ---- Fixed offsets ----\r\n\r\n const fixedLeftOffsets = useMemo(() => {\r\n const o: Record<string, number> = {}\r\n const selW = parseInt(SELECTION_COL_WIDTH)\r\n let left = (rowSelection ? selW : 0) + (expandable ? selW : 0)\r\n for (const col of columns) {\r\n if (col.fixed === 'left') {\r\n o[col.key] = left\r\n left += colWidths[col.key] ?? col.width ?? DEFAULT_COL_WIDTH\r\n }\r\n }\r\n return o\r\n }, [columns, colWidths, rowSelection, expandable])\r\n\r\n const fixedRightOffsets = useMemo(() => {\r\n const o: Record<string, number> = {}\r\n let right = 0\r\n for (let i = columns.length - 1; i >= 0; i--) {\r\n if (columns[i].fixed === 'right') {\r\n o[columns[i].key] = right\r\n right += colWidths[columns[i].key] ?? columns[i].width ?? DEFAULT_COL_WIDTH\r\n }\r\n }\r\n return o\r\n }, [columns, colWidths])\r\n\r\n const fixedStyle = (col: TableColumn, isHeader?: boolean): React.CSSProperties =>\r\n getFixedStyle(col, fixedLeftOffsets, fixedRightOffsets, isHeader)\r\n\r\n const allSelected = rowSelection\r\n ? visibleRows.length > 0 && visibleRows.every((r) => rowSelection.selectedKeys.includes(r.id))\r\n : false\r\n const someSelected = rowSelection\r\n ? visibleRows.some((r) => rowSelection.selectedKeys.includes(r.id)) && !allSelected\r\n : false\r\n\r\n const spanMap = useMemo(() => computeSpanMap(columns, flatRows), [columns, flatRows])\r\n const hiddenCells = useMemo(\r\n () => computeHiddenCells(columns, flatRows, spanMap),\r\n [columns, flatRows, spanMap],\r\n )\r\n\r\n return {\r\n visibleRows,\r\n tableState,\r\n columns,\r\n leafColumns,\r\n flatRows,\r\n headerRows,\r\n hasColumnGroups,\r\n t,\r\n // Multi-sort\r\n sorts,\r\n getSortIndex,\r\n getSortDirection,\r\n handleSort,\r\n // Selection\r\n allSelected,\r\n someSelected,\r\n handleSelectAll,\r\n handleSelectRow,\r\n // Expand\r\n expandedKeys,\r\n handleToggleExpand,\r\n // Tree\r\n isTreeMode,\r\n indentSize,\r\n treeExpanded,\r\n handleToggleTreeExpand,\r\n // Filters\r\n filterState: {\r\n activeFilters,\r\n filterSearchText,\r\n openFilterDropdown,\r\n advancedFilters,\r\n filterAnchor,\r\n },\r\n filterActions: {\r\n setOpenFilterDropdown,\r\n handleFilterToggle,\r\n handleFilterConfirm,\r\n handleFilterReset,\r\n handleFilterClose,\r\n handleSearchFilterChange,\r\n setFilterSearchText,\r\n getFilterDropdownProps,\r\n setAdvancedFilter,\r\n setFilterAnchor,\r\n },\r\n filterRef,\r\n // Drag columns\r\n dragOver,\r\n handleDragStart,\r\n handleDragOver,\r\n handleDragEnd,\r\n handleDrop,\r\n setDragOver: () => setDragOver(null),\r\n // Resize\r\n colWidths,\r\n handleResizeStart,\r\n // Grid\r\n gridTemplate,\r\n totalCols,\r\n // Fixed\r\n fixedStyle,\r\n // Span\r\n spanMap,\r\n hiddenCells,\r\n // Search\r\n searchText,\r\n setSearchText,\r\n // Pagination\r\n setPage,\r\n // Column visibility\r\n hiddenSet,\r\n toggleColumnVisibility,\r\n // Column pin\r\n handlePinColumn,\r\n // Context menu\r\n contextMenu,\r\n setContextMenu,\r\n // Fullscreen\r\n isFullscreen,\r\n toggleFullscreen,\r\n wrapperRef,\r\n // Density\r\n density,\r\n setDensity,\r\n // Group by\r\n expandedGroups,\r\n toggleGroupExpand,\r\n expandAllGroups,\r\n collapseAllGroups,\r\n // Keyboard\r\n focusedCell,\r\n setFocusedCell,\r\n handleKeyNav,\r\n // Auto-resize\r\n handleAutoResize,\r\n // Aggregation\r\n aggregates,\r\n // Pinned\r\n pinnedTop,\r\n pinnedBottom,\r\n middleRows,\r\n }\r\n}\r\n","import type React from 'react'\r\nimport type { RowId } from '@skygraph/core'\r\nimport type { TableColumn, HeaderCell, FlatRow, CellSpan, AggregateType, GroupRow } from './types'\r\n\r\n/** Returns leaf columns in visual order, flattening grouped definitions. */\r\nexport function flattenLeafColumns(cols: TableColumn[]): TableColumn[] {\r\n const result: TableColumn[] = []\r\n for (const col of cols) {\r\n if (col.children && col.children.length > 0) {\r\n result.push(...flattenLeafColumns(col.children))\r\n } else {\r\n result.push(col)\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/** Builds a row-major grid of header cells for grouped columns. */\r\nexport function buildHeaderRows(cols: TableColumn[]): HeaderCell[][] {\r\n function getDepth(c: TableColumn): number {\r\n if (!c.children || c.children.length === 0) return 1\r\n return 1 + Math.max(...c.children.map(getDepth))\r\n }\r\n\r\n const maxDepth = cols.length > 0 ? Math.max(...cols.map(getDepth)) : 1\r\n\r\n function getLeafCount(c: TableColumn): number {\r\n if (!c.children || c.children.length === 0) return 1\r\n return c.children.reduce((sum, ch) => sum + getLeafCount(ch), 0)\r\n }\r\n\r\n const rows: HeaderCell[][] = Array.from({ length: maxDepth }, () => [])\r\n\r\n function fill(list: TableColumn[], depth: number) {\r\n for (const c of list) {\r\n if (c.children && c.children.length > 0) {\r\n rows[depth].push({ col: c, colSpan: getLeafCount(c), rowSpan: 1 })\r\n fill(c.children, depth + 1)\r\n } else {\r\n rows[depth].push({ col: c, colSpan: 1, rowSpan: maxDepth - depth })\r\n }\r\n }\r\n }\r\n\r\n fill(cols, 0)\r\n return rows\r\n}\r\n\r\n/** Flattens nested row data into visible rows respecting `expandedSet`. */\r\nexport function flattenTreeRows(\r\n rows: Array<{ id: RowId; data: Record<string, unknown> }>,\r\n childrenKey: string,\r\n expandedSet: Set<RowId>,\r\n depth = 0,\r\n): FlatRow[] {\r\n const result: FlatRow[] = []\r\n for (const row of rows) {\r\n const children = row.data[childrenKey] as Array<{ id: RowId; data: Record<string, unknown> }> | undefined\r\n const hasChildren = Array.isArray(children) && children.length > 0\r\n result.push({ id: row.id, data: row.data, depth, hasChildren })\r\n if (hasChildren && expandedSet.has(row.id)) {\r\n result.push(...flattenTreeRows(children!, childrenKey, expandedSet, depth + 1))\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/** Returns every row id that has nested children (for expand-all). */\r\nexport function collectAllTreeIds(\r\n rows: Array<{ id: RowId; data: Record<string, unknown> }>,\r\n childrenKey: string,\r\n): RowId[] {\r\n const ids: RowId[] = []\r\n for (const row of rows) {\r\n const children = row.data[childrenKey] as Array<{ id: RowId; data: Record<string, unknown> }> | undefined\r\n if (Array.isArray(children) && children.length > 0) {\r\n ids.push(row.id)\r\n ids.push(...collectAllTreeIds(children, childrenKey))\r\n }\r\n }\r\n return ids\r\n}\r\n\r\n/** Maps `${rowId}:${colKey}` to rowspan/colspan from `column.onCell`. */\r\nexport function computeSpanMap(\r\n columns: TableColumn[],\r\n flatRows: FlatRow[],\r\n): Map<string, CellSpan> {\r\n const map = new Map<string, CellSpan>()\r\n const hasOnCell = columns.some((c) => c.onCell)\r\n if (!hasOnCell) return map\r\n flatRows.forEach((row, rowIndex) => {\r\n for (const col of columns) {\r\n if (col.onCell) {\r\n const span = col.onCell(row.data, rowIndex)\r\n if (span && (span.rowSpan !== undefined || span.colSpan !== undefined)) {\r\n map.set(`${row.id}:${col.key}`, span)\r\n }\r\n }\r\n }\r\n })\r\n return map\r\n}\r\n\r\n/** Keys of cells that should not render because they are covered by spans. */\r\nexport function computeHiddenCells(\r\n columns: TableColumn[],\r\n flatRows: FlatRow[],\r\n spanMap: Map<string, CellSpan>,\r\n): Set<string> {\r\n const hidden = new Set<string>()\r\n const hasOnCell = columns.some((c) => c.onCell)\r\n if (!hasOnCell) return hidden\r\n flatRows.forEach((row, rowIndex) => {\r\n for (let ci = 0; ci < columns.length; ci++) {\r\n const key = `${row.id}:${columns[ci].key}`\r\n const span = spanMap.get(key)\r\n if (!span) continue\r\n if (span.rowSpan === 0 || span.colSpan === 0) {\r\n hidden.add(key)\r\n continue\r\n }\r\n const rs = span.rowSpan ?? 1\r\n const cs = span.colSpan ?? 1\r\n for (let dr = 0; dr < rs; dr++) {\r\n for (let dc = 0; dc < cs; dc++) {\r\n if (dr === 0 && dc === 0) continue\r\n const targetRow = flatRows[rowIndex + dr]\r\n const targetCol = columns[ci + dc]\r\n if (targetRow && targetCol) {\r\n hidden.add(`${targetRow.id}:${targetCol.key}`)\r\n }\r\n }\r\n }\r\n }\r\n })\r\n return hidden\r\n}\r\n\r\n/** Computes sticky left/right, alignment, and ellipsis styles for a column. */\r\nexport function getFixedStyle(\r\n col: TableColumn,\r\n fixedLeftOffsets: Record<string, number>,\r\n fixedRightOffsets: Record<string, number>,\r\n isHeader?: boolean,\r\n): React.CSSProperties {\r\n const s: React.CSSProperties = {}\r\n if (col.align) s.textAlign = col.align\r\n if (col.ellipsis) {\r\n s.overflow = 'hidden'\r\n s.textOverflow = 'ellipsis'\r\n s.whiteSpace = 'nowrap'\r\n }\r\n if (col.fixed === 'left') {\r\n s.position = 'sticky'\r\n s.left = fixedLeftOffsets[col.key]\r\n s.zIndex = isHeader ? 4 : 2\r\n }\r\n if (col.fixed === 'right') {\r\n s.position = 'sticky'\r\n s.right = fixedRightOffsets[col.key]\r\n s.zIndex = isHeader ? 4 : 2\r\n }\r\n return s\r\n}\r\n\r\n/** Reduces numeric column values with a built-in aggregate type. */\r\nexport function computeAggregate(\r\n values: unknown[],\r\n type: AggregateType,\r\n): number | string {\r\n const nums = values.map(Number).filter((n) => !isNaN(n))\r\n if (nums.length === 0) return type === 'count' ? values.length : '-'\r\n\r\n switch (type) {\r\n case 'sum':\r\n return Math.round(nums.reduce((a, b) => a + b, 0) * 100) / 100\r\n case 'avg':\r\n return Math.round((nums.reduce((a, b) => a + b, 0) / nums.length) * 100) / 100\r\n case 'count':\r\n return values.length\r\n case 'min':\r\n return Math.min(...nums)\r\n case 'max':\r\n return Math.max(...nums)\r\n }\r\n}\r\n\r\n/** Inserts group header rows and optional child rows for one group-by field. */\r\nexport function groupByColumn(\r\n flatRows: FlatRow[],\r\n groupByKey: string,\r\n columns: TableColumn[],\r\n expandedGroups: Set<string>,\r\n): FlatRow[] {\r\n const groups = new Map<string, FlatRow[]>()\r\n const groupOrder: string[] = []\r\n\r\n for (const row of flatRows) {\r\n const val = String(row.data[groupByKey] ?? 'Other')\r\n if (!groups.has(val)) {\r\n groups.set(val, [])\r\n groupOrder.push(val)\r\n }\r\n groups.get(val)!.push(row)\r\n }\r\n\r\n const result: FlatRow[] = []\r\n for (const gKey of groupOrder) {\r\n const rows = groups.get(gKey)!\r\n const expanded = expandedGroups.has(gKey)\r\n\r\n const aggregates: Record<string, React.ReactNode> = {}\r\n for (const col of columns) {\r\n if (col.aggregate) {\r\n const values = rows.map((r) => r.data[col.key])\r\n if (typeof col.aggregate === 'function') {\r\n aggregates[col.key] = col.aggregate(values)\r\n } else {\r\n aggregates[col.key] = computeAggregate(values, col.aggregate)\r\n }\r\n }\r\n }\r\n\r\n const groupRow: GroupRow = {\r\n __isGroup: true,\r\n groupKey: gKey,\r\n groupValue: gKey,\r\n count: rows.length,\r\n expanded,\r\n aggregates,\r\n }\r\n\r\n result.push({\r\n id: `__group_${gKey}` as RowId,\r\n data: {},\r\n depth: 0,\r\n hasChildren: false,\r\n __groupRow: groupRow,\r\n })\r\n\r\n if (expanded) {\r\n result.push(...rows)\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/** Splits rows into top-pinned, middle, and bottom-pinned lists. */\r\nexport function separatePinnedRows(\r\n flatRows: FlatRow[],\r\n topIds?: RowId[],\r\n bottomIds?: RowId[],\r\n): { top: FlatRow[]; middle: FlatRow[]; bottom: FlatRow[] } {\r\n const topSet = new Set(topIds ?? [])\r\n const bottomSet = new Set(bottomIds ?? [])\r\n\r\n const top: FlatRow[] = []\r\n const middle: FlatRow[] = []\r\n const bottom: FlatRow[] = []\r\n\r\n for (const row of flatRows) {\r\n if (topSet.has(row.id)) top.push(row)\r\n else if (bottomSet.has(row.id)) bottom.push(row)\r\n else middle.push(row)\r\n }\r\n\r\n if (topIds) {\r\n top.sort((a, b) => topIds.indexOf(a.id) - topIds.indexOf(b.id))\r\n }\r\n if (bottomIds) {\r\n bottom.sort((a, b) => bottomIds.indexOf(a.id) - bottomIds.indexOf(b.id))\r\n }\r\n\r\n return { top, middle, bottom }\r\n}\r\n\r\n/** Footer aggregate values per column, or null when no aggregates configured. */\r\nexport function computeColumnAggregates(\r\n columns: TableColumn[],\r\n flatRows: FlatRow[],\r\n): Record<string, React.ReactNode> | null {\r\n const hasAny = columns.some((c) => c.aggregate)\r\n if (!hasAny) return null\r\n\r\n const result: Record<string, React.ReactNode> = {}\r\n for (const col of columns) {\r\n if (!col.aggregate) continue\r\n const values = flatRows.filter((r) => !r.__groupRow).map((r) => r.data[col.key])\r\n if (typeof col.aggregate === 'function') {\r\n result[col.key] = col.aggregate(values)\r\n } else {\r\n result[col.key] = computeAggregate(values, col.aggregate)\r\n }\r\n }\r\n return result\r\n}\r\n","import type React from 'react'\r\n\r\n/**\r\n * Дефолтные иконки заголовка таблицы. Хранятся как React-ноды, чтобы их\r\n * можно было передавать через `TableLocale` (типизировано как\r\n * `React.ReactNode`). Все иконки используют `currentColor`, поэтому цвет\r\n * задаётся CSS-классом контейнера (`.sg-table-filter-trigger`,\r\n * `.sg-table-filter-active`).\r\n */\r\n\r\n/** Воронка фильтра. */\r\nexport const FilterIcon: React.ReactElement = (\r\n <svg\r\n width=\"12\"\r\n height=\"12\"\r\n viewBox=\"0 0 16 16\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"1.5\"\r\n strokeLinejoin=\"round\"\r\n strokeLinecap=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <path d=\"M2 3h12l-5 6.5V14l-2 1V9.5L2 3z\" />\r\n </svg>\r\n)\r\n\r\n/** Лупа поиска. */\r\nexport const SearchIcon: React.ReactElement = (\r\n <svg\r\n width=\"12\"\r\n height=\"12\"\r\n viewBox=\"0 0 16 16\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"1.5\"\r\n strokeLinecap=\"round\"\r\n aria-hidden=\"true\"\r\n focusable=\"false\"\r\n >\r\n <circle cx=\"7\" cy=\"7\" r=\"4.5\" />\r\n <path d=\"M10.5 10.5L14 14\" />\r\n </svg>\r\n)\r\n","import type React from 'react'\r\nimport { FilterIcon, SearchIcon } from './defaultIcons'\r\nimport type { UseTableOptions } from '../../../hooks/useTable'\r\nimport type {\r\n AdvancedFilter,\r\n ColumnFilter,\r\n ColumnAggregate,\r\n FilterOperator,\r\n RowId,\r\n SortConfig,\r\n SortDirection,\r\n TableGroup,\r\n} from '@skygraph/core'\r\nimport type {\r\n BaseComponentProps,\r\n InteractiveProps,\r\n SizableProps,\r\n SlotClassNames,\r\n SlotStyles,\r\n} from '../../../types'\r\nimport type { TableLocale } from '../../../types/locale'\r\nimport type { ContextMenuItem } from './ContextMenu'\r\nimport type { PrintableProp } from '../../../utils/print'\r\n\r\n/**\r\n * Re-exports the canonical TableLocale from `types/locale.ts`. The two\r\n * declarations were unified during the post-stream cleanup; keep using\r\n * `from '../../../types/locale'` for new code.\r\n */\r\nexport type { TableLocale }\r\n\r\n/**\r\n * Имена слотов `Table` для пропов `classNames` / `styles`.\r\n * Полный список и описания — `docs/styling-contract.md` §4.1.\r\n */\r\nexport type TableSlot =\r\n | 'root'\r\n | 'toolbar'\r\n | 'scroll'\r\n | 'grid'\r\n | 'headerRow'\r\n | 'headerCell'\r\n | 'headerCellContent'\r\n | 'row'\r\n | 'bodyCell'\r\n | 'empty'\r\n | 'pagination'\r\n | 'footer'\r\n\r\n/** Мапа `слот → className` для `Table`. */\r\nexport type TableClassNames = SlotClassNames<TableSlot>\r\n\r\n/** Мапа `слот → inline-style` для `Table`. */\r\nexport type TableStyles = SlotStyles<TableSlot>\r\n\r\n/** Re-exports core row and sort types used by the table. */\r\nexport type {\r\n RowId,\r\n SortDirection,\r\n SortConfig,\r\n AdvancedFilter,\r\n ColumnFilter,\r\n ColumnAggregate,\r\n FilterOperator,\r\n TableGroup,\r\n}\r\n\r\n/** Cell merge span metadata from `onCell`. */\r\nexport interface CellSpan {\r\n /** Vertical span count; `0` hides the cell. */\r\n rowSpan?: number\r\n /** Horizontal span count; `0` hides the cell. */\r\n colSpan?: number\r\n}\r\n\r\n/** Props passed to a custom column filter dropdown. */\r\nexport interface FilterDropdownProps {\r\n /** Filter values currently selected in the dropdown. */\r\n selectedKeys: unknown[]\r\n /** Updates selected filter values before confirm. */\r\n setSelectedKeys: (keys: unknown[]) => void\r\n /** Applies the current selection and closes the dropdown. */\r\n confirm: () => void\r\n /** Clears active filters for the column. */\r\n clearFilters: () => void\r\n /** Closes the dropdown without applying. */\r\n close: () => void\r\n}\r\n\r\n/** Built-in footer aggregate operation identifiers. */\r\nexport type AggregateType = 'sum' | 'avg' | 'count' | 'min' | 'max'\r\n\r\n/** Column definition for `Table` (leaf or group parent). */\r\nexport interface TableColumn {\r\n /** Unique column key matching row data fields. */\r\n key: string\r\n /** Header label or node. */\r\n title: React.ReactNode\r\n /** Default column width in pixels. */\r\n width?: number\r\n /** Minimum width when resizing. */\r\n minWidth?: number\r\n /** Enables click-to-sort on this column. */\r\n sortable?: boolean\r\n /** Shows a drag handle to resize the column. */\r\n resizable?: boolean\r\n /** Allows in-cell editing when `onCellEdit` is set on the table. */\r\n editable?: boolean\r\n /** Sticky column position. */\r\n fixed?: 'left' | 'right'\r\n /** Truncates overflowing cell text with ellipsis. */\r\n ellipsis?: boolean\r\n /** Cell text alignment. */\r\n align?: 'left' | 'center' | 'right'\r\n /** Hides the column when true. */\r\n hidden?: boolean\r\n /** Preset filter options for the column filter menu. */\r\n filters?: Array<{ text: string; value: unknown }>\r\n /** Predicate to test if a row matches a filter value. */\r\n onFilter?: (value: unknown, row: Record<string, unknown>) => boolean\r\n /** Custom filter dropdown UI or render function. */\r\n filterDropdown?: React.ReactNode | ((props: FilterDropdownProps) => React.ReactNode)\r\n /** Custom filter icon in the header. */\r\n filterIcon?: React.ReactNode | ((filtered: boolean) => React.ReactNode)\r\n /** When false, filter mode is single-select radio. */\r\n filterMultiple?: boolean\r\n /** Enables or customizes filter option search in the menu. */\r\n filterSearch?: boolean | ((input: string, record: { text: string; value: unknown }) => boolean)\r\n /**\r\n * Filter UI mode:\r\n * - `'menu'` — preset list with checkboxes (default).\r\n * - `'search'` — single search input.\r\n * - `'advanced'` — operator picker + value input (`AdvancedFilter`).\r\n */\r\n filterMode?: 'menu' | 'search' | 'advanced'\r\n /**\r\n * Список доступных операторов в `advanced`-моде. По умолчанию выводится\r\n * полный набор кроме строгих строковых операторов (для нестроковых полей).\r\n * Передайте свой массив, чтобы ограничить пользователя.\r\n */\r\n advancedFilterOperators?: FilterOperator[]\r\n /**\r\n * Тип значения колонки — подсказка для `advanced`-режима, чтобы выбрать\r\n * корректный input (`number` / `text`) и стартовый набор операторов.\r\n * @default 'text'\r\n */\r\n advancedFilterType?: 'text' | 'number'\r\n /** Controlled active filter values for the column. */\r\n filteredValue?: unknown[]\r\n /** Initial filter values for uncontrolled usage. */\r\n defaultFilteredValue?: unknown[]\r\n /** Custom cell content renderer. */\r\n render?: (value: unknown, row: Record<string, unknown>, id: RowId) => React.ReactNode\r\n /** Returns rowspan/colspan for the cell at this row index. */\r\n onCell?: (row: Record<string, unknown>, rowIndex: number) => CellSpan\r\n /** Child columns for grouped headers. */\r\n children?: TableColumn[]\r\n /** Small info icon with this content in the header. */\r\n tooltip?: string | React.ReactNode\r\n /** Extra class for body cells. */\r\n cellClassName?: string | ((value: unknown, row: Record<string, unknown>, id: RowId) => string)\r\n /** Extra class for header cell of this column. */\r\n headerClassName?: string\r\n /** Shows a copy-to-clipboard control on the cell. */\r\n copyable?: boolean\r\n /** Footer aggregate for this column (built-in name or custom reducer). */\r\n aggregate?: AggregateType | ((values: unknown[]) => React.ReactNode)\r\n}\r\n\r\n/** Controlled row selection configuration. */\r\nexport interface RowSelectionConfig {\r\n /** Keys of currently selected rows. */\r\n selectedKeys: RowId[]\r\n /** Called when selection changes. */\r\n onChange: (keys: RowId[], rows: Array<Record<string, unknown>>) => void\r\n /** Selection control type. */\r\n type?: 'checkbox' | 'radio'\r\n}\r\n\r\n/** Expandable row configuration. */\r\nexport interface ExpandableConfig {\r\n /** Renders content below the row when expanded. */\r\n expandedRowRender: (row: Record<string, unknown>, id: RowId) => React.ReactNode\r\n /** Controlled expanded row keys. */\r\n expandedKeys?: RowId[]\r\n /** Keys expanded on first mount when `expandedKeys` is not controlled. */\r\n defaultExpandedRowKeys?: RowId[]\r\n /** Fires when a row expand state toggles. */\r\n onExpand?: (expanded: boolean, id: RowId) => void\r\n /** Limits which rows show an expand control. */\r\n rowExpandable?: (row: Record<string, unknown>) => boolean\r\n}\r\n\r\n/** Tree-shaped row data options for the table. */\r\nexport interface TreeConfig {\r\n /** Row field holding nested rows (default `children`). */\r\n childrenColumnName?: string\r\n /** Pixels per tree depth level. */\r\n indentSize?: number\r\n /** Starts with all tree nodes expanded. */\r\n defaultExpandAllRows?: boolean\r\n}\r\n\r\n/** One cell in a custom summary row from `summary`. */\r\nexport interface SummaryCell {\r\n /** Cell body. */\r\n content: React.ReactNode\r\n /** Horizontal span in the summary grid. */\r\n colSpan?: number\r\n /** Text alignment. */\r\n align?: 'left' | 'center' | 'right'\r\n}\r\n\r\n/** Configuration for the optional row number column. */\r\nexport interface RowNumberConfig {\r\n /** Header title for the row number column. */\r\n title?: React.ReactNode\r\n /** Column width in pixels. */\r\n width?: number\r\n /** Pins the row number column. */\r\n fixed?: 'left'\r\n}\r\n\r\n/** Row ids pinned to the top or bottom of the scroll area. */\r\nexport interface PinnedRowsConfig {\r\n /** Row ids rendered in a block above the main body. */\r\n top?: RowId[]\r\n /** Row ids rendered in a block below the main body. */\r\n bottom?: RowId[]\r\n}\r\n\r\n/** Internal metadata for a grouped header row in the body. */\r\nexport interface GroupRow {\r\n /** Marks this synthetic row as a group header. */\r\n __isGroup: true\r\n /** Stable key for the group (stringified value). */\r\n groupKey: string\r\n /** Raw grouping value. */\r\n groupValue: unknown\r\n /** Number of rows in the group. */\r\n count: number\r\n /** Whether child rows are visible. */\r\n expanded: boolean\r\n /** Per-column aggregate display for the group header. */\r\n aggregates: Record<string, React.ReactNode>\r\n}\r\n\r\nexport const DEFAULT_LOCALE: Required<TableLocale> = {\r\n emptyText: 'No data',\r\n filterReset: 'Reset',\r\n filterConfirm: 'OK',\r\n filterSearchPlaceholder: 'Search filters...',\r\n filterEmptyText: 'No filters',\r\n searchPlaceholder: 'Search...',\r\n sortAsc: '▲',\r\n sortDesc: '▼',\r\n expandIcon: '›',\r\n filterIcon: FilterIcon,\r\n searchIcon: SearchIcon,\r\n totalRows: (count) => `${count} rows`,\r\n selectedRows: (count) => `${count} selected`,\r\n exportCSV: 'Export CSV',\r\n exportJSON: 'Export JSON',\r\n copyTable: 'Copy',\r\n pinLeft: 'Pin Left',\r\n pinRight: 'Pin Right',\r\n unpin: 'Unpin',\r\n showColumns: 'Show Columns',\r\n print: 'Print',\r\n fullscreen: 'Fullscreen',\r\n exitFullscreen: 'Exit Fullscreen',\r\n density: 'Density',\r\n densitySmall: 'Compact',\r\n densityMiddle: 'Default',\r\n densityLarge: 'Comfortable',\r\n groupCollapse: 'Collapse All',\r\n groupExpand: 'Expand All',\r\n sum: 'Sum',\r\n avg: 'Avg',\r\n count: 'Count',\r\n min: 'Min',\r\n max: 'Max',\r\n copiedToClipboard: 'Copied!',\r\n rowNumber: '#',\r\n groupByLabel: 'Group by',\r\n groupByNone: 'No grouping',\r\n filterAdvancedValuePlaceholder: 'Value',\r\n filterAdvancedInPlaceholder: 'value1, value2, ...',\r\n filterAdvancedBetweenMaxPlaceholder: 'Max',\r\n filterOpEq: '=',\r\n filterOpNeq: '!=',\r\n filterOpLt: '<',\r\n filterOpLte: '<=',\r\n filterOpGt: '>',\r\n filterOpGte: '>=',\r\n filterOpBetween: 'between',\r\n filterOpIn: 'in',\r\n filterOpNotIn: 'not in',\r\n filterOpContains: 'contains',\r\n filterOpStartsWith: 'starts with',\r\n filterOpEndsWith: 'ends with',\r\n filterOpIsEmpty: 'is empty',\r\n filterOpIsNotEmpty: 'is not empty',\r\n filterOperatorAriaLabel: 'Filter operator',\r\n}\r\n\r\nexport const DEFAULT_COL_WIDTH = 150\r\nexport const MIN_COL_WIDTH = 50\r\nexport const SELECTION_COL_WIDTH = '40px'\r\n\r\n/** Action button in the selection summary bar. */\r\nexport interface SelectionSummaryAction {\r\n /** Stable action key. */\r\n key: string\r\n /** Button label. */\r\n label: React.ReactNode\r\n /** Invoked with current selection when the action is clicked. */\r\n onClick: (selectedKeys: RowId[], selectedRows: Array<Record<string, unknown>>) => void\r\n /** Destructive styling hint. */\r\n danger?: boolean\r\n}\r\n\r\n/**\r\n * Props for the `Table` component: column model, selection, scrolling, and toolbar features.\r\n * Styling and interaction props from `BaseComponentProps`, `InteractiveProps`, and `SizableProps` are inherited without per-prop docs here.\r\n */\r\nexport interface TableProps\r\n extends Omit<UseTableOptions, 'columns'>, BaseComponentProps, InteractiveProps, SizableProps {\r\n /** Column definitions (leaf and/or grouped). */\r\n columns: TableColumn[]\r\n /** Dataset rows bound to the table engine (from `useTable` options). */\r\n data?: Array<{ id: RowId; data: Record<string, unknown> }>\r\n /** Page size for built-in pagination (from table engine options). */\r\n pageSize?: number\r\n /** Row selection state and callbacks. */\r\n rowSelection?: RowSelectionConfig\r\n /** Optional expandable row renderer. */\r\n expandable?: ExpandableConfig\r\n /** Renders hierarchical rows from nested data. */\r\n tree?: TreeConfig\r\n /** Sticky header while scrolling vertically. */\r\n sticky?: boolean\r\n /** Enables column reorder by drag-and-drop in the header. */\r\n draggable?: boolean\r\n /** Shows toolbar search across visible columns. */\r\n searchable?: boolean\r\n /** @default true */\r\n showPagination?: boolean\r\n /** Outlined table borders. */\r\n bordered?: boolean\r\n\r\n /** Horizontal and/or vertical scroll constraints. */\r\n scroll?: { x?: number | string; y?: number | string }\r\n /** Custom summary rows below the body. */\r\n summary?: (data: Array<{ id: RowId; data: Record<string, unknown> }>) => SummaryCell[][]\r\n /** Row click handler. */\r\n onRowClick?: (id: RowId, data: Record<string, unknown>) => void\r\n /** Commits inline cell edit values. */\r\n onCellEdit?: (id: RowId, column: string, value: unknown) => void\r\n /** Called after header columns are reordered by drag-and-drop. */\r\n onColumnOrderChange?: (order: string[]) => void\r\n /** Extra class for each body row. */\r\n rowClassName?: string | ((row: Record<string, unknown>, id: RowId) => string)\r\n /** Overrides default locale strings. */\r\n locale?: TableLocale\r\n\r\n /** Enables shift-click multi-column sort. */\r\n multiSort?: boolean\r\n /** Controlled multi-sort model. */\r\n sorts?: SortConfig[]\r\n /** Fires when multi-sort state changes. */\r\n onSortsChange?: (sorts: SortConfig[]) => void\r\n\r\n /** Enables dragging body rows to reorder. */\r\n rowDraggable?: boolean\r\n /** Called after row reorder via drag-and-drop. */\r\n onRowOrderChange?: (fromIndex: number, toIndex: number) => void\r\n\r\n /** Builds context menu items for a header cell. */\r\n headerContextMenu?: (column: TableColumn) => ContextMenuItem[]\r\n /** Builds context menu items for a body cell. */\r\n cellContextMenu?: (id: RowId, column: string, data: Record<string, unknown>) => ContextMenuItem[]\r\n\r\n /** Shows column visibility controls in the toolbar. */\r\n columnVisibility?: boolean\r\n /** Controlled hidden column keys. */\r\n hiddenColumns?: string[]\r\n /** Fires when visible columns change. */\r\n onHiddenColumnsChange?: (keys: string[]) => void\r\n\r\n /** Enables pin/unpin via header context menu. */\r\n columnPinning?: boolean\r\n /** Fires when a column pin side changes. */\r\n onColumnPinChange?: (key: string, fixed: 'left' | 'right' | undefined) => void\r\n\r\n /**\r\n * Виртуализирует тело таблицы для больших датасетов.\r\n *\r\n * - `true` — фиксированная высота 40px.\r\n * - `{ rowHeight: 60 }` — фиксированная высота 60px.\r\n * - `{ rowHeight: (row, id) => h }` — динамическая высота, переданная\r\n * функция используется как эстимейт до того, как `ResizeObserver`\r\n * отчитается о реальной высоте каждой строки.\r\n * - `{ rowHeight: 40, estimateRowHeight: (row) => h }` — то же самое,\r\n * но с явным разделением \"первое значение / эстимейт-callback\".\r\n */\r\n virtual?:\r\n | boolean\r\n | {\r\n /**\r\n * Стартовое значение высоты строки. Число — фиксированный фоллбэк\r\n * (быстрый путь). Функция — включает динамическое измерение через\r\n * ResizeObserver, вызываясь как эстимейт до первого реального\r\n * измерения.\r\n */\r\n rowHeight?: number | ((row: Record<string, unknown>, id: RowId) => number)\r\n /**\r\n * Дополнительный эстимейт высоты, разрешает динамическое измерение\r\n * даже при числовом `rowHeight`. Имеет приоритет над `rowHeight`-\r\n * фоллбэком при выборе размера до измерения.\r\n */\r\n estimateRowHeight?: (row: Record<string, unknown>, id: RowId) => number\r\n overscan?: number\r\n height?: number | string\r\n }\r\n\r\n /** Shows CSV export and copy actions in the toolbar. */\r\n exportable?: boolean\r\n /** Custom export handler; default downloads CSV. */\r\n onExport?: (data: string[][]) => void\r\n\r\n /** Shows a bar when rows are selected. */\r\n selectionSummary?: boolean\r\n /** Buttons rendered in the selection summary bar. */\r\n selectionActions?: SelectionSummaryAction[]\r\n\r\n /** Zebra striping on body rows. */\r\n striped?: boolean\r\n\r\n /** Page size selector on the pagination control. */\r\n showSizeChanger?: boolean\r\n /** Options for page size selector. */\r\n pageSizeOptions?: number[]\r\n /** Quick jump to page input on pagination. */\r\n showQuickJumper?: boolean\r\n /** Total / range label on pagination. */\r\n showTotal?: boolean | ((total: number, range: [number, number]) => React.ReactNode)\r\n /** Fires when page size changes. */\r\n onPageSizeChange?: (size: number) => void\r\n\r\n /** Prepends a row index column. */\r\n showRowNumber?: boolean | RowNumberConfig\r\n\r\n /** Shows aggregate values in a footer row. */\r\n footer?: boolean\r\n\r\n /** Fullscreen toggle in the toolbar. */\r\n fullscreenable?: boolean\r\n\r\n /** Density (row height) selector in the toolbar. */\r\n densityToggle?: boolean\r\n\r\n /** Field key to group rows by. */\r\n groupBy?: string\r\n /** Starts with all groups expanded. */\r\n defaultGroupExpanded?: boolean\r\n /** Fires when a group expand state changes. */\r\n onGroupExpandChange?: (groupKey: string, expanded: boolean) => void\r\n /**\r\n * Optional list of fields the user can pick to group by from the toolbar\r\n * dropdown. When omitted, the dropdown is hidden and only the controlled\r\n * `groupBy` value is used.\r\n */\r\n groupByOptions?: Array<{ key: string; label: React.ReactNode }>\r\n /** Called when the user picks a different `groupBy` field from the toolbar. */\r\n onGroupByChange?: (field: string | null) => void\r\n\r\n /** Arrow-key focus navigation between cells. */\r\n keyboardNavigation?: boolean\r\n\r\n /** Pins specific row ids to top or bottom. */\r\n pinnedRows?: PinnedRowsConfig\r\n\r\n /** Replaces default empty state content. */\r\n emptyContent?: React.ReactNode\r\n\r\n /**\r\n * Print action in the toolbar и/или включение `ref.print()`.\r\n *\r\n * `true` — стандартная кнопка в тулбаре.\r\n * `{ fileName?: string }` — кнопка + имя popup-окна (используется браузером\r\n * как заголовок и дефолтное имя файла в \"Save as PDF\").\r\n * `false` / `undefined` — кнопки нет; `ref.print()` всё равно работает.\r\n */\r\n printable?: PrintableProp\r\n\r\n /** JSON export action in the toolbar. */\r\n exportJSON?: boolean\r\n\r\n /** Row hover highlight; set false to disable. */\r\n highlightOnHover?: boolean\r\n\r\n /** Double-click resize handle fits column to content. */\r\n columnAutoResize?: boolean\r\n\r\n /**\r\n * Дополнительные классы по слотам. Публичный API — см. `docs/styling-contract.md` §4.1.\r\n * Имена слотов стабильны, классы-значения применяются поверх встроенных `.sg-table-*`.\r\n */\r\n classNames?: TableClassNames\r\n /** Инлайн-стили по слотам. Публичный API — см. `docs/styling-contract.md` §4.1. */\r\n styles?: TableStyles\r\n}\r\n\r\n/** One cell in a multi-row header grid. */\r\nexport interface HeaderCell {\r\n /** Column at this header position. */\r\n col: TableColumn\r\n /** Horizontal span in header grid units. */\r\n colSpan: number\r\n /** Vertical span in header grid units. */\r\n rowSpan: number\r\n}\r\n\r\n/** Flattened row model passed to body renderers. */\r\nexport interface FlatRow {\r\n /** Row id. */\r\n id: RowId\r\n /** Row field values. */\r\n data: Record<string, unknown>\r\n /** Tree depth when tree mode is enabled. */\r\n depth: number\r\n /** Whether the row has nested children in tree mode. */\r\n hasChildren: boolean\r\n /** Present when this row is a group header. */\r\n __groupRow?: GroupRow\r\n}\r\n","import type React from 'react'\r\n\r\n/**\r\n * Слот-API: публичный контракт для точечной стилизации сложных компонентов.\r\n * См. `docs/styling-contract.md` §2.2, §4.\r\n *\r\n * - `classNames?: XxxClassNames` — дополнительный класс на конкретный слот;\r\n * - `styles?: XxxStyles` — инлайн-стили на конкретный слот;\r\n * - `className` / `style` (на корне) — применяются дополнительно к `classNames.root` / `styles.root`;\r\n * - порядок: дефолтный класс библиотеки → пользовательский слот-класс → корневой `className`.\r\n */\r\n\r\n/** Мапа `слот → className`. */\r\nexport type SlotClassNames<K extends string> = Partial<Record<K, string>>\r\n\r\n/** Мапа `слот → React.CSSProperties`. */\r\nexport type SlotStyles<K extends string> = Partial<Record<K, React.CSSProperties>>\r\n\r\n/**\r\n * Объединяет базовый класс, пользовательский класс для слота и (опционально)\r\n * дополнительные модификаторы в один className.\r\n *\r\n * ```ts\r\n * const cls = slotClass('sg-table-th', classNames?.headerCell, extraMod && 'sg-table-th-sortable')\r\n * ```\r\n */\r\nexport function slotClass(\r\n ...parts: Array<string | false | null | undefined>\r\n): string | undefined {\r\n const filtered = parts.filter((p): p is string => typeof p === 'string' && p.length > 0)\r\n return filtered.length ? filtered.join(' ') : undefined\r\n}\r\n\r\n/**\r\n * Мержит пользовательские стили слота с базовым `style`.\r\n * Пользовательские стили переопределяют базовые.\r\n */\r\nexport function slotStyle(\r\n base: React.CSSProperties | undefined,\r\n custom: React.CSSProperties | undefined,\r\n): React.CSSProperties | undefined {\r\n if (!base && !custom) return undefined\r\n if (!base) return custom\r\n if (!custom) return base\r\n return { ...base, ...custom }\r\n}\r\n"],"mappings":"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","names":["useState","jsx","jsxs","useState","useState","useEffect","useRef","React","useCallback","useMemo","useRef","jsx","jsxs","jsx","jsxs","React","useRef","useState","useEffect","useCallback","jsx","jsxs","Fragment","jsx","jsxs","useState","useRef","useEffect","useCallback","React","useEffect","useMemo","useRef","useState","Fragment","jsx","jsxs","useMemo","useEffect","useState","useRef","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","useMemo","useCallback","jsx","jsxs","useMemo","useState","useCallback","childrenKey","useRef","useEffect","aggregates","Fragment","jsx","jsxs","useRef","useMemo","useCallback","React"]}