flowbite-react
Version:
Official React components built for Flowbite and Tailwind CSS
1 lines • 17.6 kB
Source Map (JSON)
{"version":3,"file":"resolve-theme.cjs","sources":["../../src/helpers/resolve-theme.ts"],"sourcesContent":["import { deepmerge } from \"deepmerge-ts\";\nimport { klona } from \"klona/json\";\nimport { useRef } from \"react\";\nimport { getDark, getPrefix } from \"../store\";\nimport type { ApplyTheme, DeepPartialApplyTheme, DeepPartialBoolean } from \"../types\";\nimport { applyPrefix } from \"./apply-prefix\";\nimport { applyPrefixV3 } from \"./apply-prefix-v3\";\nimport { convertUtilitiesToV4 } from \"./convert-utilities-to-v4\";\nimport { deepMergeStrings } from \"./deep-merge\";\nimport { getTailwindVersion } from \"./get-tailwind-version\";\nimport { isEqual } from \"./is-equal\";\nimport { stripDark } from \"./strip-dark\";\nimport { twMerge } from \"./tailwind-merge\";\n\n/**\n * Memoize wrapper around `resolveTheme` function.\n *\n * @param {...Parameters<typeof resolveTheme>} input - Arguments to pass to `resolveTheme` function\n * @returns {ReturnType<typeof resolveTheme>} The resolved theme configuration\n */\nexport function useResolveTheme<T>(...input: Parameters<typeof resolveTheme<T>>): ReturnType<typeof resolveTheme<T>> {\n return useStableMemo(() => resolveTheme(...input), input);\n}\n\n/**\n * A custom React hook that memoizes a value similar to `useMemo`, but with stable dependency comparison.\n * This hook ensures that the memoized value only updates when the dependencies have actually changed,\n * using deep equality comparison instead of reference equality.\n *\n * @template T - The type of the memoized value\n * @param {() => T} factory - A function that creates the value to be memoized\n * @param {unknown[]} dependencies - An array of dependencies that determine when the value should be recalculated\n * @returns {T} The memoized value that only changes when dependencies change (using deep equality)\n */\nexport function useStableMemo<T>(factory: () => T, dependencies: unknown[]): T {\n const prevDepsRef = useRef<unknown[]>();\n const prevResultRef = useRef<T>();\n\n const hasChanged = !prevDepsRef.current || !isEqual(prevDepsRef.current, dependencies);\n\n if (hasChanged) {\n prevDepsRef.current = dependencies;\n prevResultRef.current = factory();\n }\n\n return prevResultRef.current!;\n}\n\n/**\n * Adds prefix to `base` and merges with custom themes, applying optional `clearTheme` and `applyTheme` modifications.\n *\n * @template T - The type of the base theme.\n * @param {[base, ...custom[]]} themes - An array where the first element is the base theme and the rest are custom themes.\n * @param {DeepPartialBoolean<T>[]} clearThemeList - An array of `clearTheme` modifications to apply to the base theme.\n * @param {DeepPartialApplyTheme<T>[]} applyThemeList - An optional array of `applyTheme` modifications to apply to the merged theme.\n * @returns {T} - The resolved and merged theme.\n */\nexport function resolveTheme<T>(\n [base, ...custom]: [\n /** base theme */\n T,\n /** custom themes */\n ...unknown[],\n ],\n clearThemeList?: DeepPartialBoolean<T>[],\n applyThemeList?: DeepPartialApplyTheme<T>[],\n): T {\n const dark = getDark();\n const prefix = getPrefix();\n const version = getTailwindVersion();\n\n const _custom = custom?.length ? custom?.filter((value) => value !== undefined) : undefined;\n const _clearThemeList = clearThemeList?.length ? clearThemeList?.filter((value) => value !== undefined) : undefined;\n const _applyThemeList = applyThemeList?.length ? applyThemeList?.filter((value) => value !== undefined) : undefined;\n\n const baseTheme = _clearThemeList?.length || dark === false || version === 4 || prefix ? klona(base) : base;\n\n if (_clearThemeList?.length) {\n const finalClearTheme = cloneWithValue<T, boolean>(baseTheme, false);\n\n let run = false;\n\n for (const clearTheme of _clearThemeList) {\n if (clearTheme) {\n run = true;\n }\n\n patchClearTheme(finalClearTheme, clearTheme);\n }\n\n if (run) {\n runClearTheme(baseTheme, finalClearTheme as DeepPartialBoolean<T>);\n }\n }\n\n if (dark === false || version === 4 || prefix) {\n stringIterator(baseTheme, (value) => {\n if (dark === false) {\n value = stripDark(value);\n }\n if (version === 4) {\n value = convertUtilitiesToV4(value);\n }\n if (prefix) {\n if (version === 3) {\n value = applyPrefixV3(value, prefix);\n }\n if (version === 4) {\n value = applyPrefix(value, prefix);\n }\n }\n\n return value;\n });\n }\n\n let theme = baseTheme;\n\n if (_custom?.length) {\n theme = deepMergeStrings(twMerge)(baseTheme, ..._custom) as T;\n }\n\n if (_applyThemeList?.length && _custom?.length) {\n const finalApplyTheme = cloneWithValue<T, ApplyTheme>(baseTheme, \"merge\");\n\n let run = false;\n\n for (const applyTheme of _applyThemeList) {\n if (applyTheme !== \"merge\") {\n run = true;\n }\n\n patchApplyTheme(finalApplyTheme, applyTheme);\n }\n\n if (run) {\n runApplyTheme(theme, deepmerge(baseTheme, ...custom) as T, finalApplyTheme as DeepPartialApplyTheme<T>);\n }\n }\n\n return theme;\n}\n\nfunction patchClearTheme<T>(base: T, clearTheme: DeepPartialBoolean<T>): void {\n function iterate(base: T, clearTheme: DeepPartialBoolean<T>) {\n if (typeof clearTheme === \"boolean\") {\n if (typeof base === \"object\" && base !== null) {\n for (const key in base) {\n // @ts-expect-error - bypass\n base[key] = iterate(base[key], clearTheme);\n }\n } else {\n return clearTheme;\n }\n }\n if (typeof clearTheme === \"object\" && clearTheme !== null) {\n for (const key in clearTheme) {\n // @ts-expect-error - bypass\n base[key] = iterate(base[key], clearTheme[key]);\n }\n }\n return base;\n }\n\n iterate(base, clearTheme);\n}\n\nfunction patchApplyTheme<T>(base: T, applyTheme: DeepPartialApplyTheme<T>): void {\n function iterate(base: T, applyTheme: DeepPartialApplyTheme<T>) {\n if (typeof applyTheme === \"string\") {\n if (typeof base === \"object\" && base !== null) {\n for (const key in base) {\n // @ts-expect-error - bypass\n base[key] = iterate(base[key], applyTheme);\n }\n } else {\n return applyTheme;\n }\n }\n if (typeof applyTheme === \"object\" && applyTheme !== null) {\n for (const key in applyTheme) {\n // @ts-expect-error - bypass\n base[key] = iterate(base[key], applyTheme[key]);\n }\n }\n return base;\n }\n\n iterate(base, applyTheme);\n}\n\n/**\n * Applies `clearTheme` modifications to a base object. If `clearTheme` is `true`,\n * it will recursively set all string properties of the base object to an empty string.\n * If `clearTheme` is an object, it will recursively apply the properties of the `clearTheme`\n * object to the base object.\n *\n * @template T - The type of the base object.\n * @param {T} base - The base object to which `clearTheme` modifications will be applied.\n * @param {DeepPartialBoolean<T>} `clearTheme` - The `clearTheme` modifications to apply. It can be a boolean or an object.\n * @returns {void}\n */\nfunction runClearTheme<T>(base: T, clearTheme: DeepPartialBoolean<T>): void {\n function iterate(base: T, clearTheme: DeepPartialBoolean<T>) {\n if (clearTheme === true) {\n if (typeof base === \"object\" && base !== null) {\n for (const key in base) {\n // @ts-expect-error - bypass\n base[key] = iterate(base[key], clearTheme);\n }\n } else {\n return \"\";\n }\n }\n if (typeof clearTheme === \"object\" && clearTheme !== null) {\n for (const key in clearTheme) {\n // @ts-expect-error - bypass\n base[key] = iterate(base[key], clearTheme[key]);\n }\n }\n return base;\n }\n\n iterate(base, clearTheme);\n}\n\n/**\n * Patches and applies a theme by recursively merging or replacing values between base and target objects\n * based on the `applyTheme` configuration.\n *\n * @template T - The type of the theme object\n * @param {T} base - The base theme object to be modified\n * @param {T} target - The target theme object containing new values\n * @param {DeepPartialApplyTheme<T>} applyTheme - Configuration object that determines how the theme should be applied\n * @returns {void}\n */\nfunction runApplyTheme<T>(base: T, target: T, applyTheme: DeepPartialApplyTheme<T>): void {\n function iterate(base: T, target: T, applyTheme: DeepPartialApplyTheme<T>) {\n if (applyTheme === \"replace\") {\n if (typeof base === \"object\" && base !== null) {\n for (const key in base) {\n // @ts-expect-error - bypass\n base[key] = iterate(base[key], target[key], applyTheme);\n }\n } else {\n return target;\n }\n }\n if (typeof applyTheme === \"object\" && applyTheme !== null) {\n for (const key in applyTheme) {\n // @ts-expect-error - bypass\n base[key] = iterate(base[key], target[key], applyTheme[key]);\n }\n }\n return base;\n }\n\n iterate(base, target, applyTheme);\n}\n\n/**\n * Iterates over a given input and applies a callback function to each string value found.\n * The input can be a string, an array, or an object containing strings.\n *\n * @template T - The type of the input.\n * @param {T} input - The input to iterate over. It can be a string, an array, or an object.\n * @param {(value: string) => string} callback - The callback function to apply to each string value.\n * @returns {void}\n */\nfunction stringIterator<T>(input: T, callback: (value: string) => string): void {\n function iterate(input: T) {\n if (typeof input === \"string\") {\n return callback(input);\n } else if (Array.isArray(input)) {\n for (let i = 0; i < input.length; i++) {\n input[i] = iterate(input[i]);\n }\n } else if (typeof input === \"object\" && input !== null) {\n for (const key in input) {\n // @ts-expect-error - bypass\n input[key] = iterate(input[key]);\n }\n }\n return input;\n }\n\n iterate(input);\n}\n\n/**\n * Creates a deep clone of an object structure with all leaf values replaced by a specified value.\n *\n * @template T - The type of the input object\n * @template V - The type of the value to replace with\n * @param {T} input - The input object to clone\n * @param {V} value - The value to replace all leaf values with\n * @returns {T} A new object with the same structure as input but all leaf values replaced with the specified value\n *\n * @example\n * const obj = { a: 1, b: { c: 2 } };\n * const result = cloneWithValue(obj, 'new');\n * // result = { a: 'new', b: { c: 'new' } }\n */\nfunction cloneWithValue<T, V>(input: T, value: V): T {\n if (input === null || typeof input !== \"object\") {\n return value as unknown as T;\n }\n\n const clone = {} as T;\n\n for (const key in input) {\n clone[key as keyof T] = cloneWithValue(input[key as keyof T], value);\n }\n\n return clone;\n}\n"],"names":["useRef","isEqual","getDark","getPrefix","getTailwindVersion","klona","stripDark","convertUtilitiesToV4","applyPrefixV3","applyPrefix","deepMergeStrings","twMerge","deepmerge"],"mappings":"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"}