diff --git a/packages/mobile-app/app/(tabs)/balances.tsx b/packages/mobile-app/app/(tabs)/balances.tsx index 3e1e66a..6f4e202 100644 --- a/packages/mobile-app/app/(tabs)/balances.tsx +++ b/packages/mobile-app/app/(tabs)/balances.tsx @@ -3,6 +3,7 @@ import { HStack, Icon, IconButton, + Tabs, Text, VStack, } from "@ironfish/tackle-box"; @@ -31,7 +32,32 @@ export default function Balances() { flexGrow={1} borderTopLeftRadius={20} borderTopRightRadius={20} - /> + > + + + Assets + Transactions + + + + Assets + Assets + Assets + Assets + Assets + + + + + Transactions + Transactions + Transactions + Transactions + Transactions + + + + ); } diff --git a/packages/tackle-box/lib/components/Tabs/Tabs.tsx b/packages/tackle-box/lib/components/Tabs/Tabs.tsx new file mode 100644 index 0000000..4bfabab --- /dev/null +++ b/packages/tackle-box/lib/components/Tabs/Tabs.tsx @@ -0,0 +1,110 @@ +import { Box } from "@/components/Box/Box"; +import { HStack } from "@/components/Stack/Stack"; +import { createContext, ReactNode, useContext, useState } from "react"; +import { css, html } from "react-strict-dom"; +import { Text } from "@/components/Text/Text"; +import { colors } from "@/vars/colors.stylex"; + +const TabsContext = createContext<{ + activeTab: string; + setActiveTab: (tab: string) => void; +}>({ + activeTab: "", + setActiveTab: () => {}, +}); + +function useTabsContext() { + return useContext(TabsContext); +} + +type RootProps = { + children: ReactNode; + defaultValue?: string; +}; + +function Root({ children, defaultValue }: RootProps) { + const [activeTab, setActiveTab] = useState(defaultValue ?? ""); + + return ( + + {children} + + ); +} + +type ListProps = { + children: ReactNode; +}; + +function List({ children }: ListProps) { + return ( + + {children} + + ); +} + +type TriggerProps = { + children: ReactNode; + value: string; +}; + +const triggerStyles = css.create({ + wrapper: { + borderWidth: 0, + paddingLeft: 16, + paddingRight: 16, + }, + activeIndicator: { + borderBottomWidth: 2, + borderColor: colors.textPrimary, + }, + textActive: { + color: "textPrimary", + }, + textInactive: { + color: "textSecondary", + }, +}); + +function Trigger({ children, value }: TriggerProps) { + const context = useTabsContext(); + const isActive = context.activeTab === value; + + return ( + context.setActiveTab(value)} + style={triggerStyles.wrapper} + > + + + {children} + + + + ); +} + +type ContentProps = { + children: ReactNode; + value: string; +}; + +function Content({ children, value }: ContentProps) { + const context = useTabsContext(); + + return context.activeTab === value ? <>{children} : null; +} + +const Tabs = { + Root, + List, + Trigger, + Content, +}; + +export { Tabs }; diff --git a/packages/tackle-box/lib/components/Text/Text.tsx b/packages/tackle-box/lib/components/Text/Text.tsx index 30285ce..2a5ffb7 100644 --- a/packages/tackle-box/lib/components/Text/Text.tsx +++ b/packages/tackle-box/lib/components/Text/Text.tsx @@ -1,3 +1,4 @@ +import { Colors, getColorValue } from "@/vars/colors.stylex"; import { ReactNode } from "react"; import { css, html } from "react-strict-dom"; @@ -36,17 +37,33 @@ const styles = css.create({ textAlign: (textAlign: "left" | "center" | "right") => ({ textAlign, }), + color: (color?: string) => ({ + color, + }), }); type Props = { children?: ReactNode; size?: Sizes; textAlign?: "left" | "center" | "right"; + color?: Colors; }; -export function Text({ children, size = "md", textAlign = "left" }: Props) { +export function Text({ + children, + size = "md", + textAlign = "left", + color = "textPrimary", +}: Props) { return ( - + {children} ); diff --git a/packages/tackle-box/lib/index.ts b/packages/tackle-box/lib/index.ts index 67e8980..7dc2179 100644 --- a/packages/tackle-box/lib/index.ts +++ b/packages/tackle-box/lib/index.ts @@ -5,4 +5,5 @@ 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 { Tabs } from "@/components/Tabs/Tabs"; export { css } from "react-strict-dom"; diff --git a/packages/tackle-box/lib/vars/colors.stylex.ts b/packages/tackle-box/lib/vars/colors.stylex.ts index 8dd77dc..e0620a4 100644 --- a/packages/tackle-box/lib/vars/colors.stylex.ts +++ b/packages/tackle-box/lib/vars/colors.stylex.ts @@ -17,6 +17,7 @@ export const palette = css.defineVars({ black: "#101010", white: "#FFFFFF", pink: "#FFC0CB", + transparent: "transparent", }); // Theme tokens