UNPKG

onecart-ui

Version:

OneCart UI: Cross-platform design tokens + React & React Native components

474 lines (460 loc) 18.3 kB
import { jsx } from 'react/jsx-runtime'; import { useState } from 'react'; import { TouchableOpacity, Text, Pressable } from 'react-native'; /** * File generated by the Figma Token Engine * Do not edit directly */ const ACTION_PRIMARY_DEFAULT$1 = "#00df88"; const ACTION_PRIMARY_HOVER$1 = "#4ce9ac"; const ACTION_PRIMARY_ACTIVE$1 = "#98f2cf"; const ACTION_PRIMARY_DISABLED$1 = "#E5FCF3"; const ACTION_DESTRUCTIVE_DEFAULT$1 = "#d60000"; const ACTION_DESTRUCTIVE_HOVER$1 = "#a90000"; const ACTION_DESTRUCTIVE_ACTIVE$1 = "#fed8d8"; const ACTION_DESTRUCTIVE_DISABLE$1 = "#feecec"; const ACTION_TERTIARY_DEFAULT$1 = "#3b3b3b"; const ACTION_TERTIARY_HOVER$1 = "#111"; const ACTION_TERTIARY_ACTIVE$1 = "#ababab"; const ACTION_TERTIARY_DISABLE$1 = "#f1f1f1"; const NEUTRAL_80$1 = "#3b3b3b"; const DISPLAY_2XL_LINE_HEIGHT = "56px"; const DISPLAY_2XL_FONT_SIZE = "52px"; const DISPLAY_2XL_LETTER_SPACING = "0%"; const DISPLAY_2XL_TEXT_DECORATION = "none"; const DISPLAY_XL_LINE_HEIGHT = "48px"; const DISPLAY_XL_FONT_SIZE = "44px"; const DISPLAY_XL_LETTER_SPACING = "0%"; const DISPLAY_XL_TEXT_DECORATION = "none"; const HEADING_XL_LINE_HEIGHT = "48px"; const HEADING_XL_FONT_SIZE = "40px"; const HEADING_XL_LETTER_SPACING = "0%"; const HEADING_XL_TEXT_DECORATION = "none"; const HEADING_LG_LINE_HEIGHT = "44px"; const HEADING_LG_FONT_SIZE = "36px"; const HEADING_LG_LETTER_SPACING = "0%"; const HEADING_LG_TEXT_DECORATION = "none"; const HEADING_MD_LINE_HEIGHT = "40px"; const HEADING_MD_FONT_SIZE = "32px"; const HEADING_MD_LETTER_SPACING = "0%"; const HEADING_MD_TEXT_DECORATION = "none"; const HEADING_SM_LINE_HEIGHT = "36px"; const HEADING_SM_FONT_SIZE = "28px"; const HEADING_SM_LETTER_SPACING = "0%"; const HEADING_SM_TEXT_DECORATION = "none"; const HEADING_XS_LINE_HEIGHT = "28px"; const HEADING_XS_FONT_SIZE = "20px"; const HEADING_XS_LETTER_SPACING = "0%"; const HEADING_XS_TEXT_DECORATION = "none"; const HEADING_2XS_LINE_HEIGHT = "24px"; const HEADING_2XS_FONT_SIZE = "18px"; const HEADING_2XS_LETTER_SPACING = "0%"; const HEADING_2XS_TEXT_DECORATION = "none"; const BODY_XL_LINE_HEIGHT = "28px"; const BODY_XL_FONT_SIZE = "18px"; const BODY_XL_LETTER_SPACING = "0%"; const BODY_XL_TEXT_DECORATION = "none"; const BODY_LG_LINE_HEIGHT = "24px"; const BODY_LG_FONT_SIZE = "16px"; const BODY_LG_LETTER_SPACING = "0%"; const BODY_LG_TEXT_DECORATION = "none"; const BODY_MD_LINE_HEIGHT = "20px"; const BODY_MD_FONT_SIZE = "14px"; const BODY_MD_LETTER_SPACING = "0%"; const BODY_MD_TEXT_DECORATION = "none"; const BODY_SM_LINE_HEIGHT = "20px"; const BODY_SM_FONT_SIZE = "12px"; const BODY_SM_LETTER_SPACING = "0%"; const BODY_SM_TEXT_DECORATION = "none"; const UTILITY_BUTTON_FONT_WEIGHT = 500; const UTILITY_BUTTON_LINE_HEIGHT = "16px"; const UTILITY_BUTTON_FONT_SIZE = "16px"; const UTILITY_BUTTON_LETTER_SPACING = "0%"; const UTILITY_BUTTON_TEXT_DECORATION = "none"; const UTILITY_LINK_FONT_WEIGHT = 500; const UTILITY_LINK_LINE_HEIGHT = "20px"; const UTILITY_LINK_FONT_SIZE = "14px"; const UTILITY_LINK_LETTER_SPACING = "0%"; const UTILITY_LINK_TEXT_DECORATION = "underline"; const UTILITY_CAPTION_FONT_WEIGHT = "book"; const UTILITY_CAPTION_LINE_HEIGHT = "16px"; const UTILITY_CAPTION_FONT_SIZE = "12px"; const UTILITY_CAPTION_LETTER_SPACING = "0%"; const UTILITY_CAPTION_TEXT_DECORATION = "none"; const FONT_FAMILIES_CAMPTON$1 = "Campton"; const SEMI_BOLD = 600; const BOOK = "book"; // Facade: curated subset of raw Figma tokens for button usage // Generated manually; consider automating selection logic later. const ACTION_PRIMARY_DEFAULT = ACTION_PRIMARY_DEFAULT$1; const ACTION_PRIMARY_HOVER = ACTION_PRIMARY_HOVER$1; const ACTION_PRIMARY_ACTIVE = ACTION_PRIMARY_ACTIVE$1; const ACTION_PRIMARY_DISABLED = ACTION_PRIMARY_DISABLED$1; const ACTION_TERTIARY_DEFAULT = ACTION_TERTIARY_DEFAULT$1; const ACTION_TERTIARY_HOVER = ACTION_TERTIARY_HOVER$1; const ACTION_TERTIARY_ACTIVE = ACTION_TERTIARY_ACTIVE$1; const ACTION_TERTIARY_DISABLE = ACTION_TERTIARY_DISABLE$1; const ACTION_DESTRUCTIVE_DEFAULT = ACTION_DESTRUCTIVE_DEFAULT$1; const ACTION_DESTRUCTIVE_HOVER = ACTION_DESTRUCTIVE_HOVER$1; const ACTION_DESTRUCTIVE_ACTIVE = ACTION_DESTRUCTIVE_ACTIVE$1; const ACTION_DESTRUCTIVE_DISABLE = ACTION_DESTRUCTIVE_DISABLE$1; const NEUTRAL_80 = NEUTRAL_80$1; const FONT_FAMILIES_CAMPTON = FONT_FAMILIES_CAMPTON$1; // Central design tokens import facade for components. // Pulls curated subset from the tokens package facade; extend as needed. const buttonTokens = { primary: { default: ACTION_PRIMARY_DEFAULT, hover: ACTION_PRIMARY_HOVER, active: ACTION_PRIMARY_ACTIVE, disabled: ACTION_PRIMARY_DISABLED, }, outline: { text: { default: ACTION_TERTIARY_DEFAULT, hover: ACTION_TERTIARY_HOVER, active: ACTION_TERTIARY_ACTIVE, disabled: ACTION_TERTIARY_DISABLE, }, }, ghost: { text: { default: ACTION_TERTIARY_DEFAULT, hover: ACTION_TERTIARY_HOVER, active: ACTION_TERTIARY_ACTIVE, disabled: ACTION_TERTIARY_DISABLE, }, }, destructive: { text: { default: ACTION_DESTRUCTIVE_DEFAULT, hover: ACTION_DESTRUCTIVE_HOVER, active: ACTION_DESTRUCTIVE_ACTIVE, disabled: ACTION_DESTRUCTIVE_DISABLE, }, }, typography: { family: FONT_FAMILIES_CAMPTON}, neutralText: NEUTRAL_80, }; const computeMobileButtonStyles = (type, state, size, overrides) => { const basePaddingVertical = size === "large" ? 14 : size === "small" ? 8 : 10; const basePaddingHorizontal = 16; const container = { flexDirection: "row", alignItems: "center", justifyContent: "center", paddingVertical: basePaddingVertical, paddingHorizontal: basePaddingHorizontal, borderRadius: 999, opacity: state === "disabled" ? 0.6 : 1, }; switch (type) { case "primary": container.backgroundColor = buttonTokens.primary[state === "default" ? "default" : state]; break; case "outline": container.backgroundColor = "transparent"; container.borderWidth = 1; container.borderColor = buttonTokens.outline.text[state === "default" ? "default" : state]; break; case "ghost": container.backgroundColor = "transparent"; break; case "destructive": container.backgroundColor = "transparent"; break; } const label = { fontFamily: buttonTokens.typography.family, fontWeight: 500, fontSize: size === "large" ? 16 : size === "small" ? 14 : 15, lineHeight: size === "large" ? 20 : size === "small" ? 18 : 19, color: type === "primary" ? buttonTokens.neutralText : undefined, }; if (type === "outline") { label.color = buttonTokens.outline.text[state === "default" ? "default" : state]; } else if (type === "ghost") { label.color = buttonTokens.ghost.text[state === "default" ? "default" : state]; } else if (type === "destructive") { label.color = buttonTokens.destructive.text[state === "default" ? "default" : state]; } return { container: { ...container, ...({}) }, label }; }; const Button = ({ label, type = "primary", size = "large", disabled = false, onPress, style, accessibilityLabel, testID, }) => { const [buttonState] = useState(disabled ? "disabled" : "default"); const rnSize = (size === "large" ? "large" : "small"); const styles = computeMobileButtonStyles(type, buttonState, rnSize); return (jsx(TouchableOpacity, { accessibilityRole: "button", accessibilityLabel: accessibilityLabel || label, disabled: disabled, testID: testID, style: [styles.container, style], onPress: () => !disabled && onPress?.(), children: jsx(Text, { style: styles.label, children: label }) })); }; // Typography token mapping (bridge raw tokens -> component friendly sets) // For now we access raw tokens via the facade raw escape hatch. function px(n) { if (n == null) return 0; const s = String(n).replace("px", ""); const v = parseFloat(s); return Number.isNaN(v) ? 0 : v; } const typographyTokens = { // Display display2xl: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(DISPLAY_2XL_FONT_SIZE), lineHeight: px(DISPLAY_2XL_LINE_HEIGHT), fontWeight: String(SEMI_BOLD), color: String(NEUTRAL_80$1), letterSpacing: String(DISPLAY_2XL_LETTER_SPACING), textDecoration: String(DISPLAY_2XL_TEXT_DECORATION), }, displayXl: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(DISPLAY_XL_FONT_SIZE), lineHeight: px(DISPLAY_XL_LINE_HEIGHT), fontWeight: String(SEMI_BOLD), color: String(NEUTRAL_80$1), letterSpacing: String(DISPLAY_XL_LETTER_SPACING), textDecoration: String(DISPLAY_XL_TEXT_DECORATION), }, // Heading headingXl: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(HEADING_XL_FONT_SIZE), lineHeight: px(HEADING_XL_LINE_HEIGHT), fontWeight: String(SEMI_BOLD), color: String(NEUTRAL_80$1), letterSpacing: String(HEADING_XL_LETTER_SPACING), textDecoration: String(HEADING_XL_TEXT_DECORATION), }, headingLg: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(HEADING_LG_FONT_SIZE), lineHeight: px(HEADING_LG_LINE_HEIGHT), fontWeight: String(SEMI_BOLD), color: String(NEUTRAL_80$1), letterSpacing: String(HEADING_LG_LETTER_SPACING), textDecoration: String(HEADING_LG_TEXT_DECORATION), }, headingMd: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(HEADING_MD_FONT_SIZE), lineHeight: px(HEADING_MD_LINE_HEIGHT), fontWeight: String(SEMI_BOLD), color: String(NEUTRAL_80$1), letterSpacing: String(HEADING_MD_LETTER_SPACING), textDecoration: String(HEADING_MD_TEXT_DECORATION), }, headingSm: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(HEADING_SM_FONT_SIZE), lineHeight: px(HEADING_SM_LINE_HEIGHT), fontWeight: String(SEMI_BOLD), color: String(NEUTRAL_80$1), letterSpacing: String(HEADING_SM_LETTER_SPACING), textDecoration: String(HEADING_SM_TEXT_DECORATION), }, headingXs: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(HEADING_XS_FONT_SIZE), lineHeight: px(HEADING_XS_LINE_HEIGHT), fontWeight: String(SEMI_BOLD), color: String(NEUTRAL_80$1), letterSpacing: String(HEADING_XS_LETTER_SPACING), textDecoration: String(HEADING_XS_TEXT_DECORATION), }, heading2xs: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(HEADING_2XS_FONT_SIZE), lineHeight: px(HEADING_2XS_LINE_HEIGHT), fontWeight: String(SEMI_BOLD), color: String(NEUTRAL_80$1), letterSpacing: String(HEADING_2XS_LETTER_SPACING), textDecoration: String(HEADING_2XS_TEXT_DECORATION), }, // Body bodyXl: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(BODY_XL_FONT_SIZE), lineHeight: px(BODY_XL_LINE_HEIGHT), fontWeight: String(BOOK), color: String(NEUTRAL_80$1), letterSpacing: String(BODY_XL_LETTER_SPACING), textDecoration: String(BODY_XL_TEXT_DECORATION), }, bodyLg: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(BODY_LG_FONT_SIZE), lineHeight: px(BODY_LG_LINE_HEIGHT), fontWeight: String(BOOK), color: String(NEUTRAL_80$1), letterSpacing: String(BODY_LG_LETTER_SPACING), textDecoration: String(BODY_LG_TEXT_DECORATION), }, bodyMd: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(BODY_MD_FONT_SIZE), lineHeight: px(BODY_MD_LINE_HEIGHT), fontWeight: String(BOOK), color: String(NEUTRAL_80$1), letterSpacing: String(BODY_MD_LETTER_SPACING), textDecoration: String(BODY_MD_TEXT_DECORATION), }, bodySm: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(BODY_SM_FONT_SIZE), lineHeight: px(BODY_SM_LINE_HEIGHT), fontWeight: String(BOOK), color: String(NEUTRAL_80$1), letterSpacing: String(BODY_SM_LETTER_SPACING), textDecoration: String(BODY_SM_TEXT_DECORATION), }, // Utility / labels labelLg: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(UTILITY_BUTTON_FONT_SIZE), lineHeight: px(UTILITY_BUTTON_LINE_HEIGHT), fontWeight: String(UTILITY_BUTTON_FONT_WEIGHT), color: String(NEUTRAL_80$1), letterSpacing: String(UTILITY_BUTTON_LETTER_SPACING), textDecoration: String(UTILITY_BUTTON_TEXT_DECORATION), }, labelMd: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(UTILITY_LINK_FONT_SIZE), lineHeight: px(UTILITY_LINK_LINE_HEIGHT), fontWeight: String(UTILITY_LINK_FONT_WEIGHT), color: String(NEUTRAL_80$1), letterSpacing: String(UTILITY_LINK_LETTER_SPACING), textDecoration: String(UTILITY_LINK_TEXT_DECORATION), }, labelSm: { fontFamily: String(FONT_FAMILIES_CAMPTON$1), fontSize: px(UTILITY_CAPTION_FONT_SIZE), lineHeight: px(UTILITY_CAPTION_LINE_HEIGHT), fontWeight: String(UTILITY_CAPTION_FONT_WEIGHT), color: String(NEUTRAL_80$1), letterSpacing: String(UTILITY_CAPTION_LETTER_SPACING), textDecoration: String(UTILITY_CAPTION_TEXT_DECORATION), }, }; const Display = ({ size = "2xl", align = "left", color, truncate = false, lineClamp, children, style, onPress, testID, }) => { const tokenSet = size === "2xl" ? typographyTokens.display2xl : typographyTokens.displayXl; const fontWeightValue = parseInt(tokenSet.fontWeight); const textStyle = { fontFamily: tokenSet.fontFamily, fontSize: tokenSet.fontSize, lineHeight: tokenSet.lineHeight, fontWeight: fontWeightValue, color: color || tokenSet.color, textAlign: align, letterSpacing: tokenSet.letterSpacing, }; const textProps = { style: [textStyle, style], numberOfLines: truncate ? 1 : lineClamp, ellipsizeMode: truncate || lineClamp ? "tail" : undefined, testID, }; if (onPress) { return (jsx(Pressable, { onPress: onPress, children: jsx(Text, { ...textProps, children: children }) })); } return jsx(Text, { ...textProps, children: children }); }; const headingTokenKey = { xl: "headingXl", lg: "headingLg", md: "headingMd", sm: "headingSm", xs: "headingXs", "2xs": "heading2xs", }; const Heading = ({ size = "xl", align = "left", color, truncate = false, lineClamp, children, style, onPress, testID, }) => { const tokenSet = typographyTokens[headingTokenKey[size]]; const fontWeightValue = parseInt(tokenSet.fontWeight); const textStyle = { fontFamily: tokenSet.fontFamily, fontSize: tokenSet.fontSize, lineHeight: tokenSet.lineHeight, fontWeight: fontWeightValue, color: color || tokenSet.color, textAlign: align, letterSpacing: tokenSet.letterSpacing, }; const textProps = { style: [textStyle, style], numberOfLines: truncate ? 1 : lineClamp, ellipsizeMode: truncate || lineClamp ? "tail" : undefined, testID, }; if (onPress) { return (jsx(Pressable, { onPress: onPress, children: jsx(Text, { ...textProps, children: children }) })); } return jsx(Text, { ...textProps, children: children }); }; const Body = ({ size = "lg", align = "left", color, truncate = false, lineClamp, children, style, onPress, testID, }) => { const tokenMap = { xl: typographyTokens.bodyXl, lg: typographyTokens.bodyLg, md: typographyTokens.bodyMd, sm: typographyTokens.bodySm, }; const tokenSet = tokenMap[size]; const fontWeightValue = parseInt(tokenSet.fontWeight); const textStyle = { fontFamily: tokenSet.fontFamily, fontSize: tokenSet.fontSize, lineHeight: tokenSet.lineHeight, fontWeight: fontWeightValue, color: color || tokenSet.color, textAlign: align, letterSpacing: tokenSet.letterSpacing, }; const textProps = { style: [textStyle, style], numberOfLines: truncate ? 1 : lineClamp, ellipsizeMode: truncate || lineClamp ? "tail" : undefined, testID, }; if (onPress) { return (jsx(Pressable, { onPress: onPress, children: jsx(Text, { ...textProps, children: children }) })); } return jsx(Text, { ...textProps, children: children }); }; const Utility = ({ variant = "button", align = "left", color, truncate = false, lineClamp, children, style, onPress, testID, }) => { const tokenMap = { button: typographyTokens.labelLg, link: typographyTokens.labelMd, caption: typographyTokens.labelSm, }; const tokenSet = tokenMap[variant]; const fontWeightValue = parseInt(tokenSet.fontWeight); const textStyle = { fontFamily: tokenSet.fontFamily, fontSize: tokenSet.fontSize, lineHeight: tokenSet.lineHeight, fontWeight: fontWeightValue, color: color || tokenSet.color, textAlign: align, letterSpacing: tokenSet.letterSpacing, textDecorationLine: variant === "link" ? "underline" : "none", }; const textProps = { style: [textStyle, style], numberOfLines: truncate ? 1 : lineClamp, ellipsizeMode: truncate || lineClamp ? "tail" : undefined, testID, }; if (onPress) { return (jsx(Pressable, { onPress: onPress, children: jsx(Text, { ...textProps, children: children }) })); } return jsx(Text, { ...textProps, children: children }); }; export { Body, Button, Display, Heading, Utility }; //# sourceMappingURL=index.mobile.js.map