import { TOKENS, PROPS } from '../../../config/index'; import { WithArbitraryString, ArrayElement, ExtractArrayValues, ExtractObjectKeys, ExtractPropertyValue } from './utils'; import { MakeResponsive } from './ResponsiveProps'; type PropsConfig = typeof PROPS; type TokensConfig = typeof TOKENS; /** * TOKENS のキーから対応する値の型を取得 * - 配列形式: TOKENS[K] が配列の場合、その要素の型 * - オブジェクト形式: TOKENS[K].values が配列の場合、その要素の型 * * @example * ```ts * type FzValues = TokenConfigValues<'fz'>; * // 結果: 'root' | 'base' | '5xl' | ... * * type SpaceValues = TokenConfigValues<'space'>; * // 結果: '5' | '10' | '15' | ... * ``` */ type TokenConfigValues = TokensConfig[K] extends readonly unknown[] ? ArrayElement : ExtractArrayValues; /** * token プロパティから対応する TOKENS の値を抽出 */ type ExtractTokenValues = ExtractPropertyValue extends never ? never : ExtractPropertyValue extends keyof TokensConfig ? TokenConfigValues> : never; /** * プロパティの設定から利用可能な値の型を抽出 * presets の値 + utils のキー + token の値 */ type ExtractPropValues = ExtractArrayValues | ExtractObjectKeys | ExtractTokenValues; /** * プロパティの設定から値の型を決定 * - presets/utils/token がある場合: 具体的な値 + 任意文字列 + number | boolean | null * - ない場合: string | number(フォールバック) */ type PropValueType = ExtractPropValues extends never ? string | number | boolean : WithArbitraryString> | number | boolean | null; /** * bp プロパティが 1 に設定されているかを判定 * never チェックを先に行うことで、bp プロパティが存在しない場合を正しく判定 */ type HasBreakpointSupport = [ExtractPropertyValue] extends [never] ? false : ExtractPropertyValue extends 1 ? true : false; type AllPropKeys = keyof PropsConfig; /** * bp: 1 が設定されているプロパティのキーを抽出 */ type PropsWithBreakpoint = { [K in AllPropKeys]: HasBreakpointSupport extends true ? K : never; }[AllPropKeys]; /** * bp: 1 が設定されていないプロパティのキーを抽出 */ type PropsWithoutBreakpoint = Exclude; /** * bp: 1 が設定されているプロパティの型(レスポンシブ対応あり) */ export type ResponsivePropValueTypes = { [K in PropsWithBreakpoint]?: PropValueType; }; /** * bp: 1 が設定されていないプロパティの型(レスポンシブ対応なし) */ export type NonResponsivePropValueTypes = { [K in PropsWithoutBreakpoint]?: PropValueType; }; /** * PROPS 設定から生成される Props 型(レスポンシブ対応含む) * - bp: 1 のプロパティ: レスポンシブ対応(配列・オブジェクト形式可) * - bp なしのプロパティ: 単一値のみ * - presets/utils/token なしのプロパティ: string | number(フォールバック) * * @example * ```ts * // bp: 1 のプロパティ(fz など) * fz?: 'root' | 'base' | ... | ['root', 'base'] | { base: 'root', md: 'base' } * * // bp なしのプロパティ(fw など) * fw?: 'thin' | 'light' | 'normal' | ... * * // presets/utils/token なしのプロパティ(bg など) * bg?: Responsive * ``` */ export type PropValueTypes = MakeResponsive & NonResponsivePropValueTypes; export {};