1 | {"version":3,"file":"classNamesFunction.js","sourceRoot":"../src/","sources":["classNamesFunction.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n mergeCssSets,\n IStyleSet,\n IProcessedStyleSet,\n Stylesheet,\n IStyleFunctionOrObject,\n} from '@uifabric/merge-styles';\nimport { getRTL } from './rtl';\nimport { getWindow } from './dom';\nimport { StyleFunction } from './styled';\n\nconst MAX_CACHE_COUNT = 50;\nconst DEFAULT_SPECIFICITY_MULTIPLIER = 5;\n\nlet _memoizedClassNames = 0;\n\nconst stylesheet = Stylesheet.getInstance();\n\nif (stylesheet && stylesheet.onReset) {\n stylesheet.onReset(() => _memoizedClassNames++);\n}\n\n// Note that because of the caching nature within the classNames memoization,\n// I've disabled this rule to simply be able to work with any types.\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n// This represents a prop we attach to each Map to indicate the cached return value\n// associated with the graph node.\nconst retVal = '__retval__';\n\ninterface IRecursiveMemoNode extends Map<any, IRecursiveMemoNode> {\n [retVal]?: string;\n}\n\ntype AppWindow = (Window & { FabricConfig?: { enableClassNameCacheFullWarning?: boolean } }) | undefined;\n\nexport interface IClassNamesFunctionOptions {\n /**\n * Disables class caching for scenarios where styleProp parts mutate frequently.\n */\n disableCaching?: boolean;\n\n /**\n * Size of the cache. It overwrites default cache size when defined.\n */\n cacheSize?: number;\n\n /**\n * Set to true if component base styles are implemented in scss instead of css-in-js.\n */\n useStaticStyles?: boolean;\n}\n\n/**\n * Creates a getClassNames function which calls getStyles given the props, and injects them\n * into mergeStyleSets.\n *\n * Note that the props you pass in on every render should be in the same order and\n * immutable (numbers, strings, and booleans). This will allow the results to be memoized. Violating\n * these will cause extra recalcs to occur.\n */\nexport function classNamesFunction<TStyleProps extends {}, TStyleSet extends IStyleSet<TStyleSet>>(\n options: IClassNamesFunctionOptions = {},\n): (\n getStyles: IStyleFunctionOrObject<TStyleProps, TStyleSet> | undefined,\n styleProps?: TStyleProps,\n) => IProcessedStyleSet<TStyleSet> {\n // We build a trie where each node is a Map. The map entry key represents an argument\n // value, and the entry value is another node (Map). Each node has a `__retval__`\n // property which is used to hold the cached response.\n\n // To derive the response, we can simply ensure the arguments are added or already\n // exist in the trie. At the last node, if there is a `__retval__` we return that. Otherwise\n // we call the `getStyles` api to evaluate, cache on the property, and return that.\n let map: IRecursiveMemoNode = new Map();\n let styleCalcCount = 0;\n let getClassNamesCount = 0;\n let currentMemoizedClassNames = _memoizedClassNames;\n\n const getClassNames = (\n styleFunctionOrObject: IStyleFunctionOrObject<TStyleProps, TStyleSet> | undefined,\n styleProps: TStyleProps = {} as TStyleProps,\n ): IProcessedStyleSet<TStyleSet> => {\n // If useStaticStyles is true, styleFunctionOrObject returns slot to classname mappings.\n // If there is also no style overrides, we can skip merge styles completely and\n // simply return the result from the style funcion.\n if (\n options.useStaticStyles &&\n typeof styleFunctionOrObject === 'function' &&\n (styleFunctionOrObject as StyleFunction<TStyleProps, TStyleSet>).__noStyleOverride__\n ) {\n return styleFunctionOrObject(styleProps) as IProcessedStyleSet<TStyleSet>;\n }\n\n getClassNamesCount++;\n let current: Map<any, any> = map;\n const { theme } = styleProps as any;\n const rtl = theme && theme.rtl !== undefined ? theme.rtl : getRTL();\n\n const disableCaching = options.disableCaching;\n\n // On reset of our stylesheet, reset memoized cache.\n if (currentMemoizedClassNames !== _memoizedClassNames) {\n currentMemoizedClassNames = _memoizedClassNames;\n map = new Map();\n styleCalcCount = 0;\n }\n\n if (!options.disableCaching) {\n current = _traverseMap(map, styleFunctionOrObject as any);\n current = _traverseMap(current, styleProps);\n }\n\n if (disableCaching || !(current as any)[retVal]) {\n if (styleFunctionOrObject === undefined) {\n (current as any)[retVal] = {} as IProcessedStyleSet<TStyleSet>;\n } else {\n (current as any)[retVal] = mergeCssSets(\n [\n (typeof styleFunctionOrObject === 'function'\n ? styleFunctionOrObject(styleProps)\n : styleFunctionOrObject) as IStyleSet<TStyleSet>,\n ],\n { rtl: !!rtl, specificityMultiplier: options.useStaticStyles ? DEFAULT_SPECIFICITY_MULTIPLIER : undefined },\n );\n }\n\n if (!disableCaching) {\n styleCalcCount++;\n }\n }\n\n if (styleCalcCount > (options.cacheSize || MAX_CACHE_COUNT)) {\n const win = getWindow() as AppWindow;\n if (win?.FabricConfig?.enableClassNameCacheFullWarning) {\n // eslint-disable-next-line no-console\n console.warn(\n `Styles are being recalculated too frequently. Cache miss rate is ${styleCalcCount}/${getClassNamesCount}.`,\n );\n // eslint-disable-next-line no-console\n console.trace();\n }\n\n map.clear();\n styleCalcCount = 0;\n\n // Mutate the options passed in, that's all we can do.\n options.disableCaching = true;\n }\n\n // Note: the retVal is an attached property on the Map; not a key in the Map. We use this attached property to\n // cache the return value for this branch of the graph.\n return (current as any)[retVal];\n };\n\n return getClassNames;\n}\n\nfunction _traverseEdge(current: Map<any, any>, value: any): Map<any, any> {\n value = _normalizeValue(value);\n\n if (!current.has(value)) {\n current.set(value, new Map<any, any>());\n }\n\n return current.get(value);\n}\n\nfunction _traverseMap(current: Map<any, any>, inputs: any[] | Object): Map<any, any> {\n if (typeof inputs === 'function') {\n const cachedInputsFromStyled = (inputs as StyleFunction<any, any>).__cachedInputs__;\n if (cachedInputsFromStyled) {\n // The styled helper will generate the styles function and will attach the cached\n // inputs (consisting of the default styles, customzied styles, and user provided styles.)\n // These should be used as cache keys for deriving the memoized value.\n for (const input of (inputs as any).__cachedInputs__) {\n current = _traverseEdge(current, input);\n }\n } else {\n current = _traverseEdge(current, inputs);\n }\n } else if (typeof inputs === 'object') {\n for (const propName in inputs) {\n if (inputs.hasOwnProperty(propName)) {\n current = _traverseEdge(current, (inputs as any)[propName]);\n }\n }\n }\n\n return current;\n}\n\nfunction _normalizeValue(value: any): string {\n switch (value) {\n case undefined:\n return '__undefined__';\n case null:\n return '__null__';\n default:\n return value;\n }\n}\n"]} |