@ryuzaki13/react-foundation-lib 2.31.3 → 2.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analytical-table/index.js +2 -2
- package/dist/chunks/{formatters-CO40zvVB.js → formatters-CMfD97RB.js} +3 -3
- package/dist/chunks/{formatters-CO40zvVB.js.map → formatters-CMfD97RB.js.map} +1 -1
- package/dist/chunks/{formulas-Y0HOcFhe.js → formulas-BZtCqzBj.js} +71 -39
- package/dist/chunks/formulas-BZtCqzBj.js.map +1 -0
- package/dist/chunks/{validate-8URYKKly.js → validate-rivmPJyV.js} +5 -5
- package/dist/chunks/{validate-8URYKKly.js.map → validate-rivmPJyV.js.map} +1 -1
- package/dist/error-report/index.js +1 -1
- package/dist/excel/index.js +1 -1
- package/dist/formatters/index.js +2 -2
- package/dist/formulas/execute.d.ts +23 -1
- package/dist/formulas/execute.d.ts.map +1 -1
- package/dist/formulas/index.js +2 -2
- package/dist/formulas/types.d.ts +11 -1
- package/dist/formulas/types.d.ts.map +1 -1
- package/dist/table/columnSizing.d.ts +11 -3
- package/dist/table/columnSizing.d.ts.map +1 -1
- package/dist/table/index.d.ts +1 -0
- package/dist/table/index.d.ts.map +1 -1
- package/dist/table/index.js +74 -68
- package/dist/table/index.js.map +1 -1
- package/dist/table/resolveTableColumnsWidth.d.ts +9 -0
- package/dist/table/resolveTableColumnsWidth.d.ts.map +1 -0
- package/dist/table/types.d.ts +1 -1
- package/dist/table/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/formulas/README.mdx +111 -38
- package/src/table/README.mdx +49 -23
- package/dist/chunks/formulas-Y0HOcFhe.js.map +0 -1
package/dist/table/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/table/columnLayout.ts","../../src/table/columnOrder.ts","../../src/table/columnSizing.ts","../../src/table/tableSelectionConstants.ts","../../src/table/cellSelection.ts","../../src/table/tableColumnConstants.ts","../../src/table/odataAdapter.ts","../../src/table/selection.ts","../../src/table/tanStackFeatures.ts","../../src/table/useTableRowSelection.ts","../../src/table/utils.ts"],"sourcesContent":["import { appendMissingIds, filterAndDeduplicateIds } from \"../array\";\n\nexport type TableColumnLayoutItem<TColumnId extends string = string, TWidth = number> = {\n\tid: TColumnId;\n\twidth: TWidth;\n};\n\nexport type ResolveTableColumnOrderArgs<TColumnId extends string = string> = {\n\tids: readonly TColumnId[];\n\torder?: readonly string[];\n};\n\nexport type BuildTableColumnLayoutArgs<TColumnId extends string = string, TWidth = number> = {\n\tids: readonly TColumnId[];\n\tgetWidth: (id: TColumnId) => TWidth;\n};\n\n/**\n * Возвращает порядок колонок как в AnalyticalTable: сначала сохранённый order,\n * затем новые или отсутствующие в order id. Ширины при этом остаются привязаны\n * к columnId, а не к визуальной позиции.\n */\nexport function resolveTableColumnOrder<TColumnId extends string>({ ids, order }: ResolveTableColumnOrderArgs<TColumnId>): TColumnId[] {\n\treturn appendMissingIds(filterAndDeduplicateIds(order, ids), ids);\n}\n\n/**\n * Строит layout колонок из уже вычисленного порядка и функции ширины по id.\n */\nexport function buildTableColumnLayout<TColumnId extends string, TWidth>({\n\tids,\n\tgetWidth\n}: BuildTableColumnLayoutArgs<TColumnId, TWidth>): TableColumnLayoutItem<TColumnId, TWidth>[] {\n\treturn ids.map((id) => ({\n\t\tid,\n\t\twidth: getWidth(id)\n\t}));\n}\n","import { arraysEqual } from \"../array\";\n\nexport type ReorderTableHeaderColumnsArgs = {\n\torder: readonly string[];\n\theaderIds: readonly string[];\n\tlockedIds?: readonly string[];\n\tpinnedIds?: readonly string[];\n\tactiveId: string;\n\toverId: string;\n};\n\nexport type TableColumnOrderState = string[];\n\nexport function normalizeTableColumnOrder(order: readonly string[] | undefined): TableColumnOrderState {\n\treturn Array.from(new Set((order ?? []).filter((columnId) => columnId.trim().length > 0)));\n}\n\nfunction moveItem<T>(items: readonly T[], fromIndex: number, toIndex: number): T[] {\n\tconst nextItems = [...items];\n\tconst [item] = nextItems.splice(fromIndex, 1);\n\n\tif (item === undefined) {\n\t\treturn nextItems;\n\t}\n\n\tnextItems.splice(toIndex, 0, item);\n\treturn nextItems;\n}\n\n/**\n * Переставляет только верхнеуровневые колонки табличной шапки.\n *\n * Ограничения:\n * - дочерние колонки групп не являются самостоятельными draggable-элементами;\n * - locked-колонки остаются в фиксированном порядке;\n * - pinned-колонки не переносятся между закреплённой и обычной зонами.\n */\nexport function reorderTableHeaderColumns(args: ReorderTableHeaderColumnsArgs): string[] {\n\tconst { activeId, overId, order } = args;\n\tif (!activeId || !overId || activeId === overId) return [...order];\n\n\tconst headerSet = new Set(args.headerIds);\n\tif (!headerSet.has(activeId) || !headerSet.has(overId)) return [...order];\n\n\tconst lockedSet = new Set(args.lockedIds ?? []);\n\tif (lockedSet.has(activeId) || lockedSet.has(overId)) return [...order];\n\n\tconst pinnedSet = new Set(args.pinnedIds ?? []);\n\tif (pinnedSet.has(activeId) || pinnedSet.has(overId)) return [...order];\n\n\tconst nextOrder = [...order];\n\tif (!nextOrder.includes(activeId)) {\n\t\tnextOrder.push(activeId);\n\t}\n\tif (!nextOrder.includes(overId)) {\n\t\tnextOrder.push(overId);\n\t}\n\n\tconst fromIndex = nextOrder.indexOf(activeId);\n\tconst toIndex = nextOrder.indexOf(overId);\n\tif (fromIndex === -1 || toIndex === -1 || fromIndex === toIndex) return nextOrder;\n\n\treturn moveItem(nextOrder, fromIndex, toIndex);\n}\n\nexport function resolveReorderedTableHeaderColumns(args: ReorderTableHeaderColumnsArgs): string[] | null {\n\tconst nextOrder = reorderTableHeaderColumns(args);\n\n\treturn arraysEqual(nextOrder, args.order) ? null : nextOrder;\n}\n","export type TableColumnSizingState = Record<string, number>;\n\nexport const DEFAULT_TABLE_COLUMN_MIN_WIDTH = 60;\n\nexport function normalizeTableColumnWidth(px: number, minWidth: number = DEFAULT_TABLE_COLUMN_MIN_WIDTH): number {\n\tconst normalizedMinWidth = Number.isFinite(minWidth) && minWidth > 0 ? Math.floor(minWidth) : DEFAULT_TABLE_COLUMN_MIN_WIDTH;\n\tconst normalizedWidth = Number.isFinite(px) ? Math.floor(px) : normalizedMinWidth;\n\n\treturn Math.max(normalizedMinWidth, normalizedWidth);\n}\n\nexport function normalizeTableColumnSizing(\n\tstate: Readonly<Record<string, number>> | undefined,\n\tminWidth: number = DEFAULT_TABLE_COLUMN_MIN_WIDTH\n): TableColumnSizingState {\n\tconst nextState: TableColumnSizingState = {};\n\n\tfor (const [columnId, width] of Object.entries(state ?? {})) {\n\t\tif (typeof columnId !== \"string\" || columnId.trim().length === 0 || !Number.isFinite(width)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tnextState[columnId] = normalizeTableColumnWidth(width, minWidth);\n\t}\n\n\treturn nextState;\n}\n\nexport function patchTableColumnWidth(\n\tstate: Readonly<Record<string, number>>,\n\tcolumnId: string,\n\twidth: number,\n\tminWidth: number = DEFAULT_TABLE_COLUMN_MIN_WIDTH\n): TableColumnSizingState {\n\tif (columnId.trim().length === 0) {\n\t\treturn normalizeTableColumnSizing(state, minWidth);\n\t}\n\n\treturn {\n\t\t...normalizeTableColumnSizing(state, minWidth),\n\t\t[columnId]: normalizeTableColumnWidth(width, minWidth)\n\t};\n}\n\nexport function removeTableColumnWidth(state: Readonly<Record<string, number>>, columnId: string): TableColumnSizingState {\n\tconst nextState: TableColumnSizingState = {};\n\n\tfor (const [key, width] of Object.entries(state)) {\n\t\tif (key !== columnId) {\n\t\t\tnextState[key] = width;\n\t\t}\n\t}\n\n\treturn nextState;\n}\n","/** Общие значения кардинальности выбора строк и ячеек; публичные типы используют те же константы. */\nexport const TABLE_SELECTION_MODE_NONE = \"none\";\nexport const TABLE_SELECTION_MODE_SINGLE = \"single\";\nexport const TABLE_SELECTION_MODE_MULTI = \"multi\";\n\n/** Активация выбора отделена от кардинальности и не зависит от платформы пользователя. */\nexport const TABLE_CELL_SELECTION_ACTIVATION_DIRECT = \"direct\";\nexport const TABLE_CELL_SELECTION_ACTIVATION_PRIMARY_MODIFIER = \"primary-modifier\";\n","import {\n\tTABLE_CELL_SELECTION_ACTIVATION_DIRECT,\n\tTABLE_CELL_SELECTION_ACTIVATION_PRIMARY_MODIFIER,\n\tTABLE_SELECTION_MODE_NONE,\n\tTABLE_SELECTION_MODE_SINGLE\n} from \"./tableSelectionConstants\";\nimport {\n\ttype TableCellCoordinates,\n\ttype TableCellSelectionActivationMode,\n\ttype TableCellSelectionMode,\n\ttype TableCellSelectionState,\n\ttype TableSelectionModifierEvent\n} from \"./types\";\n\nconst TABLE_CELL_SELECTION_ACTIVATION_MODES: ReadonlySet<TableCellSelectionActivationMode> = new Set([\n\tTABLE_CELL_SELECTION_ACTIVATION_DIRECT,\n\tTABLE_CELL_SELECTION_ACTIVATION_PRIMARY_MODIFIER\n]);\n\n/** Строит collision-safe identity координат для дедупликации и сравнения. */\nfunction buildTableCellKey(cell: TableCellCoordinates): string {\n\treturn `${encodeURIComponent(cell.rowId)}::${encodeURIComponent(cell.columnId)}`;\n}\n\n/** Проверяет равенство двух наборов координат без зависимости от порядка. */\nexport function areTableCellSelectionsEqual(left: TableCellSelectionState, right: TableCellSelectionState): boolean {\n\tconst leftKeys = new Set(left.map(buildTableCellKey));\n\tconst rightKeys = new Set(right.map(buildTableCellKey));\n\n\tif (leftKeys.size !== rightKeys.size) {\n\t\treturn false;\n\t}\n\n\treturn [...leftKeys].every((key) => rightKeys.has(key));\n}\n\n/**\n * Оставляет только доступные координаты и приводит их к порядку строк/колонок.\n *\n * Функция не мутирует входные массивы. В `single` последняя координата в\n * детерминированном порядке становится единственным выбранным значением.\n */\nexport function pruneTableCellSelection(\n\tselection: TableCellSelectionState | undefined,\n\tavailableRowIds: readonly string[],\n\tavailableColumnIds: readonly string[],\n\tselectionMode: TableCellSelectionMode\n): TableCellCoordinates[] {\n\tif (selectionMode === TABLE_SELECTION_MODE_NONE || !selection?.length) {\n\t\treturn [];\n\t}\n\n\tconst rowOrder = new Map(availableRowIds.map((rowId, index) => [rowId, index]));\n\tconst columnOrder = new Map(availableColumnIds.map((columnId, index) => [columnId, index]));\n\tconst seen = new Set<string>();\n\tconst nextSelection = selection\n\t\t.filter((cell) => {\n\t\t\tif (!(rowOrder.has(cell.rowId) && columnOrder.has(cell.columnId))) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst key = buildTableCellKey(cell);\n\t\t\tif (seen.has(key)) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tseen.add(key);\n\t\t\treturn true;\n\t\t})\n\t\t.sort((left, right) => {\n\t\t\tconst rowDelta = (rowOrder.get(left.rowId) ?? 0) - (rowOrder.get(right.rowId) ?? 0);\n\t\t\tif (rowDelta !== 0) {\n\t\t\t\treturn rowDelta;\n\t\t\t}\n\n\t\t\treturn (columnOrder.get(left.columnId) ?? 0) - (columnOrder.get(right.columnId) ?? 0);\n\t\t});\n\n\tif (selectionMode === TABLE_SELECTION_MODE_SINGLE) {\n\t\tconst lastCell = nextSelection.at(-1);\n\t\treturn lastCell ? [lastCell] : [];\n\t}\n\n\treturn nextSelection;\n}\n\n/**\n * Вычисляет следующее состояние после активации ячейки.\n *\n * Одиночный выбор допускает явное снятие повторной активацией, а `multi`\n * переключает только переданную координату.\n */\nexport function toggleTableCellSelection(\n\tselection: TableCellSelectionState,\n\tcell: TableCellCoordinates,\n\tselectionMode: TableCellSelectionMode\n): TableCellCoordinates[] {\n\tif (selectionMode === TABLE_SELECTION_MODE_NONE) {\n\t\treturn [];\n\t}\n\n\tconst cellKey = buildTableCellKey(cell);\n\tconst hasCell = selection.some((item) => buildTableCellKey(item) === cellKey);\n\n\tif (selectionMode === TABLE_SELECTION_MODE_SINGLE) {\n\t\treturn hasCell ? [] : [cell];\n\t}\n\n\treturn hasCell ? selection.filter((item) => buildTableCellKey(item) !== cellKey) : [...selection, cell];\n}\n\n/** Нормализует способ активации ячейки на внешней config-boundary. */\nexport function normalizeTableCellSelectionActivationMode(\n\tvalue: unknown,\n\tfallback: TableCellSelectionActivationMode = TABLE_CELL_SELECTION_ACTIVATION_DIRECT\n): TableCellSelectionActivationMode {\n\treturn typeof value === \"string\" && TABLE_CELL_SELECTION_ACTIVATION_MODES.has(value as TableCellSelectionActivationMode)\n\t\t? (value as TableCellSelectionActivationMode)\n\t\t: fallback;\n}\n\n/**\n * Проверяет, должно ли событие активировать выбор ячейки.\n *\n * Для `primary-modifier` принимается Ctrl или Command, но не комбинации с\n * Shift/Alt: они зарезервированы браузером, ОС и стандартными selection-flow.\n */\nexport function shouldActivateTableCellSelection(\n\tevent: TableSelectionModifierEvent,\n\tactivationMode: TableCellSelectionActivationMode\n): boolean {\n\tif (activationMode === TABLE_CELL_SELECTION_ACTIVATION_DIRECT) {\n\t\treturn true;\n\t}\n\n\treturn (event.ctrlKey || event.metaKey) && !event.shiftKey && !event.altKey;\n}\n","/** Значения выравнивания общие для metadata-адаптера и публичного типа колонки. */\nexport const TABLE_COLUMN_ALIGN_LEFT = \"left\";\nexport const TABLE_COLUMN_ALIGN_CENTER = \"center\";\nexport const TABLE_COLUMN_ALIGN_RIGHT = \"right\";\n","import { type FormattersPipelineTypedValueContext } from \"../formatters/pipeline\";\nimport { SCALAR_ROLE_MEASURE } from \"../metadata/scalarTypeConstants\";\nimport { type EntityColumnProperty } from \"../odata-service\";\n\nimport { TABLE_COLUMN_ALIGN_LEFT, TABLE_COLUMN_ALIGN_RIGHT } from \"./tableColumnConstants\";\nimport { type TableColumnAlign, type TableColumnDef, type TableColumnFormattingMetaInput } from \"./types\";\n\n/**\n * Опции генерации колонок по OData metadata.\n */\nexport interface CreateTableColumnsFromODataMetadataOptions {\n\t/**\n\t * Позволяет переопределить заголовок колонки.\n\t */\n\tresolveHeader?: (column: EntityColumnProperty) => string;\n\t/**\n\t * Позволяет сразу навесить formatting-конфиг на generated column.\n\t *\n\t * `id`, `role` и `type` будут автоматически получены из metadata.\n\t */\n\tresolveFormatting?: (column: EntityColumnProperty) => TableColumnFormattingMetaInput | undefined;\n}\n\n/**\n * Опции обогащения уже существующих колонок данными OData metadata.\n */\nexport interface EnrichTableColumnsWithODataFormattingOptions {\n\t/**\n\t * Позволяет подменить стратегию поиска metadata по колонке.\n\t */\n\tresolveMetadataColumn?: (args: {\n\t\tcolumnId: string;\n\t\tmetadataColumnsById: ReadonlyMap<string, EntityColumnProperty>;\n\t}) => EntityColumnProperty | undefined;\n}\n\n/**\n * Опции построения стартовой карты видимости колонок по OData metadata.\n */\nexport interface CreateTableColumnVisibilityFromODataMetadataOptions {\n\t/**\n\t * Позволяет явно переопределить стартовую видимость колонки.\n\t */\n\tresolveVisible?: (column: EntityColumnProperty) => boolean;\n}\n\n/**\n * Возвращает typed-formatting контекст по metadata OData-колонки.\n */\nexport function resolveTableColumnFormattingContextFromODataColumn(column: EntityColumnProperty): FormattersPipelineTypedValueContext {\n\tconst { role, type } = column;\n\tconst forceMeasure = type === \"decimal\" || type === \"float\" || type === \"double\" || type === \"int\" || type === \"byte\";\n\n\treturn {\n\t\trole: forceMeasure ? SCALAR_ROLE_MEASURE : role,\n\t\ttype: type\n\t};\n}\n\n/**\n * Создаёт базовое выравнивание по семантике OData-колонки.\n *\n * NOTE: \"не аналитические\" все поля возвращают как \"dimension\"...\n */\nfunction resolveTableColumnAlignFromODataColumn(columnContext: FormattersPipelineTypedValueContext): TableColumnAlign {\n\treturn columnContext.role === SCALAR_ROLE_MEASURE ? TABLE_COLUMN_ALIGN_RIGHT : TABLE_COLUMN_ALIGN_LEFT;\n}\n\n/**\n * Определяет видимость metadata-колонки по умолчанию.\n *\n * Кодовые поля скрываются только если у них есть явная text-пара,\n * чтобы экран по умолчанию показывал человекочитаемое значение.\n */\nfunction resolveMetadataColumnVisibleByDefault(\n\tcolumn: EntityColumnProperty,\n\tmetadataColumnsById: ReadonlyMap<string, EntityColumnProperty>\n): boolean {\n\tif (column.semanticType !== \"code\" || !column.linkedColumnId) {\n\t\treturn true;\n\t}\n\n\tconst linkedColumn = metadataColumnsById.get(column.linkedColumnId);\n\n\treturn linkedColumn?.semanticType !== \"text\";\n}\n\n/**\n * Определяет стабильный идентификатор колонки для сопоставления с metadata.\n */\nexport function resolveStableColumnId<TData extends object>(column: TableColumnDef<TData>): string | undefined {\n\tif (typeof column.id === \"string\" && column.id.trim()) {\n\t\treturn column.id;\n\t}\n\n\tif (\"accessorKey\" in column && typeof column.accessorKey === \"string\" && column.accessorKey.trim()) {\n\t\treturn column.accessorKey;\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Рекурсивно обходит только leaf-колонки.\n */\nfunction mapLeafTableColumns<TData extends object>(\n\tcolumns: readonly TableColumnDef<TData>[],\n\tmapper: (column: TableColumnDef<TData>) => TableColumnDef<TData>\n): TableColumnDef<TData>[] {\n\treturn columns.map((column) => {\n\t\tif (\"columns\" in column && Array.isArray(column.columns) && column.columns.length > 0) {\n\t\t\treturn {\n\t\t\t\t...column,\n\t\t\t\tcolumns: mapLeafTableColumns(column.columns as TableColumnDef<TData>[], mapper)\n\t\t\t};\n\t\t}\n\n\t\treturn mapper(column);\n\t});\n}\n\n/**\n * Строит стартовую карту видимости колонок из metadata OData-сущности.\n *\n * Возвращает visibility-state для TanStack Table, не удаляя сами колонки\n * из результата build-режима.\n */\nexport function createTableColumnVisibilityFromODataMetadata(\n\tmetadataColumns: readonly EntityColumnProperty[],\n\toptions?: CreateTableColumnVisibilityFromODataMetadataOptions\n): Record<string, boolean> {\n\tconst metadataColumnsById = new Map(metadataColumns.map((column) => [column.id, column]));\n\n\treturn Object.fromEntries(\n\t\tmetadataColumns.map((column) => {\n\t\t\tconst visible = options?.resolveVisible?.(column) ?? resolveMetadataColumnVisibleByDefault(column, metadataColumnsById);\n\n\t\t\treturn [column.id, visible];\n\t\t})\n\t);\n}\n\n/**\n * Создаёт базовые generic-колонки из metadata OData-сущности.\n */\nexport function createTableColumnsFromODataMetadata<TData extends object = Record<string, unknown>>(\n\tmetadataColumns: readonly EntityColumnProperty[],\n\toptions?: CreateTableColumnsFromODataMetadataOptions\n): TableColumnDef<TData>[] {\n\treturn metadataColumns.map((metadataColumn) => {\n\t\t// NOTE: Ячейка сама определит выравнивание, `align` только для переопределения\n\t\tconst columnContext = resolveTableColumnFormattingContextFromODataColumn(metadataColumn);\n\t\tconst align = resolveTableColumnAlignFromODataColumn(columnContext);\n\t\tconst resolvedFormatting = options?.resolveFormatting?.(metadataColumn);\n\n\t\treturn {\n\t\t\tid: metadataColumn.id,\n\t\t\taccessorKey: metadataColumn.id,\n\t\t\theader: options?.resolveHeader?.(metadataColumn) ?? metadataColumn.label ?? metadataColumn.id,\n\t\t\tmeta: {\n\t\t\t\talign,\n\t\t\t\tformatting: {\n\t\t\t\t\t...resolvedFormatting,\n\t\t\t\t\tid: metadataColumn.id,\n\t\t\t\t\trole: columnContext.role,\n\t\t\t\t\ttype: columnContext.type\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}) as TableColumnDef<TData>[];\n}\n\n/**\n * Дозаполняет уже существующие колонки typed-formatting контекстом из OData metadata.\n */\nexport function enrichTableColumnsWithODataFormatting<TData extends object>(\n\tcolumns: readonly TableColumnDef<TData>[],\n\tmetadataColumns: readonly EntityColumnProperty[],\n\toptions?: EnrichTableColumnsWithODataFormattingOptions\n): TableColumnDef<TData>[] {\n\tconst metadataColumnsById = new Map(metadataColumns.map((column) => [column.id, column]));\n\n\treturn mapLeafTableColumns(columns, (column) => {\n\t\tconst columnId = resolveStableColumnId(column);\n\t\tif (!columnId) {\n\t\t\treturn column;\n\t\t}\n\n\t\tconst metadataColumn =\n\t\t\toptions?.resolveMetadataColumn?.({\n\t\t\t\tcolumnId,\n\t\t\t\tmetadataColumnsById\n\t\t\t}) ?? metadataColumnsById.get(columnId);\n\n\t\tif (!metadataColumn) {\n\t\t\treturn column;\n\t\t}\n\n\t\tif (column.meta?.formatting?.role && column.meta.formatting.type) {\n\t\t\treturn column;\n\t\t}\n\t\tconst columnContext = resolveTableColumnFormattingContextFromODataColumn(metadataColumn);\n\n\t\treturn {\n\t\t\t...column,\n\t\t\tmeta: {\n\t\t\t\t...column.meta,\n\t\t\t\tformatting: {\n\t\t\t\t\t...column.meta?.formatting,\n\t\t\t\t\tid: columnId,\n\t\t\t\t\trole: columnContext.role,\n\t\t\t\t\ttype: columnContext.type\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n","import { type RowSelectionState } from \"@tanstack/react-table\";\n\nimport { TABLE_SELECTION_MODE_MULTI, TABLE_SELECTION_MODE_NONE, TABLE_SELECTION_MODE_SINGLE } from \"./tableSelectionConstants\";\nimport { type TableSelectionMode } from \"./types\";\n\nconst TABLE_SELECTION_MODES: ReadonlySet<TableSelectionMode> = new Set([\n\tTABLE_SELECTION_MODE_NONE,\n\tTABLE_SELECTION_MODE_SINGLE,\n\tTABLE_SELECTION_MODE_MULTI\n]);\n\n/**\n * Возвращает только активные идентификаторы выбранных строк.\n */\nfunction getSelectedRowIds(selection: RowSelectionState): string[] {\n\treturn Object.keys(selection).filter((rowId) => selection[rowId]);\n}\n\n/** Проверяет равенство активных row-selection идентификаторов без учёта порядка ключей. */\nexport function areTableRowSelectionsEqual(left: RowSelectionState, right: RowSelectionState): boolean {\n\tconst leftRowIds = getSelectedRowIds(left);\n\tconst rightRowIds = getSelectedRowIds(right);\n\n\tif (leftRowIds.length !== rightRowIds.length) {\n\t\treturn false;\n\t}\n\n\treturn leftRowIds.every((rowId) => right[rowId]);\n}\n\n/** Нормализует неизвестное значение режима выбора строк на внешней config-boundary. */\nexport function normalizeTableSelectionMode(value: unknown, fallback: TableSelectionMode = TABLE_SELECTION_MODE_NONE): TableSelectionMode {\n\treturn typeof value === \"string\" && TABLE_SELECTION_MODES.has(value as TableSelectionMode) ? (value as TableSelectionMode) : fallback;\n}\n\n/**\n * Нормализует состояние выбора относительно списка доступных строк и текущего режима.\n */\nexport function pruneTableRowSelection(\n\tselection: RowSelectionState,\n\tavailableRowIds: readonly string[],\n\tselectionMode: TableSelectionMode\n): RowSelectionState {\n\tif (selectionMode === TABLE_SELECTION_MODE_NONE) {\n\t\treturn {};\n\t}\n\n\tconst availableRowIdSet = new Set(availableRowIds);\n\tconst selectedRowIds = getSelectedRowIds(selection).filter((rowId) => availableRowIdSet.has(rowId));\n\n\tif (selectionMode === TABLE_SELECTION_MODE_SINGLE) {\n\t\tconst lastSelectedRowId = selectedRowIds.at(-1);\n\n\t\treturn lastSelectedRowId ? { [lastSelectedRowId]: true } : {};\n\t}\n\n\treturn Object.fromEntries(selectedRowIds.map((rowId) => [rowId, true]));\n}\n\n/**\n * Вычисляет следующее состояние выбора после активации строки пользователем.\n *\n * Семантика:\n * - `none` не хранит выбор;\n * - `single` всегда оставляет только одну строку и не снимает выбор повторным кликом;\n * - `multi` переключает строку как toggle.\n */\nexport function toggleTableRowSelection(selection: RowSelectionState, rowId: string, selectionMode: TableSelectionMode): RowSelectionState {\n\tif (selectionMode === TABLE_SELECTION_MODE_NONE) {\n\t\treturn {};\n\t}\n\n\tif (selectionMode === TABLE_SELECTION_MODE_SINGLE) {\n\t\tconst selectedRowIds = getSelectedRowIds(selection);\n\t\treturn selectedRowIds.length === 1 && selectedRowIds[0] === rowId ? selection : { [rowId]: true };\n\t}\n\n\tif (selection[rowId]) {\n\t\tconst nextSelection = { ...selection };\n\n\t\tdelete nextSelection[rowId];\n\n\t\treturn nextSelection;\n\t}\n\n\treturn {\n\t\t...selection,\n\t\t[rowId]: true\n\t};\n}\n","import {\n\tcolumnOrderingFeature,\n\tcolumnPinningFeature,\n\tcolumnResizingFeature,\n\tcolumnSizingFeature,\n\tcolumnVisibilityFeature,\n\tcreateExpandedRowModel,\n\trowExpandingFeature,\n\trowSelectionFeature,\n\ttableFeatures\n} from \"@tanstack/react-table\";\n\n/**\n * Единый набор TanStack Table v9 features для foundation-таблиц.\n *\n * Контракт хранится в `lib`, чтобы определения колонок, строк и экземпляров\n * таблицы в `lib` и `ui` всегда использовали один и тот же набор generic-типов.\n */\nexport const foundationTableFeatures = tableFeatures({\n\tcolumnOrderingFeature,\n\tcolumnPinningFeature,\n\tcolumnSizingFeature,\n\tcolumnResizingFeature,\n\tcolumnVisibilityFeature,\n\trowSelectionFeature,\n\trowExpandingFeature,\n\texpandedRowModel: createExpandedRowModel()\n});\n\n/** Generic-контракт features для публичных типов foundation-таблиц. */\nexport type FoundationTableFeatures = typeof foundationTableFeatures;\n","import { useCallback, useEffect, useEffectEvent, useRef, useState } from \"react\";\n\nimport { type RowSelectionState } from \"@tanstack/react-table\";\n\nimport { pruneTableRowSelection, toggleTableRowSelection } from \"./selection\";\nimport { TABLE_SELECTION_MODE_NONE } from \"./tableSelectionConstants\";\nimport { type TableSelectionMode } from \"./types\";\n\ninterface UseTableRowSelectionParams<TData extends object> {\n\tavailableRowIds: readonly string[];\n\trowById: ReadonlyMap<string, TData>;\n\tselectionMode: TableSelectionMode;\n\tselectedRowIds?: readonly string[];\n\tonRowSelectionChange?: (rows: TData[]) => void;\n}\n\n/**\n * Общая модель выбора строк для плоской и древовидной таблиц.\n */\nexport function useTableRowSelection<TData extends object>({\n\tavailableRowIds,\n\trowById,\n\tselectionMode,\n\tselectedRowIds,\n\tonRowSelectionChange\n}: UseTableRowSelectionParams<TData>) {\n\tconst [rowSelection, setRowSelection] = useState<RowSelectionState>({});\n\tconst shouldSkipNextSelectionEmitRef = useRef(false);\n\n\t/**\n\t * Сравнивает состояния выбора без лишних перерисовок.\n\t */\n\tconst areSelectionsEqual = useCallback((left: RowSelectionState, right: RowSelectionState) => {\n\t\tconst leftRowIds = Object.keys(left).filter((rowId) => left[rowId]);\n\t\tconst rightRowIds = Object.keys(right).filter((rowId) => right[rowId]);\n\n\t\tif (leftRowIds.length !== rightRowIds.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn leftRowIds.every((rowId) => right[rowId]);\n\n\t\t/*\n\n Более оптимизированная версия, но для текущего случая может быть практически незначительной\n\n let leftCount = 0;\n\t\tlet rightCount = 0;\n\n\t\tfor (const rowId of Object.keys(left)) {\n\t\t\tif (!left[rowId]) continue;\n\t\t\tleftCount += 1;\n\t\t\tif (!right[rowId]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfor (const rowId of Object.keys(right)) {\n\t\t\tif (right[rowId]) {\n\t\t\t\trightCount += 1;\n\t\t\t}\n\t\t}\n\n\t\tif (leftCount !== rightCount) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\n */\n\t}, []);\n\n\tconst syncRowSelectionState = useEffectEvent((nextAvailableRowIds: readonly string[]) => {\n\t\tsetRowSelection((currentSelection) => pruneTableRowSelection(currentSelection, nextAvailableRowIds, selectionMode));\n\t});\n\n\tconst syncControlledRowSelectionState = useEffectEvent(\n\t\t(nextSelectedRowIds: readonly string[], nextAvailableRowIds: readonly string[]) => {\n\t\t\tconst nextSelection = pruneTableRowSelection(\n\t\t\t\tObject.fromEntries(nextSelectedRowIds.map((rowId) => [rowId, true])),\n\t\t\t\tnextAvailableRowIds,\n\t\t\t\tselectionMode\n\t\t\t);\n\n\t\t\tsetRowSelection((currentSelection) => {\n\t\t\t\tif (areSelectionsEqual(currentSelection, nextSelection)) {\n\t\t\t\t\treturn currentSelection;\n\t\t\t\t}\n\n\t\t\t\t// Пропускаем следующий emit, потому что это синхронизация от внешнего controlled-состояния,\n\t\t\t\t// а не пользовательское изменение выбора внутри таблицы.\n\t\t\t\tshouldSkipNextSelectionEmitRef.current = true;\n\n\t\t\t\treturn nextSelection;\n\t\t\t});\n\t\t}\n\t);\n\n\tconst emitRowSelectionChange = useEffectEvent((currentSelection: RowSelectionState) => {\n\t\tif (!onRowSelectionChange) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst selectedRows: TData[] = [];\n\n\t\tfor (const rowId of Object.keys(currentSelection)) {\n\t\t\tif (!currentSelection[rowId]) continue;\n\n\t\t\tconst row = rowById.get(rowId);\n\t\t\tif (row) {\n\t\t\t\tselectedRows.push(row);\n\t\t\t}\n\t\t}\n\n\t\tonRowSelectionChange(selectedRows);\n\t});\n\n\tuseEffect(() => {\n\t\tif (selectedRowIds !== undefined) {\n\t\t\tsyncControlledRowSelectionState(selectedRowIds, availableRowIds);\n\t\t\treturn;\n\t\t}\n\n\t\tsyncRowSelectionState(availableRowIds);\n\t}, [availableRowIds, selectedRowIds, selectionMode]);\n\n\tuseEffect(() => {\n\t\tif (shouldSkipNextSelectionEmitRef.current) {\n\t\t\tshouldSkipNextSelectionEmitRef.current = false;\n\t\t\treturn;\n\t\t}\n\n\t\temitRowSelectionChange(rowSelection);\n\t}, [rowSelection]);\n\n\t/**\n\t * Применяет изменение выбора при активации конкретной строки.\n\t */\n\tconst activateRowSelection = useCallback(\n\t\t(rowId: string, canSelect: boolean) => {\n\t\t\tif (selectionMode === TABLE_SELECTION_MODE_NONE || !canSelect) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetRowSelection((currentSelection) => toggleTableRowSelection(currentSelection, rowId, selectionMode));\n\t\t},\n\t\t[selectionMode]\n\t);\n\n\treturn {\n\t\trowSelection,\n\t\tsetRowSelection,\n\t\tactivateRowSelection\n\t};\n}\n","import { TableColumnDef, TableColumnFormattingMeta, TableColumnMeta } from \"./types\";\n\n/**\n * Интерактивные descendants, действие которых таблица не должна подменять\n * выбором строки или ячейки.\n *\n * `td`, `th` и `tr` намеренно исключены из tabindex-ветки: сама таблица может\n * использовать roving tabindex для selection, не превращая ячейку в nested control.\n */\nconst TABLE_INTERACTIVE_ELEMENT_SELECTOR = [\n\t\"button\",\n\t\"a\",\n\t\"input\",\n\t\"select\",\n\t\"textarea\",\n\t\"label\",\n\t\"summary\",\n\t\"audio[controls]\",\n\t\"video[controls]\",\n\t'[contenteditable]:not([contenteditable=\"false\"])',\n\t\"[tabindex]:not(td):not(th):not(tr)\",\n\t'[draggable=\"true\"]',\n\t'[role=\"button\"]',\n\t'[role=\"link\"]',\n\t'[role=\"checkbox\"]',\n\t'[role=\"radio\"]',\n\t'[role=\"switch\"]',\n\t'[role=\"menu\"]',\n\t'[role=\"menuitem\"]',\n\t'[role=\"menuitemcheckbox\"]',\n\t'[role=\"menuitemradio\"]',\n\t'[role=\"listbox\"]',\n\t'[role=\"option\"]',\n\t'[role=\"tab\"]',\n\t'[role=\"tablist\"]',\n\t'[role=\"tree\"]',\n\t'[role=\"treeitem\"]',\n\t'[role=\"slider\"]',\n\t'[role=\"spinbutton\"]',\n\t'[role=\"textbox\"]',\n\t'[role=\"searchbox\"]',\n\t'[role=\"combobox\"]'\n].join(\", \");\n\n/**\n * Возвращает метаданные колонки таблицы.\n */\nexport function getTableColumnMeta<TData extends object>(column: TableColumnDef<TData>): TableColumnMeta | undefined {\n\treturn column.meta;\n}\n\n/**\n * Возвращает форматирующий блок метаданных колонки.\n */\nexport function getTableColumnFormattingMeta<TData extends object>(column: TableColumnDef<TData>): TableColumnFormattingMeta | undefined {\n\treturn column.meta?.formatting;\n}\n\n/**\n * Нормализует размер таблицы.\n *\n * Числовое значение трактуется как `em`, чтобы разметка масштабировалась вместе со шрифтом.\n */\nexport function resolveTableLength(length: string | number): string {\n\tif (typeof length === \"number\") {\n\t\treturn `${length}em`;\n\t}\n\n\treturn length;\n}\n\n/**\n * Определяет, пришёл ли клик из интерактивного элемента внутри таблицы.\n * Учитывает только элементы внутри ближайшей строки: фокусируемая вкладка или\n * диалог вокруг таблицы не должны перехватывать выбор её строк.\n */\nexport function isTableInteractiveElement(target: EventTarget | null, extraSelector?: string): boolean {\n\tif (typeof Element === \"undefined\" || !(target instanceof Element)) {\n\t\treturn false;\n\t}\n\n\tconst selector = extraSelector ? `${TABLE_INTERACTIVE_ELEMENT_SELECTOR}, ${extraSelector}` : TABLE_INTERACTIVE_ELEMENT_SELECTOR;\n\tconst interactiveElement = target.closest(selector);\n\tif (!interactiveElement) return false;\n\n\tconst row = target.closest(\"tr\");\n\treturn !row || row.contains(interactiveElement);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/table/columnLayout.ts","../../src/table/columnOrder.ts","../../src/table/columnSizing.ts","../../src/table/resolveTableColumnsWidth.ts","../../src/table/tableSelectionConstants.ts","../../src/table/cellSelection.ts","../../src/table/tableColumnConstants.ts","../../src/table/odataAdapter.ts","../../src/table/selection.ts","../../src/table/tanStackFeatures.ts","../../src/table/useTableRowSelection.ts","../../src/table/utils.ts"],"sourcesContent":["import { appendMissingIds, filterAndDeduplicateIds } from \"../array\";\n\nexport type TableColumnLayoutItem<TColumnId extends string = string, TWidth = number> = {\n\tid: TColumnId;\n\twidth: TWidth;\n};\n\nexport type ResolveTableColumnOrderArgs<TColumnId extends string = string> = {\n\tids: readonly TColumnId[];\n\torder?: readonly string[];\n};\n\nexport type BuildTableColumnLayoutArgs<TColumnId extends string = string, TWidth = number> = {\n\tids: readonly TColumnId[];\n\tgetWidth: (id: TColumnId) => TWidth;\n};\n\n/**\n * Возвращает порядок колонок как в AnalyticalTable: сначала сохранённый order,\n * затем новые или отсутствующие в order id. Ширины при этом остаются привязаны\n * к columnId, а не к визуальной позиции.\n */\nexport function resolveTableColumnOrder<TColumnId extends string>({ ids, order }: ResolveTableColumnOrderArgs<TColumnId>): TColumnId[] {\n\treturn appendMissingIds(filterAndDeduplicateIds(order, ids), ids);\n}\n\n/**\n * Строит layout колонок из уже вычисленного порядка и функции ширины по id.\n */\nexport function buildTableColumnLayout<TColumnId extends string, TWidth>({\n\tids,\n\tgetWidth\n}: BuildTableColumnLayoutArgs<TColumnId, TWidth>): TableColumnLayoutItem<TColumnId, TWidth>[] {\n\treturn ids.map((id) => ({\n\t\tid,\n\t\twidth: getWidth(id)\n\t}));\n}\n","import { arraysEqual } from \"../array\";\n\nexport type ReorderTableHeaderColumnsArgs = {\n\torder: readonly string[];\n\theaderIds: readonly string[];\n\tlockedIds?: readonly string[];\n\tpinnedIds?: readonly string[];\n\tactiveId: string;\n\toverId: string;\n};\n\nexport type TableColumnOrderState = string[];\n\nexport function normalizeTableColumnOrder(order: readonly string[] | undefined): TableColumnOrderState {\n\treturn Array.from(new Set((order ?? []).filter((columnId) => columnId.trim().length > 0)));\n}\n\nfunction moveItem<T>(items: readonly T[], fromIndex: number, toIndex: number): T[] {\n\tconst nextItems = [...items];\n\tconst [item] = nextItems.splice(fromIndex, 1);\n\n\tif (item === undefined) {\n\t\treturn nextItems;\n\t}\n\n\tnextItems.splice(toIndex, 0, item);\n\treturn nextItems;\n}\n\n/**\n * Переставляет только верхнеуровневые колонки табличной шапки.\n *\n * Ограничения:\n * - дочерние колонки групп не являются самостоятельными draggable-элементами;\n * - locked-колонки остаются в фиксированном порядке;\n * - pinned-колонки не переносятся между закреплённой и обычной зонами.\n */\nexport function reorderTableHeaderColumns(args: ReorderTableHeaderColumnsArgs): string[] {\n\tconst { activeId, overId, order } = args;\n\tif (!activeId || !overId || activeId === overId) return [...order];\n\n\tconst headerSet = new Set(args.headerIds);\n\tif (!headerSet.has(activeId) || !headerSet.has(overId)) return [...order];\n\n\tconst lockedSet = new Set(args.lockedIds ?? []);\n\tif (lockedSet.has(activeId) || lockedSet.has(overId)) return [...order];\n\n\tconst pinnedSet = new Set(args.pinnedIds ?? []);\n\tif (pinnedSet.has(activeId) || pinnedSet.has(overId)) return [...order];\n\n\tconst nextOrder = [...order];\n\tif (!nextOrder.includes(activeId)) {\n\t\tnextOrder.push(activeId);\n\t}\n\tif (!nextOrder.includes(overId)) {\n\t\tnextOrder.push(overId);\n\t}\n\n\tconst fromIndex = nextOrder.indexOf(activeId);\n\tconst toIndex = nextOrder.indexOf(overId);\n\tif (fromIndex === -1 || toIndex === -1 || fromIndex === toIndex) return nextOrder;\n\n\treturn moveItem(nextOrder, fromIndex, toIndex);\n}\n\nexport function resolveReorderedTableHeaderColumns(args: ReorderTableHeaderColumnsArgs): string[] | null {\n\tconst nextOrder = reorderTableHeaderColumns(args);\n\n\treturn arraysEqual(nextOrder, args.order) ? null : nextOrder;\n}\n","/** Числа sizing-state используют единицу, явно выбранную потребителем; по умолчанию это px. */\nexport type TableColumnSizingState = Record<string, number>;\n\n/** Единица сохранённого размера не зависит от экранных координат pointer/keyboard events. */\nexport type TableColumnSizingUnit = \"px\" | \"em\";\n\nexport const DEFAULT_TABLE_COLUMN_MIN_WIDTH = 60;\nexport const DEFAULT_TABLE_COLUMN_MIN_WIDTH_EM = 4;\n\n/**\n * Нормализует размер в выбранной единице. Для px сохраняется целочисленный контракт,\n * для em остаются четыре знака, чтобы resize не округлялся до целого размера шрифта.\n */\nexport function normalizeTableColumnWidth(width: number, minWidth?: number, unit: TableColumnSizingUnit = \"px\"): number {\n\tconst defaultMinWidth = unit === \"em\" ? DEFAULT_TABLE_COLUMN_MIN_WIDTH_EM : DEFAULT_TABLE_COLUMN_MIN_WIDTH;\n\tconst precision = unit === \"em\" ? 10_000 : 1;\n\tconst normalizedMinWidth =\n\t\ttypeof minWidth === \"number\" && Number.isFinite(minWidth) && minWidth > 0\n\t\t\t? Math.floor(minWidth * precision) / precision\n\t\t\t: defaultMinWidth;\n\tconst normalizedWidth = Number.isFinite(width) ? Math.floor(width * precision) / precision : normalizedMinWidth;\n\n\treturn Math.max(normalizedMinWidth, normalizedWidth);\n}\n\nexport function normalizeTableColumnSizing(\n\tstate: Readonly<Record<string, number>> | undefined,\n\tminWidth?: number,\n\tunit: TableColumnSizingUnit = \"px\"\n): TableColumnSizingState {\n\tconst nextState: TableColumnSizingState = {};\n\n\tfor (const [columnId, width] of Object.entries(state ?? {})) {\n\t\tif (typeof columnId !== \"string\" || columnId.trim().length === 0 || !Number.isFinite(width)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tnextState[columnId] = normalizeTableColumnWidth(width, minWidth, unit);\n\t}\n\n\treturn nextState;\n}\n\nexport function patchTableColumnWidth(\n\tstate: Readonly<Record<string, number>>,\n\tcolumnId: string,\n\twidth: number,\n\tminWidth?: number,\n\tunit: TableColumnSizingUnit = \"px\"\n): TableColumnSizingState {\n\tif (columnId.trim().length === 0) {\n\t\treturn normalizeTableColumnSizing(state, minWidth, unit);\n\t}\n\n\treturn {\n\t\t...normalizeTableColumnSizing(state, minWidth, unit),\n\t\t[columnId]: normalizeTableColumnWidth(width, minWidth, unit)\n\t};\n}\n\nexport function removeTableColumnWidth(state: Readonly<Record<string, number>>, columnId: string): TableColumnSizingState {\n\tconst nextState: TableColumnSizingState = {};\n\n\tfor (const [key, width] of Object.entries(state)) {\n\t\tif (key !== columnId) {\n\t\t\tnextState[key] = width;\n\t\t}\n\t}\n\n\treturn nextState;\n}\n","const TABLE_COLUMN_FIXED_WIDTH_PATTERN = /^(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:em|px)$/;\n\n/**\n * Возвращает сумму определённых ширин колонок без измерения DOM.\n *\n * em сохраняются в CSS, поэтому таблица масштабируется вместе со шрифтом уже\n * при SSR. auto и проценты требуют доступной ширины и остаются в ведении\n * браузерной раскладки: для них нельзя получить независимую сумму колонок.\n */\nexport function resolveTableColumnsWidth(widths: readonly string[]): string | undefined {\n\tif (widths.length === 0 || widths.some((width) => !TABLE_COLUMN_FIXED_WIDTH_PATTERN.test(width))) {\n\t\treturn undefined;\n\t}\n\n\treturn widths.length === 1 ? widths[0] : `calc(${widths.join(\" + \")})`;\n}\n","/** Общие значения кардинальности выбора строк и ячеек; публичные типы используют те же константы. */\nexport const TABLE_SELECTION_MODE_NONE = \"none\";\nexport const TABLE_SELECTION_MODE_SINGLE = \"single\";\nexport const TABLE_SELECTION_MODE_MULTI = \"multi\";\n\n/** Активация выбора отделена от кардинальности и не зависит от платформы пользователя. */\nexport const TABLE_CELL_SELECTION_ACTIVATION_DIRECT = \"direct\";\nexport const TABLE_CELL_SELECTION_ACTIVATION_PRIMARY_MODIFIER = \"primary-modifier\";\n","import {\n\tTABLE_CELL_SELECTION_ACTIVATION_DIRECT,\n\tTABLE_CELL_SELECTION_ACTIVATION_PRIMARY_MODIFIER,\n\tTABLE_SELECTION_MODE_NONE,\n\tTABLE_SELECTION_MODE_SINGLE\n} from \"./tableSelectionConstants\";\nimport {\n\ttype TableCellCoordinates,\n\ttype TableCellSelectionActivationMode,\n\ttype TableCellSelectionMode,\n\ttype TableCellSelectionState,\n\ttype TableSelectionModifierEvent\n} from \"./types\";\n\nconst TABLE_CELL_SELECTION_ACTIVATION_MODES: ReadonlySet<TableCellSelectionActivationMode> = new Set([\n\tTABLE_CELL_SELECTION_ACTIVATION_DIRECT,\n\tTABLE_CELL_SELECTION_ACTIVATION_PRIMARY_MODIFIER\n]);\n\n/** Строит collision-safe identity координат для дедупликации и сравнения. */\nfunction buildTableCellKey(cell: TableCellCoordinates): string {\n\treturn `${encodeURIComponent(cell.rowId)}::${encodeURIComponent(cell.columnId)}`;\n}\n\n/** Проверяет равенство двух наборов координат без зависимости от порядка. */\nexport function areTableCellSelectionsEqual(left: TableCellSelectionState, right: TableCellSelectionState): boolean {\n\tconst leftKeys = new Set(left.map(buildTableCellKey));\n\tconst rightKeys = new Set(right.map(buildTableCellKey));\n\n\tif (leftKeys.size !== rightKeys.size) {\n\t\treturn false;\n\t}\n\n\treturn [...leftKeys].every((key) => rightKeys.has(key));\n}\n\n/**\n * Оставляет только доступные координаты и приводит их к порядку строк/колонок.\n *\n * Функция не мутирует входные массивы. В `single` последняя координата в\n * детерминированном порядке становится единственным выбранным значением.\n */\nexport function pruneTableCellSelection(\n\tselection: TableCellSelectionState | undefined,\n\tavailableRowIds: readonly string[],\n\tavailableColumnIds: readonly string[],\n\tselectionMode: TableCellSelectionMode\n): TableCellCoordinates[] {\n\tif (selectionMode === TABLE_SELECTION_MODE_NONE || !selection?.length) {\n\t\treturn [];\n\t}\n\n\tconst rowOrder = new Map(availableRowIds.map((rowId, index) => [rowId, index]));\n\tconst columnOrder = new Map(availableColumnIds.map((columnId, index) => [columnId, index]));\n\tconst seen = new Set<string>();\n\tconst nextSelection = selection\n\t\t.filter((cell) => {\n\t\t\tif (!(rowOrder.has(cell.rowId) && columnOrder.has(cell.columnId))) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst key = buildTableCellKey(cell);\n\t\t\tif (seen.has(key)) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tseen.add(key);\n\t\t\treturn true;\n\t\t})\n\t\t.sort((left, right) => {\n\t\t\tconst rowDelta = (rowOrder.get(left.rowId) ?? 0) - (rowOrder.get(right.rowId) ?? 0);\n\t\t\tif (rowDelta !== 0) {\n\t\t\t\treturn rowDelta;\n\t\t\t}\n\n\t\t\treturn (columnOrder.get(left.columnId) ?? 0) - (columnOrder.get(right.columnId) ?? 0);\n\t\t});\n\n\tif (selectionMode === TABLE_SELECTION_MODE_SINGLE) {\n\t\tconst lastCell = nextSelection.at(-1);\n\t\treturn lastCell ? [lastCell] : [];\n\t}\n\n\treturn nextSelection;\n}\n\n/**\n * Вычисляет следующее состояние после активации ячейки.\n *\n * Одиночный выбор допускает явное снятие повторной активацией, а `multi`\n * переключает только переданную координату.\n */\nexport function toggleTableCellSelection(\n\tselection: TableCellSelectionState,\n\tcell: TableCellCoordinates,\n\tselectionMode: TableCellSelectionMode\n): TableCellCoordinates[] {\n\tif (selectionMode === TABLE_SELECTION_MODE_NONE) {\n\t\treturn [];\n\t}\n\n\tconst cellKey = buildTableCellKey(cell);\n\tconst hasCell = selection.some((item) => buildTableCellKey(item) === cellKey);\n\n\tif (selectionMode === TABLE_SELECTION_MODE_SINGLE) {\n\t\treturn hasCell ? [] : [cell];\n\t}\n\n\treturn hasCell ? selection.filter((item) => buildTableCellKey(item) !== cellKey) : [...selection, cell];\n}\n\n/** Нормализует способ активации ячейки на внешней config-boundary. */\nexport function normalizeTableCellSelectionActivationMode(\n\tvalue: unknown,\n\tfallback: TableCellSelectionActivationMode = TABLE_CELL_SELECTION_ACTIVATION_DIRECT\n): TableCellSelectionActivationMode {\n\treturn typeof value === \"string\" && TABLE_CELL_SELECTION_ACTIVATION_MODES.has(value as TableCellSelectionActivationMode)\n\t\t? (value as TableCellSelectionActivationMode)\n\t\t: fallback;\n}\n\n/**\n * Проверяет, должно ли событие активировать выбор ячейки.\n *\n * Для `primary-modifier` принимается Ctrl или Command, но не комбинации с\n * Shift/Alt: они зарезервированы браузером, ОС и стандартными selection-flow.\n */\nexport function shouldActivateTableCellSelection(\n\tevent: TableSelectionModifierEvent,\n\tactivationMode: TableCellSelectionActivationMode\n): boolean {\n\tif (activationMode === TABLE_CELL_SELECTION_ACTIVATION_DIRECT) {\n\t\treturn true;\n\t}\n\n\treturn (event.ctrlKey || event.metaKey) && !event.shiftKey && !event.altKey;\n}\n","/** Значения выравнивания общие для metadata-адаптера и публичного типа колонки. */\nexport const TABLE_COLUMN_ALIGN_LEFT = \"left\";\nexport const TABLE_COLUMN_ALIGN_CENTER = \"center\";\nexport const TABLE_COLUMN_ALIGN_RIGHT = \"right\";\n","import { type FormattersPipelineTypedValueContext } from \"../formatters/pipeline\";\nimport { SCALAR_ROLE_MEASURE } from \"../metadata/scalarTypeConstants\";\nimport { type EntityColumnProperty } from \"../odata-service\";\n\nimport { TABLE_COLUMN_ALIGN_LEFT, TABLE_COLUMN_ALIGN_RIGHT } from \"./tableColumnConstants\";\nimport { type TableColumnAlign, type TableColumnDef, type TableColumnFormattingMetaInput } from \"./types\";\n\n/**\n * Опции генерации колонок по OData metadata.\n */\nexport interface CreateTableColumnsFromODataMetadataOptions {\n\t/**\n\t * Позволяет переопределить заголовок колонки.\n\t */\n\tresolveHeader?: (column: EntityColumnProperty) => string;\n\t/**\n\t * Позволяет сразу навесить formatting-конфиг на generated column.\n\t *\n\t * `id`, `role` и `type` будут автоматически получены из metadata.\n\t */\n\tresolveFormatting?: (column: EntityColumnProperty) => TableColumnFormattingMetaInput | undefined;\n}\n\n/**\n * Опции обогащения уже существующих колонок данными OData metadata.\n */\nexport interface EnrichTableColumnsWithODataFormattingOptions {\n\t/**\n\t * Позволяет подменить стратегию поиска metadata по колонке.\n\t */\n\tresolveMetadataColumn?: (args: {\n\t\tcolumnId: string;\n\t\tmetadataColumnsById: ReadonlyMap<string, EntityColumnProperty>;\n\t}) => EntityColumnProperty | undefined;\n}\n\n/**\n * Опции построения стартовой карты видимости колонок по OData metadata.\n */\nexport interface CreateTableColumnVisibilityFromODataMetadataOptions {\n\t/**\n\t * Позволяет явно переопределить стартовую видимость колонки.\n\t */\n\tresolveVisible?: (column: EntityColumnProperty) => boolean;\n}\n\n/**\n * Возвращает typed-formatting контекст по metadata OData-колонки.\n */\nexport function resolveTableColumnFormattingContextFromODataColumn(column: EntityColumnProperty): FormattersPipelineTypedValueContext {\n\tconst { role, type } = column;\n\tconst forceMeasure = type === \"decimal\" || type === \"float\" || type === \"double\" || type === \"int\" || type === \"byte\";\n\n\treturn {\n\t\trole: forceMeasure ? SCALAR_ROLE_MEASURE : role,\n\t\ttype: type\n\t};\n}\n\n/**\n * Создаёт базовое выравнивание по семантике OData-колонки.\n *\n * NOTE: \"не аналитические\" все поля возвращают как \"dimension\"...\n */\nfunction resolveTableColumnAlignFromODataColumn(columnContext: FormattersPipelineTypedValueContext): TableColumnAlign {\n\treturn columnContext.role === SCALAR_ROLE_MEASURE ? TABLE_COLUMN_ALIGN_RIGHT : TABLE_COLUMN_ALIGN_LEFT;\n}\n\n/**\n * Определяет видимость metadata-колонки по умолчанию.\n *\n * Кодовые поля скрываются только если у них есть явная text-пара,\n * чтобы экран по умолчанию показывал человекочитаемое значение.\n */\nfunction resolveMetadataColumnVisibleByDefault(\n\tcolumn: EntityColumnProperty,\n\tmetadataColumnsById: ReadonlyMap<string, EntityColumnProperty>\n): boolean {\n\tif (column.semanticType !== \"code\" || !column.linkedColumnId) {\n\t\treturn true;\n\t}\n\n\tconst linkedColumn = metadataColumnsById.get(column.linkedColumnId);\n\n\treturn linkedColumn?.semanticType !== \"text\";\n}\n\n/**\n * Определяет стабильный идентификатор колонки для сопоставления с metadata.\n */\nexport function resolveStableColumnId<TData extends object>(column: TableColumnDef<TData>): string | undefined {\n\tif (typeof column.id === \"string\" && column.id.trim()) {\n\t\treturn column.id;\n\t}\n\n\tif (\"accessorKey\" in column && typeof column.accessorKey === \"string\" && column.accessorKey.trim()) {\n\t\treturn column.accessorKey;\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Рекурсивно обходит только leaf-колонки.\n */\nfunction mapLeafTableColumns<TData extends object>(\n\tcolumns: readonly TableColumnDef<TData>[],\n\tmapper: (column: TableColumnDef<TData>) => TableColumnDef<TData>\n): TableColumnDef<TData>[] {\n\treturn columns.map((column) => {\n\t\tif (\"columns\" in column && Array.isArray(column.columns) && column.columns.length > 0) {\n\t\t\treturn {\n\t\t\t\t...column,\n\t\t\t\tcolumns: mapLeafTableColumns(column.columns as TableColumnDef<TData>[], mapper)\n\t\t\t};\n\t\t}\n\n\t\treturn mapper(column);\n\t});\n}\n\n/**\n * Строит стартовую карту видимости колонок из metadata OData-сущности.\n *\n * Возвращает visibility-state для TanStack Table, не удаляя сами колонки\n * из результата build-режима.\n */\nexport function createTableColumnVisibilityFromODataMetadata(\n\tmetadataColumns: readonly EntityColumnProperty[],\n\toptions?: CreateTableColumnVisibilityFromODataMetadataOptions\n): Record<string, boolean> {\n\tconst metadataColumnsById = new Map(metadataColumns.map((column) => [column.id, column]));\n\n\treturn Object.fromEntries(\n\t\tmetadataColumns.map((column) => {\n\t\t\tconst visible = options?.resolveVisible?.(column) ?? resolveMetadataColumnVisibleByDefault(column, metadataColumnsById);\n\n\t\t\treturn [column.id, visible];\n\t\t})\n\t);\n}\n\n/**\n * Создаёт базовые generic-колонки из metadata OData-сущности.\n */\nexport function createTableColumnsFromODataMetadata<TData extends object = Record<string, unknown>>(\n\tmetadataColumns: readonly EntityColumnProperty[],\n\toptions?: CreateTableColumnsFromODataMetadataOptions\n): TableColumnDef<TData>[] {\n\treturn metadataColumns.map((metadataColumn) => {\n\t\t// NOTE: Ячейка сама определит выравнивание, `align` только для переопределения\n\t\tconst columnContext = resolveTableColumnFormattingContextFromODataColumn(metadataColumn);\n\t\tconst align = resolveTableColumnAlignFromODataColumn(columnContext);\n\t\tconst resolvedFormatting = options?.resolveFormatting?.(metadataColumn);\n\n\t\treturn {\n\t\t\tid: metadataColumn.id,\n\t\t\taccessorKey: metadataColumn.id,\n\t\t\theader: options?.resolveHeader?.(metadataColumn) ?? metadataColumn.label ?? metadataColumn.id,\n\t\t\tmeta: {\n\t\t\t\talign,\n\t\t\t\tformatting: {\n\t\t\t\t\t...resolvedFormatting,\n\t\t\t\t\tid: metadataColumn.id,\n\t\t\t\t\trole: columnContext.role,\n\t\t\t\t\ttype: columnContext.type\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}) as TableColumnDef<TData>[];\n}\n\n/**\n * Дозаполняет уже существующие колонки typed-formatting контекстом из OData metadata.\n */\nexport function enrichTableColumnsWithODataFormatting<TData extends object>(\n\tcolumns: readonly TableColumnDef<TData>[],\n\tmetadataColumns: readonly EntityColumnProperty[],\n\toptions?: EnrichTableColumnsWithODataFormattingOptions\n): TableColumnDef<TData>[] {\n\tconst metadataColumnsById = new Map(metadataColumns.map((column) => [column.id, column]));\n\n\treturn mapLeafTableColumns(columns, (column) => {\n\t\tconst columnId = resolveStableColumnId(column);\n\t\tif (!columnId) {\n\t\t\treturn column;\n\t\t}\n\n\t\tconst metadataColumn =\n\t\t\toptions?.resolveMetadataColumn?.({\n\t\t\t\tcolumnId,\n\t\t\t\tmetadataColumnsById\n\t\t\t}) ?? metadataColumnsById.get(columnId);\n\n\t\tif (!metadataColumn) {\n\t\t\treturn column;\n\t\t}\n\n\t\tif (column.meta?.formatting?.role && column.meta.formatting.type) {\n\t\t\treturn column;\n\t\t}\n\t\tconst columnContext = resolveTableColumnFormattingContextFromODataColumn(metadataColumn);\n\n\t\treturn {\n\t\t\t...column,\n\t\t\tmeta: {\n\t\t\t\t...column.meta,\n\t\t\t\tformatting: {\n\t\t\t\t\t...column.meta?.formatting,\n\t\t\t\t\tid: columnId,\n\t\t\t\t\trole: columnContext.role,\n\t\t\t\t\ttype: columnContext.type\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n","import { type RowSelectionState } from \"@tanstack/react-table\";\n\nimport { TABLE_SELECTION_MODE_MULTI, TABLE_SELECTION_MODE_NONE, TABLE_SELECTION_MODE_SINGLE } from \"./tableSelectionConstants\";\nimport { type TableSelectionMode } from \"./types\";\n\nconst TABLE_SELECTION_MODES: ReadonlySet<TableSelectionMode> = new Set([\n\tTABLE_SELECTION_MODE_NONE,\n\tTABLE_SELECTION_MODE_SINGLE,\n\tTABLE_SELECTION_MODE_MULTI\n]);\n\n/**\n * Возвращает только активные идентификаторы выбранных строк.\n */\nfunction getSelectedRowIds(selection: RowSelectionState): string[] {\n\treturn Object.keys(selection).filter((rowId) => selection[rowId]);\n}\n\n/** Проверяет равенство активных row-selection идентификаторов без учёта порядка ключей. */\nexport function areTableRowSelectionsEqual(left: RowSelectionState, right: RowSelectionState): boolean {\n\tconst leftRowIds = getSelectedRowIds(left);\n\tconst rightRowIds = getSelectedRowIds(right);\n\n\tif (leftRowIds.length !== rightRowIds.length) {\n\t\treturn false;\n\t}\n\n\treturn leftRowIds.every((rowId) => right[rowId]);\n}\n\n/** Нормализует неизвестное значение режима выбора строк на внешней config-boundary. */\nexport function normalizeTableSelectionMode(value: unknown, fallback: TableSelectionMode = TABLE_SELECTION_MODE_NONE): TableSelectionMode {\n\treturn typeof value === \"string\" && TABLE_SELECTION_MODES.has(value as TableSelectionMode) ? (value as TableSelectionMode) : fallback;\n}\n\n/**\n * Нормализует состояние выбора относительно списка доступных строк и текущего режима.\n */\nexport function pruneTableRowSelection(\n\tselection: RowSelectionState,\n\tavailableRowIds: readonly string[],\n\tselectionMode: TableSelectionMode\n): RowSelectionState {\n\tif (selectionMode === TABLE_SELECTION_MODE_NONE) {\n\t\treturn {};\n\t}\n\n\tconst availableRowIdSet = new Set(availableRowIds);\n\tconst selectedRowIds = getSelectedRowIds(selection).filter((rowId) => availableRowIdSet.has(rowId));\n\n\tif (selectionMode === TABLE_SELECTION_MODE_SINGLE) {\n\t\tconst lastSelectedRowId = selectedRowIds.at(-1);\n\n\t\treturn lastSelectedRowId ? { [lastSelectedRowId]: true } : {};\n\t}\n\n\treturn Object.fromEntries(selectedRowIds.map((rowId) => [rowId, true]));\n}\n\n/**\n * Вычисляет следующее состояние выбора после активации строки пользователем.\n *\n * Семантика:\n * - `none` не хранит выбор;\n * - `single` всегда оставляет только одну строку и не снимает выбор повторным кликом;\n * - `multi` переключает строку как toggle.\n */\nexport function toggleTableRowSelection(selection: RowSelectionState, rowId: string, selectionMode: TableSelectionMode): RowSelectionState {\n\tif (selectionMode === TABLE_SELECTION_MODE_NONE) {\n\t\treturn {};\n\t}\n\n\tif (selectionMode === TABLE_SELECTION_MODE_SINGLE) {\n\t\tconst selectedRowIds = getSelectedRowIds(selection);\n\t\treturn selectedRowIds.length === 1 && selectedRowIds[0] === rowId ? selection : { [rowId]: true };\n\t}\n\n\tif (selection[rowId]) {\n\t\tconst nextSelection = { ...selection };\n\n\t\tdelete nextSelection[rowId];\n\n\t\treturn nextSelection;\n\t}\n\n\treturn {\n\t\t...selection,\n\t\t[rowId]: true\n\t};\n}\n","import {\n\tcolumnOrderingFeature,\n\tcolumnPinningFeature,\n\tcolumnResizingFeature,\n\tcolumnSizingFeature,\n\tcolumnVisibilityFeature,\n\tcreateExpandedRowModel,\n\trowExpandingFeature,\n\trowSelectionFeature,\n\ttableFeatures\n} from \"@tanstack/react-table\";\n\n/**\n * Единый набор TanStack Table v9 features для foundation-таблиц.\n *\n * Контракт хранится в `lib`, чтобы определения колонок, строк и экземпляров\n * таблицы в `lib` и `ui` всегда использовали один и тот же набор generic-типов.\n */\nexport const foundationTableFeatures = tableFeatures({\n\tcolumnOrderingFeature,\n\tcolumnPinningFeature,\n\tcolumnSizingFeature,\n\tcolumnResizingFeature,\n\tcolumnVisibilityFeature,\n\trowSelectionFeature,\n\trowExpandingFeature,\n\texpandedRowModel: createExpandedRowModel()\n});\n\n/** Generic-контракт features для публичных типов foundation-таблиц. */\nexport type FoundationTableFeatures = typeof foundationTableFeatures;\n","import { useCallback, useEffect, useEffectEvent, useRef, useState } from \"react\";\n\nimport { type RowSelectionState } from \"@tanstack/react-table\";\n\nimport { pruneTableRowSelection, toggleTableRowSelection } from \"./selection\";\nimport { TABLE_SELECTION_MODE_NONE } from \"./tableSelectionConstants\";\nimport { type TableSelectionMode } from \"./types\";\n\ninterface UseTableRowSelectionParams<TData extends object> {\n\tavailableRowIds: readonly string[];\n\trowById: ReadonlyMap<string, TData>;\n\tselectionMode: TableSelectionMode;\n\tselectedRowIds?: readonly string[];\n\tonRowSelectionChange?: (rows: TData[]) => void;\n}\n\n/**\n * Общая модель выбора строк для плоской и древовидной таблиц.\n */\nexport function useTableRowSelection<TData extends object>({\n\tavailableRowIds,\n\trowById,\n\tselectionMode,\n\tselectedRowIds,\n\tonRowSelectionChange\n}: UseTableRowSelectionParams<TData>) {\n\tconst [rowSelection, setRowSelection] = useState<RowSelectionState>({});\n\tconst shouldSkipNextSelectionEmitRef = useRef(false);\n\n\t/**\n\t * Сравнивает состояния выбора без лишних перерисовок.\n\t */\n\tconst areSelectionsEqual = useCallback((left: RowSelectionState, right: RowSelectionState) => {\n\t\tconst leftRowIds = Object.keys(left).filter((rowId) => left[rowId]);\n\t\tconst rightRowIds = Object.keys(right).filter((rowId) => right[rowId]);\n\n\t\tif (leftRowIds.length !== rightRowIds.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn leftRowIds.every((rowId) => right[rowId]);\n\n\t\t/*\n\n Более оптимизированная версия, но для текущего случая может быть практически незначительной\n\n let leftCount = 0;\n\t\tlet rightCount = 0;\n\n\t\tfor (const rowId of Object.keys(left)) {\n\t\t\tif (!left[rowId]) continue;\n\t\t\tleftCount += 1;\n\t\t\tif (!right[rowId]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfor (const rowId of Object.keys(right)) {\n\t\t\tif (right[rowId]) {\n\t\t\t\trightCount += 1;\n\t\t\t}\n\t\t}\n\n\t\tif (leftCount !== rightCount) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\n */\n\t}, []);\n\n\tconst syncRowSelectionState = useEffectEvent((nextAvailableRowIds: readonly string[]) => {\n\t\tsetRowSelection((currentSelection) => pruneTableRowSelection(currentSelection, nextAvailableRowIds, selectionMode));\n\t});\n\n\tconst syncControlledRowSelectionState = useEffectEvent(\n\t\t(nextSelectedRowIds: readonly string[], nextAvailableRowIds: readonly string[]) => {\n\t\t\tconst nextSelection = pruneTableRowSelection(\n\t\t\t\tObject.fromEntries(nextSelectedRowIds.map((rowId) => [rowId, true])),\n\t\t\t\tnextAvailableRowIds,\n\t\t\t\tselectionMode\n\t\t\t);\n\n\t\t\tsetRowSelection((currentSelection) => {\n\t\t\t\tif (areSelectionsEqual(currentSelection, nextSelection)) {\n\t\t\t\t\treturn currentSelection;\n\t\t\t\t}\n\n\t\t\t\t// Пропускаем следующий emit, потому что это синхронизация от внешнего controlled-состояния,\n\t\t\t\t// а не пользовательское изменение выбора внутри таблицы.\n\t\t\t\tshouldSkipNextSelectionEmitRef.current = true;\n\n\t\t\t\treturn nextSelection;\n\t\t\t});\n\t\t}\n\t);\n\n\tconst emitRowSelectionChange = useEffectEvent((currentSelection: RowSelectionState) => {\n\t\tif (!onRowSelectionChange) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst selectedRows: TData[] = [];\n\n\t\tfor (const rowId of Object.keys(currentSelection)) {\n\t\t\tif (!currentSelection[rowId]) continue;\n\n\t\t\tconst row = rowById.get(rowId);\n\t\t\tif (row) {\n\t\t\t\tselectedRows.push(row);\n\t\t\t}\n\t\t}\n\n\t\tonRowSelectionChange(selectedRows);\n\t});\n\n\tuseEffect(() => {\n\t\tif (selectedRowIds !== undefined) {\n\t\t\tsyncControlledRowSelectionState(selectedRowIds, availableRowIds);\n\t\t\treturn;\n\t\t}\n\n\t\tsyncRowSelectionState(availableRowIds);\n\t}, [availableRowIds, selectedRowIds, selectionMode]);\n\n\tuseEffect(() => {\n\t\tif (shouldSkipNextSelectionEmitRef.current) {\n\t\t\tshouldSkipNextSelectionEmitRef.current = false;\n\t\t\treturn;\n\t\t}\n\n\t\temitRowSelectionChange(rowSelection);\n\t}, [rowSelection]);\n\n\t/**\n\t * Применяет изменение выбора при активации конкретной строки.\n\t */\n\tconst activateRowSelection = useCallback(\n\t\t(rowId: string, canSelect: boolean) => {\n\t\t\tif (selectionMode === TABLE_SELECTION_MODE_NONE || !canSelect) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetRowSelection((currentSelection) => toggleTableRowSelection(currentSelection, rowId, selectionMode));\n\t\t},\n\t\t[selectionMode]\n\t);\n\n\treturn {\n\t\trowSelection,\n\t\tsetRowSelection,\n\t\tactivateRowSelection\n\t};\n}\n","import { TableColumnDef, TableColumnFormattingMeta, TableColumnMeta } from \"./types\";\n\n/**\n * Интерактивные descendants, действие которых таблица не должна подменять\n * выбором строки или ячейки.\n *\n * `td`, `th` и `tr` намеренно исключены из tabindex-ветки: сама таблица может\n * использовать roving tabindex для selection, не превращая ячейку в nested control.\n */\nconst TABLE_INTERACTIVE_ELEMENT_SELECTOR = [\n\t\"button\",\n\t\"a\",\n\t\"input\",\n\t\"select\",\n\t\"textarea\",\n\t\"label\",\n\t\"summary\",\n\t\"audio[controls]\",\n\t\"video[controls]\",\n\t'[contenteditable]:not([contenteditable=\"false\"])',\n\t\"[tabindex]:not(td):not(th):not(tr)\",\n\t'[draggable=\"true\"]',\n\t'[role=\"button\"]',\n\t'[role=\"link\"]',\n\t'[role=\"checkbox\"]',\n\t'[role=\"radio\"]',\n\t'[role=\"switch\"]',\n\t'[role=\"menu\"]',\n\t'[role=\"menuitem\"]',\n\t'[role=\"menuitemcheckbox\"]',\n\t'[role=\"menuitemradio\"]',\n\t'[role=\"listbox\"]',\n\t'[role=\"option\"]',\n\t'[role=\"tab\"]',\n\t'[role=\"tablist\"]',\n\t'[role=\"tree\"]',\n\t'[role=\"treeitem\"]',\n\t'[role=\"slider\"]',\n\t'[role=\"spinbutton\"]',\n\t'[role=\"textbox\"]',\n\t'[role=\"searchbox\"]',\n\t'[role=\"combobox\"]'\n].join(\", \");\n\n/**\n * Возвращает метаданные колонки таблицы.\n */\nexport function getTableColumnMeta<TData extends object>(column: TableColumnDef<TData>): TableColumnMeta | undefined {\n\treturn column.meta;\n}\n\n/**\n * Возвращает форматирующий блок метаданных колонки.\n */\nexport function getTableColumnFormattingMeta<TData extends object>(column: TableColumnDef<TData>): TableColumnFormattingMeta | undefined {\n\treturn column.meta?.formatting;\n}\n\n/**\n * Нормализует размер таблицы.\n *\n * Числовое значение трактуется как `em`, чтобы разметка масштабировалась вместе со шрифтом.\n */\nexport function resolveTableLength(length: string | number): string {\n\tif (typeof length === \"number\") {\n\t\treturn `${length}em`;\n\t}\n\n\treturn length;\n}\n\n/**\n * Определяет, пришёл ли клик из интерактивного элемента внутри таблицы.\n * Учитывает только элементы внутри ближайшей строки: фокусируемая вкладка или\n * диалог вокруг таблицы не должны перехватывать выбор её строк.\n */\nexport function isTableInteractiveElement(target: EventTarget | null, extraSelector?: string): boolean {\n\tif (typeof Element === \"undefined\" || !(target instanceof Element)) {\n\t\treturn false;\n\t}\n\n\tconst selector = extraSelector ? `${TABLE_INTERACTIVE_ELEMENT_SELECTOR}, ${extraSelector}` : TABLE_INTERACTIVE_ELEMENT_SELECTOR;\n\tconst interactiveElement = target.closest(selector);\n\tif (!interactiveElement) return false;\n\n\tconst row = target.closest(\"tr\");\n\treturn !row || row.contains(interactiveElement);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Возвращает сумму определённых ширин колонок без измерения DOM.
|
|
3
|
+
*
|
|
4
|
+
* em сохраняются в CSS, поэтому таблица масштабируется вместе со шрифтом уже
|
|
5
|
+
* при SSR. auto и проценты требуют доступной ширины и остаются в ведении
|
|
6
|
+
* браузерной раскладки: для них нельзя получить независимую сумму колонок.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveTableColumnsWidth(widths: readonly string[]): string | undefined;
|
|
9
|
+
//# sourceMappingURL=resolveTableColumnsWidth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveTableColumnsWidth.d.ts","sourceRoot":"","sources":["../../src/table/resolveTableColumnsWidth.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAMtF"}
|
package/dist/table/types.d.ts
CHANGED
|
@@ -66,7 +66,7 @@ export interface TableColumnMeta {
|
|
|
66
66
|
*
|
|
67
67
|
* Строка используется как CSS-значение, число трактуется как `em`.
|
|
68
68
|
*/
|
|
69
|
-
width?: number | "auto" | `${number}
|
|
69
|
+
width?: number | "auto" | `${number}%` | `${number}px` | `${number}em`;
|
|
70
70
|
/**
|
|
71
71
|
* Выравнивание содержимого заголовка и ячеек.
|
|
72
72
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/table/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,IAAI,EACT,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACX,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,UAAU,EACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,KAAK,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AAE7E,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,uBAAuB,EAAE,KAAK,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AACrI,OAAO,EACN,KAAK,sCAAsC,EAC3C,KAAK,gDAAgD,EACrD,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,yBAAyB,GAAG,OAAO,2BAA2B,GAAG,OAAO,0BAA0B,CAAC;AAE3I;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,CAAC;AAExD;;;;;GAKG;AACH,MAAM,MAAM,gCAAgC,GAC3C,OAAO,sCAAsC,GAAG,OAAO,gDAAgD,CAAC;AAEzG,kFAAkF;AAClF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAEH,4CAA4C;AAC5C,MAAM,MAAM,uBAAuB,GAAG,SAAS,oBAAoB,EAAE,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IAClD,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CAChB,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,uBAAuB,GAAG,OAAO,yBAAyB,GAAG,OAAO,wBAAwB,CAAC;AAEnI,KAAK,4BAA4B,GAAG,IAAI,CACvC,8BAA8B,EAC9B,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,iBAAiB,GAAG,4BAA4B,CACzE,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,yBAAyB,GAAG,4BAA4B,GACnE,OAAO,CAAC,IAAI,CAAC,8BAA8B,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;AAEvE;;;GAGG;AACH,MAAM,MAAM,8BAA8B,GAAG,4BAA4B,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/table/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/formulas/README.mdx
CHANGED
|
@@ -6,7 +6,7 @@ import { Meta } from "@storybook/addon-docs/blocks";
|
|
|
6
6
|
|
|
7
7
|
Модуль `@ryuzaki13/react-foundation-lib/formulas` предоставляет безопасную инфраструктуру для заранее написанных клиентских формул таблицы.
|
|
8
8
|
|
|
9
|
-
Формула получает значения полей текущей строки и числовые
|
|
9
|
+
Формула получает значения полей текущей строки и числовые константы либо заранее подготовленные host-приложением позиции, выполняет синхронный расчёт и возвращает конечное JavaScript-число. Например, она может вычислить сумму, разницу, отношение или процент для calculated-колонки.
|
|
10
10
|
|
|
11
11
|
```text
|
|
12
12
|
данные строки + упорядоченные зависимости
|
|
@@ -30,6 +30,7 @@ import { Meta } from "@storybook/addon-docs/blocks";
|
|
|
30
30
|
- [Чтение активного реестра](#чтение-активного-реестра)
|
|
31
31
|
- [Выполнение формулы](#выполнение-формулы)
|
|
32
32
|
- [Предварительная компиляция](#предварительная-компиляция)
|
|
33
|
+
- [Заранее разрешённые аргументы](#заранее-разрешённые-аргументы)
|
|
33
34
|
- [Валидация зависимостей](#валидация-зависимостей)
|
|
34
35
|
- [Интеграция с formatter pipeline](#интеграция-с-formatter-pipeline)
|
|
35
36
|
- [Отличие от row-based formatter](#отличие-от-row-based-formatter)
|
|
@@ -50,6 +51,7 @@ import { Meta } from "@storybook/addon-docs/blocks";
|
|
|
50
51
|
- хранит один активный реестр в текущем экземпляре модуля;
|
|
51
52
|
- выполняет формулы без выбрасывания их runtime-ошибок наружу;
|
|
52
53
|
- компилирует formula + keys в переиспользуемый executor;
|
|
54
|
+
- исполняет ту же зарегистрированную функцию над готовыми позиционными значениями без промежуточных полей строки;
|
|
53
55
|
- проверяет существование формулы и корректность выбранных dependencies;
|
|
54
56
|
- сообщает, какие dependency indexes реально использовала формула на тестовых данных.
|
|
55
57
|
|
|
@@ -68,7 +70,7 @@ import { Meta } from "@storybook/addon-docs/blocks";
|
|
|
68
70
|
|
|
69
71
|
Host-приложение владеет прикладными `TableFormulaDefinition`: оно объявляет их в коде, тестирует, собирает в реестр и устанавливает на старте приложения.
|
|
70
72
|
|
|
71
|
-
|
|
73
|
+
В row-only API сериализуемая конфигурация колонки хранит стабильный `formulaId` и ordered dependencies. Реальная функция остаётся доверенным кодом приложения.
|
|
72
74
|
|
|
73
75
|
## Импорт
|
|
74
76
|
|
|
@@ -77,16 +79,21 @@ Host-приложение владеет прикладными `TableFormulaDef
|
|
|
77
79
|
```ts
|
|
78
80
|
import {
|
|
79
81
|
compileTableFormula,
|
|
82
|
+
compileTableFormulaWithResolvedArguments,
|
|
80
83
|
configureTableFormulaRegistry,
|
|
81
84
|
createTableFormulaRegistry,
|
|
82
85
|
executeTableFormula,
|
|
86
|
+
executeTableFormulaWithResolvedArguments,
|
|
83
87
|
getTableFormulaById,
|
|
84
88
|
getTableFormulaList,
|
|
85
89
|
formatTableFormulaExpression,
|
|
86
|
-
validateTableFormulaDependencies
|
|
90
|
+
validateTableFormulaDependencies,
|
|
91
|
+
type TableFormulaDefinition,
|
|
92
|
+
type TableFormulaExecutionResult,
|
|
93
|
+
type TableFormulaRegistry,
|
|
94
|
+
type TableFormulaResolvedArgument,
|
|
95
|
+
type TableFormulaResolvedExecutor
|
|
87
96
|
} from "@ryuzaki13/react-foundation-lib/formulas";
|
|
88
|
-
|
|
89
|
-
import type { TableFormulaDefinition, TableFormulaExecutionResult, TableFormulaRegistry } from "@ryuzaki13/react-foundation-lib/formulas";
|
|
90
97
|
```
|
|
91
98
|
|
|
92
99
|
Корневой импорт пакета и private imports из исходников не поддерживаются:
|
|
@@ -365,7 +372,7 @@ interface TableFormulaContext {
|
|
|
365
372
|
|
|
366
373
|
### `ctx.key(index)`
|
|
367
374
|
|
|
368
|
-
|
|
375
|
+
В row-only API возвращает id dependency по индексу:
|
|
369
376
|
|
|
370
377
|
```ts
|
|
371
378
|
// keys = ["planned", "actual"]
|
|
@@ -380,6 +387,8 @@ ctx.key(1.5); // undefined
|
|
|
380
387
|
|
|
381
388
|
Пустая строка технически может вернуться из `key`, если она была передана в `keys`, но `value` и `num` считают пустой key отсутствующим. Используйте только непустые dependency ids.
|
|
382
389
|
|
|
390
|
+
Для [заранее разрешённых аргументов](#заранее-разрешённые-аргументы) key передаёт host; он не используется для поиска значения в строке.
|
|
391
|
+
|
|
383
392
|
### `ctx.value(index)`
|
|
384
393
|
|
|
385
394
|
Возвращает исходное значение без преобразования:
|
|
@@ -389,7 +398,7 @@ ctx.key(1.5); // undefined
|
|
|
389
398
|
ctx.value(1); // "25"
|
|
390
399
|
```
|
|
391
400
|
|
|
392
|
-
|
|
401
|
+
В row-only API для константы возвращается непосредственно её числовое значение. Для неправильного индекса, пустого key или отсутствующего свойства возвращается `undefined`. Для готовых позиций действуют [правила разрешённых аргументов](#заранее-разрешённые-аргументы).
|
|
393
402
|
|
|
394
403
|
Используйте `value`, когда нужно отличать отсутствующее значение от нуля или применять собственный parser:
|
|
395
404
|
|
|
@@ -809,9 +818,69 @@ if (compiled.ok) {
|
|
|
809
818
|
|
|
810
819
|
### Синхронность и повторный вход
|
|
811
820
|
|
|
812
|
-
|
|
821
|
+
Executor `compileTableFormula` переиспользует один context с изменяемой внутренней ссылкой на `rowData`. Это безопасно для обычной синхронной формулы.
|
|
822
|
+
|
|
823
|
+
Не делайте formula `async`, не сохраняйте `ctx` во внешнем state и не запускайте тот же row-only executor рекурсивно из formula. Такой код нарушает lifecycle переиспользуемого context. Отдельный контракт повторного входа для готовых позиций описан ниже.
|
|
824
|
+
|
|
825
|
+
## Заранее разрешённые аргументы
|
|
826
|
+
|
|
827
|
+
Когда значения относятся к разным строкам или вычисляются host-приложением, передайте их в позициях непосредственно. Используются существующие `TableFormulaDefinition`, registry и методы `ctx.key`, `ctx.value`, `ctx.num`; новую арифметическую функцию для другого источника писать не требуется.
|
|
828
|
+
|
|
829
|
+
```ts
|
|
830
|
+
type TableFormulaResolvedArgument = {
|
|
831
|
+
readonly value: unknown;
|
|
832
|
+
readonly key?: string;
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
type TableFormulaResolvedExecutor = (resolvedArguments: readonly TableFormulaResolvedArgument[]) => TableFormulaExecutionResult;
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
### Подготовка и выполнение
|
|
839
|
+
|
|
840
|
+
Реестр из быстрого старта уже содержит `sum`. Host получает значения до вызова runtime и сохраняет нужный порядок:
|
|
841
|
+
|
|
842
|
+
```ts
|
|
843
|
+
import {
|
|
844
|
+
compileTableFormulaWithResolvedArguments,
|
|
845
|
+
executeTableFormulaWithResolvedArguments,
|
|
846
|
+
type TableFormulaResolvedArgument
|
|
847
|
+
} from "@ryuzaki13/react-foundation-lib/formulas";
|
|
848
|
+
|
|
849
|
+
const resolvedArguments: readonly TableFormulaResolvedArgument[] = [
|
|
850
|
+
{ value: 20, key: "amount" }, // Поле текущей строки.
|
|
851
|
+
{ value: 100 } // Уже полученное host-ом значение другой строки.
|
|
852
|
+
];
|
|
853
|
+
|
|
854
|
+
const result = executeTableFormulaWithResolvedArguments({ formulaId: "sum", arguments: resolvedArguments });
|
|
855
|
+
// result: { ok: true, value: 120 }
|
|
856
|
+
|
|
857
|
+
const compiled = compileTableFormulaWithResolvedArguments({ formulaId: "sum" });
|
|
858
|
+
|
|
859
|
+
if (compiled.ok) {
|
|
860
|
+
const first = compiled.execute(resolvedArguments);
|
|
861
|
+
const second = compiled.execute([{ value: 30, key: "amount" }, { value: 200 }]);
|
|
862
|
+
// first.value === 120, second.value === 230 при успешном результате.
|
|
863
|
+
}
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
Compile result содержит либо `ok: true` и `execute: TableFormulaResolvedExecutor`, либо `ok: false, reason: "formula_not_found"`. Массив передаётся при каждом execute, а не при compile. Для разового вычисления `executeTableFormulaWithResolvedArguments` выполняет compile и один вызов executor.
|
|
867
|
+
|
|
868
|
+
### Значения, ключи и границы
|
|
869
|
+
|
|
870
|
+
- `value(index)` возвращает переданный `value` буквально, включая `null`, `undefined`, число или числовую строку. Значение не ищется в `rowData`; `key` не влияет на его чтение.
|
|
871
|
+
- Host задаёт `key` только для поля текущей строки. Для константы и внешнего источника его опускают, поэтому `key(index)` возвращает `undefined`. Не создавайте фиктивные ID вроде `TOTAL:Amount`.
|
|
872
|
+
- Порядок и повторы сохраняются. Для отрицательного, нецелого или вышедшего за массив индекса `key()` и `value()` возвращают `undefined`, `num()` — `0`.
|
|
873
|
+
- `num()` использует [действующее числовое преобразование](#числовое-преобразование-ctxnum). Исключение преобразования даёт `runtime_error`, а не успешный ноль.
|
|
874
|
+
- Каждая позиция содержит собственное поле `value`: `{ value: undefined }` корректен, дырка массива или запись без `value` дают `runtime_error`. Ошибка подготовки не подменяется временным нулём.
|
|
875
|
+
- Используется существующий `TableFormulaExecutionResult`: не конечный результат формулы даёт `invalid_result`, исключение — `runtime_error`. Значения и текст исключения не добавляются в результат ошибки.
|
|
876
|
+
|
|
877
|
+
### Время жизни и ответственность host
|
|
878
|
+
|
|
879
|
+
Compiled executor сохраняет зарегистрированную функцию без массива аргументов. Контекст создаётся для отдельного синхронного вызова, поэтому вложенное выполнение того же executor не подменяет значения внешнего или следующего вызова. Входные массивы и записи не изменяются; значения не нормализуются и не копируются глубоко. Формулы остаются чистыми и синхронными; `ctx` нельзя сохранять для чтения после завершения вызова.
|
|
880
|
+
|
|
881
|
+
Host владеет сериализуемой ссылкой на источник, её доступностью, загрузкой, выбором исходного или вычисленного значения и проверкой циклов. Для ожидания данных он может явно подготовить `{ value: 0 }`, сохраняя состояние загрузки и диагностику отдельно. Runtime не получает DataSource callbacks и не разрешает ИТОГО или родителя самостоятельно.
|
|
813
882
|
|
|
814
|
-
|
|
883
|
+
`TableFormulaDependency`, row-only compile/execute, validator зависимостей, formatter выражения и formatter pipeline сохраняют свои контракты. `validateTableFormulaDependencies` не проверяет адреса внешних источников, а `formatTableFormulaExpression` не строит для них scoped preview. Готовые позиции — вход текущего выполнения, а не новый формат сохранённой конфигурации.
|
|
815
884
|
|
|
816
885
|
## Валидация зависимостей
|
|
817
886
|
|
|
@@ -862,7 +931,7 @@ Validator:
|
|
|
862
931
|
| ------------------------------- | ----------------------------------------------------------- |
|
|
863
932
|
| `formula_not_found` | Formula id отсутствует в registry |
|
|
864
933
|
| `dependency_not_available` | Dependency id отсутствует среди доступных колонок |
|
|
865
|
-
| `invalid_constant` | Константа не содержит конечное числовое значение
|
|
934
|
+
| `invalid_constant` | Константа не содержит конечное числовое значение |
|
|
866
935
|
| `dependency_index_out_of_range` | Formula прочитала index, для которого dependency не передан |
|
|
867
936
|
|
|
868
937
|
### Warnings
|
|
@@ -1165,7 +1234,7 @@ expect(
|
|
|
1165
1234
|
быстрее: compileTableFormula один раз → execute(rowData) для каждой строки
|
|
1166
1235
|
```
|
|
1167
1236
|
|
|
1168
|
-
|
|
1237
|
+
Executor `compileTableFormula` переиспользует context и не делает registry lookup на каждую строку. `compileTableFormulaWithResolvedArguments` также находит функцию один раз, но создаёт отдельный контекст на каждый вызов; значения host подготавливает перед execute.
|
|
1169
1238
|
|
|
1170
1239
|
Formatter pipeline уже использует этот подход: runtime field компилируется на construction-stage.
|
|
1171
1240
|
|
|
@@ -1235,42 +1304,46 @@ Promise не является конечным number и даст `invalid_resul
|
|
|
1235
1304
|
|
|
1236
1305
|
### Runtime functions
|
|
1237
1306
|
|
|
1238
|
-
| API
|
|
1239
|
-
|
|
|
1240
|
-
| `createTableFormulaContext`
|
|
1241
|
-
| `createTableFormulaRegistry`
|
|
1242
|
-
| `configureTableFormulaRegistry`
|
|
1243
|
-
| `getTableFormulaList`
|
|
1244
|
-
| `getTableFormulaById`
|
|
1245
|
-
| `formatTableFormulaExpression`
|
|
1246
|
-
| `compileTableFormula`
|
|
1247
|
-
| `executeTableFormula`
|
|
1248
|
-
| `
|
|
1307
|
+
| API | Назначение | Важное поведение |
|
|
1308
|
+
| ------------------------------------------ | ------------------------------------ | ------------------------------------------------------- |
|
|
1309
|
+
| `createTableFormulaContext` | Создать context вручную | Копирует keys, но не rowData; `num` использует `Number` |
|
|
1310
|
+
| `createTableFormulaRegistry` | Собрать нормализованный registry | Бросает `Error` для пустого/повторного id |
|
|
1311
|
+
| `configureTableFormulaRegistry` | Установить активный registry | Полностью заменяет module-level registry |
|
|
1312
|
+
| `getTableFormulaList` | Получить ordered catalog | Возвращает тот же readonly list |
|
|
1313
|
+
| `getTableFormulaById` | Найти definition | Trim id; `undefined` для пустого/неизвестного |
|
|
1314
|
+
| `formatTableFormulaExpression` | Подставить ID в шаблон превью | Сохраняет незаполненные `$n`; не исполняет выражение |
|
|
1315
|
+
| `compileTableFormula` | Подготовить reusable executor | Фиксирует formula и копирует keys |
|
|
1316
|
+
| `executeTableFormula` | Compile + один execute | Возвращает controlled result, не бросает formula error |
|
|
1317
|
+
| `compileTableFormulaWithResolvedArguments` | Подготовить executor готовых позиций | Фиксирует функцию; аргументы передаются при execute |
|
|
1318
|
+
| `executeTableFormulaWithResolvedArguments` | Выполнить готовые позиции один раз | Использует тот же registry и execution result |
|
|
1319
|
+
| `validateTableFormulaDependencies` | Проверить mapping dependencies | Дважды исполняет formula на synthetic data |
|
|
1249
1320
|
|
|
1250
1321
|
### Публичные TypeScript-типы
|
|
1251
1322
|
|
|
1252
|
-
| Тип | Назначение
|
|
1253
|
-
| ------------------------------------------ |
|
|
1254
|
-
| `TableFormulaRowData` | Строка `Record<string, unknown>`
|
|
1323
|
+
| Тип | Назначение |
|
|
1324
|
+
| ------------------------------------------ | ----------------------------------------------- |
|
|
1325
|
+
| `TableFormulaRowData` | Строка `Record<string, unknown>` |
|
|
1255
1326
|
| `TableFormulaDependency` | ID поля либо объект конечной числовой константы |
|
|
1256
|
-
| `TableFormulaContext` | Методы `key`, `value`, `num`
|
|
1257
|
-
| `TableFormulaFn` | Синхронная function `context → number`
|
|
1258
|
-
| `TableFormulaDefinition` | Metadata и function одной formula
|
|
1259
|
-
| `TableFormulaRegistry` | Readonly `list` + `byId`
|
|
1260
|
-
| `TableFormulaExecutionResult` | Success/error результат execute
|
|
1261
|
-
| `TableFormulaCompiledExecutor` | Переиспользуемый `(rowData) → result`
|
|
1262
|
-
| `
|
|
1263
|
-
| `
|
|
1327
|
+
| `TableFormulaContext` | Методы `key`, `value`, `num` |
|
|
1328
|
+
| `TableFormulaFn` | Синхронная function `context → number` |
|
|
1329
|
+
| `TableFormulaDefinition` | Metadata и function одной formula |
|
|
1330
|
+
| `TableFormulaRegistry` | Readonly `list` + `byId` |
|
|
1331
|
+
| `TableFormulaExecutionResult` | Success/error результат execute |
|
|
1332
|
+
| `TableFormulaCompiledExecutor` | Переиспользуемый `(rowData) → result` |
|
|
1333
|
+
| `TableFormulaResolvedArgument` | Готовое `value` и optional `key` позиции |
|
|
1334
|
+
| `TableFormulaResolvedExecutor` | Переиспользуемый `(resolvedArguments) → result` |
|
|
1335
|
+
| `TableFormulaValidationMessage` | `{ code, message }` validation diagnostics |
|
|
1336
|
+
| `TableFormulaDependenciesValidationResult` | Errors, warnings и usage dependencies |
|
|
1264
1337
|
|
|
1265
1338
|
`ValidationCode`, instrumentation type и compile-result type не экспортируются как именованные публичные типы. Их конкретные значения доступны через публичные function signatures и unions, описанные выше.
|
|
1266
1339
|
|
|
1267
1340
|
### Причины execution error
|
|
1268
1341
|
|
|
1269
|
-
| Reason | Значение
|
|
1270
|
-
| ------------------- |
|
|
1271
|
-
| `formula_not_found` | Formula отсутствует в активном registry
|
|
1272
|
-
| `invalid_result` | Function вернула не конечный number
|
|
1273
|
-
| `runtime_error` |
|
|
1342
|
+
| Reason | Значение |
|
|
1343
|
+
| ------------------- | --------------------------------------------------------------------- |
|
|
1344
|
+
| `formula_not_found` | Formula отсутствует в активном registry |
|
|
1345
|
+
| `invalid_result` | Function вернула не конечный number |
|
|
1346
|
+
| `runtime_error` | Некорректные готовые позиции или исключение выполнения/преобразования |
|
|
1274
1347
|
|
|
1275
1348
|
### Validation codes
|
|
1276
1349
|
|