@open-pioneer/result-list 1.4.0-dev.20260727093741 → 1.4.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/CHANGELOG.md CHANGED
@@ -1,10 +1,15 @@
1
1
  # @open-pioneer/result-list
2
2
 
3
- ## 1.4.0-dev.20260727093741
3
+ ## 1.4.0
4
4
 
5
5
  ### Minor Changes
6
6
 
7
7
  - c30396d: Update Chakra to 3.36.1
8
+ - d862003: Update to trails core-packages 4.7.0
9
+
10
+ ### Patch Changes
11
+
12
+ - c16a401: Migrated from eslint to oxlint and from prettier to oxfmt.
8
13
 
9
14
  ## 1.3.0
10
15
 
@@ -76,6 +81,7 @@
76
81
  ```
77
82
 
78
83
  - 5c2cca2: Fix a11y issues:
84
+
79
85
  - Fix wrong `aria-labelledby` ids
80
86
  - Introduce optional property `labelProperty` to result list's `input` option
81
87
  - A feature's property value is used to provide context in aria attributes.
@@ -1 +1 @@
1
- {"version":3,"file":"ColumnResizer.js","sources":["ColumnResizer.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { chakra } from \"@chakra-ui/react\";\nimport { classNames } from \"@open-pioneer/react-utils\";\nimport { ReactNode } from \"react\";\n\nexport function ColumnResizer(props: {\n onDoubleClick: React.MouseEventHandler<HTMLElement>;\n onMouseDown: React.MouseEventHandler<HTMLElement>;\n onTouchStart: React.TouchEventHandler<HTMLElement>;\n isResizing: boolean;\n}): ReactNode {\n const { onDoubleClick, onMouseDown, onTouchStart, isResizing } = props;\n return (\n <chakra.span\n className={classNames(\n \"result-list-resizer\",\n isResizing && \"result-list-resizer--is-resizing\"\n )}\n aria-hidden=\"true\"\n onDoubleClick={onDoubleClick}\n onMouseDown={onMouseDown}\n onTouchStart={onTouchStart}\n onClick={(e) => e.stopPropagation()}\n />\n );\n}\n"],"names":[],"mappings":";;;;AAMO,SAAS,cAAc,KAAA,EAKhB;AACV,EAAA,MAAM,EAAE,aAAA,EAAe,WAAA,EAAa,YAAA,EAAc,YAAW,GAAI,KAAA;AACjE,EAAA,uBACI,GAAA;AAAA,IAAC,MAAA,CAAO,IAAA;AAAA,IAAP;AAAA,MACG,SAAA,EAAW,UAAA;AAAA,QACP,qBAAA;AAAA,QACA,UAAA,IAAc;AAAA,OAClB;AAAA,MACA,aAAA,EAAY,MAAA;AAAA,MACZ,aAAA;AAAA,MACA,WAAA;AAAA,MACA,YAAA;AAAA,MACA,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,eAAA;AAAgB;AAAA,GACtC;AAER;;;;"}
1
+ {"version":3,"file":"ColumnResizer.js","sources":["ColumnResizer.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { chakra } from \"@chakra-ui/react\";\nimport { classNames } from \"@open-pioneer/react-utils\";\nimport { ReactNode } from \"react\";\n\nexport function ColumnResizer(props: {\n onDoubleClick: React.MouseEventHandler<HTMLElement>;\n onMouseDown: React.MouseEventHandler<HTMLElement>;\n onTouchStart: React.TouchEventHandler<HTMLElement>;\n isResizing: boolean;\n}): ReactNode {\n const { onDoubleClick, onMouseDown, onTouchStart, isResizing } = props;\n return (\n <chakra.span\n className={classNames(\n \"result-list-resizer\",\n isResizing && \"result-list-resizer--is-resizing\"\n )}\n aria-hidden=\"true\"\n onDoubleClick={onDoubleClick}\n onMouseDown={onMouseDown}\n onTouchStart={onTouchStart}\n onClick={(e) => e.stopPropagation()}\n />\n );\n}\n"],"names":[],"mappings":";;;;AAOO,SAAS,cAAc,KAAA,EAKhB;AACV,EAAA,MAAM,EAAE,aAAA,EAAe,WAAA,EAAa,YAAA,EAAc,YAAW,GAAI,KAAA;AACjE,EAAA,uBACI,GAAA;AAAA,IAAC,MAAA,CAAO,IAAA;AAAA,IAAP;AAAA,MACG,SAAA,EAAW,UAAA;AAAA,QACP,qBAAA;AAAA,QACA,UAAA,IAAc;AAAA,OAClB;AAAA,MACA,aAAA,EAAY,MAAA;AAAA,MACZ,aAAA;AAAA,MACA,WAAA;AAAA,MACA,YAAA;AAAA,MACA,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,eAAA;AAAgB;AAAA,GACtC;AAER;;;;"}
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { TbCaretDownFilled, TbCaretUpFilled } from 'react-icons/tb';
3
2
  import { chakra } from '@chakra-ui/react';
3
+ import { TbCaretDownFilled, TbCaretUpFilled } from 'react-icons/tb';
4
4
 
5
5
  function ColumnSortIndicator(props) {
6
6
  const { isSorted } = props;
@@ -1 +1 @@
1
- {"version":3,"file":"ColumnSortIndicator.js","sources":["ColumnSortIndicator.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { TbCaretDownFilled, TbCaretUpFilled } from \"react-icons/tb\";\nimport { chakra } from \"@chakra-ui/react\";\nimport { SortDirection } from \"@tanstack/react-table\";\nimport { ReactNode } from \"react\";\n\nexport function ColumnSortIndicator(props: { isSorted: false | SortDirection }): ReactNode {\n const { isSorted } = props;\n return (\n <chakra.span ml=\"4\" className=\"result-list-sort-indicator\" aria-hidden=\"true\">\n {isSorted ? isSorted === \"desc\" ? <TbCaretDownFilled /> : <TbCaretUpFilled /> : null}\n </chakra.span>\n );\n}\n"],"names":[],"mappings":";;;;AAOO,SAAS,oBAAoB,KAAA,EAAuD;AACvF,EAAA,MAAM,EAAE,UAAS,GAAI,KAAA;AACrB,EAAA,2BACK,MAAA,CAAO,IAAA,EAAP,EAAY,EAAA,EAAG,GAAA,EAAI,WAAU,4BAAA,EAA6B,aAAA,EAAY,QAClE,QAAA,EAAA,QAAA,GAAW,QAAA,KAAa,yBAAS,GAAA,CAAC,iBAAA,EAAA,EAAkB,oBAAK,GAAA,CAAC,eAAA,EAAA,EAAgB,IAAK,IAAA,EACpF,CAAA;AAER;;;;"}
1
+ {"version":3,"file":"ColumnSortIndicator.js","sources":["ColumnSortIndicator.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { chakra } from \"@chakra-ui/react\";\nimport { SortDirection } from \"@tanstack/react-table\";\nimport { ReactNode } from \"react\";\nimport { TbCaretDownFilled, TbCaretUpFilled } from \"react-icons/tb\";\n\nexport function ColumnSortIndicator(props: { isSorted: false | SortDirection }): ReactNode {\n const { isSorted } = props;\n return (\n <chakra.span ml=\"4\" className=\"result-list-sort-indicator\" aria-hidden=\"true\">\n {isSorted ? isSorted === \"desc\" ? <TbCaretDownFilled /> : <TbCaretUpFilled /> : null}\n </chakra.span>\n );\n}\n"],"names":[],"mappings":";;;;AAQO,SAAS,oBAAoB,KAAA,EAAuD;AACvF,EAAA,MAAM,EAAE,UAAS,GAAI,KAAA;AACrB,EAAA,2BACK,MAAA,CAAO,IAAA,EAAP,EAAY,EAAA,EAAG,GAAA,EAAI,WAAU,4BAAA,EAA6B,aAAA,EAAY,QAClE,QAAA,EAAA,QAAA,GAAW,QAAA,KAAa,yBAAS,GAAA,CAAC,iBAAA,EAAA,EAAkB,oBAAK,GAAA,CAAC,eAAA,EAAA,EAAgB,IAAK,IAAA,EACpF,CAAA;AAER;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.js","sources":["DataTable.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Table, chakra, useToken } from \"@chakra-ui/react\";\nimport { Reactive, reactive } from \"@conterra/reactivity-core\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport { BaseFeature } from \"@open-pioneer/map\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport {\n ColumnDef,\n Header,\n HeaderGroup,\n SortDirection,\n Table as TanstackTable,\n flexRender\n} from \"@tanstack/react-table\";\nimport { classNames } from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { MouseEvent, createContext, useContext, useEffect, useMemo, useState } from \"react\";\nimport { ResultListSelectionChangeEvent, SelectionMode } from \"../ResultList\";\nimport { ColumnResizer } from \"./ColumnResizer\";\nimport { ColumnSortIndicator } from \"./ColumnSortIndicator\";\nimport { useSetupTable } from \"./useSetupTable\";\n\nconst LOG = createLogger(sourceId);\n\nexport interface DataTableProps<Data extends BaseFeature> {\n data: Data[];\n columns: ColumnDef<Data>[];\n memoizeRows: boolean;\n selectionMode: SelectionMode;\n onSelectionChange?(event: ResultListSelectionChangeEvent): void;\n}\n\nconst TableContext = createContext<TableContext<unknown> | undefined>(undefined);\n\ninterface TableContext<Data> {\n /** The tanstack table instance. This object is stable. */\n table: TanstackTable<Data>;\n\n /** A signal to trigger re-rendering in the children of the chakra table. */\n forceRerender: Reactive<number>;\n}\n\nexport function DataTable<Data extends BaseFeature>(props: DataTableProps<Data>) {\n const intl = useIntl();\n const { memoizeRows } = props;\n const { table } = useSetupTable(props); // NOTE: Triggers re-render often when table state changes!\n const isResizing = !!table.getState().columnSizingInfo.isResizingColumn;\n const useMemoOptimization = isResizing || memoizeRows;\n const columnSizeVars = useColumnSizeVars(table);\n\n const context = useMemo((): TableContext<Data> => {\n return {\n table,\n forceRerender: reactive(0)\n };\n }, [table]);\n\n // XXX: Bad practice, but works\n context.forceRerender.value += 1; // Force rerendering of the TableContent child.\n\n // Block click events while dragging the resize handle.\n // If the click event gets through, the user may accidentally trigger column sorting on mouse release.\n // Note that this is in a useEffect() on purpose to defer \"freeing\" click events a bit.\n const [isClickBlocked, setIsClickBlocked] = useState(false);\n useEffect(() => {\n setIsClickBlocked(isResizing);\n }, [isResizing]);\n const blockClicksIfResizing = useEvent((e: MouseEvent) => {\n if (isClickBlocked) {\n LOG.debug(\"Blocking click event because resizing is active\");\n e.stopPropagation();\n e.preventDefault();\n }\n });\n\n // We cache the table's root because chakra's table has some broken memo behavior: it recomputes\n // its styles and rerenders all its children via context when some props change.\n // We keep both the props and the table's children as stable as possible.\n //\n // The table content instead uses a force rerender bypass via the `forceRerender` signal:\n // When react-table tells us to rerender, we trigger a rerender on our grandchild as well.\n const chakraTable = useMemo(() => {\n const content = <TableContent useMemo={useMemoOptimization} />;\n const chakraTable = (\n <Table.Root\n className=\"result-list-table\"\n width=\"99.9%\"\n onClickCapture={blockClicksIfResizing}\n >\n {content}\n </Table.Root>\n );\n return chakraTable;\n }, [blockClicksIfResizing, useMemoOptimization]);\n\n if (!table.getRowModel().rows.length) {\n return (\n <chakra.div className={\"result-list-no-data-message\"}>\n {intl.formatMessage({ id: \"noDataMessage\" })}\n </chakra.div>\n );\n }\n return (\n <chakra.div\n className={classNames(\"result-list-table-container\", {\n \"result-list-table-container--is-resizing\": isResizing\n })}\n h=\"100%\"\n w=\"100%\"\n style={columnSizeVars}\n >\n <TableContext.Provider value={context as TableContext<unknown>}>\n {chakraTable}\n </TableContext.Provider>\n </chakra.div>\n );\n}\n\nfunction TableContent<Data extends BaseFeature>(props: { useMemo: boolean }) {\n const store = useContext(TableContext) as TableContext<Data>;\n const table = store.table;\n\n // Hack to let the grandparent of this component force a rerender.\n useReactiveSnapshot(() => store.forceRerender.value, [store.forceRerender]);\n\n return (\n <>\n <Table.Header>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableHeaderGroup key={headerGroup.id} headerGroup={headerGroup} />\n ))}\n </Table.Header>\n <Table.Body className=\"result-list-table-body\">\n {props.useMemo ? <MemoizedTableRows table={table} /> : <TableRows table={table} />}\n </Table.Body>\n </>\n );\n}\n\nfunction TableHeaderGroup<Data>(props: { headerGroup: HeaderGroup<Data> }) {\n const { headerGroup } = props;\n const borderColor = useToken(\"colors\", \"trails.100\")[0] ?? \"#000000\";\n return (\n <Table.Row key={headerGroup.id} className=\"result-list-headers\">\n {headerGroup.headers.map((header, index) => {\n return (\n <TableHeader\n key={header.id}\n header={header}\n index={index}\n borderColor={borderColor}\n />\n );\n })}\n </Table.Row>\n );\n}\n\nfunction TableHeader<Data>(props: {\n header: Header<Data, unknown>;\n index: number;\n borderColor: string;\n}) {\n const { header, index, borderColor } = props;\n\n let width: string | undefined;\n let minWidth: string | undefined;\n if (index > 0) {\n width = `calc(var(--header-${header.id}-size) * 1px)`;\n } else {\n minWidth = \"50px\"; // Selection column\n }\n\n return (\n <Table.ColumnHeader\n className=\"result-list-header\"\n fontWeight=\"semi-bold\"\n tabIndex={0}\n aria-sort={mapAriaSorting(header.column.getIsSorted())}\n onClick={() => header.column.getCanSort() && header.column.toggleSorting()}\n cursor={header.column.getCanSort() ? \"pointer\" : \"unset\"}\n style={{ width, minWidth }}\n onKeyDown={(evt) => {\n if (evt.key === \"Enter\" && header.column.getCanSort()) {\n header.column.toggleSorting(undefined);\n }\n }}\n /* use box shadow instead of border because it works better with position: sticky */\n border=\"none\"\n boxShadow={`inset 0 -2px 0 0 ${borderColor}`}\n whiteSpace=\"nowrap\" // prevent wrapping between header title and sort indicator\n userSelect=\"none\"\n _focusVisible={{ textDecorationLine: \"underline\" }}\n _focus={{ outline: \"none\" }}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {header.column.getCanSort() && (\n <ColumnSortIndicator isSorted={header.column.getIsSorted()} />\n )}\n <ColumnResizer\n onDoubleClick={() => header.column.resetSize()}\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n isResizing={header.column.getIsResizing()}\n />\n </Table.ColumnHeader>\n );\n}\n\nfunction TableRows<Data extends object>({ table }: { table: TanstackTable<Data> }) {\n return table.getRowModel().rows.map((row) => {\n return (\n <Table.Row key={row.id} className=\"result-list-table-row\">\n {row.getVisibleCells().map((cell) => {\n const width = `calc(var(--header-${cell.column.id}-size) * 1px)`;\n return (\n <Table.Cell\n key={cell.id}\n style={{ width: width }}\n className=\"result-list-table-row\"\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </Table.Cell>\n );\n })}\n </Table.Row>\n );\n });\n}\n\n/**\n * Rows are memoized and only updating on changes due to sorting columns or selecting rows.\n * Removed full Memoization on Resizing because it does not have an additional effect.\n */\nfunction MemoizedTableRows<Data extends object>({ table }: { table: TanstackTable<Data> }) {\n const memoizedRows = useMemo(() => {\n return <TableRows table={table} />;\n // eslint-disable-next-line react-hooks/exhaustive-deps, react-hooks/use-memo\n }, [table, table.getSortedRowModel().rows, table.getSelectedRowModel().rows]);\n return memoizedRows;\n}\n\n/**\n * Instead of calling `column.getSize()` on every render for every header\n * and especially every data cell (very expensive),\n * we will calculate all column sizes at once at the root table level in a useMemo\n * and pass the column sizes down as CSS variables to the <table> element.\n */\nfunction useColumnSizeVars<Data>(table: TanstackTable<Data>) {\n const columnSizingInfo = table.getState().columnSizingInfo;\n const columnSizing = table.getState().columnSizing;\n const tableHeaders = table.getFlatHeaders();\n\n // Needs to be useMemo, not useEffect, to avoid multiple render calls?\n // Need to add columnSizingInfo to the dependency array to make resizing work\n return useMemo(() => {\n // Not used directly, but the memo must re-execute whenever this changes.\n // Note: columnSizing seems to be needed as well, because otherwise resetting the column size (header.column.resetSize())\n // won't to anything.\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n (void columnSizingInfo, columnSizing);\n const colSizes: { [key: string]: number } = {};\n for (let i = 0; i < tableHeaders.length; i++) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const header = tableHeaders[i]!;\n colSizes[`--header-${header.id}-size`] = header.getSize();\n colSizes[`--col-${header.column.id}-size`] = header.column.getSize();\n }\n return colSizes;\n }, [tableHeaders, columnSizingInfo, columnSizing]);\n}\n\ntype SortState = SortDirection | false;\n\nfunction mapAriaSorting(sortState: SortState) {\n switch (sortState) {\n case \"asc\":\n return \"ascending\";\n case \"desc\":\n return \"descending\";\n default:\n return \"none\";\n }\n}\n"],"names":["chakraTable"],"mappings":"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"}
1
+ {"version":3,"file":"DataTable.js","sources":["DataTable.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Table, chakra, useToken } from \"@chakra-ui/react\";\nimport { Reactive, reactive } from \"@conterra/reactivity-core\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport { BaseFeature } from \"@open-pioneer/map\";\nimport { useEvent, classNames } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport {\n ColumnDef,\n Header,\n HeaderGroup,\n SortDirection,\n Table as TanstackTable,\n flexRender\n} from \"@tanstack/react-table\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { MouseEvent, createContext, useContext, useEffect, useMemo, useState } from \"react\";\nimport { ResultListSelectionChangeEvent, SelectionMode } from \"../ResultList\";\nimport { ColumnResizer } from \"./ColumnResizer\";\nimport { ColumnSortIndicator } from \"./ColumnSortIndicator\";\nimport { useSetupTable } from \"./useSetupTable\";\n\nconst LOG = createLogger(sourceId);\n\nexport interface DataTableProps<Data extends BaseFeature> {\n data: Data[];\n columns: ColumnDef<Data>[];\n memoizeRows: boolean;\n selectionMode: SelectionMode;\n onSelectionChange?(event: ResultListSelectionChangeEvent): void;\n}\n\nconst TableContext = createContext<TableContext<unknown> | undefined>(undefined);\n\ninterface TableContext<Data> {\n /** The tanstack table instance. This object is stable. */\n table: TanstackTable<Data>;\n\n /** A signal to trigger re-rendering in the children of the chakra table. */\n forceRerender: Reactive<number>;\n}\n\nexport function DataTable<Data extends BaseFeature>(props: DataTableProps<Data>) {\n const intl = useIntl();\n const { memoizeRows } = props;\n const { table } = useSetupTable(props); // NOTE: Triggers re-render often when table state changes!\n const isResizing = !!table.getState().columnSizingInfo.isResizingColumn;\n const useMemoOptimization = isResizing || memoizeRows;\n const columnSizeVars = useColumnSizeVars(table);\n\n const context = useMemo((): TableContext<Data> => {\n return {\n table,\n forceRerender: reactive(0)\n };\n }, [table]);\n\n // XXX: Bad practice, but works\n context.forceRerender.value += 1; // Force rerendering of the TableContent child.\n\n // Block click events while dragging the resize handle.\n // If the click event gets through, the user may accidentally trigger column sorting on mouse release.\n // Note that this is in a useEffect() on purpose to defer \"freeing\" click events a bit.\n const [isClickBlocked, setIsClickBlocked] = useState(false);\n useEffect(() => {\n setIsClickBlocked(isResizing);\n }, [isResizing]);\n const blockClicksIfResizing = useEvent((e: MouseEvent) => {\n if (isClickBlocked) {\n LOG.debug(\"Blocking click event because resizing is active\");\n e.stopPropagation();\n e.preventDefault();\n }\n });\n\n // We cache the table's root because chakra's table has some broken memo behavior: it recomputes\n // its styles and rerenders all its children via context when some props change.\n // We keep both the props and the table's children as stable as possible.\n //\n // The table content instead uses a force rerender bypass via the `forceRerender` signal:\n // When react-table tells us to rerender, we trigger a rerender on our grandchild as well.\n const chakraTable = useMemo(() => {\n const content = <TableContent useMemo={useMemoOptimization} />;\n const chakraTable = (\n <Table.Root\n className=\"result-list-table\"\n width=\"99.9%\"\n onClickCapture={blockClicksIfResizing}\n >\n {content}\n </Table.Root>\n );\n return chakraTable;\n }, [blockClicksIfResizing, useMemoOptimization]);\n\n if (!table.getRowModel().rows.length) {\n return (\n <chakra.div className={\"result-list-no-data-message\"}>\n {intl.formatMessage({ id: \"noDataMessage\" })}\n </chakra.div>\n );\n }\n return (\n <chakra.div\n className={classNames(\"result-list-table-container\", {\n \"result-list-table-container--is-resizing\": isResizing\n })}\n h=\"100%\"\n w=\"100%\"\n style={columnSizeVars}\n >\n <TableContext.Provider value={context as TableContext<unknown>}>\n {chakraTable}\n </TableContext.Provider>\n </chakra.div>\n );\n}\n\nfunction TableContent<Data extends BaseFeature>(props: { useMemo: boolean }) {\n const store = useContext(TableContext) as TableContext<Data>;\n const table = store.table;\n\n // Hack to let the grandparent of this component force a rerender.\n useReactiveSnapshot(() => store.forceRerender.value, [store.forceRerender]);\n\n return (\n <>\n <Table.Header>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableHeaderGroup key={headerGroup.id} headerGroup={headerGroup} />\n ))}\n </Table.Header>\n <Table.Body className=\"result-list-table-body\">\n {props.useMemo ? <MemoizedTableRows table={table} /> : <TableRows table={table} />}\n </Table.Body>\n </>\n );\n}\n\nfunction TableHeaderGroup<Data>(props: { headerGroup: HeaderGroup<Data> }) {\n const { headerGroup } = props;\n const borderColor = useToken(\"colors\", \"trails.100\")[0] ?? \"#000000\";\n return (\n <Table.Row key={headerGroup.id} className=\"result-list-headers\">\n {headerGroup.headers.map((header, index) => {\n return (\n <TableHeader\n key={header.id}\n header={header}\n index={index}\n borderColor={borderColor}\n />\n );\n })}\n </Table.Row>\n );\n}\n\nfunction TableHeader<Data>(props: {\n header: Header<Data, unknown>;\n index: number;\n borderColor: string;\n}) {\n const { header, index, borderColor } = props;\n\n let width: string | undefined;\n let minWidth: string | undefined;\n if (index > 0) {\n width = `calc(var(--header-${header.id}-size) * 1px)`;\n } else {\n minWidth = \"50px\"; // Selection column\n }\n\n return (\n <Table.ColumnHeader\n className=\"result-list-header\"\n fontWeight=\"semi-bold\"\n tabIndex={0}\n aria-sort={mapAriaSorting(header.column.getIsSorted())}\n onClick={() => header.column.getCanSort() && header.column.toggleSorting()}\n cursor={header.column.getCanSort() ? \"pointer\" : \"unset\"}\n style={{ width, minWidth }}\n onKeyDown={(evt) => {\n if (evt.key === \"Enter\" && header.column.getCanSort()) {\n header.column.toggleSorting(undefined);\n }\n }}\n /* use box shadow instead of border because it works better with position: sticky */\n border=\"none\"\n boxShadow={`inset 0 -2px 0 0 ${borderColor}`}\n whiteSpace=\"nowrap\" // prevent wrapping between header title and sort indicator\n userSelect=\"none\"\n _focusVisible={{ textDecorationLine: \"underline\" }}\n _focus={{ outline: \"none\" }}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {header.column.getCanSort() && (\n <ColumnSortIndicator isSorted={header.column.getIsSorted()} />\n )}\n <ColumnResizer\n onDoubleClick={() => header.column.resetSize()}\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n isResizing={header.column.getIsResizing()}\n />\n </Table.ColumnHeader>\n );\n}\n\nfunction TableRows<Data extends object>({ table }: { table: TanstackTable<Data> }) {\n return table.getRowModel().rows.map((row) => {\n return (\n <Table.Row key={row.id} className=\"result-list-table-row\">\n {row.getVisibleCells().map((cell) => {\n const width = `calc(var(--header-${cell.column.id}-size) * 1px)`;\n return (\n <Table.Cell\n key={cell.id}\n style={{ width: width }}\n className=\"result-list-table-row\"\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </Table.Cell>\n );\n })}\n </Table.Row>\n );\n });\n}\n\n/**\n * Rows are memoized and only updating on changes due to sorting columns or selecting rows.\n * Removed full Memoization on Resizing because it does not have an additional effect.\n */\nfunction MemoizedTableRows<Data extends object>({ table }: { table: TanstackTable<Data> }) {\n const memoizedRows = useMemo(() => {\n return <TableRows table={table} />;\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, [table, table.getSortedRowModel().rows, table.getSelectedRowModel().rows]);\n return memoizedRows;\n}\n\n/**\n * Instead of calling `column.getSize()` on every render for every header\n * and especially every data cell (very expensive),\n * we will calculate all column sizes at once at the root table level in a useMemo\n * and pass the column sizes down as CSS variables to the <table> element.\n */\nfunction useColumnSizeVars<Data>(table: TanstackTable<Data>) {\n const columnSizingInfo = table.getState().columnSizingInfo;\n const columnSizing = table.getState().columnSizing;\n const tableHeaders = table.getFlatHeaders();\n\n // Needs to be useMemo, not useEffect, to avoid multiple render calls?\n // Need to add columnSizingInfo to the dependency array to make resizing work\n return useMemo(() => {\n // Not used directly, but the memo must re-execute whenever this changes.\n // Note: columnSizing seems to be needed as well, because otherwise resetting the column size (header.column.resetSize())\n // won't to anything.\n // oxlint-disable-next-line @typescript-eslint/no-unused-expressions\n (void columnSizingInfo, columnSizing);\n const colSizes: { [key: string]: number } = {};\n for (let i = 0; i < tableHeaders.length; i++) {\n // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion\n const header = tableHeaders[i]!;\n colSizes[`--header-${header.id}-size`] = header.getSize();\n colSizes[`--col-${header.column.id}-size`] = header.column.getSize();\n }\n return colSizes;\n }, [tableHeaders, columnSizingInfo, columnSizing]);\n}\n\ntype SortState = SortDirection | false;\n\nfunction mapAriaSorting(sortState: SortState) {\n switch (sortState) {\n case \"asc\":\n return \"ascending\";\n case \"desc\":\n return \"descending\";\n default:\n return \"none\";\n }\n}\n"],"names":["chakraTable"],"mappings":";;;;;;;;;;;;;;AAyBA,MAAM,GAAA,GAAM,aAAa,QAAQ,CAAA;AAUjC,MAAM,YAAA,GAAe,cAAiD,MAAS,CAAA;AAUxE,SAAS,UAAoC,KAAA,EAA6B;AAC7E,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,EAAE,aAAY,GAAI,KAAA;AACxB,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,aAAA,CAAc,KAAK,CAAA;AACrC,EAAA,MAAM,aAAa,CAAC,CAAC,KAAA,CAAM,QAAA,GAAW,gBAAA,CAAiB,gBAAA;AACvD,EAAA,MAAM,sBAAsB,UAAA,IAAc,WAAA;AAC1C,EAAA,MAAM,cAAA,GAAiB,kBAAkB,KAAK,CAAA;AAE9C,EAAA,MAAM,OAAA,GAAU,QAAQ,MAA0B;AAC9C,IAAA,OAAO;AAAA,MACH,KAAA;AAAA,MACA,aAAA,EAAe,SAAS,CAAC;AAAA,KAC7B;AAAA,EACJ,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAGV,EAAA,OAAA,CAAQ,cAAc,KAAA,IAAS,CAAA;AAK/B,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAAS,KAAK,CAAA;AAC1D,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,iBAAA,CAAkB,UAAU,CAAA;AAAA,EAChC,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AACf,EAAA,MAAM,qBAAA,GAAwB,QAAA,CAAS,CAAC,CAAA,KAAkB;AACtD,IAAA,IAAI,cAAA,EAAgB;AAChB,MAAA,GAAA,CAAI,MAAM,iDAAiD,CAAA;AAC3D,MAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,MAAA,CAAA,CAAE,cAAA,EAAe;AAAA,IACrB;AAAA,EACJ,CAAC,CAAA;AAQD,EAAA,MAAM,WAAA,GAAc,QAAQ,MAAM;AAC9B,IAAA,MAAM,OAAA,mBAAU,GAAA,CAAC,YAAA,EAAA,EAAa,OAAA,EAAS,mBAAA,EAAqB,CAAA;AAC5D,IAAA,MAAMA,YAAAA,mBACF,GAAA;AAAA,MAAC,KAAA,CAAM,IAAA;AAAA,MAAN;AAAA,QACG,SAAA,EAAU,mBAAA;AAAA,QACV,KAAA,EAAM,OAAA;AAAA,QACN,cAAA,EAAgB,qBAAA;AAAA,QAEf,QAAA,EAAA;AAAA;AAAA,KACL;AAEJ,IAAA,OAAOA,YAAAA;AAAA,EACX,CAAA,EAAG,CAAC,qBAAA,EAAuB,mBAAmB,CAAC,CAAA;AAE/C,EAAA,IAAI,CAAC,KAAA,CAAM,WAAA,EAAY,CAAE,KAAK,MAAA,EAAQ;AAClC,IAAA,uBACI,GAAA,CAAC,MAAA,CAAO,GAAA,EAAP,EAAW,SAAA,EAAW,6BAAA,EAClB,QAAA,EAAA,IAAA,CAAK,aAAA,CAAc,EAAE,EAAA,EAAI,eAAA,EAAiB,CAAA,EAC/C,CAAA;AAAA,EAER;AACA,EAAA,uBACI,GAAA;AAAA,IAAC,MAAA,CAAO,GAAA;AAAA,IAAP;AAAA,MACG,SAAA,EAAW,WAAW,6BAAA,EAA+B;AAAA,QACjD,0CAAA,EAA4C;AAAA,OAC/C,CAAA;AAAA,MACD,CAAA,EAAE,MAAA;AAAA,MACF,CAAA,EAAE,MAAA;AAAA,MACF,KAAA,EAAO,cAAA;AAAA,MAEP,8BAAC,YAAA,CAAa,QAAA,EAAb,EAAsB,KAAA,EAAO,SACzB,QAAA,EAAA,WAAA,EACL;AAAA;AAAA,GACJ;AAER;AAEA,SAAS,aAAuC,KAAA,EAA6B;AACzE,EAAA,MAAM,KAAA,GAAQ,WAAW,YAAY,CAAA;AACrC,EAAA,MAAM,QAAQ,KAAA,CAAM,KAAA;AAGpB,EAAA,mBAAA,CAAoB,MAAM,KAAA,CAAM,aAAA,CAAc,OAAO,CAAC,KAAA,CAAM,aAAa,CAAC,CAAA;AAE1E,EAAA,uBACI,IAAA,CAAA,QAAA,EAAA,EACI,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,KAAA,CAAM,MAAA,EAAN,EACI,QAAA,EAAA,KAAA,CAAM,iBAAgB,CAAE,GAAA,CAAI,CAAC,WAAA,yBACzB,gBAAA,EAAA,EAAsC,WAAA,EAAA,EAAhB,WAAA,CAAY,EAA8B,CACpE,CAAA,EACL,CAAA;AAAA,oBACA,GAAA,CAAC,KAAA,CAAM,IAAA,EAAN,EAAW,WAAU,wBAAA,EACjB,QAAA,EAAA,KAAA,CAAM,OAAA,mBAAU,GAAA,CAAC,qBAAkB,KAAA,EAAc,CAAA,mBAAK,GAAA,CAAC,SAAA,EAAA,EAAU,OAAc,CAAA,EACpF;AAAA,GAAA,EACJ,CAAA;AAER;AAEA,SAAS,iBAAuB,KAAA,EAA2C;AACvE,EAAA,MAAM,EAAE,aAAY,GAAI,KAAA;AACxB,EAAA,MAAM,cAAc,QAAA,CAAS,QAAA,EAAU,YAAY,CAAA,CAAE,CAAC,CAAA,IAAK,SAAA;AAC3D,EAAA,uBACI,GAAA,CAAC,KAAA,CAAM,GAAA,EAAN,EAA+B,SAAA,EAAU,qBAAA,EACrC,QAAA,EAAA,WAAA,CAAY,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,EAAQ,KAAA,KAAU;AACxC,IAAA,uBACI,GAAA;AAAA,MAAC,WAAA;AAAA,MAAA;AAAA,QAEG,MAAA;AAAA,QACA,KAAA;AAAA,QACA;AAAA,OAAA;AAAA,MAHK,MAAA,CAAO;AAAA,KAIhB;AAAA,EAER,CAAC,CAAA,EAAA,EAVW,WAAA,CAAY,EAW5B,CAAA;AAER;AAEA,SAAS,YAAkB,KAAA,EAIxB;AACC,EAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,WAAA,EAAY,GAAI,KAAA;AAEvC,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI,QAAQ,CAAA,EAAG;AACX,IAAA,KAAA,GAAQ,CAAA,kBAAA,EAAqB,OAAO,EAAE,CAAA,aAAA,CAAA;AAAA,EAC1C,CAAA,MAAO;AACH,IAAA,QAAA,GAAW,MAAA;AAAA,EACf;AAEA,EAAA,uBACI,IAAA;AAAA,IAAC,KAAA,CAAM,YAAA;AAAA,IAAN;AAAA,MACG,SAAA,EAAU,oBAAA;AAAA,MACV,UAAA,EAAW,WAAA;AAAA,MACX,QAAA,EAAU,CAAA;AAAA,MACV,WAAA,EAAW,cAAA,CAAe,MAAA,CAAO,MAAA,CAAO,aAAa,CAAA;AAAA,MACrD,OAAA,EAAS,MAAM,MAAA,CAAO,MAAA,CAAO,YAAW,IAAK,MAAA,CAAO,OAAO,aAAA,EAAc;AAAA,MACzE,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,UAAA,KAAe,SAAA,GAAY,OAAA;AAAA,MACjD,KAAA,EAAO,EAAE,KAAA,EAAO,QAAA,EAAS;AAAA,MACzB,SAAA,EAAW,CAAC,GAAA,KAAQ;AAChB,QAAA,IAAI,IAAI,GAAA,KAAQ,OAAA,IAAW,MAAA,CAAO,MAAA,CAAO,YAAW,EAAG;AACnD,UAAA,MAAA,CAAO,MAAA,CAAO,cAAc,MAAS,CAAA;AAAA,QACzC;AAAA,MACJ,CAAA;AAAA,MAEA,MAAA,EAAO,MAAA;AAAA,MACP,SAAA,EAAW,oBAAoB,WAAW,CAAA,CAAA;AAAA,MAC1C,UAAA,EAAW,QAAA;AAAA,MACX,UAAA,EAAW,MAAA;AAAA,MACX,aAAA,EAAe,EAAE,kBAAA,EAAoB,WAAA,EAAY;AAAA,MACjD,MAAA,EAAQ,EAAE,OAAA,EAAS,MAAA,EAAO;AAAA,MAEzB,QAAA,EAAA;AAAA,QAAA,UAAA,CAAW,OAAO,MAAA,CAAO,SAAA,CAAU,MAAA,EAAQ,MAAA,CAAO,YAAY,CAAA;AAAA,QAC9D,MAAA,CAAO,MAAA,CAAO,UAAA,EAAW,oBACtB,GAAA,CAAC,uBAAoB,QAAA,EAAU,MAAA,CAAO,MAAA,CAAO,WAAA,EAAY,EAAG,CAAA;AAAA,wBAEhE,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACG,aAAA,EAAe,MAAM,MAAA,CAAO,MAAA,CAAO,SAAA,EAAU;AAAA,YAC7C,WAAA,EAAa,OAAO,gBAAA,EAAiB;AAAA,YACrC,YAAA,EAAc,OAAO,gBAAA,EAAiB;AAAA,YACtC,UAAA,EAAY,MAAA,CAAO,MAAA,CAAO,aAAA;AAAc;AAAA;AAC5C;AAAA;AAAA,GACJ;AAER;AAEA,SAAS,SAAA,CAA+B,EAAE,KAAA,EAAM,EAAmC;AAC/E,EAAA,OAAO,MAAM,WAAA,EAAY,CAAE,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,KAAQ;AACzC,IAAA,uBACI,GAAA,CAAC,KAAA,CAAM,GAAA,EAAN,EAAuB,SAAA,EAAU,uBAAA,EAC7B,QAAA,EAAA,GAAA,CAAI,eAAA,EAAgB,CAAE,GAAA,CAAI,CAAC,IAAA,KAAS;AACjC,MAAA,MAAM,KAAA,GAAQ,CAAA,kBAAA,EAAqB,IAAA,CAAK,MAAA,CAAO,EAAE,CAAA,aAAA,CAAA;AACjD,MAAA,uBACI,GAAA;AAAA,QAAC,KAAA,CAAM,IAAA;AAAA,QAAN;AAAA,UAEG,KAAA,EAAO,EAAE,KAAA,EAAa;AAAA,UACtB,SAAA,EAAU,uBAAA;AAAA,UAET,qBAAW,IAAA,CAAK,MAAA,CAAO,UAAU,IAAA,EAAM,IAAA,CAAK,YAAY;AAAA,SAAA;AAAA,QAJpD,IAAA,CAAK;AAAA,OAKd;AAAA,IAER,CAAC,CAAA,EAAA,EAZW,GAAA,CAAI,EAapB,CAAA;AAAA,EAER,CAAC,CAAA;AACL;AAMA,SAAS,iBAAA,CAAuC,EAAE,KAAA,EAAM,EAAmC;AACvF,EAAA,MAAM,YAAA,GAAe,QAAQ,MAAM;AAC/B,IAAA,uBAAO,GAAA,CAAC,aAAU,KAAA,EAAc,CAAA;AAAA,EAEpC,CAAA,EAAG,CAAC,KAAA,EAAO,KAAA,CAAM,iBAAA,EAAkB,CAAE,IAAA,EAAM,KAAA,CAAM,mBAAA,EAAoB,CAAE,IAAI,CAAC,CAAA;AAC5E,EAAA,OAAO,YAAA;AACX;AAQA,SAAS,kBAAwB,KAAA,EAA4B;AACzD,EAAA,MAAM,gBAAA,GAAmB,KAAA,CAAM,QAAA,EAAS,CAAE,gBAAA;AAC1C,EAAA,MAAM,YAAA,GAAe,KAAA,CAAM,QAAA,EAAS,CAAE,YAAA;AACtC,EAAA,MAAM,YAAA,GAAe,MAAM,cAAA,EAAe;AAI1C,EAAA,OAAO,QAAQ,MAAM;AAMjB,IAAA,MAAM,WAAsC,EAAC;AAC7C,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,YAAA,CAAa,QAAQ,CAAA,EAAA,EAAK;AAE1C,MAAA,MAAM,MAAA,GAAS,aAAa,CAAC,CAAA;AAC7B,MAAA,QAAA,CAAS,YAAY,MAAA,CAAO,EAAE,CAAA,KAAA,CAAO,CAAA,GAAI,OAAO,OAAA,EAAQ;AACxD,MAAA,QAAA,CAAS,CAAA,MAAA,EAAS,OAAO,MAAA,CAAO,EAAE,OAAO,CAAA,GAAI,MAAA,CAAO,OAAO,OAAA,EAAQ;AAAA,IACvE;AACA,IAAA,OAAO,QAAA;AAAA,EACX,CAAA,EAAG,CAAC,YAAA,EAAc,gBAAA,EAAkB,YAAY,CAAC,CAAA;AACrD;AAIA,SAAS,eAAe,SAAA,EAAsB;AAC1C,EAAA,QAAQ,SAAA;AAAW,IACf,KAAK,KAAA;AACD,MAAA,OAAO,WAAA;AAAA,IACX,KAAK,MAAA;AACD,MAAA,OAAO,YAAA;AAAA,IACX;AACI,MAAA,OAAO,MAAA;AAAA;AAEnB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectComponent.js","sources":["SelectComponent.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { chakra, Checkbox } from \"@chakra-ui/react\";\nimport { Radio, RadioGroup } from \"@open-pioneer/chakra-snippets/radio\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { memo, ReactNode, useId } from \"react\";\n\nexport interface SelectComponentProps {\n mode?: \"checkbox\" | \"radio\";\n toolTipLabel?: string;\n\n className?: string;\n ariaLabel?: string;\n checked: boolean | \"indeterminate\";\n disabled?: boolean;\n onChange?: (newIsChecked: boolean) => void;\n}\n\nexport function createSelectComponent(props: SelectComponentProps): ReactNode {\n const { mode = \"checkbox\", toolTipLabel, ariaLabel = props.toolTipLabel, ...rest } = props;\n\n let control: ReactNode;\n switch (mode) {\n case \"checkbox\": {\n control = <SelectCheckbox ariaLabel={ariaLabel} {...rest} />;\n break;\n }\n case \"radio\": {\n control = <SelectRadio ariaLabel={ariaLabel} {...rest} />;\n break;\n }\n }\n\n if (toolTipLabel) {\n /*\n wrap tooltip content into span to fix tooltip around checkbox, see https://github.com/chakra-ui/chakra-ui/issues/6353\n */\n control = (\n <Tooltip\n content={toolTipLabel}\n positioning={{ placement: \"right\" }}\n closeOnClick={false}\n >\n <chakra.span>{control}</chakra.span>\n </Tooltip>\n );\n }\n return control;\n}\n\ntype SelectComponentInnerProps = Omit<SelectComponentProps, \"mode\" | \"toolTipLabel\">;\n\nconst SelectCheckbox = memo(function SelectCheckbox({\n className,\n ariaLabel,\n checked,\n disabled,\n onChange\n}: SelectComponentInnerProps) {\n const checkboxId = useId();\n return (\n <Checkbox.Root\n //fix invalid aria-labeledby, this works because we never actually render the label\n ids={{ root: checkboxId, label: checkboxId }}\n className={className}\n aria-label={ariaLabel}\n checked={checked}\n disabled={disabled}\n onCheckedChange={(e) => {\n onChange?.(!!e.checked); // \"indeterminate\" not required -> map to true\n }}\n >\n <Checkbox.HiddenInput />\n <Checkbox.Control>\n <Checkbox.Indicator />\n </Checkbox.Control>\n </Checkbox.Root>\n );\n});\n\nconst SelectRadio = memo(function SelectRadio({\n className,\n ariaLabel,\n checked: checkedProp,\n disabled,\n onChange\n}: SelectComponentInnerProps) {\n const id = useId();\n const checked = !!checkedProp; // indeterminate not supported, default to \"true\"\n\n /** Name seems to be required for screen reader tabbing support. */\n return (\n <RadioGroup\n name={id}\n value={checked ? id : null}\n onValueChange={(e) => {\n onChange?.(e.value === id);\n }}\n >\n <Radio className={className} value={id} disabled={disabled} aria-label={ariaLabel} />\n </RadioGroup>\n );\n});\n"],"names":["SelectCheckbox","SelectRadio"],"mappings":";;;;;;AAkBO,SAAS,sBAAsB,KAAA,EAAwC;AAC1E,EAAA,MAAM,EAAE,OAAO,UAAA,EAAY,YAAA,EAAc,YAAY,KAAA,CAAM,YAAA,EAAc,GAAG,IAAA,EAAK,GAAI,KAAA;AAErF,EAAA,IAAI,OAAA;AACJ,EAAA,QAAQ,IAAA;AAAM,IACV,KAAK,UAAA,EAAY;AACb,MAAA,OAAA,mBAAU,GAAA,CAAC,cAAA,EAAA,EAAe,SAAA,EAAuB,GAAG,IAAA,EAAM,CAAA;AAC1D,MAAA;AAAA,IACJ;AAAA,IACA,KAAK,OAAA,EAAS;AACV,MAAA,OAAA,mBAAU,GAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAuB,GAAG,IAAA,EAAM,CAAA;AACvD,MAAA;AAAA,IACJ;AAAA;AAGJ,EAAA,IAAI,YAAA,EAAc;AAId,IAAA,OAAA,mBACI,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACG,OAAA,EAAS,YAAA;AAAA,QACT,WAAA,EAAa,EAAE,SAAA,EAAW,OAAA,EAAQ;AAAA,QAClC,YAAA,EAAc,KAAA;AAAA,QAEd,QAAA,kBAAA,GAAA,CAAC,MAAA,CAAO,IAAA,EAAP,EAAa,QAAA,EAAA,OAAA,EAAQ;AAAA;AAAA,KAC1B;AAAA,EAER;AACA,EAAA,OAAO,OAAA;AACX;AAIA,MAAM,cAAA,GAAiB,IAAA,CAAK,SAASA,eAAAA,CAAe;AAAA,EAChD,SAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA;AACJ,CAAA,EAA8B;AAC1B,EAAA,MAAM,aAAa,KAAA,EAAM;AACzB,EAAA,uBACI,IAAA;AAAA,IAAC,QAAA,CAAS,IAAA;AAAA,IAAT;AAAA,MAEG,GAAA,EAAK,EAAE,IAAA,EAAM,UAAA,EAAY,OAAO,UAAA,EAAW;AAAA,MAC3C,SAAA;AAAA,MACA,YAAA,EAAY,SAAA;AAAA,MACZ,OAAA;AAAA,MACA,QAAA;AAAA,MACA,eAAA,EAAiB,CAAC,CAAA,KAAM;AACpB,QAAA,QAAA,GAAW,CAAC,CAAC,CAAA,CAAE,OAAO,CAAA;AAAA,MAC1B,CAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAA,CAAS,aAAT,EAAqB,CAAA;AAAA,wBACtB,GAAA,CAAC,SAAS,OAAA,EAAT,EACG,8BAAC,QAAA,CAAS,SAAA,EAAT,EAAmB,CAAA,EACxB;AAAA;AAAA;AAAA,GACJ;AAER,CAAC,CAAA;AAED,MAAM,WAAA,GAAc,IAAA,CAAK,SAASC,YAAAA,CAAY;AAAA,EAC1C,SAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA,EAAS,WAAA;AAAA,EACT,QAAA;AAAA,EACA;AACJ,CAAA,EAA8B;AAC1B,EAAA,MAAM,KAAK,KAAA,EAAM;AACjB,EAAA,MAAM,OAAA,GAAU,CAAC,CAAC,WAAA;AAGlB,EAAA,uBACI,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACG,IAAA,EAAM,EAAA;AAAA,MACN,KAAA,EAAO,UAAU,EAAA,GAAK,IAAA;AAAA,MACtB,aAAA,EAAe,CAAC,CAAA,KAAM;AAClB,QAAA,QAAA,GAAW,CAAA,CAAE,UAAU,EAAE,CAAA;AAAA,MAC7B,CAAA;AAAA,MAEA,8BAAC,KAAA,EAAA,EAAM,SAAA,EAAsB,OAAO,EAAA,EAAI,QAAA,EAAoB,cAAY,SAAA,EAAW;AAAA;AAAA,GACvF;AAER,CAAC,CAAA;;;;"}
1
+ {"version":3,"file":"SelectComponent.js","sources":["SelectComponent.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { chakra, Checkbox } from \"@chakra-ui/react\";\nimport { Radio, RadioGroup } from \"@open-pioneer/chakra-snippets/radio\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { memo, ReactNode, useId } from \"react\";\n\nexport interface SelectComponentProps {\n mode?: \"checkbox\" | \"radio\";\n toolTipLabel?: string;\n\n className?: string;\n ariaLabel?: string;\n checked: boolean | \"indeterminate\";\n disabled?: boolean;\n onChange?: (newIsChecked: boolean) => void;\n}\n\nexport function createSelectComponent(props: SelectComponentProps): ReactNode {\n const { mode = \"checkbox\", toolTipLabel, ariaLabel = props.toolTipLabel, ...rest } = props;\n\n let control: ReactNode;\n switch (mode) {\n case \"checkbox\": {\n control = <SelectCheckbox ariaLabel={ariaLabel} {...rest} />;\n break;\n }\n case \"radio\": {\n control = <SelectRadio ariaLabel={ariaLabel} {...rest} />;\n break;\n }\n }\n\n if (toolTipLabel) {\n /*\n wrap tooltip content into span to fix tooltip around checkbox, see https://github.com/chakra-ui/chakra-ui/issues/6353\n */\n control = (\n <Tooltip\n content={toolTipLabel}\n positioning={{ placement: \"right\" }}\n closeOnClick={false}\n >\n <chakra.span>{control}</chakra.span>\n </Tooltip>\n );\n }\n return control;\n}\n\ntype SelectComponentInnerProps = Omit<SelectComponentProps, \"mode\" | \"toolTipLabel\">;\n\nconst SelectCheckbox = memo(function SelectCheckbox({\n className,\n ariaLabel,\n checked,\n disabled,\n onChange\n}: SelectComponentInnerProps) {\n const checkboxId = useId();\n return (\n <Checkbox.Root\n //fix invalid aria-labeledby, this works because we never actually render the label\n ids={{ root: checkboxId, label: checkboxId }}\n className={className}\n aria-label={ariaLabel}\n checked={checked}\n disabled={disabled}\n onCheckedChange={(e) => {\n onChange?.(!!e.checked); // \"indeterminate\" not required -> map to true\n }}\n >\n <Checkbox.HiddenInput />\n <Checkbox.Control>\n <Checkbox.Indicator />\n </Checkbox.Control>\n </Checkbox.Root>\n );\n});\n\nconst SelectRadio = memo(function SelectRadio({\n className,\n ariaLabel,\n checked: checkedProp,\n disabled,\n onChange\n}: SelectComponentInnerProps) {\n const id = useId();\n const checked = !!checkedProp; // indeterminate not supported, default to \"true\"\n\n /** Name seems to be required for screen reader tabbing support. */\n return (\n <RadioGroup\n name={id}\n value={checked ? id : null}\n onValueChange={(e) => {\n onChange?.(e.value === id);\n }}\n >\n <Radio className={className} value={id} disabled={disabled} aria-label={ariaLabel} />\n </RadioGroup>\n );\n});\n"],"names":["SelectCheckbox","SelectRadio"],"mappings":";;;;;;AAmBO,SAAS,sBAAsB,KAAA,EAAwC;AAC1E,EAAA,MAAM,EAAE,OAAO,UAAA,EAAY,YAAA,EAAc,YAAY,KAAA,CAAM,YAAA,EAAc,GAAG,IAAA,EAAK,GAAI,KAAA;AAErF,EAAA,IAAI,OAAA;AACJ,EAAA,QAAQ,IAAA;AAAM,IACV,KAAK,UAAA,EAAY;AACb,MAAA,OAAA,mBAAU,GAAA,CAAC,cAAA,EAAA,EAAe,SAAA,EAAuB,GAAG,IAAA,EAAM,CAAA;AAC1D,MAAA;AAAA,IACJ;AAAA,IACA,KAAK,OAAA,EAAS;AACV,MAAA,OAAA,mBAAU,GAAA,CAAC,WAAA,EAAA,EAAY,SAAA,EAAuB,GAAG,IAAA,EAAM,CAAA;AACvD,MAAA;AAAA,IACJ;AAAA;AAGJ,EAAA,IAAI,YAAA,EAAc;AAId,IAAA,OAAA,mBACI,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACG,OAAA,EAAS,YAAA;AAAA,QACT,WAAA,EAAa,EAAE,SAAA,EAAW,OAAA,EAAQ;AAAA,QAClC,YAAA,EAAc,KAAA;AAAA,QAEd,QAAA,kBAAA,GAAA,CAAC,MAAA,CAAO,IAAA,EAAP,EAAa,QAAA,EAAA,OAAA,EAAQ;AAAA;AAAA,KAC1B;AAAA,EAER;AACA,EAAA,OAAO,OAAA;AACX;AAIA,MAAM,cAAA,GAAiB,IAAA,CAAK,SAASA,eAAAA,CAAe;AAAA,EAChD,SAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA;AACJ,CAAA,EAA8B;AAC1B,EAAA,MAAM,aAAa,KAAA,EAAM;AACzB,EAAA,uBACI,IAAA;AAAA,IAAC,QAAA,CAAS,IAAA;AAAA,IAAT;AAAA,MAEG,GAAA,EAAK,EAAE,IAAA,EAAM,UAAA,EAAY,OAAO,UAAA,EAAW;AAAA,MAC3C,SAAA;AAAA,MACA,YAAA,EAAY,SAAA;AAAA,MACZ,OAAA;AAAA,MACA,QAAA;AAAA,MACA,eAAA,EAAiB,CAAC,CAAA,KAAM;AACpB,QAAA,QAAA,GAAW,CAAC,CAAC,CAAA,CAAE,OAAO,CAAA;AAAA,MAC1B,CAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAA,CAAS,aAAT,EAAqB,CAAA;AAAA,wBACtB,GAAA,CAAC,SAAS,OAAA,EAAT,EACG,8BAAC,QAAA,CAAS,SAAA,EAAT,EAAmB,CAAA,EACxB;AAAA;AAAA;AAAA,GACJ;AAER,CAAC,CAAA;AAED,MAAM,WAAA,GAAc,IAAA,CAAK,SAASC,YAAAA,CAAY;AAAA,EAC1C,SAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA,EAAS,WAAA;AAAA,EACT,QAAA;AAAA,EACA;AACJ,CAAA,EAA8B;AAC1B,EAAA,MAAM,KAAK,KAAA,EAAM;AACjB,EAAA,MAAM,OAAA,GAAU,CAAC,CAAC,WAAA;AAGlB,EAAA,uBACI,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACG,IAAA,EAAM,EAAA;AAAA,MACN,KAAA,EAAO,UAAU,EAAA,GAAK,IAAA;AAAA,MACtB,aAAA,EAAe,CAAC,CAAA,KAAM;AAClB,QAAA,QAAA,GAAW,CAAA,CAAE,UAAU,EAAE,CAAA;AAAA,MAC7B,CAAA;AAAA,MAEA,8BAAC,KAAA,EAAA,EAAM,SAAA,EAAsB,OAAO,EAAA,EAAI,QAAA,EAAoB,cAAY,SAAA,EAAW;AAAA;AAAA,GACvF;AAER,CAAC,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"createColumns.js","sources":["createColumns.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { chakra } from \"@chakra-ui/react\";\nimport { BaseFeature } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { createColumnHelper, Table as TanstackTable } from \"@tanstack/react-table\";\nimport { FormatOptions, ResultColumn, SelectionMode } from \"../ResultList\";\nimport { createSelectComponent } from \"./SelectComponent\";\n\nexport const SELECT_COLUMN_SIZE = 70;\n\nconst columnHelper = createColumnHelper<BaseFeature>();\n\nexport interface CreateColumnsOptions {\n columns: ResultColumn[];\n intl: PackageIntl;\n tableWidth?: number;\n formatOptions?: FormatOptions;\n selectionMode: SelectionMode;\n selectionStyle: \"radio\" | \"checkbox\";\n labelProperty?: string;\n}\n\nexport function createColumns(options: CreateColumnsOptions) {\n const {\n columns,\n intl,\n tableWidth,\n formatOptions,\n selectionMode,\n selectionStyle,\n labelProperty\n } = options;\n const remainingColumnWidth: number | undefined =\n tableWidth === undefined ? undefined : calcRemainingColumnWidth(columns, tableWidth);\n const selectionColumn = createSelectionColumn(\n intl,\n selectionMode,\n selectionStyle,\n labelProperty\n );\n const columnDefs = columns.map((column, index) => {\n const columnWidth = column.width || remainingColumnWidth;\n const configuredId =\n column.id || (column.propertyName && slug(column.propertyName)) || String(index);\n return createColumn({\n id: \"result-list-col_\" + configuredId,\n column: column,\n intl: intl,\n columnWidth: columnWidth,\n formatOptions: formatOptions\n });\n });\n return [selectionColumn, ...columnDefs];\n}\n\ninterface CreateColumnOptions {\n id: string;\n column: ResultColumn;\n intl: PackageIntl;\n columnWidth?: number;\n formatOptions?: FormatOptions;\n}\n\nfunction createColumn(options: CreateColumnOptions) {\n const { id, column, columnWidth, formatOptions, intl } = options;\n const { propertyName, getPropertyValue } = column;\n\n if (getPropertyValue == null && propertyName == null) {\n throw new Error(\n \"Display columns are not yet implemented. You must either specify 'propertyName' or 'getPropertyValue'.\"\n );\n }\n\n return columnHelper.accessor(\n (feature: BaseFeature) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return getPropertyValue?.(feature) ?? feature.properties?.[propertyName!];\n },\n {\n id: id,\n cell: (info) => {\n const cellValue = info.getValue();\n if (column.renderCell) {\n return column.renderCell({\n feature: info.row.original,\n value: cellValue\n });\n }\n return defaultRenderCell(cellValue, intl, formatOptions);\n },\n header: column.displayName ?? column.propertyName,\n size: columnWidth\n }\n );\n}\n\nfunction defaultRenderCell(cellValue: unknown, intl: PackageIntl, formatOptions?: FormatOptions) {\n if (cellValue === null || cellValue === undefined) return \"\";\n const type = typeof cellValue;\n const formatNumber = (num: number | bigint) => {\n if (Number.isNaN(num)) return \"\";\n return intl.formatNumber(num, formatOptions?.numberOptions);\n };\n\n switch (type) {\n case \"number\": {\n return formatNumber(cellValue as number);\n }\n case \"bigint\": {\n return formatNumber(cellValue as bigint);\n }\n case \"boolean\": {\n return intl.formatMessage({ id: `displayBoolean.${cellValue}` });\n }\n case \"string\": {\n return cellValue as string;\n }\n case \"object\": {\n if (cellValue instanceof Date)\n return intl.formatDate(cellValue, formatOptions?.dateOptions);\n return cellValue.toString();\n }\n default:\n return String(cellValue);\n }\n}\n\nfunction createSelectionColumn(\n intl: PackageIntl,\n selectionMode: SelectionMode,\n selectionStyle: \"radio\" | \"checkbox\",\n labelProperty?: string\n) {\n return columnHelper.display({\n id: \"selection-buttons\",\n size: SELECT_COLUMN_SIZE,\n enableSorting: false,\n header: ({ table }) => {\n if (selectionMode !== \"multi\") return;\n\n return (\n <chakra.div\n display=\"inline-block\"\n onClick={(e) => {\n e.stopPropagation();\n }}\n className=\"result-list-select-all-container\"\n >\n {createSelectComponent({\n className: \"result-list-select-all-checkbox\",\n toolTipLabel: getCheckboxTooltip(table, intl),\n checked: table.getIsAllRowsSelected()\n ? true\n : table.getIsSomeRowsSelected()\n ? \"indeterminate\"\n : false,\n onChange(newIsChecked) {\n table.toggleAllRowsSelected(newIsChecked);\n }\n })}\n </chakra.div>\n );\n },\n cell: ({ row }) => {\n const className =\n selectionStyle === \"radio\"\n ? \"result-list-select-row-radio\"\n : \"result-list-select-row-checkbox\";\n const ariaLabel = intl.formatMessage(\n {\n id: \"ariaLabel.selectSingle\"\n },\n { featureProperty: getLabel(row.original, labelProperty) }\n );\n return (\n <chakra.div\n display=\"inline-block\"\n onClick={(e) => {\n e.stopPropagation();\n }}\n className=\"result-list-select-row-container\"\n >\n {createSelectComponent({\n mode: selectionStyle,\n className,\n checked: row.getIsSomeSelected() ? \"indeterminate\" : row.getIsSelected(),\n disabled: !row.getCanSelect(),\n onChange(newIsChecked) {\n row.toggleSelected(newIsChecked);\n },\n ariaLabel: ariaLabel\n })}\n </chakra.div>\n );\n }\n });\n}\n\nfunction getLabel(feature: BaseFeature, labelProperty: string | undefined) {\n if (labelProperty && feature.properties && feature.properties[labelProperty] != null) {\n return feature.properties[labelProperty].toString();\n }\n // use feature id as fallback if property not provided or does not exist for this feature\n return feature.id.toString();\n}\n\nfunction calcRemainingColumnWidth(\n columns: ResultColumn[],\n tableWidth: number,\n selectColumnWidth: number = SELECT_COLUMN_SIZE\n) {\n const fullWidth = columns.reduce((sum, column) => (column.width ?? 0) + sum, 0);\n const undefinedWidthCount = columns.reduce(\n (sum, column) => (column.width === undefined ? sum + 1 : sum),\n 0\n );\n const remainingWidth = tableWidth - selectColumnWidth - fullWidth;\n return remainingWidth / undefinedWidthCount;\n}\n\nfunction getCheckboxTooltip<Data>(table: TanstackTable<Data>, intl: PackageIntl) {\n if (table.getIsAllRowsSelected()) {\n return intl.formatMessage({ id: \"deSelectAllTooltip\" });\n } else {\n return intl.formatMessage({ id: \"selectAllTooltip\" });\n }\n}\n\nfunction slug(id: string) {\n return id\n .toLowerCase()\n .replace(/[^a-z0-9 -]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .replace(/-+/g, \"-\");\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"createColumns.js","sources":["createColumns.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { chakra } from \"@chakra-ui/react\";\nimport { BaseFeature } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { createColumnHelper, Table as TanstackTable } from \"@tanstack/react-table\";\nimport { FormatOptions, ResultColumn, SelectionMode } from \"../ResultList\";\nimport { createSelectComponent } from \"./SelectComponent\";\n\nexport const SELECT_COLUMN_SIZE = 70;\n\nconst columnHelper = createColumnHelper<BaseFeature>();\n\nexport interface CreateColumnsOptions {\n columns: ResultColumn[];\n intl: PackageIntl;\n tableWidth?: number;\n formatOptions?: FormatOptions;\n selectionMode: SelectionMode;\n selectionStyle: \"radio\" | \"checkbox\";\n labelProperty?: string;\n}\n\nexport function createColumns(options: CreateColumnsOptions) {\n const {\n columns,\n intl,\n tableWidth,\n formatOptions,\n selectionMode,\n selectionStyle,\n labelProperty\n } = options;\n const remainingColumnWidth: number | undefined =\n tableWidth === undefined ? undefined : calcRemainingColumnWidth(columns, tableWidth);\n const selectionColumn = createSelectionColumn(\n intl,\n selectionMode,\n selectionStyle,\n labelProperty\n );\n const columnDefs = columns.map((column, index) => {\n const columnWidth = column.width || remainingColumnWidth;\n const configuredId =\n column.id || (column.propertyName && slug(column.propertyName)) || String(index);\n return createColumn({\n id: \"result-list-col_\" + configuredId,\n column: column,\n intl: intl,\n columnWidth: columnWidth,\n formatOptions: formatOptions\n });\n });\n return [selectionColumn, ...columnDefs];\n}\n\ninterface CreateColumnOptions {\n id: string;\n column: ResultColumn;\n intl: PackageIntl;\n columnWidth?: number;\n formatOptions?: FormatOptions;\n}\n\nfunction createColumn(options: CreateColumnOptions) {\n const { id, column, columnWidth, formatOptions, intl } = options;\n const { propertyName, getPropertyValue } = column;\n\n if (getPropertyValue == null && propertyName == null) {\n throw new Error(\n \"Display columns are not yet implemented. You must either specify 'propertyName' or 'getPropertyValue'.\"\n );\n }\n\n return columnHelper.accessor(\n (feature: BaseFeature) => {\n // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion\n return getPropertyValue?.(feature) ?? feature.properties?.[propertyName!];\n },\n {\n id: id,\n cell: (info) => {\n const cellValue = info.getValue();\n if (column.renderCell) {\n return column.renderCell({\n feature: info.row.original,\n value: cellValue\n });\n }\n return defaultRenderCell(cellValue, intl, formatOptions);\n },\n header: column.displayName ?? column.propertyName,\n size: columnWidth\n }\n );\n}\n\nfunction defaultRenderCell(cellValue: unknown, intl: PackageIntl, formatOptions?: FormatOptions) {\n if (cellValue === null || cellValue === undefined) return \"\";\n const type = typeof cellValue;\n const formatNumber = (num: number | bigint) => {\n if (Number.isNaN(num)) return \"\";\n return intl.formatNumber(num, formatOptions?.numberOptions);\n };\n\n switch (type) {\n case \"number\": {\n return formatNumber(cellValue as number);\n }\n case \"bigint\": {\n return formatNumber(cellValue as bigint);\n }\n case \"boolean\": {\n return intl.formatMessage({ id: `displayBoolean.${cellValue}` });\n }\n case \"string\": {\n return cellValue as string;\n }\n case \"object\": {\n if (cellValue instanceof Date)\n return intl.formatDate(cellValue, formatOptions?.dateOptions);\n return cellValue.toString();\n }\n default:\n return String(cellValue);\n }\n}\n\nfunction createSelectionColumn(\n intl: PackageIntl,\n selectionMode: SelectionMode,\n selectionStyle: \"radio\" | \"checkbox\",\n labelProperty?: string\n) {\n return columnHelper.display({\n id: \"selection-buttons\",\n size: SELECT_COLUMN_SIZE,\n enableSorting: false,\n header: ({ table }) => {\n if (selectionMode !== \"multi\") return;\n\n return (\n <chakra.div\n display=\"inline-block\"\n onClick={(e) => {\n e.stopPropagation();\n }}\n className=\"result-list-select-all-container\"\n >\n {createSelectComponent({\n className: \"result-list-select-all-checkbox\",\n toolTipLabel: getCheckboxTooltip(table, intl),\n checked: table.getIsAllRowsSelected()\n ? true\n : table.getIsSomeRowsSelected()\n ? \"indeterminate\"\n : false,\n onChange(newIsChecked) {\n table.toggleAllRowsSelected(newIsChecked);\n }\n })}\n </chakra.div>\n );\n },\n cell: ({ row }) => {\n const className =\n selectionStyle === \"radio\"\n ? \"result-list-select-row-radio\"\n : \"result-list-select-row-checkbox\";\n const ariaLabel = intl.formatMessage(\n {\n id: \"ariaLabel.selectSingle\"\n },\n { featureProperty: getLabel(row.original, labelProperty) }\n );\n return (\n <chakra.div\n display=\"inline-block\"\n onClick={(e) => {\n e.stopPropagation();\n }}\n className=\"result-list-select-row-container\"\n >\n {createSelectComponent({\n mode: selectionStyle,\n className,\n checked: row.getIsSomeSelected() ? \"indeterminate\" : row.getIsSelected(),\n disabled: !row.getCanSelect(),\n onChange(newIsChecked) {\n row.toggleSelected(newIsChecked);\n },\n ariaLabel: ariaLabel\n })}\n </chakra.div>\n );\n }\n });\n}\n\nfunction getLabel(feature: BaseFeature, labelProperty: string | undefined) {\n if (labelProperty && feature.properties && feature.properties[labelProperty] != null) {\n return feature.properties[labelProperty].toString();\n }\n // use feature id as fallback if property not provided or does not exist for this feature\n return feature.id.toString();\n}\n\nfunction calcRemainingColumnWidth(\n columns: ResultColumn[],\n tableWidth: number,\n selectColumnWidth: number = SELECT_COLUMN_SIZE\n) {\n const fullWidth = columns.reduce((sum, column) => (column.width ?? 0) + sum, 0);\n const undefinedWidthCount = columns.reduce(\n (sum, column) => (column.width === undefined ? sum + 1 : sum),\n 0\n );\n const remainingWidth = tableWidth - selectColumnWidth - fullWidth;\n return remainingWidth / undefinedWidthCount;\n}\n\nfunction getCheckboxTooltip<Data>(table: TanstackTable<Data>, intl: PackageIntl) {\n if (table.getIsAllRowsSelected()) {\n return intl.formatMessage({ id: \"deSelectAllTooltip\" });\n } else {\n return intl.formatMessage({ id: \"selectAllTooltip\" });\n }\n}\n\nfunction slug(id: string) {\n return id\n .toLowerCase()\n .replace(/[^a-z0-9 -]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .replace(/-+/g, \"-\");\n}\n"],"names":[],"mappings":";;;;;AAUO,MAAM,kBAAA,GAAqB,EAAA;AAElC,MAAM,eAAe,kBAAA,EAAgC;AAY9C,SAAS,cAAc,OAAA,EAA+B;AACzD,EAAA,MAAM;AAAA,IACF,OAAA;AAAA,IACA,IAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,GACJ,GAAI,OAAA;AACJ,EAAA,MAAM,uBACF,UAAA,KAAe,MAAA,GAAY,MAAA,GAAY,wBAAA,CAAyB,SAAS,UAAU,CAAA;AACvF,EAAA,MAAM,eAAA,GAAkB,qBAAA;AAAA,IACpB,IAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,GACJ;AACA,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,GAAA,CAAI,CAAC,QAAQ,KAAA,KAAU;AAC9C,IAAA,MAAM,WAAA,GAAc,OAAO,KAAA,IAAS,oBAAA;AACpC,IAAA,MAAM,YAAA,GACF,MAAA,CAAO,EAAA,IAAO,MAAA,CAAO,YAAA,IAAgB,KAAK,MAAA,CAAO,YAAY,CAAA,IAAM,MAAA,CAAO,KAAK,CAAA;AACnF,IAAA,OAAO,YAAA,CAAa;AAAA,MAChB,IAAI,kBAAA,GAAqB,YAAA;AAAA,MACzB,MAAA;AAAA,MACA,IAAA;AAAA,MACA,WAAA;AAAA,MACA;AAAA,KACH,CAAA;AAAA,EACL,CAAC,CAAA;AACD,EAAA,OAAO,CAAC,eAAA,EAAiB,GAAG,UAAU,CAAA;AAC1C;AAUA,SAAS,aAAa,OAAA,EAA8B;AAChD,EAAA,MAAM,EAAE,EAAA,EAAI,MAAA,EAAQ,WAAA,EAAa,aAAA,EAAe,MAAK,GAAI,OAAA;AACzD,EAAA,MAAM,EAAE,YAAA,EAAc,gBAAA,EAAiB,GAAI,MAAA;AAE3C,EAAA,IAAI,gBAAA,IAAoB,IAAA,IAAQ,YAAA,IAAgB,IAAA,EAAM;AAClD,IAAA,MAAM,IAAI,KAAA;AAAA,MACN;AAAA,KACJ;AAAA,EACJ;AAEA,EAAA,OAAO,YAAA,CAAa,QAAA;AAAA,IAChB,CAAC,OAAA,KAAyB;AAEtB,MAAA,OAAO,gBAAA,GAAmB,OAAO,CAAA,IAAK,OAAA,CAAQ,aAAa,YAAa,CAAA;AAAA,IAC5E,CAAA;AAAA,IACA;AAAA,MACI,EAAA;AAAA,MACA,IAAA,EAAM,CAAC,IAAA,KAAS;AACZ,QAAA,MAAM,SAAA,GAAY,KAAK,QAAA,EAAS;AAChC,QAAA,IAAI,OAAO,UAAA,EAAY;AACnB,UAAA,OAAO,OAAO,UAAA,CAAW;AAAA,YACrB,OAAA,EAAS,KAAK,GAAA,CAAI,QAAA;AAAA,YAClB,KAAA,EAAO;AAAA,WACV,CAAA;AAAA,QACL;AACA,QAAA,OAAO,iBAAA,CAAkB,SAAA,EAAW,IAAA,EAAM,aAAa,CAAA;AAAA,MAC3D,CAAA;AAAA,MACA,MAAA,EAAQ,MAAA,CAAO,WAAA,IAAe,MAAA,CAAO,YAAA;AAAA,MACrC,IAAA,EAAM;AAAA;AACV,GACJ;AACJ;AAEA,SAAS,iBAAA,CAAkB,SAAA,EAAoB,IAAA,EAAmB,aAAA,EAA+B;AAC7F,EAAA,IAAI,SAAA,KAAc,IAAA,IAAQ,SAAA,KAAc,MAAA,EAAW,OAAO,EAAA;AAC1D,EAAA,MAAM,OAAO,OAAO,SAAA;AACpB,EAAA,MAAM,YAAA,GAAe,CAAC,GAAA,KAAyB;AAC3C,IAAA,IAAI,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,EAAG,OAAO,EAAA;AAC9B,IAAA,OAAO,IAAA,CAAK,YAAA,CAAa,GAAA,EAAK,aAAA,EAAe,aAAa,CAAA;AAAA,EAC9D,CAAA;AAEA,EAAA,QAAQ,IAAA;AAAM,IACV,KAAK,QAAA,EAAU;AACX,MAAA,OAAO,aAAa,SAAmB,CAAA;AAAA,IAC3C;AAAA,IACA,KAAK,QAAA,EAAU;AACX,MAAA,OAAO,aAAa,SAAmB,CAAA;AAAA,IAC3C;AAAA,IACA,KAAK,SAAA,EAAW;AACZ,MAAA,OAAO,KAAK,aAAA,CAAc,EAAE,IAAI,CAAA,eAAA,EAAkB,SAAS,IAAI,CAAA;AAAA,IACnE;AAAA,IACA,KAAK,QAAA,EAAU;AACX,MAAA,OAAO,SAAA;AAAA,IACX;AAAA,IACA,KAAK,QAAA,EAAU;AACX,MAAA,IAAI,SAAA,YAAqB,IAAA;AACrB,QAAA,OAAO,IAAA,CAAK,UAAA,CAAW,SAAA,EAAW,aAAA,EAAe,WAAW,CAAA;AAChE,MAAA,OAAO,UAAU,QAAA,EAAS;AAAA,IAC9B;AAAA,IACA;AACI,MAAA,OAAO,OAAO,SAAS,CAAA;AAAA;AAEnC;AAEA,SAAS,qBAAA,CACL,IAAA,EACA,aAAA,EACA,cAAA,EACA,aAAA,EACF;AACE,EAAA,OAAO,aAAa,OAAA,CAAQ;AAAA,IACxB,EAAA,EAAI,mBAAA;AAAA,IACJ,IAAA,EAAM,kBAAA;AAAA,IACN,aAAA,EAAe,KAAA;AAAA,IACf,MAAA,EAAQ,CAAC,EAAE,KAAA,EAAM,KAAM;AACnB,MAAA,IAAI,kBAAkB,OAAA,EAAS;AAE/B,MAAA,uBACI,GAAA;AAAA,QAAC,MAAA,CAAO,GAAA;AAAA,QAAP;AAAA,UACG,OAAA,EAAQ,cAAA;AAAA,UACR,OAAA,EAAS,CAAC,CAAA,KAAM;AACZ,YAAA,CAAA,CAAE,eAAA,EAAgB;AAAA,UACtB,CAAA;AAAA,UACA,SAAA,EAAU,kCAAA;AAAA,UAET,QAAA,EAAA,qBAAA,CAAsB;AAAA,YACnB,SAAA,EAAW,iCAAA;AAAA,YACX,YAAA,EAAc,kBAAA,CAAmB,KAAA,EAAO,IAAI,CAAA;AAAA,YAC5C,OAAA,EAAS,MAAM,oBAAA,EAAqB,GAC9B,OACA,KAAA,CAAM,qBAAA,KACJ,eAAA,GACA,KAAA;AAAA,YACR,SAAS,YAAA,EAAc;AACnB,cAAA,KAAA,CAAM,sBAAsB,YAAY,CAAA;AAAA,YAC5C;AAAA,WACH;AAAA;AAAA,OACL;AAAA,IAER,CAAA;AAAA,IACA,IAAA,EAAM,CAAC,EAAE,GAAA,EAAI,KAAM;AACf,MAAA,MAAM,SAAA,GACF,cAAA,KAAmB,OAAA,GACb,8BAAA,GACA,iCAAA;AACV,MAAA,MAAM,YAAY,IAAA,CAAK,aAAA;AAAA,QACnB;AAAA,UACI,EAAA,EAAI;AAAA,SACR;AAAA,QACA,EAAE,eAAA,EAAiB,QAAA,CAAS,GAAA,CAAI,QAAA,EAAU,aAAa,CAAA;AAAE,OAC7D;AACA,MAAA,uBACI,GAAA;AAAA,QAAC,MAAA,CAAO,GAAA;AAAA,QAAP;AAAA,UACG,OAAA,EAAQ,cAAA;AAAA,UACR,OAAA,EAAS,CAAC,CAAA,KAAM;AACZ,YAAA,CAAA,CAAE,eAAA,EAAgB;AAAA,UACtB,CAAA;AAAA,UACA,SAAA,EAAU,kCAAA;AAAA,UAET,QAAA,EAAA,qBAAA,CAAsB;AAAA,YACnB,IAAA,EAAM,cAAA;AAAA,YACN,SAAA;AAAA,YACA,SAAS,GAAA,CAAI,iBAAA,EAAkB,GAAI,eAAA,GAAkB,IAAI,aAAA,EAAc;AAAA,YACvE,QAAA,EAAU,CAAC,GAAA,CAAI,YAAA,EAAa;AAAA,YAC5B,SAAS,YAAA,EAAc;AACnB,cAAA,GAAA,CAAI,eAAe,YAAY,CAAA;AAAA,YACnC,CAAA;AAAA,YACA;AAAA,WACH;AAAA;AAAA,OACL;AAAA,IAER;AAAA,GACH,CAAA;AACL;AAEA,SAAS,QAAA,CAAS,SAAsB,aAAA,EAAmC;AACvE,EAAA,IAAI,iBAAiB,OAAA,CAAQ,UAAA,IAAc,QAAQ,UAAA,CAAW,aAAa,KAAK,IAAA,EAAM;AAClF,IAAA,OAAO,OAAA,CAAQ,UAAA,CAAW,aAAa,CAAA,CAAE,QAAA,EAAS;AAAA,EACtD;AAEA,EAAA,OAAO,OAAA,CAAQ,GAAG,QAAA,EAAS;AAC/B;AAEA,SAAS,wBAAA,CACL,OAAA,EACA,UAAA,EACA,iBAAA,GAA4B,kBAAA,EAC9B;AACE,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,MAAA,CAAO,CAAC,GAAA,EAAK,YAAY,MAAA,CAAO,KAAA,IAAS,CAAA,IAAK,GAAA,EAAK,CAAC,CAAA;AAC9E,EAAA,MAAM,sBAAsB,OAAA,CAAQ,MAAA;AAAA,IAChC,CAAC,GAAA,EAAK,MAAA,KAAY,OAAO,KAAA,KAAU,MAAA,GAAY,MAAM,CAAA,GAAI,GAAA;AAAA,IACzD;AAAA,GACJ;AACA,EAAA,MAAM,cAAA,GAAiB,aAAa,iBAAA,GAAoB,SAAA;AACxD,EAAA,OAAO,cAAA,GAAiB,mBAAA;AAC5B;AAEA,SAAS,kBAAA,CAAyB,OAA4B,IAAA,EAAmB;AAC7E,EAAA,IAAI,KAAA,CAAM,sBAAqB,EAAG;AAC9B,IAAA,OAAO,IAAA,CAAK,aAAA,CAAc,EAAE,EAAA,EAAI,sBAAsB,CAAA;AAAA,EAC1D,CAAA,MAAO;AACH,IAAA,OAAO,IAAA,CAAK,aAAA,CAAc,EAAE,EAAA,EAAI,oBAAoB,CAAA;AAAA,EACxD;AACJ;AAEA,SAAS,KAAK,EAAA,EAAY;AACtB,EAAA,OAAO,EAAA,CACF,WAAA,EAAY,CACZ,OAAA,CAAQ,cAAA,EAAgB,EAAE,CAAA,CAC1B,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA,CACnB,OAAA,CAAQ,OAAO,GAAG,CAAA;AAC3B;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSetupTable.js","sources":["useSetupTable.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { BaseFeature } from \"@open-pioneer/map\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport {\n RowSelectionState,\n SortingState,\n Updater,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable\n} from \"@tanstack/react-table\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { usePrevious } from \"react-use\";\nimport { DataTableProps } from \"./DataTable\";\n\nexport function useSetupTable<Data extends BaseFeature>(props: DataTableProps<Data>) {\n const { data, columns, onSelectionChange: onSelectionChange, selectionMode } = props;\n const [sorting, setSorting] = useState<SortingState>([]);\n const previousSelectionMode = usePrevious(props.selectionMode);\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({});\n\n // Only sort by columns which actually exist\n const actualSort = useMemo(() => {\n return sorting.filter((sort) => columns.some((c) => c.id === sort.id));\n }, [sorting, columns]);\n\n const updateSelection = useEvent((updaterOrValue: Updater<RowSelectionState>) => {\n const newSelection = applyUpdate(rowSelection, updaterOrValue);\n if (newSelection === rowSelection) {\n return;\n }\n\n setRowSelection(newSelection);\n\n if (onSelectionChange) {\n const rowsById = table.getCoreRowModel().rowsById;\n const selectedFeatures: BaseFeature[] = [];\n for (const rowId of Object.keys(newSelection)) {\n if (!newSelection[rowId]) {\n continue;\n }\n\n const row = rowsById[rowId];\n if (!row) {\n continue;\n }\n\n selectedFeatures.push(row.original);\n }\n\n onSelectionChange({\n features: selectedFeatures,\n getFeatureIds: () => {\n return selectedFeatures.map((feature: BaseFeature) => feature.id);\n }\n });\n }\n });\n\n // eslint-disable-next-line react-hooks/incompatible-library\n const table = useReactTable({\n columns: columns,\n data,\n getRowId(feature) {\n return String(feature.id);\n },\n columnResizeMode: \"onChange\",\n getCoreRowModel: getCoreRowModel(),\n enableRowSelection: true,\n enableMultiRowSelection: selectionMode === \"multi\",\n onRowSelectionChange: updateSelection,\n onSortingChange: setSorting,\n getSortedRowModel: getSortedRowModel(),\n state: {\n sorting: actualSort,\n rowSelection\n }\n });\n\n useEffect(() => {\n if (previousSelectionMode && selectionMode !== previousSelectionMode) {\n table.resetRowSelection();\n }\n }, [table, previousSelectionMode, selectionMode]);\n\n return { table, sorting, rowSelection };\n}\n\nfunction applyUpdate<T>(current: T, updaterOrValue: Updater<T>): T {\n if (typeof updaterOrValue === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (updaterOrValue as any)(current);\n }\n return updaterOrValue;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useSetupTable.js","sources":["useSetupTable.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { BaseFeature } from \"@open-pioneer/map\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport {\n RowSelectionState,\n SortingState,\n Updater,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable\n} from \"@tanstack/react-table\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { usePrevious } from \"react-use\";\nimport { DataTableProps } from \"./DataTable\";\n\nexport function useSetupTable<Data extends BaseFeature>(props: DataTableProps<Data>) {\n const { data, columns, onSelectionChange, selectionMode } = props;\n const [sorting, setSorting] = useState<SortingState>([]);\n const previousSelectionMode = usePrevious(props.selectionMode);\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({});\n\n // Only sort by columns which actually exist\n const actualSort = useMemo(() => {\n return sorting.filter((sort) => columns.some((c) => c.id === sort.id));\n }, [sorting, columns]);\n\n const updateSelection = useEvent((updaterOrValue: Updater<RowSelectionState>) => {\n const newSelection = applyUpdate(rowSelection, updaterOrValue);\n if (newSelection === rowSelection) {\n return;\n }\n\n setRowSelection(newSelection);\n\n if (onSelectionChange) {\n const rowsById = table.getCoreRowModel().rowsById;\n const selectedFeatures: BaseFeature[] = [];\n for (const rowId of Object.keys(newSelection)) {\n if (!newSelection[rowId]) {\n continue;\n }\n\n const row = rowsById[rowId];\n if (!row) {\n continue;\n }\n\n selectedFeatures.push(row.original);\n }\n\n onSelectionChange({\n features: selectedFeatures,\n getFeatureIds: () => {\n return selectedFeatures.map((feature: BaseFeature) => feature.id);\n }\n });\n }\n });\n\n const table = useReactTable({\n columns: columns,\n data,\n getRowId(feature) {\n return String(feature.id);\n },\n columnResizeMode: \"onChange\",\n getCoreRowModel: getCoreRowModel(),\n enableRowSelection: true,\n enableMultiRowSelection: selectionMode === \"multi\",\n onRowSelectionChange: updateSelection,\n onSortingChange: setSorting,\n getSortedRowModel: getSortedRowModel(),\n state: {\n sorting: actualSort,\n rowSelection\n }\n });\n\n useEffect(() => {\n if (previousSelectionMode && selectionMode !== previousSelectionMode) {\n table.resetRowSelection();\n }\n }, [table, previousSelectionMode, selectionMode]);\n\n return { table, sorting, rowSelection };\n}\n\nfunction applyUpdate<T>(current: T, updaterOrValue: Updater<T>): T {\n if (typeof updaterOrValue === \"function\") {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n return (updaterOrValue as any)(current);\n }\n return updaterOrValue;\n}\n"],"names":[],"mappings":"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"}
package/ResultList.js CHANGED
@@ -4,8 +4,8 @@ import { useMapModelValue } from '@open-pioneer/map';
4
4
  import { useCommonComponentProps, mergeChakraProps } from '@open-pioneer/react-utils';
5
5
  import { useIntl } from './_virtual/hooks.js';
6
6
  import { useRef, useMemo, useEffect, useState } from 'react';
7
- import { DataTable } from './DataTable/DataTable.js';
8
7
  import { createColumns } from './DataTable/createColumns.js';
8
+ import { DataTable } from './DataTable/DataTable.js';
9
9
 
10
10
  const ResultList = (props) => {
11
11
  const { containerProps } = useCommonComponentProps("result-list", props);
package/ResultList.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ResultList.js","sources":["ResultList.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Box, BoxProps } from \"@chakra-ui/react\";\nimport { FormatNumberOptions } from \"@formatjs/intl\";\nimport {\n BaseFeature,\n HighlightOptions,\n MapModelProps,\n useMapModelValue,\n ZoomOptions\n} from \"@open-pioneer/map\";\nimport {\n CommonComponentProps,\n mergeChakraProps,\n useCommonComponentProps\n} from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, ReactNode, RefObject, useEffect, useMemo, useRef, useState } from \"react\";\nimport { DataTable } from \"./DataTable/DataTable\";\nimport { createColumns } from \"./DataTable/createColumns\";\n\n/**\n * Configures a column in the result list component.\n *\n * A column typically renders a property from the underlying feature.\n */\nexport interface ResultColumn {\n /**\n * Use this option to define an explicit column id.\n * This can be helpful to track your column when it moves in the table (for example, the sort order can be maintained).\n *\n * If this is not defined, {@link propertyName} will serve as a fallback.\n * If that is also not defined, the column index will be used instead.\n *\n * It is recommended to specify an id, if no {@link propertyName} has been set, because the\n * column index fallback is not advised.\n */\n id?: string;\n\n /**\n * The display name of this column.\n *\n * If no `displayName` has been configured, {@link propertyName} will serve as a fallback value.\n * If `propertyName` is also undefined, no column header will be rendered at all.\n */\n displayName?: string;\n\n /**\n * The width of this column, in pixels.\n */\n width?: number;\n\n /**\n * The property name to render.\n *\n * The value is expected to be available as `feature.properties[propertyName]`.\n *\n * See also {@link getPropertyValue}.\n */\n propertyName?: string;\n\n /**\n * Define this function to return a custom property value for this column.\n *\n * This can be used to create derived columns (by combining multiple properties into one value)\n * or to create columns for property that don't exist directly on the feature.\n *\n * The return value of this function will be rendered by the table.\n */\n getPropertyValue?: (feature: BaseFeature) => unknown;\n\n /** Custom render function to render a table cell in this column. */\n renderCell?: (context: RenderCellContext) => ReactNode;\n}\n\n/**\n * The arguments passed to {@link ResultColumn.renderCell | renderCell}.\n */\nexport interface RenderCellContext {\n /**\n * The feature in this row.\n */\n feature: BaseFeature;\n\n /**\n * The value of this column.\n * May be undefined if neither `propertyName` nor `getPropertyValue` was specified on the column.\n */\n value: unknown;\n}\n\n/**\n * To specify the format of cell values if they are of number or date type.\n */\nexport interface FormatOptions {\n /**\n * To specify the format of number type values\n */\n numberOptions?: FormatNumberOptions;\n /**\n * To specify the format of date type values\n */\n dateOptions?: Intl.DateTimeFormatOptions;\n}\n\n/**\n * Configures the result list's content.\n */\nexport interface ResultListInput {\n /**\n * Configures the columns shown by the result list.\n */\n columns: ResultColumn[];\n\n /**\n * Property of the features in the result list that is used to enrich aria labels with context.\n *\n * The feature's id is used by default or as fallback if this option is not configured or the\n * property does not exist on the feature.\n */\n labelProperty?: string;\n\n /**\n * The data shown by the result list component.\n * Every feature will be rendered as an individual row.\n */\n data: BaseFeature[];\n\n /**\n * Optional formatOptions to specify the `numberOptions` for number type values and\n * `dateOptions` to specify the format of date type values\n */\n formatOptions?: FormatOptions;\n}\n\n/**\n * Emitted when the selection within the ResultList changes.\n */\nexport interface ResultListSelectionChangeEvent {\n features: BaseFeature[];\n getFeatureIds: () => (number | string)[];\n}\n\n/**\n * Specifies whether it should be possible to select multiple or only single rows.\n */\nexport type SelectionMode = \"multi\" | \"single\";\n\n/**\n * Properties supported by the {@link ResultList} component.\n */\nexport interface ResultListProps extends CommonComponentProps, MapModelProps {\n /**\n * Describes the data rendered by the component.\n */\n input: ResultListInput;\n\n /**\n * The selection mode used by the result list. Defaults to `\"multi\"`.\n */\n selectionMode?: SelectionMode;\n\n /**\n * The style used for the selection controls in a row.\n * Defaults to `\"checkbox\"` if `selectionMode` is `\"multi\"`, or `\"radio\"` if `selectionMode` is `\"single\"`.\n *\n * Note: `\"radio\"` can not be used together with multi selection.\n */\n selectionStyle?: \"radio\" | \"checkbox\";\n\n /**\n * This handler is called whenever the user has changed the selected features in the result-list.\n */\n onSelectionChange?: (event: ResultListSelectionChangeEvent) => void;\n\n /**\n * Specifies if the map should zoom to features when they are loaded into the result-list. Defaults to true.\n */\n enableZoom?: boolean;\n\n /**\n * Should data be highlighted in the map. Default true.\n */\n enableHighlight?: boolean;\n\n /**\n * Optional styling option\n */\n highlightOptions?: HighlightOptions;\n\n /**\n * Optional zooming options\n */\n zoomOptions?: ZoomOptions;\n\n /**\n * Should each row be memoized to improve render performance. Default `false`.\n */\n memoizeRows?: boolean;\n}\n\n/**\n * A component that displays a set of features as a list.\n */\nexport const ResultList: FC<ResultListProps> = (props) => {\n const { containerProps } = useCommonComponentProps(\"result-list\", props);\n const intl = useIntl();\n const map = useMapModelValue(props);\n const {\n input: { data, columns, labelProperty, formatOptions },\n memoizeRows = false,\n onSelectionChange,\n enableZoom = true,\n zoomOptions,\n enableHighlight = true,\n selectionMode = \"multi\",\n selectionStyle = selectionMode === \"single\" ? \"radio\" : \"checkbox\",\n highlightOptions\n } = props;\n\n if (columns.length === 0) {\n throw Error(\"No columns were defined. The result list cannot be displayed.\");\n }\n\n if (selectionMode === \"multi\" && selectionStyle === \"radio\") {\n throw new Error(\"Cannot mix multi selection with selectionStyle 'radio'.\");\n }\n\n const containerRef = useRef<HTMLDivElement>(null);\n const tableWidth = useTableWidth(containerRef);\n const dataTableColumns = useMemo(\n () =>\n createColumns({\n columns: columns,\n intl: intl,\n tableWidth: tableWidth,\n formatOptions: formatOptions,\n selectionMode,\n selectionStyle,\n labelProperty\n }),\n [columns, intl, tableWidth, formatOptions, selectionMode, selectionStyle, labelProperty]\n );\n\n useEffect(() => {\n if (enableZoom) {\n map.zoom(data, zoomOptions);\n }\n\n if (enableHighlight) {\n const highlight = map.highlights.add(data, highlightOptions);\n return () => highlight.destroy();\n }\n }, [map, data, zoomOptions, enableZoom, enableHighlight, highlightOptions]);\n\n const mergedBoxProps = useMemo(\n () => mergeChakraProps<BoxProps>({ height: \"100%\", overflowY: \"auto\" }, containerProps),\n [containerProps]\n );\n return (\n <Box ref={containerRef} {...mergedBoxProps}>\n <DataTable\n columns={dataTableColumns}\n data={data}\n memoizeRows={memoizeRows}\n selectionMode={selectionMode}\n onSelectionChange={onSelectionChange}\n />\n </Box>\n );\n};\n\nfunction useTableWidth(tableRef: RefObject<HTMLDivElement | null>) {\n const [tableWidth, setTableWidth] = useState<number>();\n\n useEffect(() => {\n if (!tableRef?.current) return;\n const resizeObserver = new ResizeObserver((event) => {\n // Depending on the layout, you may need to swap inlineSize with blockSize\n // https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/contentBoxSize\n const width = event[0]?.contentBoxSize[0]?.inlineSize;\n if (width != null) {\n setTableWidth(width);\n }\n });\n resizeObserver.observe(tableRef.current);\n return () => resizeObserver.disconnect();\n }, [tableRef]);\n return tableWidth;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ResultList.js","sources":["ResultList.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Box, BoxProps } from \"@chakra-ui/react\";\nimport { FormatNumberOptions } from \"@formatjs/intl\";\nimport {\n BaseFeature,\n HighlightOptions,\n MapModelProps,\n useMapModelValue,\n ZoomOptions\n} from \"@open-pioneer/map\";\nimport {\n CommonComponentProps,\n mergeChakraProps,\n useCommonComponentProps\n} from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, ReactNode, RefObject, useEffect, useMemo, useRef, useState } from \"react\";\nimport { createColumns } from \"./DataTable/createColumns\";\nimport { DataTable } from \"./DataTable/DataTable\";\n\n/**\n * Configures a column in the result list component.\n *\n * A column typically renders a property from the underlying feature.\n */\nexport interface ResultColumn {\n /**\n * Use this option to define an explicit column id.\n * This can be helpful to track your column when it moves in the table (for example, the sort order can be maintained).\n *\n * If this is not defined, {@link propertyName} will serve as a fallback.\n * If that is also not defined, the column index will be used instead.\n *\n * It is recommended to specify an id, if no {@link propertyName} has been set, because the\n * column index fallback is not advised.\n */\n id?: string;\n\n /**\n * The display name of this column.\n *\n * If no `displayName` has been configured, {@link propertyName} will serve as a fallback value.\n * If `propertyName` is also undefined, no column header will be rendered at all.\n */\n displayName?: string;\n\n /**\n * The width of this column, in pixels.\n */\n width?: number;\n\n /**\n * The property name to render.\n *\n * The value is expected to be available as `feature.properties[propertyName]`.\n *\n * See also {@link getPropertyValue}.\n */\n propertyName?: string;\n\n /**\n * Define this function to return a custom property value for this column.\n *\n * This can be used to create derived columns (by combining multiple properties into one value)\n * or to create columns for property that don't exist directly on the feature.\n *\n * The return value of this function will be rendered by the table.\n */\n getPropertyValue?: (feature: BaseFeature) => unknown;\n\n /** Custom render function to render a table cell in this column. */\n renderCell?: (context: RenderCellContext) => ReactNode;\n}\n\n/**\n * The arguments passed to {@link ResultColumn.renderCell | renderCell}.\n */\nexport interface RenderCellContext {\n /**\n * The feature in this row.\n */\n feature: BaseFeature;\n\n /**\n * The value of this column.\n * May be undefined if neither `propertyName` nor `getPropertyValue` was specified on the column.\n */\n value: unknown;\n}\n\n/**\n * To specify the format of cell values if they are of number or date type.\n */\nexport interface FormatOptions {\n /**\n * To specify the format of number type values\n */\n numberOptions?: FormatNumberOptions;\n /**\n * To specify the format of date type values\n */\n dateOptions?: Intl.DateTimeFormatOptions;\n}\n\n/**\n * Configures the result list's content.\n */\nexport interface ResultListInput {\n /**\n * Configures the columns shown by the result list.\n */\n columns: ResultColumn[];\n\n /**\n * Property of the features in the result list that is used to enrich aria labels with context.\n *\n * The feature's id is used by default or as fallback if this option is not configured or the\n * property does not exist on the feature.\n */\n labelProperty?: string;\n\n /**\n * The data shown by the result list component.\n * Every feature will be rendered as an individual row.\n */\n data: BaseFeature[];\n\n /**\n * Optional formatOptions to specify the `numberOptions` for number type values and\n * `dateOptions` to specify the format of date type values\n */\n formatOptions?: FormatOptions;\n}\n\n/**\n * Emitted when the selection within the ResultList changes.\n */\nexport interface ResultListSelectionChangeEvent {\n features: BaseFeature[];\n getFeatureIds: () => (number | string)[];\n}\n\n/**\n * Specifies whether it should be possible to select multiple or only single rows.\n */\nexport type SelectionMode = \"multi\" | \"single\";\n\n/**\n * Properties supported by the {@link ResultList} component.\n */\nexport interface ResultListProps extends CommonComponentProps, MapModelProps {\n /**\n * Describes the data rendered by the component.\n */\n input: ResultListInput;\n\n /**\n * The selection mode used by the result list. Defaults to `\"multi\"`.\n */\n selectionMode?: SelectionMode;\n\n /**\n * The style used for the selection controls in a row.\n * Defaults to `\"checkbox\"` if `selectionMode` is `\"multi\"`, or `\"radio\"` if `selectionMode` is `\"single\"`.\n *\n * Note: `\"radio\"` can not be used together with multi selection.\n */\n selectionStyle?: \"radio\" | \"checkbox\";\n\n /**\n * This handler is called whenever the user has changed the selected features in the result-list.\n */\n onSelectionChange?: (event: ResultListSelectionChangeEvent) => void;\n\n /**\n * Specifies if the map should zoom to features when they are loaded into the result-list. Defaults to true.\n */\n enableZoom?: boolean;\n\n /**\n * Should data be highlighted in the map. Default true.\n */\n enableHighlight?: boolean;\n\n /**\n * Optional styling option\n */\n highlightOptions?: HighlightOptions;\n\n /**\n * Optional zooming options\n */\n zoomOptions?: ZoomOptions;\n\n /**\n * Should each row be memoized to improve render performance. Default `false`.\n */\n memoizeRows?: boolean;\n}\n\n/**\n * A component that displays a set of features as a list.\n */\nexport const ResultList: FC<ResultListProps> = (props) => {\n const { containerProps } = useCommonComponentProps(\"result-list\", props);\n const intl = useIntl();\n const map = useMapModelValue(props);\n const {\n input: { data, columns, labelProperty, formatOptions },\n memoizeRows = false,\n onSelectionChange,\n enableZoom = true,\n zoomOptions,\n enableHighlight = true,\n selectionMode = \"multi\",\n selectionStyle = selectionMode === \"single\" ? \"radio\" : \"checkbox\",\n highlightOptions\n } = props;\n\n if (columns.length === 0) {\n throw Error(\"No columns were defined. The result list cannot be displayed.\");\n }\n\n if (selectionMode === \"multi\" && selectionStyle === \"radio\") {\n throw new Error(\"Cannot mix multi selection with selectionStyle 'radio'.\");\n }\n\n const containerRef = useRef<HTMLDivElement>(null);\n const tableWidth = useTableWidth(containerRef);\n const dataTableColumns = useMemo(\n () =>\n createColumns({\n columns: columns,\n intl: intl,\n tableWidth: tableWidth,\n formatOptions: formatOptions,\n selectionMode,\n selectionStyle,\n labelProperty\n }),\n [columns, intl, tableWidth, formatOptions, selectionMode, selectionStyle, labelProperty]\n );\n\n useEffect(() => {\n if (enableZoom) {\n map.zoom(data, zoomOptions);\n }\n\n if (enableHighlight) {\n const highlight = map.highlights.add(data, highlightOptions);\n return () => highlight.destroy();\n }\n }, [map, data, zoomOptions, enableZoom, enableHighlight, highlightOptions]);\n\n const mergedBoxProps = useMemo(\n () => mergeChakraProps<BoxProps>({ height: \"100%\", overflowY: \"auto\" }, containerProps),\n [containerProps]\n );\n return (\n <Box ref={containerRef} {...mergedBoxProps}>\n <DataTable\n columns={dataTableColumns}\n data={data}\n memoizeRows={memoizeRows}\n selectionMode={selectionMode}\n onSelectionChange={onSelectionChange}\n />\n </Box>\n );\n};\n\nfunction useTableWidth(tableRef: RefObject<HTMLDivElement | null>) {\n const [tableWidth, setTableWidth] = useState<number>();\n\n useEffect(() => {\n if (!tableRef?.current) return;\n const resizeObserver = new ResizeObserver((event) => {\n // Depending on the layout, you may need to swap inlineSize with blockSize\n // https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/contentBoxSize\n const width = event[0]?.contentBoxSize[0]?.inlineSize;\n if (width != null) {\n setTableWidth(width);\n }\n });\n resizeObserver.observe(tableRef.current);\n return () => resizeObserver.disconnect();\n }, [tableRef]);\n return tableWidth;\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@open-pioneer/result-list",
4
- "version": "1.4.0-dev.20260727093741",
4
+ "version": "1.4.0",
5
5
  "description": "This package provides a UI component to display features and their attributes.",
6
6
  "keywords": [
7
7
  "open-pioneer-trails"
@@ -16,17 +16,17 @@
16
16
  "dependencies": {
17
17
  "@chakra-ui/react": "^3.36.1",
18
18
  "@conterra/reactivity-core": "^0.8.6",
19
- "@open-pioneer/reactivity": "4.7.0-dev.20260727091735",
20
- "@open-pioneer/core": "4.7.0-dev.20260727091735",
21
- "@open-pioneer/chakra-snippets": "4.7.0-dev.20260727091735",
22
- "@open-pioneer/react-utils": "4.7.0-dev.20260727091735",
23
- "@open-pioneer/runtime": "4.7.0-dev.20260727091735",
19
+ "@open-pioneer/chakra-snippets": "^4.7.0",
20
+ "@open-pioneer/core": "^4.7.0",
21
+ "@open-pioneer/react-utils": "^4.7.0",
22
+ "@open-pioneer/reactivity": "^4.7.0",
23
+ "@open-pioneer/runtime": "^4.7.0",
24
24
  "@tanstack/react-table": "^8.21.3",
25
25
  "ol": "^10.9.0",
26
26
  "react": "^19.2.8",
27
- "react-use": "^17.6.1",
28
27
  "react-icons": "^5.7.0",
29
- "@open-pioneer/map": "1.4.0-dev.20260727093741"
28
+ "react-use": "^17.6.1",
29
+ "@open-pioneer/map": "1.4.0"
30
30
  },
31
31
  "exports": {
32
32
  "./package.json": "./package.json",