| 1 |
import { TableCellStylesType } from "../attributes"; |
| 2 |
import { useTableStore } from "../store"; |
| 3 |
|
| 4 |
interface UseCellStyleControlOptions<T> { |
| 5 |
styleKey: keyof TableCellStylesType; |
| 6 |
defaultValue: T; |
| 7 |
hasValue: (value: T) => boolean; |
| 8 |
label: string; |
| 9 |
labelSelected?: string; |
| 10 |
} |
| 11 |
|
| 12 |
interface CellStyleControlProps<T> { |
| 13 |
value: T; |
| 14 |
hasValue: () => boolean; |
| 15 |
onChange: (value: T) => void; |
| 16 |
onDeselect: () => void; |
| 17 |
label: string; |
| 18 |
} |
| 19 |
|
| 20 |
export function useCellStyleControl<T>({ |
| 21 |
styleKey, |
| 22 |
defaultValue, |
| 23 |
hasValue: hasValueFn, |
| 24 |
label, |
| 25 |
labelSelected, |
| 26 |
}: UseCellStyleControlOptions<T>): CellStyleControlProps<T> { |
| 27 |
const selectedCells = useTableStore(state => state.selectedCells); |
| 28 |
const cellDefaults = useTableStore(state => state.cellDefaults.styles); |
| 29 |
const getCellStyle = useTableStore(state => state.getCellStyle); |
| 30 |
const updateCellStyles = useTableStore(state => state.updateCellStyles); |
| 31 |
const updateCellGlobalStyles = useTableStore( |
| 32 |
state => state.updateCellGlobalStyles |
| 33 |
); |
| 34 |
|
| 35 |
const firstSelectedCellStyle = |
| 36 |
selectedCells.length > 0 ? getCellStyle(selectedCells[0]) || {} : {}; |
| 37 |
|
| 38 |
const value = |
| 39 |
selectedCells.length > 0 && firstSelectedCellStyle[styleKey] |
| 40 |
? ((firstSelectedCellStyle[styleKey] as T) ?? defaultValue) |
| 41 |
: (cellDefaults[styleKey] as T); |
| 42 |
|
| 43 |
const hasValue = () => { |
| 44 |
if (selectedCells.length > 0) { |
| 45 |
const cellValue = firstSelectedCellStyle[styleKey] as T; |
| 46 |
return cellValue ? hasValueFn(cellValue) : false; |
| 47 |
} else { |
| 48 |
const globalValue = cellDefaults[styleKey] as T; |
| 49 |
return hasValueFn(globalValue); |
| 50 |
} |
| 51 |
}; |
| 52 |
|
| 53 |
const computedLabel = |
| 54 |
selectedCells.length > 0 && labelSelected ? labelSelected : label; |
| 55 |
|
| 56 |
const onChange = (newValue: T) => { |
| 57 |
if (selectedCells.length > 0) { |
| 58 |
selectedCells.forEach(coord => { |
| 59 |
updateCellStyles(coord, { |
| 60 |
[styleKey]: newValue, |
| 61 |
} as Partial<TableCellStylesType>); |
| 62 |
}); |
| 63 |
} else { |
| 64 |
updateCellGlobalStyles({ |
| 65 |
[styleKey]: newValue, |
| 66 |
} as Partial<TableCellStylesType>); |
| 67 |
} |
| 68 |
}; |
| 69 |
|
| 70 |
const onDeselect = () => { |
| 71 |
if (selectedCells.length > 0) { |
| 72 |
selectedCells.forEach(coord => { |
| 73 |
updateCellStyles(coord, { |
| 74 |
[styleKey]: defaultValue, |
| 75 |
} as Partial<TableCellStylesType>); |
| 76 |
}); |
| 77 |
} else { |
| 78 |
updateCellGlobalStyles({ |
| 79 |
[styleKey]: defaultValue, |
| 80 |
} as Partial<TableCellStylesType>); |
| 81 |
} |
| 82 |
}; |
| 83 |
|
| 84 |
return { |
| 85 |
value, |
| 86 |
hasValue, |
| 87 |
onChange, |
| 88 |
onDeselect, |
| 89 |
label: computedLabel, |
| 90 |
}; |
| 91 |
} |
| 92 |
|