import React$1 from 'react';
/**
* @fileoverview Type Helper Utilities for MockFrame
*
* This module provides advanced TypeScript utility types that power MockFrame's
* type-safe API. These utilities enable discriminated union types that provide
* compile-time safety for device-specific props without any runtime overhead.
*
* @example How these types work together in MockFrame:
* ```ts
* // The DeviceFramesetProps type uses these helpers to ensure:
* // - `color` prop is only required for devices that have color options
* // - `landscape` prop is only available for devices that support rotation
* // - Props display cleanly in IDE tooltips
*
* // Valid: iPhone 17 requires a color
*
*
* // Valid: iPhone X has no colors, so color prop is omitted
*
*
* // TypeScript Error: iPhone X doesn't accept color
*
* ```
*
* @module helper
*/
/**
* Extracts keys from type `T` where the value type exactly matches type `F`.
*
* Uses bidirectional extends check to ensure exact type matching:
* - `[F] extends [T[key]]` checks if F is assignable to the value
* - `[T[key]] extends [F]` checks if the value is assignable to F
* Both must be true for an exact match.
*
* The tuple wrapper `[X]` prevents TypeScript from distributing over unions,
* ensuring we match the complete type rather than individual union members.
*
* @template T - The object type to extract keys from
* @template F - The value type to match exactly
* @returns Union of keys whose values exactly match type F
*
* @example
* ```ts
* type Device = { name: string; colors: never; width: number }
*
* type NeverKeys = KeysOfType
* // Result: 'colors'
*
* type StringKeys = KeysOfType
* // Result: 'name'
* ```
*/
type KeysOfType = {
[key in keyof T]: [F] extends [T[key]] ? [T[key]] extends [F] ? key : never : never;
}[keyof T];
/**
* Extracts keys from type `T` where type `F` is assignable to the value type.
*
* Unlike `KeysOfType`, this only checks one direction: whether F can be
* assigned to the value. This is useful for finding keys that accept
* a specific type as part of a union.
*
* @template T - The object type to extract keys from
* @template F - The type that should be assignable to the value
* @returns Union of keys whose values accept type F
*
* @example
* ```ts
* type Props = {
* required: string;
* optional: string | undefined;
* alsoOptional: number | undefined;
* }
*
* type UndefinedKeys = KeysOfSubType
* // Result: 'optional' | 'alsoOptional'
* ```
*/
type KeysOfSubType = {
[key in keyof T]: [F] extends [T[key]] ? key : never;
}[keyof T];
/**
* Creates a new type by omitting fields from `T` whose value type exactly matches `F`.
*
* Primary use case: Remove fields typed as `never` from discriminated unions.
* When building conditional prop types, some device configurations result in
* `never` typed fields that should be excluded from the final type.
*
* @template T - The object type to transform
* @template F - The value type to filter out
* @returns New type with matching fields removed
*
* @example
* ```ts
* // Internal type before cleanup
* type RawProps = {
* device: 'iPhone X';
* color: never; // iPhone X has no color options
* landscape: boolean;
* }
*
* type CleanProps = OmitFieldByType
* // Result: { device: 'iPhone X'; landscape: boolean }
* // The `color` field is removed since it's typed as `never`
* ```
*/
type OmitFieldByType = Omit>;
/**
* Makes fields optional if their type includes `undefined`.
*
* TypeScript distinguishes between optional fields (`key?: T`) and fields that
* accept undefined (`key: T | undefined`). This utility converts the latter
* to the former, allowing callers to omit the prop entirely rather than
* passing an explicit `undefined`.
*
* Implementation:
* 1. `Omit>` - Remove all undefined-accepting keys
* 2. `Partial>>` - Add them back as optional
* 3. Intersection combines both parts
*
* @template T - The object type to transform
* @returns New type with undefined-accepting fields made optional
*
* @example
* ```ts
* type BeforeTransform = {
* device: 'iPad Pro';
* color: 'silver' | 'space-gray';
* landscape: boolean | undefined; // Accepts undefined but is required
* }
*
* type AfterTransform = OptionField
* // Result: {
* // device: 'iPad Pro';
* // color: 'silver' | 'space-gray';
* // landscape?: boolean | undefined; // Now truly optional
* // }
* ```
*/
type OptionField = Omit> & Partial>>;
/**
* Flattens a type for cleaner IDE display and better autocomplete.
*
* Complex types built from intersections (`A & B`) and mapped types can
* display as unwieldy expressions in IDE tooltips. This utility forces
* TypeScript to eagerly compute the final object shape, resulting in
* cleaner, more readable type hints.
*
* The `& unknown` is a TypeScript trick that triggers type simplification
* without affecting the resulting type (since `T & unknown = T`).
*
* @template A - The type to flatten
* @returns Simplified type with identical structure but cleaner display
*
* @example
* ```ts
* // Without Compute - IDE shows:
* // Omit<{ device: string; color: never }, 'color'> & { landscape?: boolean }
*
* // With Compute - IDE shows:
* // { device: string; landscape?: boolean }
*
* type Complex = { a: string } & { b: number } & { c: boolean }
* type Simple = Compute
* // Hover shows: { a: string; b: number; c: boolean }
* ```
*/
type Compute = {
[K in keyof A]: A[K];
} & unknown;
/**
* Internal type representing a device configuration
*/
type DeviceType = {
/** CSS class name for the device frame */
device: Device;
/** Available color variants */
colors: Colors;
/** Whether the device supports landscape orientation */
hasLandscape: boolean;
/** Default content width in pixels */
width?: number;
/** Default content height in pixels */
height?: number;
};
declare const DeviceOptions: {
"iPhone X": {
device: "iphone-x";
colors: readonly [];
hasLandscape: true;
width: number;
height: number;
};
"iPhone 8": {
device: "iphone8";
colors: readonly ["black", "silver", "gold"];
hasLandscape: true;
width: number;
height: number;
};
"iPhone 8 Plus": {
device: "iphone8plus";
colors: readonly ["black", "silver", "gold"];
hasLandscape: true;
width: number;
height: number;
};
"iPhone 17": {
device: "iphone17";
colors: readonly ["black", "white", "mist-blue", "sage", "lavender", "cosmic-orange", "deep-blue"];
hasLandscape: true;
width: number;
height: number;
};
"Pixel 10": {
device: "pixel10";
colors: readonly ["obsidian", "porcelain", "mint", "rose"];
hasLandscape: true;
width: number;
height: number;
};
"Galaxy S25": {
device: "galaxy-s25";
colors: readonly ["phantom-black", "icy-blue", "navy", "silver", "mint"];
hasLandscape: true;
width: number;
height: number;
};
"iPad Mini": {
device: "ipad";
colors: readonly ["black", "silver"];
hasLandscape: true;
width: number;
height: number;
};
"iPad Pro": {
device: "ipad-pro";
colors: readonly ["space-gray", "silver"];
hasLandscape: true;
width: number;
height: number;
};
"MacBook Pro 2020": {
device: "macbook";
colors: readonly [];
hasLandscape: false;
width: number;
height: number;
};
"MacBook Pro": {
device: "macbook-pro";
colors: readonly ["space-gray", "silver"];
hasLandscape: false;
width: number;
height: number;
};
};
/**
* Union type of all available device names
* @example 'iPhone X' | 'iPhone 8' | 'iPhone 17' | 'Pixel 10' | ...
*/
type DeviceName = keyof typeof DeviceOptions;
/**
* Array of all available device names
*/
declare const DeviceNames: DeviceName[];
/**
* Get the device configuration for a specific device
*/
type DeviceConfig = typeof DeviceOptions[D];
/**
* Get the available colors for a specific device
* @example DeviceColor<'iPhone 8'> = 'black' | 'silver' | 'gold'
*/
type DeviceColor = typeof DeviceOptions[D]['colors'][number];
/**
* Check if a device supports landscape orientation
*/
type DeviceHasLandscape = typeof DeviceOptions[D]['hasLandscape'];
/**
* Internal type for generating discriminated union props
*/
type DevicesType>> = {
[key in keyof R]: Compute>>;
}[keyof R];
/**
* Props for the MockFrame component
*
* This is a discriminated union type that provides type-safe props based on the selected device.
* The `color` prop is only required for devices that have color variants.
* The `landscape` prop is only available for devices that support landscape orientation.
*
* @example
* // iPhone X - no color required, landscape supported
*
*
* @example
* // iPhone 8 - color required, landscape supported
*
*
* @example
* // MacBook Pro - color required, no landscape support
*
*/
type MockFrameProps = DevicesType & Omit, 'color'>;
/**
* @fileoverview MockFrame Components
*
* This module exports two main components:
* - `MockFrame` - Renders predefined device frames (iPhone, Android, iPad, MacBook)
* - `CustomMockFrame` - Creates custom device frames with configurable bezels
*
* @example Basic usage
* ```tsx
* import { MockFrame } from 'react-mockframe'
* import 'react-mockframe/styles/mockframe.css'
*
*
*
*
* ```
*
* @module MockFrame
*/
/**
* Props for the CustomMockFrame component.
*/
interface CustomMockFrameProps extends React$1.HTMLAttributes {
/** Content to render inside the device screen */
children?: React$1.ReactNode;
/** Width of the screen area in pixels (required) */
width: number;
/** Height of the screen area in pixels (required) */
height: number;
/**
* Bezel thickness around the screen.
* Can be a uniform number or per-side object.
* @default 12
*
* @example Uniform bezel
* bezelWidth={16}
*
* @example Per-side bezel (like older iPhones with chin)
* bezelWidth={{ top: 20, right: 8, bottom: 40, left: 8 }}
*/
bezelWidth?: number | {
top?: number;
right?: number;
bottom?: number;
left?: number;
};
/**
* Border radius of the outer device frame.
* @default 44
*/
borderRadius?: number;
/**
* Border radius of the screen area.
* If not specified, calculated as `borderRadius - bezelWidth`.
*/
screenBorderRadius?: number;
/**
* Background color of the device bezel.
* @default '#1a1a1a'
*/
bezelColor?: string;
/**
* Background color of the screen area.
* @default '#ffffff'
*/
screenColor?: string;
/**
* Scale factor for the entire device frame.
* Values less than 1 shrink, greater than 1 enlarge.
* @example zoom={0.75} // 75% size
*/
zoom?: number;
/**
* Enable smooth CSS transitions for zoom and color changes.
* Useful when zoom is controlled by user interaction.
*/
animated?: boolean;
/**
* Display the device in landscape orientation.
* Swaps width and height dimensions.
*/
landscape?: boolean;
/** Additional CSS class for the outer frame element */
frameClassName?: string;
/** Additional CSS class for the screen area element */
screenClassName?: string;
}
/**
* Creates a custom device frame with configurable bezel, colors, and dimensions.
*
* Use this component when you need a device frame that doesn't match any
* predefined device, or when you want full control over the frame appearance.
*
* @example Basic usage
* ```tsx
*
*
*
* ```
*
* @example With asymmetric bezels (like older phones with chin)
* ```tsx
*
*
*
* ```
*/
declare const CustomMockFrame: React$1.NamedExoticComponent;
/**
* Renders a realistic device frame around your content.
*
* This is the primary component for displaying content inside predefined
* device mockups. The component is fully type-safe - TypeScript will only
* allow valid color options for each device.
*
* @example iPhone with color
* ```tsx
*
*
*
* ```
*
* @example iPhone X (no color options)
* ```tsx
*
*
*
* ```
*
* @example With zoom and animation
* ```tsx
*
*
*
* ```
*
* @see {@link DeviceOptions} for available devices and their configurations
*/
declare const MockFrame: React$1.NamedExoticComponent;
export { CustomMockFrame, type CustomMockFrameProps, type DeviceColor, type DeviceConfig, type DeviceHasLandscape, type DeviceName, DeviceNames, DeviceOptions, MockFrame, type MockFrameProps };