UNPKG

@oslokommune/punkt-react

Version:

React komponentbibliotek til Punkt, et designsystem laget av Oslo Origo

55 lines (48 loc) 2.14 kB
import { useCallback, useMemo } from 'react' import { FileItem, TFileAttributes, TFileId, TFileItemList, TQueueOperationContext } from '../types' /** * Build accessors that let queue-item operations read and write per-file * attributes without ever mutating the current `value` list. All changes are * propagated via `onFileUpdated`, so controlled parents stay authoritative. */ export const useFileAttributes = ( value: TFileItemList, onFileUpdated: (fileId: TFileId, updates: Partial<FileItem>) => void, ) => { const getAttributeForFile = useCallback( <T>(fileId: TFileId, attributeName: string): T | undefined => { const fileItem = value.find((file) => file.fileId === fileId) return fileItem?.attributes?.[attributeName] as T | undefined }, [value], ) const setAttributeForFile = useCallback( (fileId: TFileId, attributeName: string, attributeValue: unknown) => { const fileItem = value.find((file) => file.fileId === fileId) if (!fileItem) return const nextAttributes = { ...fileItem.attributes, [attributeName]: attributeValue } if (attributeValue === undefined) { delete nextAttributes[attributeName] } onFileUpdated(fileId, { attributes: nextAttributes as FileItem['attributes'] }) }, [onFileUpdated, value], ) const fileAttributes: TFileAttributes = useMemo( () => <T>(attributeName: string) => ({ get: (fileId: TFileId) => getAttributeForFile<T>(fileId, attributeName), set: (fileId: TFileId, attributeValue: T | undefined) => setAttributeForFile(fileId, attributeName, attributeValue), }), [getAttributeForFile, setAttributeForFile], ) const buildAttributeAccessors = useCallback( (fileId: TFileId): Pick<TQueueOperationContext, 'getAttribute' | 'setAttribute'> => ({ getAttribute: <T>(name: string) => getAttributeForFile<T>(fileId, name), setAttribute: (name, attributeValue) => setAttributeForFile(fileId, name, attributeValue), }), [getAttributeForFile, setAttributeForFile], ) return { fileAttributes, buildAttributeAccessors } as const }