UNPKG

@wordpress/preferences

Version:
103 lines (92 loc) 2.47 kB
/** * WordPress dependencies */ import { combineReducers } from '@wordpress/data'; /** * Internal dependencies */ import type { StoreState, WPPreferencesPersistenceLayer } from './types'; import type { AvailableActions } from './actions'; /** * Reducer returning the defaults for user preferences. * * This is kept intentionally separate from the preferences * themselves so that defaults are not persisted. * * @param state Current state. * @param action Dispatched action. * * @return Updated state. */ export function defaults( state: StoreState[ 'defaults' ] = {}, action: AvailableActions ): StoreState[ 'defaults' ] { if ( action.type === 'SET_PREFERENCE_DEFAULTS' ) { const { scope, defaults: values } = action; return { ...state, [ scope ]: { ...state[ scope ], ...values, }, }; } return state; } type PreferencesReducer = ( state: StoreState[ 'preferences' ], action: AvailableActions ) => StoreState[ 'preferences' ]; /** * Higher order reducer that does the following: * - Merges any data from the persistence layer into the state when the * `SET_PERSISTENCE_LAYER` action is received. * - Passes any preferences changes to the persistence layer. * * @param reducer The preferences reducer. * * @return The enhanced reducer. */ function withPersistenceLayer( reducer: PreferencesReducer ) { let persistenceLayer: WPPreferencesPersistenceLayer< any >; return ( state: StoreState[ 'preferences' ], action: AvailableActions ) => { // Set up the persistence layer, and return the persisted data // as the state. if ( action.type === 'SET_PERSISTENCE_LAYER' ) { const { persistenceLayer: persistence, persistedData } = action; persistenceLayer = persistence; return persistedData; } const nextState = reducer( state, action ); if ( action.type === 'SET_PREFERENCE_VALUE' ) { persistenceLayer?.set( nextState ); } return nextState; }; } /** * Reducer returning the user preferences. * * @param {Object} state Current state. * @param {Object} action Dispatched action. * * @return {Object} Updated state. */ export const preferences = withPersistenceLayer( ( state = {}, action ) => { if ( action.type === 'SET_PREFERENCE_VALUE' ) { const { scope, name, value } = action; return { ...state, [ scope ]: { ...state[ scope ], [ name ]: value, }, }; } return state; } ); export default combineReducers( { defaults, preferences, } );