diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/table/Examples.tsx b/packages/dnb-design-system-portal/src/docs/uilib/components/table/Examples.tsx
index 9070a0e6a22..7b069bde357 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/components/table/Examples.tsx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/components/table/Examples.tsx
@@ -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 (
diff --git a/packages/dnb-eufemia/src/components/table/__tests__/useHandleSortState.test.tsx b/packages/dnb-eufemia/src/components/table/__tests__/useHandleSortState.test.tsx
index b1a64f176e3..1fc651ba85d 100644
--- a/packages/dnb-eufemia/src/components/table/__tests__/useHandleSortState.test.tsx
+++ b/packages/dnb-eufemia/src/components/table/__tests__/useHandleSortState.test.tsx
@@ -28,9 +28,9 @@ describe('useHandleSortState', () => {
},
sortState: {
one: {
- active: undefined,
- reversed: false,
- direction: 'asc',
+ active: false,
+ reversed: undefined,
+ direction: 'off',
},
},
})
@@ -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 },
@@ -117,8 +117,8 @@ describe('useHandleSortState', () => {
sortState: {
one: {
active: true,
- reversed: false,
- direction: 'asc',
+ reversed: undefined,
+ direction: 'off',
},
},
})
@@ -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,
@@ -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,
@@ -326,8 +359,8 @@ describe('useHandleSortState', () => {
sortState: {
one: {
active: true,
- reversed: false,
direction: 'asc',
+ reversed: false,
},
two: {
active: false,
@@ -345,8 +378,8 @@ describe('useHandleSortState', () => {
sortState: {
one: {
active: true,
- reversed: true,
direction: 'desc',
+ reversed: true,
},
two: {
active: false,
diff --git a/packages/dnb-eufemia/src/components/table/stories/Table.stories.tsx b/packages/dnb-eufemia/src/components/table/stories/Table.stories.tsx
index 31a397e02f8..814a2c69ec8 100644
--- a/packages/dnb-eufemia/src/components/table/stories/Table.stories.tsx
+++ b/packages/dnb-eufemia/src/components/table/stories/Table.stories.tsx
@@ -274,7 +274,7 @@ export const ContainerTable = () => {
- Footer
+ {/* Footer
*/}
)
@@ -614,3 +614,80 @@ export const TableAccordion = () => {
)
}
+
+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(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 (
+
+
+
+
+ |
+
+
+ |
+
+
+
+
+ {sortedColumn1.map((product) => (
+
+ {product.name} |
+ {product.minAmount} |
+
+ ))}
+
+
+ )
+
+ function compareDesc(a: Column1, b: Column1) {
+ return b.name.localeCompare(a.name)
+ }
+
+ function compareAsc(a: Column1, b: Column1) {
+ return a.name.localeCompare(b.name)
+ }
+}
diff --git a/packages/dnb-eufemia/src/components/table/useHandleSortState.tsx b/packages/dnb-eufemia/src/components/table/useHandleSortState.tsx
index 531d0a056d5..0f869aa3e2a 100644
--- a/packages/dnb-eufemia/src/components/table/useHandleSortState.tsx
+++ b/packages/dnb-eufemia/src/components/table/useHandleSortState.tsx
@@ -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
@@ -19,7 +19,7 @@ export type useHandleSortStateOptions = {
*/
modes?: Array
}
-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<
@@ -50,7 +50,7 @@ type SortStateInternalEntry = Record<
SortStateInternalStateOptions
>
type GetNextMode = {
- state: SortStateInternalState
+ direction: useHandleSortStateDirection
opts: SortStateInternalStateOptions
defaults: useHandleSortStateOptions
}
@@ -58,16 +58,14 @@ type GetNextMode = {
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])
@@ -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'
}
@@ -113,11 +115,14 @@ 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
},
{}
@@ -125,25 +130,31 @@ export function useHandleSortState(
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
}
}