From eeac57d4f4e47a96c15f5a68cdcff6cada1eaddd Mon Sep 17 00:00:00 2001 From: Daniel Cortes Date: Mon, 2 Dec 2024 14:37:34 -0700 Subject: [PATCH] Build out top part of balances view --- package-lock.json | 8 +- packages/mobile-app/.eslintrc.js | 7 +- packages/mobile-app/app/(tabs)/temp.tsx | 75 +++++++++---------- .../SafeAreaGradient/SafeAreaGradient.tsx | 64 ++++++++++++++++ packages/mobile-app/package.json | 6 +- packages/mobile-app/tsconfig.json | 6 +- .../tackle-box/lib/components/Box/Box.tsx | 18 +++-- .../lib/components/Button/Button.tsx | 63 +--------------- .../lib/components/Button/IconButton.tsx | 38 ++++++++++ .../lib/components/Button/shared.ts | 57 ++++++++++++++ .../tackle-box/lib/components/Icon/Icon.tsx | 4 +- .../tackle-box/lib/components/Text/Text.tsx | 9 --- packages/tackle-box/lib/index.ts | 6 ++ packages/tackle-box/lib/vars/colors.stylex.ts | 12 +++ 14 files changed, 253 insertions(+), 120 deletions(-) create mode 100644 packages/mobile-app/components/SafeAreaGradient/SafeAreaGradient.tsx create mode 100644 packages/tackle-box/lib/components/Button/IconButton.tsx create mode 100644 packages/tackle-box/lib/components/Button/shared.ts diff --git a/package-lock.json b/package-lock.json index 13a68ee..4f91b9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11010,8 +11010,9 @@ }, "node_modules/eslint-import-resolver-typescript": { "version": "3.6.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.3.tgz", + "integrity": "sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==", "dev": true, - "license": "ISC", "dependencies": { "@nolyfill/is-core-module": "1.0.39", "debug": "^4.3.5", @@ -11135,8 +11136,9 @@ }, "node_modules/eslint-plugin-import": { "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "dev": true, - "license": "MIT", "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.8", @@ -22020,6 +22022,8 @@ "@types/react": "~18.2.79", "eslint-config-expo": "^7.0.0", "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-prettier": "^5.1.3", "expo-build-properties": "^0.12.5", "prettier": "^3.3.2", diff --git a/packages/mobile-app/.eslintrc.js b/packages/mobile-app/.eslintrc.js index fe5b366..b24f00f 100644 --- a/packages/mobile-app/.eslintrc.js +++ b/packages/mobile-app/.eslintrc.js @@ -1,8 +1,13 @@ // https://docs.expo.dev/guides/using-eslint/ module.exports = { extends: ["expo", "prettier"], - plugins: ["prettier"], + plugins: ["prettier", "plugin:import/typescript"], rules: { "prettier/prettier": "error", }, + settings: { + "import/resolver": { + typescript: {}, + }, + }, }; diff --git a/packages/mobile-app/app/(tabs)/temp.tsx b/packages/mobile-app/app/(tabs)/temp.tsx index 45e60e3..57614f2 100644 --- a/packages/mobile-app/app/(tabs)/temp.tsx +++ b/packages/mobile-app/app/(tabs)/temp.tsx @@ -1,49 +1,46 @@ -import { StyleSheet } from "react-native"; -import { Box, HStack, Icon, Text } from "@ironfish/tackle-box"; -import { SafeAreaView } from "react-native-safe-area-context"; -import Svg, { RadialGradient, Rect, Stop } from "react-native-svg"; +import { + Box, + HStack, + Icon, + IconButton, + Text, + VStack, +} from "@ironfish/tackle-box"; +import { SafeAreaGradient } from "@/components/SafeAreaGradient/SafeAreaGradient"; const GRADIENT_COLORS = ["#DE83F0", "#FFC2E8"]; export default function Balances() { return ( - - - - - - - - + + - - - Account 1 - - + + 100.55 + IRON - - Balance - - + + + + + + + + + ); } -const styles = StyleSheet.create({ - safeArea: { - flex: 1, - backgroundColor: "lightblue", - }, - svg: { - height: "100%", - width: "100%", - zIndex: -1, - }, -}); +function NavBar() { + return ( + + + + + Account 1 + + + + + ); +} diff --git a/packages/mobile-app/components/SafeAreaGradient/SafeAreaGradient.tsx b/packages/mobile-app/components/SafeAreaGradient/SafeAreaGradient.tsx new file mode 100644 index 0000000..92a5b11 --- /dev/null +++ b/packages/mobile-app/components/SafeAreaGradient/SafeAreaGradient.tsx @@ -0,0 +1,64 @@ +import { ReactNode } from "react"; +import { type Edges, SafeAreaView } from "react-native-safe-area-context"; +import { StyleSheet, View } from "react-native"; +import Svg, { RadialGradient, Rect, Stop } from "react-native-svg"; + +type Props = { + from: string; + to: string; + children: ReactNode; + edges?: Edges; +}; + +export function SafeAreaGradient({ + from, + to, + children, + edges = ["top"], +}: Props) { + return ( + + + + + + + + + + + {children} + + ); +} + +const styles = StyleSheet.create({ + safeArea: { + flex: 1, + }, + svgContainer: { + position: "absolute", + top: 140, + left: 0, + width: "100%", + aspectRatio: 1, + zIndex: -1, + flexDirection: "row", + justifyContent: "center", + }, +}); diff --git a/packages/mobile-app/package.json b/packages/mobile-app/package.json index 8944cad..aae03d7 100644 --- a/packages/mobile-app/package.json +++ b/packages/mobile-app/package.json @@ -17,6 +17,7 @@ "expo": "~51.0.39", "expo-constants": "~16.0.2", "expo-font": "~12.0.10", + "expo-linear-gradient": "~13.0.2", "expo-linking": "~6.3.1", "expo-router": "~3.5.24", "expo-secure-store": "13.0.2", @@ -36,8 +37,7 @@ "react-native-safe-area-context": "4.10.5", "react-native-screens": "~3.34.0", "react-native-svg": "15.9.0", - "zod": "^3.22.4", - "expo-linear-gradient": "~13.0.2" + "zod": "^3.22.4" }, "devDependencies": { "@babel/core": "^7.20.0", @@ -46,6 +46,8 @@ "@types/react": "~18.2.79", "eslint-config-expo": "^7.0.0", "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-prettier": "^5.1.3", "expo-build-properties": "^0.12.5", "prettier": "^3.3.2", diff --git a/packages/mobile-app/tsconfig.json b/packages/mobile-app/tsconfig.json index 446639e..39b3156 100644 --- a/packages/mobile-app/tsconfig.json +++ b/packages/mobile-app/tsconfig.json @@ -2,6 +2,10 @@ "extends": "expo/tsconfig.base", "compilerOptions": { "strict": true, - "moduleResolution": "bundler" + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "@/*": ["./*"] + } } } diff --git a/packages/tackle-box/lib/components/Box/Box.tsx b/packages/tackle-box/lib/components/Box/Box.tsx index 3f9b851..3c49046 100644 --- a/packages/tackle-box/lib/components/Box/Box.tsx +++ b/packages/tackle-box/lib/components/Box/Box.tsx @@ -1,6 +1,6 @@ import { ReactNode } from "react"; import { css, html } from "react-strict-dom"; -import { palette, type PaletteColors } from "@/vars/colors.stylex"; +import { type Colors, getColorValue } from "@/vars/colors.stylex"; import { StyleObj, UnitValue } from "@/utils/types"; import { useMarginPaddingValues, @@ -53,6 +53,9 @@ const styles = css.create({ borderWidth: (width: number) => ({ borderWidth: width, }), + flexGrow: (grow?: number) => ({ + flexGrow: grow, + }), }); export type BoxProps = { @@ -60,9 +63,10 @@ export type BoxProps = { height?: UnitValue; width?: UnitValue; borderRadius?: "full" | number; - bg?: PaletteColors; - borderColor?: PaletteColors; + bg?: Colors; + borderColor?: Colors; borderWidth?: number; + flexGrow?: number; style?: StyleObj; } & MarginPadding; @@ -74,6 +78,7 @@ export function Box({ borderColor, borderRadius = 0, borderWidth = 0, + flexGrow, style, ...marginPadding }: BoxProps) { @@ -87,9 +92,12 @@ export function Box({ styles.margin(...margin), styles.padding(...padding), styles.borderRadius(borderRadius === "full" ? 9999 : borderRadius), - styles.backgroundColor(bg ? palette[bg] : undefined), - styles.borderColor(borderColor ? palette[borderColor] : undefined), + styles.backgroundColor(bg ? getColorValue(bg) : undefined), + styles.borderColor( + borderColor ? getColorValue(borderColor) : undefined, + ), styles.borderWidth(borderWidth), + styles.flexGrow(flexGrow), style, ]} > diff --git a/packages/tackle-box/lib/components/Button/Button.tsx b/packages/tackle-box/lib/components/Button/Button.tsx index dfcd373..5f31572 100644 --- a/packages/tackle-box/lib/components/Button/Button.tsx +++ b/packages/tackle-box/lib/components/Button/Button.tsx @@ -1,68 +1,13 @@ -import { html, css } from "react-strict-dom"; -import { ComponentProps } from "react"; +import { html } from "react-strict-dom"; import { HStack, Text } from "@/index"; import { Icon, type IconName } from "@/components/Icon/Icon"; -import { colors } from "@/vars/index.stylex"; - -const styles = css.create({ - base: { - boxSizing: "border-box", - display: "flex", - alignItems: "center", - justifyContent: "center", - textAlign: "center", - paddingTop: 14, - paddingBottom: 14, - paddingLeft: 24, - paddingRight: 24, - fontSize: 20, - borderRadius: 9999, - }, - solid: { - backgroundColor: { - default: colors.backgroundInverse, - ":active": colors.backgroundHoverInverse, - }, - borderWidth: 0, - color: colors.textPrimaryInverse, - }, - outline: { - backgroundColor: { - default: "rgba(0, 0, 0, 0.0)", - ":active": "rgba(0, 0, 0, 0.05)", - }, - borderWidth: 1, - borderStyle: "solid", - borderColor: colors.border, - color: colors.textPrimary, - }, - ghost: { - backgroundColor: { - default: "rgba(0, 0, 0, 0.0)", - ":active": "rgba(0, 0, 0, 0.05)", - }, - borderWidth: 0, - borderColor: "transparent", - color: colors.textPrimary, - }, - disabled: { - backgroundColor: colors.backgroundDisabled, - borderColor: "transparent", - color: colors.textDisabled, - }, - icon: { - width: 17, - height: 18, - }, -}); - -type ButtonProps = ComponentProps; +import { type OnClick, styles } from "./shared"; type Props = { disabled?: boolean; title: string; variant?: "solid" | "outline" | "ghost"; - onClick?: ButtonProps["onClick"]; + onClick?: OnClick; rightIcon?: IconName; }; @@ -86,7 +31,7 @@ export function Button({ style={computedStyles} onClick={(e) => { if (disabled) return; - onClick?.(e); + onClick(e); }} > diff --git a/packages/tackle-box/lib/components/Button/IconButton.tsx b/packages/tackle-box/lib/components/Button/IconButton.tsx new file mode 100644 index 0000000..315e1d6 --- /dev/null +++ b/packages/tackle-box/lib/components/Button/IconButton.tsx @@ -0,0 +1,38 @@ +import { html, css } from "react-strict-dom"; +import { Icon, type IconName } from "@/components/Icon/Icon"; +import { type OnClick, styles as sharedStyles } from "./shared"; +import { VStack } from "../Stack/Stack"; +import { Text } from "../Text/Text"; + +const styles = css.create({ + button: { + height: 55, + width: 55, + }, +}); + +type Props = { + label: string; + onClick?: OnClick; + icon: IconName; +}; + +export function IconButton({ label, onClick, icon }: Props) { + const computedStyles = [sharedStyles.base, sharedStyles.solid]; + const Component = onClick ? html.button : html.div; + + return ( + + { + onClick?.(e); + }} + > + + + {label} + + ); +} diff --git a/packages/tackle-box/lib/components/Button/shared.ts b/packages/tackle-box/lib/components/Button/shared.ts new file mode 100644 index 0000000..878de0f --- /dev/null +++ b/packages/tackle-box/lib/components/Button/shared.ts @@ -0,0 +1,57 @@ +import { html, css } from "react-strict-dom"; +import { ComponentProps } from "react"; +import { colors } from "@/vars/index.stylex"; + +export const styles = css.create({ + base: { + boxSizing: "border-box", + display: "flex", + alignItems: "center", + justifyContent: "center", + textAlign: "center", + paddingTop: 14, + paddingBottom: 14, + paddingLeft: 24, + paddingRight: 24, + fontSize: 20, + borderRadius: 9999, + }, + solid: { + backgroundColor: { + default: colors.backgroundInverse, + ":active": colors.backgroundHoverInverse, + }, + borderWidth: 0, + color: colors.textPrimaryInverse, + }, + outline: { + backgroundColor: { + default: "rgba(0, 0, 0, 0.0)", + ":active": "rgba(0, 0, 0, 0.05)", + }, + borderWidth: 1, + borderStyle: "solid", + borderColor: colors.border, + color: colors.textPrimary, + }, + ghost: { + backgroundColor: { + default: "rgba(0, 0, 0, 0.0)", + ":active": "rgba(0, 0, 0, 0.05)", + }, + borderWidth: 0, + borderColor: "transparent", + color: colors.textPrimary, + }, + disabled: { + backgroundColor: colors.backgroundDisabled, + borderColor: "transparent", + color: colors.textDisabled, + }, + icon: { + width: 17, + height: 18, + }, +}); + +export type OnClick = ComponentProps["onClick"]; diff --git a/packages/tackle-box/lib/components/Icon/Icon.tsx b/packages/tackle-box/lib/components/Icon/Icon.tsx index bd31cbb..e96d154 100644 --- a/packages/tackle-box/lib/components/Icon/Icon.tsx +++ b/packages/tackle-box/lib/components/Icon/Icon.tsx @@ -15,10 +15,10 @@ const ICONS = { export type IconName = keyof typeof ICONS; type Props = { - name?: IconName; + name: IconName; } & React.SVGProps; -export function Icon({ name = "arrow-receive", ...props }: Props) { +export function Icon({ name, ...props }: Props) { const IconComponent = ICONS[name]; return ; diff --git a/packages/tackle-box/lib/components/Text/Text.tsx b/packages/tackle-box/lib/components/Text/Text.tsx index 8f0c93d..55d018a 100644 --- a/packages/tackle-box/lib/components/Text/Text.tsx +++ b/packages/tackle-box/lib/components/Text/Text.tsx @@ -6,42 +6,33 @@ type Sizes = "4xl" | "3xl" | "2xl" | "xl" | "lg" | "md" | "sm" | "xs"; const styles = css.create({ base: { fontFamily: "Favorit", - color: "red", textAlign: "center", }, "4xl": { fontFamily: "FavoritExtended", fontSize: 70, - lineHeight: 0.885, }, "3xl": { fontFamily: "FavoritExtended", fontSize: 44, - lineHeight: 1.136, }, "2xl": { fontSize: 40, - lineHeight: 1.35, }, xl: { fontSize: 32, - lineHeight: 1.125, }, lg: { fontSize: 24, - lineHeight: 1.083, }, md: { fontSize: 20, - lineHeight: 1.35, }, sm: { fontSize: 16, - lineHeight: 1.312, }, xs: { fontSize: 12, - lineHeight: 1.583, }, textAlign: (textAlign: "left" | "center" | "right") => ({ textAlign, diff --git a/packages/tackle-box/lib/index.ts b/packages/tackle-box/lib/index.ts index 8c593c5..8c7f4d9 100644 --- a/packages/tackle-box/lib/index.ts +++ b/packages/tackle-box/lib/index.ts @@ -1,6 +1,12 @@ +import * as vars from "@/vars/index.stylex"; + export { Box } from "@/components/Box/Box"; export { Button } from "@/components/Button/Button"; +export { IconButton } from "@/components/Button/IconButton"; export { HStack, VStack } from "@/components/Stack/Stack"; export { Text } from "@/components/Text/Text"; export { TextInput } from "@/components/TextInput/TextInput"; export { Icon } from "@/components/Icon/Icon"; +export { css } from "react-strict-dom"; + +export { vars }; diff --git a/packages/tackle-box/lib/vars/colors.stylex.ts b/packages/tackle-box/lib/vars/colors.stylex.ts index dee0bd9..8dd77dc 100644 --- a/packages/tackle-box/lib/vars/colors.stylex.ts +++ b/packages/tackle-box/lib/vars/colors.stylex.ts @@ -90,3 +90,15 @@ export const colors = css.defineVars({ }); export type PaletteColors = VarKeys; + +export type VarColors = VarKeys; + +export type Colors = PaletteColors | VarColors; + +export function getColorValue(color: PaletteColors | VarColors): string { + if (color in palette) { + return palette[color as PaletteColors]; + } + + return colors[color as VarColors]; +}