@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
85 lines (84 loc) • 4.54 kB
TypeScript
import type { JsonObject } from '../../utils/json-pointer';
import type { SharedStateId, SharedStateReturn } from '../../../../shared/helpers/useSharedState';
import { createSharedState } from '../../../../shared/helpers/useSharedState';
import type { Path } from '../../types';
import type { PathValue } from '../../typed-paths';
import type { ContextState, FilterData, VisibleDataHandler } from '../../DataContext/Context';
import type { DataContextRef } from '../../DataContext/DataContextRefContext';
import type { SharedAttachments } from '../../DataContext/Provider';
type IsAny<T> = 0 extends 1 & T ? true : false;
type IsUnknownOrNever<T> = IsAny<T> extends true ? false : [T] extends [never] ? true : unknown extends T ? true : false;
/**
* Resolves the value type located at the JSON Pointer path `P` in `Data`,
* reusing the shared {@link PathValue} resolver from the typed-paths support.
*
* When `Data` is a concrete type, this yields the precise value type. `Data`
* becomes concrete when it is passed explicitly as a generic
* (`useData<MyData>()` / `getData<MyData>()`) or inferred from the passed
* `initialData`. It falls back to `any` when the type cannot be resolved (for
* example the default untyped `JsonObject` data, or an explicit `any`), so
* untyped usage stays cast-free while typed data no longer collapses to `any`
* (which is what the previous `PathType<Data, P> | any` union always did).
*
* The value is typed optimistically from the declared `Data` shape: `undefined`
* appears only where a field is declared optional, not for required fields that
* may be unset at runtime. This keeps `getValue` and `update` consistent with
* `data`, `onChange` and `onSubmit`, which are all typed as the complete `Data`.
*
* Note: a globally registered form data type (via the typed-paths `Register`)
* is not adopted automatically here – `useData` defaults its `Data` generic to
* `JsonObject`, and `getData` leaves it unresolved when omitted. Pass
* `RegisteredFormData` (or your own type) explicitly – or, for `useData`, let
* it infer from `initialData` – to get precise value types.
*/
export type PathType<Data, P extends string> = IsUnknownOrNever<PathValue<Data, P>> extends true ? any : PathValue<Data, P>;
/**
* Updates the value at `path`, accepting either the new value directly or a
* `setState`-style updater callback that receives the current value. The value,
* and the updater's argument and return, are all typed as {@link PathType} for
* the given path.
*/
export type UseDataReturnUpdate<Data> = <P extends Path>(path: P, value: PathType<Data, P> | ((value: PathType<Data, P>) => PathType<Data, P>)) => void;
/**
* Reads the value at `path`, typed as {@link PathType} for the given path.
*/
export type UseDataReturnGetValue<Data> = <P extends Path>(path: P) => PathType<Data, P>;
export type UseDataReturnFilterData<Data> = (filterDataHandler: FilterData, data?: Data) => Partial<Data>;
export type UseDataReturnVisibleData<Data> = VisibleDataHandler<Data>;
export type UseDataReturn<Data> = {
data: Data;
set: (newData: Data) => void;
update: UseDataReturnUpdate<Data>;
remove: (path: Path) => void;
getValue: UseDataReturnGetValue<Data>;
filterData: UseDataReturnFilterData<Data>;
reduceToVisibleFields: UseDataReturnVisibleData<Data>;
};
export type UseDataSharedData<Data> = SharedStateReturn<Data> & {
hadInitialData?: boolean;
};
type UseDataReturnOptions<Data> = {
id: SharedStateId;
initialData: Data;
sharedDataRef: {
current: UseDataSharedData<Data> | null;
};
sharedAttachmentsRef: {
current: ReturnType<typeof createSharedState<SharedAttachments<Data>>> | null;
};
dataContext: ContextState;
dataContextRef?: DataContextRef;
contextData?: Data;
errorMessage: string;
};
/**
* Custom hook that provides form data management functionality.
*
* @template Data - The type of data being managed.
* @param {SharedStateId} id - The identifier for the data.
* @param {Data} initialData - The initial data value (optional).
* @returns {UseDataReturn<Data>} An object containing the data and data management functions.
*/
export default function useData<Data = JsonObject>(id?: SharedStateId, initialData?: Data): UseDataReturn<Data>;
export declare function useDataReturn<Data = JsonObject>({ id, initialData, sharedDataRef, sharedAttachmentsRef, dataContext, dataContextRef, contextData, errorMessage, }: UseDataReturnOptions<Data>): UseDataReturn<Data>;
export {};