From 692f284ad598a05769687353827967d4c6f48779 Mon Sep 17 00:00:00 2001 From: Jay Date: Mon, 2 Sep 2024 15:16:49 +0800 Subject: [PATCH] Create ui package (#814) --- package.json | 3 +- packages/config-tamagui/src/animations.ts | 36 ++++++++ packages/config-tamagui/src/tamagui.config.ts | 4 +- packages/ui/package.json | 22 +++++ packages/ui/src/Button.tsx | 91 +++++++++++++++++++ packages/ui/src/index.ts | 1 + packages/ui/src/types.d.ts | 7 ++ pnpm-lock.yaml | 22 +++++ 8 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 packages/config-tamagui/src/animations.ts create mode 100644 packages/ui/package.json create mode 100644 packages/ui/src/Button.tsx create mode 100644 packages/ui/src/index.ts create mode 100644 packages/ui/src/types.d.ts diff --git a/package.json b/package.json index 3eebd57b..050b6302 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "lint": "turbo run lint", "test": "turbo run test", "clean": "turbo run clean && pnpm store prune && rm -rf .turbo node_modules", - "web": "pnpm --filter @helixbridge/web", + "build:web": "pnpm run build --filter @helixbridge/web", + "build:ui": "pnpm run build --filter @helixbridge/ui", "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,yaml}\"", "changeset": "changeset", "version-packages": "changeset version", diff --git a/packages/config-tamagui/src/animations.ts b/packages/config-tamagui/src/animations.ts new file mode 100644 index 00000000..1f9d3c63 --- /dev/null +++ b/packages/config-tamagui/src/animations.ts @@ -0,0 +1,36 @@ +import { createAnimations } from "@tamagui/animations-react-native"; + +export const animations = createAnimations({ + "100ms": { + type: "timing", + duration: 100, + }, + bouncy: { + damping: 9, + mass: 0.9, + stiffness: 150, + }, + lazy: { + damping: 18, + stiffness: 50, + }, + medium: { + damping: 15, + stiffness: 120, + mass: 1, + }, + slow: { + damping: 15, + stiffness: 40, + }, + quick: { + damping: 20, + mass: 1.2, + stiffness: 250, + }, + tooltip: { + damping: 10, + mass: 0.9, + stiffness: 100, + }, +}); diff --git a/packages/config-tamagui/src/tamagui.config.ts b/packages/config-tamagui/src/tamagui.config.ts index 0ef81a1d..82344258 100644 --- a/packages/config-tamagui/src/tamagui.config.ts +++ b/packages/config-tamagui/src/tamagui.config.ts @@ -4,7 +4,7 @@ import { shorthands } from "@tamagui/shorthands"; import { tokens, themes } from "@tamagui/config/v3"; import { createMedia } from "@tamagui/react-native-media-driver"; -// import { animations } from '@my/ui/src/animations' +import { animations } from "./animations"; const headingFont = createInterFont({ size: { @@ -52,7 +52,7 @@ const bodyFont = createInterFont( export const config = createTamagui({ defaultFont: "body", - // animations, + animations, shouldAddPrefersColorThemes: true, themeClassNameOnRoot: true, diff --git a/packages/ui/package.json b/packages/ui/package.json new file mode 100644 index 00000000..d8e71186 --- /dev/null +++ b/packages/ui/package.json @@ -0,0 +1,22 @@ +{ + "name": "@helixbridge/ui", + "version": "0.0.0", + "private": true, + "main": "index.js", + "scripts": { + "clean": "rm -rf node_modules .turbo dist", + "build": "tamagui-build --skip-types", + "watch": "tamagui-build --skip-types --watch" + }, + "license": "MIT", + "dependencies": { + "@tamagui/get-token": "^1.110.1", + "@tamagui/web": "^1.110.1", + "react": "^18.2.0", + "tamagui": "^1.110.1" + }, + "devDependencies": { + "@helixbridge/tamagui-config": "workspace:*", + "@tamagui/build": "^1.110.1" + } +} diff --git a/packages/ui/src/Button.tsx b/packages/ui/src/Button.tsx new file mode 100644 index 00000000..108c653c --- /dev/null +++ b/packages/ui/src/Button.tsx @@ -0,0 +1,91 @@ +import { getSize, getSpace } from "@tamagui/get-token"; +import { + GetProps, + SizeTokens, + View, + Text, + createStyledContext, + styled, + useTheme, + withStaticProperties, +} from "@tamagui/web"; +import { isValidElement, cloneElement, useContext } from "react"; + +export const ButtonContext = createStyledContext({ + size: "$md" as SizeTokens, +}); + +export const ButtonFrame = styled(View, { + name: "Button", + context: ButtonContext, + backgroundColor: "$background", + alignItems: "center", + flexDirection: "row", + + hoverStyle: { + backgroundColor: "$backgroundHover", + }, + + pressStyle: { + backgroundColor: "$backgroundPress", + }, + + variants: { + size: { + "...size": (name, { tokens }) => { + return { + height: tokens.size[name], + borderRadius: tokens.radius[name], + // note the getSpace and getSize helpers will let you shift down/up token sizes + // whereas with gap we just multiply by 0.2 + // this is a stylistic choice, and depends on your design system values + gap: tokens.space[name].val * 0.2, + paddingHorizontal: getSpace(name, { + shift: -1, + }), + }; + }, + }, + } as const, + + defaultVariants: { + size: "$md" as SizeTokens, + }, +}); + +type ButtonProps = GetProps; + +export const ButtonText = styled(Text, { + name: "ButtonText", + context: ButtonContext, + color: "$color", + userSelect: "none", + + variants: { + size: { + "...fontSize": (name, { font }) => ({ + fontSize: font?.size[name], + }), + }, + } as const, +}); + +const ButtonIcon = (props: { children: any }) => { + const { size } = useContext(ButtonContext.context); + const smaller = getSize(size, { + shift: -2, + }); + const theme = useTheme(); + return isValidElement(props.children) + ? cloneElement(props.children, { + size: smaller.val * 0.5, + color: theme?.color?.get(), + }) + : null; +}; + +export const Button = withStaticProperties(ButtonFrame, { + Props: ButtonContext.Provider, + Text: ButtonText, + Icon: ButtonIcon, +}); diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts new file mode 100644 index 00000000..e22c29ad --- /dev/null +++ b/packages/ui/src/index.ts @@ -0,0 +1 @@ +export * from "./Button"; diff --git a/packages/ui/src/types.d.ts b/packages/ui/src/types.d.ts new file mode 100644 index 00000000..aada4792 --- /dev/null +++ b/packages/ui/src/types.d.ts @@ -0,0 +1,7 @@ +import { config } from "@helixbridge/tamagui-config"; + +export type Conf = typeof config; + +declare module "tamagui" { + interface TamaguiCustomConfig extends Conf {} +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b68e86f7..63f9e216 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -311,6 +311,28 @@ importers: specifier: ^5.2.2 version: 5.5.4 + packages/ui: + dependencies: + "@tamagui/get-token": + specifier: ^1.110.1 + version: 1.110.1(react@18.3.1) + "@tamagui/web": + specifier: ^1.110.1 + version: 1.110.1(react@18.3.1) + react: + specifier: ^18.2.0 + version: 18.3.1 + tamagui: + specifier: ^1.110.1 + version: 1.110.1(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react-native@0.75.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.3.3)(react@18.3.1)(typescript@5.5.4))(react@18.3.1) + devDependencies: + "@helixbridge/tamagui-config": + specifier: workspace:* + version: link:../config-tamagui + "@tamagui/build": + specifier: ^1.110.1 + version: 1.110.1(@swc/helpers@0.5.12) + packages: "@adraffy/ens-normalize@1.10.0": resolution: