UNPKG

swiftui-react-native

Version:

A React Native component library inspired by SwiftUI

437 lines (412 loc) 9.69 kB
import { ViewStyle } from 'react-native'; type Color = | 'blue' | 'red' | 'green' | 'yellow' | 'orange' | 'purple' | 'pink' | 'primary' | 'secondary' | 'accentColor' | 'black' | 'white' | 'gray' | 'clear' | 'mint' | 'brown' | 'teal' | 'cyan' | 'indigo' | `#${string}` | `rgb${string}` | (string & {}); type LinearGradient = { linearGradient: { colors: Color[]; startPoint: | 'top' | 'bottom' | 'leading' | 'trailing' | 'topLeading' | 'topTrailing' | 'bottomLeading' | 'bottomTrailing'; endPoint: | 'top' | 'bottom' | 'leading' | 'trailing' | 'topLeading' | 'topTrailing' | 'bottomLeading' | 'bottomTrailing'; }; }; export type Modifiers = { // View ignoresSafeArea?: boolean; padding?: | number | boolean | { leading?: number; top?: number; bottom?: number; trailing?: number; horizontal?: number; vertical?: number; all?: number; }; border?: { color?: Color; width?: number; }; foregroundStyle?: Color | Color[] | LinearGradient; rotationEffect?: { degrees?: number; radians?: number; }; redacted?: 'privacy' | 'placeholder' | 'invalidated'; scaleEffect?: number; shadow?: { color?: Color; x?: number; y?: number; radius?: number; opacity?: number; }; background?: Color | LinearGradient; disabled?: boolean; hidden?: boolean; frame?: | { width?: number; height?: number; } | { minWidth?: number | 'infinity'; minHeight?: number | 'infinity'; maxWidth?: number | 'infinity'; maxHeight?: number | 'infinity'; }; zIndex?: number; opacity?: number; tint?: Color; cornerRadius?: number; position?: { x: number; y: number }; offset?: { x: number; y: number }; fixedSize?: boolean | { horizontal?: boolean; vertical?: boolean }; lineLimit?: number; animation?: { type: | 'spring' | 'easeIn' | 'easeOut' | 'easeInOut' | 'linear' | 'interpolatingSpring' | 'bouncy' | 'smooth' | 'default'; value: any; }; contentTransition?: | 'numericText' | 'opacity' | 'identity' | 'interpolate' | 'symbolEffect'; labelIsHidden?: boolean; // Filter blur?: number; saturation?: number; grayscale?: number; brightness?: number; contrast?: number; compositingGroup?: boolean; blendMode?: | 'color' | 'colorBurn' | 'colorDodge' | 'darken' | 'difference' | 'exclusion' | 'hardLight' | 'hue' | 'lighten' | 'luminosity' | 'multiply' | 'overlay' | 'saturation' | 'screen' | 'softLight' | 'sourceAtop' | 'destinationOver' | 'destinationOut' | 'plusDarker' | 'plusLighter' | 'normal'; mask?: string; clipShape?: | 'circle' | 'roundedRectangle' | 'capsule' | 'rectangle' | 'ellipse' | { shape: 'roundedRectangle'; cornerRadius: number; }; fill?: Color; stroke?: { color: Color; lineWidth: number; }; // Environment environment?: { colorScheme: 'light' | 'dark'; }; // TextField textContentType?: | 'name' | 'namePrefix' | 'givenName' | 'middleName' | 'familyName' | 'nameSuffix' | 'nickname' | 'jobTitle' | 'organizationName' | 'location' | 'fullStreetAddress' | 'streetAddressLine1' | 'streetAddressLine2' | 'addressCity' | 'addressState' | 'addressCityAndState' | 'sublocality' | 'countryName' | 'postalCode' | 'telephoneNumber' | 'emailAddress' | 'URL' | 'creditCardNumber' | 'username' | 'password' | 'newPassword' | 'oneTimeCode' | 'shipmentTrackingNumber' | 'flightNumber' | 'dateTime' | 'birthdate' | 'birthdateDay' | 'birthdateMonth' | 'birthdateYear' | 'creditCardSecurityCode' | 'creditCardName' | 'creditCardGivenName' | 'creditCardMiddleName' | 'creditCardFamilyName' | 'creditCardExpiration' | 'creditCardExpirationMonth' | 'creditCardExpirationYear' | 'creditCardType'; keyboardType?: | 'numberPad' | 'phonePad' | 'namePhonePad' | 'emailAddress' | 'decimalPad' | 'twitter' | 'webSearch' | 'asciiCapableNumberPad' | 'numbersAndPunctuation' | 'URL' | 'asciiCapable' | 'default'; textInputAutocapitalization?: 'never' | 'words' | 'sentences' | 'characters'; autocorrectionDisabled?: boolean; // Image resizable?: boolean; imageScale?: 'small' | 'medium' | 'large'; symbolRenderingMode?: | 'palette' | 'monochrome' | 'hierarchical' | 'multicolor'; // Text fontSize?: number; fontWeight?: | 'ultralight' | 'thin' | 'light' | 'regular' | 'medium' | 'semibold' | 'bold' | 'heavy' | 'black'; font?: | 'body' | 'callout' | 'caption' | 'caption2' | 'footnote' | 'headline' | 'largeTitle' | 'subheadline' | 'title' | 'title2' | 'title3'; bold?: boolean; italic?: boolean; strikethrough?: | boolean | { isActive: boolean; color?: Color; pattern?: 'dot' | 'dash' | 'solid' | 'dashDotDot' | 'dashDot'; }; underline?: | boolean | { isActive: boolean; color?: Color; pattern?: 'dot' | 'dash' | 'solid' | 'dashDotDot' | 'dashDot'; }; // Style Variants buttonStyle?: 'bordered' | 'borderless' | 'plain' | 'borderedProminent'; pickerStyle?: 'wheel' | 'segmented' | 'menu'; textFieldStyle?: 'plain' | 'roundedBorder'; listStyle?: 'inset' | 'grouped' | 'plain' | 'insetGrouped'; // Haptics sensoryFeedback?: { feedback: | 'warning' | 'error' | 'success' | 'alignment' | 'decrease' | 'impact' | 'increase' | 'levelChange' | 'selection' | 'start' | 'stop'; trigger: any; }; // List scrollDisabled?: boolean; // Lifecycle onAppear?: () => void; onDisappear?: () => void; // contextMenu?: ContextMenu; // alert?: Alert; // Sheet // sheet?: { // isPresented: boolean | BooleanBinding; // content: ReactNode; // onDismiss?: () => void; // }; // presentationCornerRadius?: number; // presentationDetents?: ( // | 'medium' // | 'large' // | { fraction: number } // | { height: number } // )[]; }; export type NativeModifiersProp = { [key: string]: any }; export type ExperimentalPrivateModifierProp = { _modifiers: NativeModifiersProp[]; }; export function getExperimentalPrivateModifiers(modifiers: Modifiers) { const experimentalPrivateMods = (modifiers as ExperimentalPrivateModifierProp) ._modifiers; if (experimentalPrivateMods) { return experimentalPrivateMods.reduce((styles, mod) => { return { ...styles, ...mod }; }, {}); } else { return modifiers; } } /** * Maps a modifiers object or function to an array of native modifiers, with * the order being preserved. */ export function mapToNativeModifiers(modifiers: Modifiers) { const experimentalPrivateMods = (modifiers as ExperimentalPrivateModifierProp) ._modifiers; if (experimentalPrivateMods) return experimentalPrivateMods; if (Array.isArray(modifiers)) return modifiers; let result: NativeModifiersProp[] = []; result = Object.keys(modifiers || {}).map((key) => { return { [key]: modifiers[key] }; }); return result; } export function getSizeFromModifiers( modifiers: Modifiers, defaultSize?: { width: number; height: number } ) { modifiers = getExperimentalPrivateModifiers(modifiers); const styles: ViewStyle = {}; let width = (modifiers.frame as any)?.width || defaultSize?.width; let height = (modifiers.frame as any)?.height || defaultSize?.height; let minWidth = (modifiers.frame as any)?.minWidth; let minHeight = (modifiers.frame as any)?.minHeight; let maxWidth = (modifiers.frame as any)?.maxWidth; let maxHeight = (modifiers.frame as any)?.maxHeight; if (width) { styles.width = width; } if (height) { styles.height = height; } if (minWidth) { styles.minWidth = minWidth === 'infinity' ? '100%' : minWidth; } if (minHeight) { styles.minHeight = minHeight === 'infinity' ? '100%' : minHeight; } if (maxWidth) { styles.maxWidth = maxWidth === 'infinity' ? '100%' : maxWidth; styles.width = maxWidth === 'infinity' ? '100%' : maxWidth; } if (maxHeight) { styles.maxHeight = maxHeight === 'infinity' ? '100%' : maxHeight; styles.height = maxHeight === 'infinity' ? '100%' : maxHeight; } if (typeof modifiers.padding === 'number') { styles.padding = modifiers.padding; } else if (typeof modifiers.padding === 'boolean') { styles.padding = modifiers.padding ? 8 : 0; } else { if (modifiers.padding?.all) { styles.padding = modifiers.padding.all; } if (modifiers.padding?.horizontal) { styles.paddingHorizontal = modifiers.padding.horizontal; } if (modifiers.padding?.vertical) { styles.paddingVertical = modifiers.padding.vertical; } if (modifiers.padding?.top) { styles.paddingTop = modifiers.padding.top; } if (modifiers.padding?.bottom) { styles.paddingBottom = modifiers.padding.bottom; } if (modifiers.padding?.leading) { styles.paddingLeft = modifiers.padding.leading; } if (modifiers.padding?.trailing) { styles.paddingRight = modifiers.padding.trailing; } } return styles; }