@meonode/ui
Version:
A structured approach to component composition, direct CSS-first prop styling, built-in theming, smart prop handling (including raw property pass-through), and dynamic children.
100 lines • 4.54 kB
TypeScript
import type { CSSProperties } from '@emotion/serialize';
import type { CssProp, Theme } from '../types/node.type.js';
interface FlexComponents {
grow: number;
shrink: number;
basis: string | number;
}
export declare class ThemeUtil {
private constructor();
/**
* Parses a CSS flex shorthand property into its individual components.
*
* The CSS flex property is a shorthand for flex-grow, flex-shrink, and flex-basis.
* This parser handles the most common flex shorthand patterns to extract the shrink value
* when it's explicitly set by the user.
*
* Supported patterns:
* - Keywords: 'none' | 'auto' | 'initial'
* - Single number: '1' → {grow: 1, shrink: 1, basis: '0%'}
* - Full shorthand: '1 0 auto' → {grow: 1, shrink: 0, basis: 'auto'}
* @param flex The CSS flex property value to parse
* @returns FlexComponents object with parsed values, or null if unparseable
* @example
* parseFlexShorthand('none') // → {grow: 0, shrink: 0, basis: 'auto'}
* parseFlexShorthand('1') // → {grow: 1, shrink: 1, basis: '0%'}
* parseFlexShorthand('1 0 auto') // → {grow: 1, shrink: 0, basis: 'auto'}
*/
static parseFlexShorthand(flex: CSSProperties['flex']): FlexComponents | null;
static isPlainObject: (value: unknown) => value is Record<string, unknown>;
/**
* Resolves theme variable references in an object's values iteratively.
* This function uses a manual work stack to traverse the object, which prevents
* "Maximum call stack size exceeded" errors for deeply nested objects.
* It performs a "smart merge" by using a copy-on-write strategy, creating new
* objects/arrays only when a value inside them has changed. This preserves
* object references for unchanged parts of the tree, which is critical for
* React's reconciliation and memoization.
*/
static resolveObjWithTheme: <O extends Record<string, unknown>>(obj: O, theme?: Theme, options?: {
processFunctions?: boolean;
themeStringsMode?: "resolve" | "vars";
}) => O;
/**
* Resolves default CSS styles to fix common flexbox layout issues.
*
* PRIMARY PURPOSE: Fix the flexbox scrolling problem
* ================================================
*
* THE PROBLEM:
* By default, flex items have `min-width: auto` and `min-height: auto`, which means they
* cannot shrink below their content size. This prevents scrollable containers from working
* properly when they are flex items.
*
* THE SOLUTION:
* 1. Set `minHeight: 0` and `minWidth: 0` to allow flex items to shrink
* 2. Control `flexShrink` behavior based on context to prevent unwanted shrinking
* 3. Respect user's explicit values to avoid overriding intentional styling
*
* FLEX SHRINK BEHAVIOR RULES:
* ===========================
*
* For FLEX CONTAINERS:
* - If overflow is NOT handled AND no wrapping → flexShrink: 0 (prevent shrinking)
* - If overflow is handled OR wrapping enabled → flexShrink: undefined (allow default)
*
* For NON-FLEX CONTAINERS (flex items):
* - Always → flexShrink: 0 (prevent unwanted shrinking)
*
* NESTED SCENARIOS:
* ================
* An element can be both a flex container AND a flex item simultaneously.
* This function handles this correctly by checking if the element itself is a container,
* not whether it's inside a flex context.
*
* EXPLICIT VALUE PRESERVATION:
* ===========================
* - If user sets `flexShrink` explicitly → never override
* - If user sets `flex` shorthand → extract and use the shrink value from it
* - Otherwise → apply smart defaults based on context
* @param style The input CSSProperties object to process
* @returns Processed CSSProperties with resolved defaults
* @example
* // Fix scrollable flex item
* resolveDefaultStyle({
* overflow: 'auto',
* height: '200px'
* })
* // → { overflow: 'auto', height: '200px', flexShrink: 0, minHeight: 0, minWidth: 0 }
* @example
* // Flex container with wrapping (allows shrinking)
* resolveDefaultStyle({
* display: 'flex',
* flexWrap: 'wrap'
* })
* // → { display: 'flex', flexWrap: 'wrap', minHeight: 0, minWidth: 0 }
*/
static resolveDefaultStyle: (style: CssProp) => {};
}
export {};
//# sourceMappingURL=theme.util.d.ts.map