Skip to content

Commit

Permalink
fix(useHandleSortState): change default direction from asc to off (#1826
Browse files Browse the repository at this point in the history
)
  • Loading branch information
tujoworker authored Dec 16, 2022
1 parent c595ff1 commit c7e4d6f
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ export const TableVariantBasic = () => (
column2: { direction: 'desc', modes: ['asc', 'desc'] },
})

// Handle your "column1" logic
React.useEffect(() => {
switch (sortState.column1.direction) {
case 'asc':
break

case 'desc':
break

default:
case 'off':
break
}
}, [sortState.column1.direction])

return (
<Table.ScrollView>
<Table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ describe('useHandleSortState', () => {
},
sortState: {
one: {
active: undefined,
reversed: false,
direction: 'asc',
active: false,
reversed: undefined,
direction: 'off',
},
},
})
Expand Down Expand Up @@ -102,7 +102,7 @@ describe('useHandleSortState', () => {
})
})

it('should return active with reverted direction', () => {
it('should return active with default direction', () => {
const { result } = renderHook(useHandleSortState, {
initialProps: {
one: { active: true },
Expand All @@ -117,8 +117,8 @@ describe('useHandleSortState', () => {
sortState: {
one: {
active: true,
reversed: false,
direction: 'asc',
reversed: undefined,
direction: 'off',
},
},
})
Expand Down Expand Up @@ -237,6 +237,20 @@ describe('useHandleSortState', () => {

simulate()

expect(result.current).toEqual({
activeSortName: 'one',
sortHandler,
sortState: {
one: {
active: true,
reversed: false,
direction: 'asc',
},
},
})

simulate()

expect(result.current).toEqual({
activeSortName: null,
sortHandler,
Expand Down Expand Up @@ -282,6 +296,25 @@ describe('useHandleSortState', () => {

simulateOne()

expect(result.current).toEqual({
activeSortName: 'one',
sortHandler,
sortState: {
one: {
active: true,
reversed: false,
direction: 'asc',
},
two: {
active: false,
reversed: true,
direction: 'desc',
},
},
})

simulateOne()

expect(result.current).toEqual({
activeSortName: 'one',
sortHandler,
Expand Down Expand Up @@ -326,8 +359,8 @@ describe('useHandleSortState', () => {
sortState: {
one: {
active: true,
reversed: false,
direction: 'asc',
reversed: false,
},
two: {
active: false,
Expand All @@ -345,8 +378,8 @@ describe('useHandleSortState', () => {
sortState: {
one: {
active: true,
reversed: true,
direction: 'desc',
reversed: true,
},
two: {
active: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ export const ContainerTable = () => {
</TableContainer.Body>

<TableContainer.Foot>
<P id="unique-ref-id">Footer</P>
{/* <P id="unique-ref-id">Footer</P> */}
</TableContainer.Foot>
</StyledContainer>
)
Expand Down Expand Up @@ -614,3 +614,80 @@ export const TableAccordion = () => {
</main>
)
}

export function TableSort() {
const { sortState, sortHandler } = useHandleSortState({
column1: {
active: true,
direction: 'off',
},
})

interface Column1 {
name: string
minAmount: number
}

const product1: Column1 = { name: 'cab', minAmount: 1 }
const product2: Column1 = { name: 'abc', minAmount: 3 }
const product3: Column1 = { name: 'bac', minAmount: 2 }

const mockData = [product1, product2, product3]

const [sortedColumn1, setColumn1Data] =
React.useState<Column1[]>(mockData)

React.useEffect(() => {
switch (sortState.column1.direction) {
case 'asc':
setColumn1Data([...mockData].sort(compareAsc))
break

case 'desc':
setColumn1Data([...mockData].sort(compareDesc))
break

default:
case 'off':
setColumn1Data(mockData)
break
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sortState.column1.direction])

return (
<Table>
<thead>
<Tr>
<Th
scope="col"
sortable
active={sortState.column1.active}
reversed={sortState.column1.reversed}
>
<Th.SortButton text={'Name'} onClick={sortHandler.column1} />
</Th>
<Th scope="col" sortable>
<Th.SortButton text={'Min amount'} />
</Th>
</Tr>
</thead>
<tbody>
{sortedColumn1.map((product) => (
<Tr key={product.minAmount}>
<Td>{product.name}</Td>
<Td>{product.minAmount}</Td>
</Tr>
))}
</tbody>
</Table>
)

function compareDesc(a: Column1, b: Column1) {
return b.name.localeCompare(a.name)
}

function compareAsc(a: Column1, b: Column1) {
return a.name.localeCompare(b.name)
}
}
41 changes: 26 additions & 15 deletions packages/dnb-eufemia/src/components/table/useHandleSortState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export type useHandleSortStateOptions = {
active?: boolean

/**
* Define the sorting direction. Can be "asc" or "desc".
* Defaults to "asc".
* Define the sorting direction. Can be "asc", "desc" or "off".
* Defaults to "off".
*/
direction?: useHandleSortStateDirection

Expand All @@ -19,7 +19,7 @@ export type useHandleSortStateOptions = {
*/
modes?: Array<useHandleSortStateMode>
}
export type useHandleSortStateDirection = 'asc' | 'desc'
export type useHandleSortStateDirection = 'asc' | 'desc' | 'off'
export type useHandleSortStateMode = 'asc' | 'desc' | 'off'
export type useHandleSortStateName = string
export type useHandleSortStateConfig = Record<
Expand Down Expand Up @@ -50,24 +50,22 @@ type SortStateInternalEntry = Record<
SortStateInternalStateOptions
>
type GetNextMode = {
state: SortStateInternalState
direction: useHandleSortStateDirection
opts: SortStateInternalStateOptions
defaults: useHandleSortStateOptions
}

export function useHandleSortState(
config: useHandleSortStateConfig,
defaults: useHandleSortStateOptions = {
direction: 'asc',
direction: 'off',
modes: ['asc', 'desc', 'off'],
}
) {
const initialState = React.useMemo(() => {
return Object.entries(config).reduce((acc, [name, opts]) => {
acc[name] = { ...defaults, ...opts }
if (!acc[name].active && !acc[name].lastDirection) {
acc[name].lastDirection = acc[name].direction
}

return acc
}, {})
}, [config, defaults])
Expand All @@ -86,7 +84,11 @@ export function useHandleSortState(
state.active = true
state.lastDirection = null
} else {
state.direction = getNextMode({ state, opts, defaults })
state.direction = getNextMode({
direction: state.direction,
opts,
defaults,
})
state.active = state.direction !== 'off'
}

Expand All @@ -113,37 +115,46 @@ export function useHandleSortState(
const reversed =
direction === 'off' ? undefined : direction === 'desc'

acc[name] = { active, direction, reversed }

if (active) {
activeSortName = name
} else {
active = false
}

acc[name] = { active, direction, reversed }

return acc
},
{}
)

return { sortState, sortHandler, activeSortName }

function getNextMode({ state, opts, defaults }: GetNextMode) {
function getNextMode({ direction, opts, defaults }: GetNextMode) {
const modes = defaults.modes.filter((mode) => {
return opts.modes.includes(mode)
})

if (!modes.includes(direction)) {
direction = modes[0]
}

let next = direction

for (let i = 0, l = modes.length; i < l; i++) {
const mode = modes[i]

if (mode === state.direction) {
if (direction === mode) {
let c = i + 1
if (c >= l) {
c = 0
}
state.direction = modes[c]
next = modes[c]
break
}
}

return state.direction
return next
}
}

Expand Down

0 comments on commit c7e4d6f

Please sign in to comment.