From 3eaf269cbc30c8e4679c9d891c008c4e6ef736eb Mon Sep 17 00:00:00 2001 From: Alexandre Philibeaux Date: Thu, 26 Dec 2024 12:35:06 +0100 Subject: [PATCH] feat(list): use list context on Table component Signed-off-by: Alexandre Philibeaux --- packages/ui/src/components/Checkbox/index.tsx | 2 +- .../ui/src/components/List/ListContext.tsx | 73 +++-- packages/ui/src/components/List/Row.tsx | 13 +- packages/ui/src/components/List/index.tsx | 9 +- packages/ui/src/components/Table/Row.tsx | 7 +- .../ui/src/components/Table/TableContext.tsx | 296 ++---------------- .../__snapshots__/index.test.tsx.snap | 102 +----- .../components/Table/__tests__/index.test.tsx | 11 +- packages/ui/src/components/Table/index.tsx | 18 +- 9 files changed, 126 insertions(+), 405 deletions(-) diff --git a/packages/ui/src/components/Checkbox/index.tsx b/packages/ui/src/components/Checkbox/index.tsx index 91b69b5866..a14433a376 100644 --- a/packages/ui/src/components/Checkbox/index.tsx +++ b/packages/ui/src/components/Checkbox/index.tsx @@ -335,7 +335,7 @@ export const Checkbox = forwardRef( const uniqId = useId() const localId = id ?? uniqId - const isDisabled = disabled || progress ? true : false + const isDisabled = disabled || progress /** * note: checked should be true | undefined as it's seems to break e2e playwright test actually * as the checked attribue is added to html, maybe related to playwright toCheck code || emotion should not add this attributes when it's false or react 19 related ? diff --git a/packages/ui/src/components/List/ListContext.tsx b/packages/ui/src/components/List/ListContext.tsx index 308958a6f1..05db18a3b1 100644 --- a/packages/ui/src/components/List/ListContext.tsx +++ b/packages/ui/src/components/List/ListContext.tsx @@ -37,6 +37,7 @@ export type ListContextValue = { registerSelectableRow: (rowId: string) => () => void allRowSelectValue: ComponentProps['checked'] checkboxAllHandler: (event: ChangeEvent) => void + subscribeHandler: () => void columns: ColumnProps[] inRange: string[] refList: RefObject @@ -194,6 +195,7 @@ export const ListProvider = ({ ) const [lastCheckedIndex, setLastCheckedIndex] = useState(null) + const [isShiftEvent, setIsShiftEvent] = useState(false) const [inRange, setInRange] = useState([]) const checkboxAllHandler: ListContextValue['checkboxAllHandler'] = @@ -210,20 +212,18 @@ export const ListProvider = ({ } }, [allRowSelectValue, unselectAll, selectAll]) - useEffect(() => { + const subscribeHandler = useCallback(() => { const handlers: (() => void)[] = [] if (refList.current) { const handleClick = (index: number, isShiftPressed: boolean) => { if (index !== 0) { - setLastCheckedIndex(index) - // Only handle shift click event + // Only handle shift click event, onChangeHandler will controle naturals events if (isShiftPressed && lastCheckedIndex !== null) { + setIsShiftEvent(true) const start = Math.min(lastCheckedIndex, index) const end = Math.max(lastCheckedIndex, index) - const newSelectedRowIds = { - ...selectedRowIds, - } + const newSelectedRowIds = structuredClone(selectedRowIds) for (let i = start; i <= end; i += 1) { const checkbox = refList.current[i] @@ -236,7 +236,10 @@ export const ListProvider = ({ } } } + setSelectedRowIds(newSelectedRowIds) + setInRange([]) + if (onSelectedChange) { onSelectedChange( Object.keys(newSelectedRowIds).filter( @@ -246,6 +249,9 @@ export const ListProvider = ({ } } } else setLastCheckedIndex(null) + + // clean up + setIsShiftEvent(false) } const handleHover = ( @@ -253,11 +259,11 @@ export const ListProvider = ({ isShiftPressed: boolean, leaving: boolean, ) => { - const newRange: string[] = [] - if (isShiftPressed && lastCheckedIndex !== null) { const start = Math.min(lastCheckedIndex, index) - const end = Math.max(lastCheckedIndex, index) + const end = Math.max(lastCheckedIndex, index + 1) + + const newRange: string[] = [] for (let i = start; i < end; i += 1) { const checkbox = refList.current[i] @@ -265,41 +271,55 @@ export const ListProvider = ({ newRange.push(checkbox.value) } } + setInRange([...new Set(newRange)]) + } + + if (!lastCheckedIndex) { + if (index < refList.current.length && index > 0) { + setLastCheckedIndex(index) + } } - setInRange(newRange) } - const handleOnChange = (index: number, checked: boolean) => { - const checkbox = refList.current[index] - const checkboxValue = checkbox.value - if (checked) selectRow(checkboxValue) - else unselectRow(checkboxValue) + const handleOnChange = (index: number) => { + // if it's shiftEvent it's control by clickEvent + if (!isShiftEvent) { + const checkbox = refList.current[index] + if (checkbox.checked) { + unselectRow(checkbox.value) + } else { + selectRow(checkbox.value) + } + setLastCheckedIndex(index) + setInRange([]) + } } refList.current.forEach((checkbox, index) => { - const clickHandler = (event: MouseEvent) => + const clickHandler = (event: MouseEvent) => { handleClick(index, event.shiftKey) + } - const hoverEnteringHandler = (event: MouseEvent) => + const mouseEnterHandler = (event: MouseEvent) => handleHover(index, event.shiftKey, false) - const hoverLeavingHandler = (event: MouseEvent) => + const mouseOutHandler = (event: MouseEvent) => handleHover(index, event.shiftKey, true) - const changeHandler = (event: Event) => { - handleOnChange(index, (event.target as HTMLInputElement).checked) + const changeHandler = () => { + handleOnChange(index) } checkbox.addEventListener('click', clickHandler) checkbox.addEventListener('change', changeHandler) - checkbox.addEventListener('mousemove', hoverEnteringHandler) - checkbox.addEventListener('mouseout', hoverLeavingHandler) + checkbox.addEventListener('mouseenter', mouseEnterHandler) + checkbox.addEventListener('mouseout', mouseOutHandler) handlers.push(() => { checkbox.removeEventListener('click', clickHandler) checkbox.removeEventListener('change', changeHandler) - checkbox.removeEventListener('mousemove', hoverEnteringHandler) - checkbox.removeEventListener('mouseout', hoverLeavingHandler) + checkbox.removeEventListener('mouseenter', mouseEnterHandler) + checkbox.removeEventListener('mouseout', mouseOutHandler) }) }) } @@ -313,12 +333,16 @@ export const ListProvider = ({ selectedRowIds, unselectRow, selectRow, + isShiftEvent, ]) + useEffect(subscribeHandler, [subscribeHandler]) + const value = useMemo( () => ({ allRowSelectValue, checkboxAllHandler, + subscribeHandler, collapseRow, columns, expandButton, @@ -338,6 +362,7 @@ export const ListProvider = ({ [ allRowSelectValue, checkboxAllHandler, + subscribeHandler, collapseRow, columns, expandButton, diff --git a/packages/ui/src/components/List/Row.tsx b/packages/ui/src/components/List/Row.tsx index 1a8625fd2d..a395650369 100644 --- a/packages/ui/src/components/List/Row.tsx +++ b/packages/ui/src/components/List/Row.tsx @@ -216,8 +216,6 @@ export const Row = forwardRef( collapseRow, registerSelectableRow, selectedRowIds, - selectRow, - unselectRow, expandButton, refList, inRange, @@ -230,14 +228,6 @@ export const Row = forwardRef( const checkboxRef = useRef(null) - const onCheckboxHandler = () => { - if (selectedRowIds[id]) { - unselectRow(id) - } else { - selectRow(id) - } - } - const isSelectDisabled = disabled || (selectDisabled !== undefined && selectDisabled !== false) @@ -332,9 +322,8 @@ export const Row = forwardRef( checked={selectedRowIds[id]} value={id} ref={checkboxRef} - onChange={onCheckboxHandler} disabled={isSelectDisabled} - inRange={inRange.includes(id)} + inRange={inRange?.includes(id)} /> diff --git a/packages/ui/src/components/List/index.tsx b/packages/ui/src/components/List/index.tsx index 3f991e548a..78893d338c 100644 --- a/packages/ui/src/components/List/index.tsx +++ b/packages/ui/src/components/List/index.tsx @@ -1,5 +1,5 @@ import styled from '@emotion/styled' -import type { Dispatch, ForwardedRef, ReactNode, SetStateAction } from 'react' +import type { Dispatch, ReactNode, SetStateAction } from 'react' import { forwardRef } from 'react' import { Cell } from './Cell' import { HeaderCell } from './HeaderCell' @@ -25,6 +25,7 @@ const StyledTable = styled.table` position: relative; ` +// TODO: Get type optional type from omit values of ListContext type ListProps = { expandable?: boolean selectable?: boolean @@ -44,7 +45,7 @@ type ListProps = { onSelectedChange?: Dispatch> } -const BaseList = forwardRef( +const BaseList = forwardRef( ( { expandable = false, @@ -54,8 +55,8 @@ const BaseList = forwardRef( loading, autoCollapse = false, onSelectedChange, - }: ListProps, - ref: ForwardedRef, + }, + ref, ) => ( (null) const hasExpandable = !!expandable @@ -160,6 +161,10 @@ export const Row = ({ if (refAtEffectStart && current && !refAtEffectStart.includes(current)) { refList.current.push(current) } + + return () => { + // TODO should add a clean up function to remove the ref of the currentList maybe find an other way of getting the checkbox refList + } }, [refList]) const theme = useTheme() @@ -194,7 +199,7 @@ export const Row = ({ value={id} disabled={selectDisabled !== undefined} ref={checkboxRowRef} - inRange={inRange.includes(id)} + inRange={inRange?.includes(id)} /> diff --git a/packages/ui/src/components/Table/TableContext.tsx b/packages/ui/src/components/Table/TableContext.tsx index baaf9f3700..6f034669f5 100644 --- a/packages/ui/src/components/Table/TableContext.tsx +++ b/packages/ui/src/components/Table/TableContext.tsx @@ -1,21 +1,8 @@ -import type { ComponentProps } from 'react' -import { - createContext, - useCallback, - useContext, - useEffect, - useMemo, - useRef, - useState, -} from 'react' -import type { Checkbox } from '../Checkbox' +import { createContext, useContext, useEffect, useMemo } from 'react' import type { ListContextValue, ListProviderProps } from '../List/ListContext' +import { ListProvider, useListContext } from '../List/ListContext' import type { ColumnProps } from './types' -type RowState = Record - -// TODO: useContext list and override to avoid duplicate code between context - type TableContextValue = Omit & { stripped: boolean columns: ColumnProps[] @@ -29,276 +16,49 @@ export type TableProviderProps = Omit & { columns: ColumnProps[] } -export const TableProvider = ({ +const Provider = ({ children, - selectable, bordered, stripped, - expandButton, - autoCollapse, columns, }: TableProviderProps) => { - const [selectedRowIds, setSelectedRowIds] = useState({}) - const [expandedRowIds, setExpandedRowIds] = useState({}) - - const refList = useRef([]) - - const registerExpandableRow = useCallback( - (rowId: string, expanded = false) => { - setExpandedRowIds(current => ({ ...current, [rowId]: expanded })) - - return () => { - setExpandedRowIds(current => { - const { [rowId]: relatedId, ...otherIds } = current - - return otherIds - }) - } - }, - [], - ) - - const expandRow = useCallback( - (rowId: string) => { - setExpandedRowIds(current => ({ - ...(autoCollapse ? {} : current), - [rowId]: true, - })) - }, - [autoCollapse], - ) - - const collapseRow = useCallback((rowId: string) => { - setExpandedRowIds(current => ({ - ...current, - [rowId]: false, - })) - }, []) - - const registerSelectableRow = useCallback((rowId: string) => { - setSelectedRowIds(current => ({ ...current, [rowId]: false })) - - return () => { - setSelectedRowIds(current => { - const { [rowId]: relatedId, ...otherIds } = current - - return otherIds - }) - } - }, []) - - const allRowSelectValue = useMemo< - ComponentProps['checked'] - >(() => { - const selectableRowCount = Object.keys(selectedRowIds).length - if (!selectableRowCount) { - return false - } - - const selectedRowCount = Object.values(selectedRowIds).reduce( - (acc, isSelected) => acc + (isSelected ? 1 : 0), - 0, - ) - if (selectedRowCount === 0) { - return false - } - if (selectableRowCount === selectedRowCount) { - return true - } - - return 'indeterminate' - }, [selectedRowIds]) - - const selectAll = useCallback(() => { - setSelectedRowIds(current => - Object.keys(current).reduce( - (acc, rowId) => ({ ...acc, [rowId]: true }), - {}, - ), - ) - }, []) - - const unselectAll = useCallback(() => { - setSelectedRowIds(current => - Object.keys(current).reduce( - (acc, rowId) => ({ ...acc, [rowId]: false }), - {}, - ), - ) - }, []) - - const selectRow = useCallback((rowId: string) => { - setSelectedRowIds(current => ({ - ...current, - [rowId]: true, - })) - }, []) - - const unselectRow = useCallback((rowId: string) => { - setSelectedRowIds(current => ({ - ...current, - [rowId]: false, - })) - }, []) - - const [lastCheckedIndex, setLastCheckedIndex] = useState(null) - const [inRange, setInRange] = useState([]) - - const checkboxAllHandler: ListContextValue['checkboxAllHandler'] = - useCallback(() => { - // we choose to unselect all when checkbox is in indeterminate state - if ( - allRowSelectValue && - [true, 'indeterminate'].includes(allRowSelectValue) - ) { - unselectAll() - } - if (allRowSelectValue === false) { - selectAll() - } - }, [allRowSelectValue, unselectAll, selectAll]) + const { subscribeHandler, ...listContext } = useListContext() - // Multiselect with shift key - useEffect(() => { - const handlers: (() => void)[] = [] - - if (refList.current) { - const handleClick = (index: number, isShiftPressed: boolean) => { - setLastCheckedIndex(index) - - // Only handle shift click event - if (isShiftPressed && lastCheckedIndex !== null) { - const start = Math.min(lastCheckedIndex, index) - const end = Math.max(lastCheckedIndex, index) - - for (let i = start; i <= end; i += 1) { - const checkbox = refList.current[i] - - if (!checkbox.disabled) { - if (checkbox.checked) { - unselectRow(checkbox.value) - } else { - selectRow(checkbox.value) - } - } - } - } - } - - const handleOnChange = (index: number) => { - const checkbox = refList.current[index] - if (checkbox.checked) { - unselectRow(checkbox.value) - } else { - selectRow(checkbox.value) - } - } - - const handleHover = ( - index: number, - isShiftPressed: boolean, - leaving: boolean, - ) => { - const newRange: string[] = [] - - if (isShiftPressed && lastCheckedIndex !== null) { - const start = Math.min(lastCheckedIndex, index) - const end = Math.max(lastCheckedIndex, index) - - for (let i = start; i < end; i += 1) { - const checkbox = refList.current[i] - if (!checkbox.disabled && !leaving) { - newRange.push(checkbox.value) - } - } - } - setInRange(newRange) - } - - refList.current.forEach((checkbox, index) => { - const clickHandler = (event: MouseEvent) => { - handleClick( - Number((event.target as HTMLInputElement).value), - event.shiftKey, - ) - } - - const changeHandler = () => { - handleOnChange(index) - } - const hoverEnteringHandler = (event: MouseEvent) => - handleHover(index, event.shiftKey, false) - - const hoverLeavingHandler = (event: MouseEvent) => - handleHover(index, event.shiftKey, true) - - checkbox.addEventListener('click', clickHandler) - checkbox.addEventListener('change', changeHandler) - checkbox.addEventListener('mouseenter', hoverEnteringHandler) - checkbox.addEventListener('mouseleave', hoverLeavingHandler) - - handlers.push(() => { - checkbox.removeEventListener('click', clickHandler) - checkbox.removeEventListener('change', changeHandler) - checkbox.removeEventListener('mouseenter', hoverEnteringHandler) - checkbox.removeEventListener('mouseleave', hoverLeavingHandler) - }) - }) - } - - return () => { - handlers.forEach(cleanup => cleanup()) - } - }, [lastCheckedIndex, selectedRowIds, unselectRow, selectRow]) + useEffect(subscribeHandler, [subscribeHandler]) const value = useMemo( () => ({ - allRowSelectValue, + ...listContext, + subscribeHandler, bordered, - checkboxAllHandler, - collapseRow, columns, - expandButton, - expandedRowIds, - expandRow, - inRange, - refList, - registerExpandableRow, - registerSelectableRow, - selectable, - selectAll, - selectedRowIds, - selectRow, stripped, - unselectAll, - unselectRow, }), - [ - allRowSelectValue, - bordered, - checkboxAllHandler, - collapseRow, - columns, - expandButton, - expandedRowIds, - expandRow, - inRange, - refList, - registerExpandableRow, - registerSelectableRow, - selectable, - selectAll, - selectedRowIds, - selectRow, - stripped, - unselectAll, - unselectRow, - ], + [bordered, columns, stripped, subscribeHandler, listContext], ) - return {children} + return {children} } +export const TableProvider = ({ + children, + bordered, + stripped, + columns, + ...props +}: TableProviderProps) => ( + + + {children} + + +) + export const useTableContext = () => { const context = useContext(TableContext) if (!context) { diff --git a/packages/ui/src/components/Table/__tests__/__snapshots__/index.test.tsx.snap b/packages/ui/src/components/Table/__tests__/__snapshots__/index.test.tsx.snap index 6fdedc6b6f..79836ba617 100644 --- a/packages/ui/src/components/Table/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/ui/src/components/Table/__tests__/__snapshots__/index.test.tsx.snap @@ -3515,25 +3515,6 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` width: 100%; } -.emotion-0 { - min-width: 100%; - overflow-x: auto; - width: 100%; -} - -.emotion-2 { - width: 100%; - box-sizing: content-box; - border-collapse: collapse; -} - -.emotion-2 [role="row"], -.emotion-2 [role="button row"] { - width: 100%; - display: table-row; - vertical-align: middle; -} - .emotion-2 { width: 100%; box-sizing: content-box; @@ -3551,10 +3532,6 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` border-bottom: 1px solid #d9dadd; } -.emotion-4 { - border-bottom: 1px solid #d9dadd; -} - .emotion-6 { max-width: 2.5rem; display: table-cell; @@ -3598,30 +3575,6 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` gap: 0.5rem; } -.emotion-9 { - color: #3f4250; - font-size: 0.875rem; - font-family: Inter,Asap,sans-serif; - font-weight: 400; - letter-spacing: 0; - line-height: 1.25rem; - text-transform: none; - -webkit-text-decoration: none; - text-decoration: none; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - gap: 0.5rem; -} - .emotion-11 { position: relative; display: -webkit-inline-box; @@ -3917,27 +3870,6 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` padding-left: 1rem; } -.emotion-25 { - width: 100px; - max-width: 200px; - min-width: 100px; - display: table-cell; - vertical-align: middle; - padding: 0.5rem; -} - -.emotion-25[role*='button'] { - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.emotion-25:first-of-type { - padding-left: 1rem; -} - .emotion-50 { -webkit-animation: 3s linear; animation: 3s linear; @@ -4141,14 +4073,6 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` text-align: left; } -.emotion-70 { - display: table-cell; - vertical-align: middle; - padding: 0.5rem; - font-size: 0.875rem; - text-align: left; -} -
@@ -4182,7 +4106,7 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` aria-invalid="false" aria-label="select all" class="emotion-13 emotion-14" - id=":r3j:" + id=":r1:" name="table-select-all-checkbox" type="checkbox" value="all" @@ -4296,7 +4220,7 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` aria-invalid="false" aria-label="select" class="emotion-13 emotion-14" - id=":r3r:" + id=":r9:" name="table-select-checkbox" type="checkbox" value="1" @@ -4385,7 +4309,7 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` aria-invalid="false" aria-label="select" class="emotion-13 emotion-14" - id=":r3u:" + id=":rc:" name="table-select-checkbox" type="checkbox" value="2" @@ -4474,7 +4398,7 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` aria-invalid="false" aria-label="select" class="emotion-13 emotion-14" - id=":r41:" + id=":rf:" name="table-select-checkbox" type="checkbox" value="3" @@ -4555,15 +4479,15 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = `
Should render correctly with selectable and shift click 1`] = ` aria-invalid="false" aria-label="select" class="emotion-13 emotion-14" - id=":r47:" + id=":rl:" name="table-select-checkbox" type="checkbox" value="5" @@ -4741,7 +4665,7 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` aria-invalid="false" aria-label="select" class="emotion-13 emotion-14" - id=":r4a:" + id=":ro:" name="table-select-checkbox" type="checkbox" value="6" @@ -4830,7 +4754,7 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` aria-invalid="false" aria-label="select" class="emotion-13 emotion-14" - id=":r4d:" + id=":rr:" name="table-select-checkbox" type="checkbox" value="7" @@ -4919,7 +4843,7 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` aria-invalid="false" aria-label="select" class="emotion-13 emotion-14" - id=":r4g:" + id=":ru:" name="table-select-checkbox" type="checkbox" value="8" @@ -5008,7 +4932,7 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` aria-invalid="false" aria-label="select" class="emotion-13 emotion-14" - id=":r4j:" + id=":r11:" name="table-select-checkbox" type="checkbox" value="9" @@ -5097,7 +5021,7 @@ exports[`Table > Should render correctly with selectable and shift click 1`] = ` aria-invalid="false" aria-label="select" class="emotion-13 emotion-14" - id=":r4m:" + id=":r14:" name="table-select-checkbox" type="checkbox" value="10" diff --git a/packages/ui/src/components/Table/__tests__/index.test.tsx b/packages/ui/src/components/Table/__tests__/index.test.tsx index a8e014fe0e..11bb67260b 100644 --- a/packages/ui/src/components/Table/__tests__/index.test.tsx +++ b/packages/ui/src/components/Table/__tests__/index.test.tsx @@ -382,8 +382,8 @@ describe('Table', () => { , )) - test('Should render correctly with selectable and shift click', async () => { - const { asFragment } = renderWithTheme( + test.only('Should render correctly with selectable and shift click', async () => { + const { asFragment, debug } = renderWithTheme( {data.map(({ id, columnA, columnB, columnC, columnD, columnE }) => ( @@ -423,12 +423,13 @@ describe('Table', () => { fireEvent.keyDown(document, { key: 'Shift', code: 'ShiftLeft' }) // Test hovering - fireEvent.mouseMove(secondRowCheckbox, { shiftKey: true }) - fireEvent.mouseMove(thirdRowCheckbox, { shiftKey: true }) + fireEvent.mouseEnter(secondRowCheckbox, { shiftKey: true }) + fireEvent.mouseEnter(thirdRowCheckbox, { shiftKey: true }) fireEvent.mouseLeave(thirdRowCheckbox, { shiftKey: true }) - fireEvent.keyUp(document, { key: 'Shift', code: 'ShiftLeft' }) fireEvent.click(thirdRowCheckbox, { shiftKey: true }) + debug() + fireEvent.keyUp(document, { key: 'Shift', code: 'ShiftLeft' }) expect(secondRowCheckbox).toBeChecked() expect(thirdRowCheckbox).toBeChecked() diff --git a/packages/ui/src/components/Table/index.tsx b/packages/ui/src/components/Table/index.tsx index 40a4c94b6f..089f379f3e 100644 --- a/packages/ui/src/components/Table/index.tsx +++ b/packages/ui/src/components/Table/index.tsx @@ -59,8 +59,23 @@ const StyledTable = styled('table', { } `} ` +// type OptionalKeys = { +// [K in keyof T]: {} extends Pick ? K : never +// }[keyof T] -type TableProps = TableProviderProps & { +// type OptionalOnly = Pick> + +// TODO: Get type optional from omit values +type TableProps = Omit< + TableProviderProps, + | 'selectable' + | 'loading' + | 'bordered' + | 'stripped' + | 'autoCollapse' + | 'columns' + | 'expandButton' +> & { selectable?: boolean /** * Set it to true if you want to display a placeholder during loading @@ -73,6 +88,7 @@ type TableProps = TableProviderProps & { * Auto collapse is collapsing expandable row when another is expanding * */ autoCollapse?: boolean + expandButton?: boolean columns: ColumnProps[] }