surf-uiby COLDSURF
Native

Getting Started

React Native 레인 — 같은 계약, 다른 구현.

@coldsurfers/surf-ui/native 는 React Native 앱을 위한 별도 구현입니다. 웹 primitives 와 같은 prop 계약을 따르지만 스타일 엔진이 다릅니다 — 웹은 vanilla-extract, 이쪽은 @emotion/native 입니다.

왜 구현이 둘인가

웹 레인의 산출물은 CSS 파일과 클래스 이름 문자열입니다. RN 에는 그 둘을 받을 곳이 없습니다 — className 도 스타일시트도 없습니다. 그래서 공유선은 토큰 값과 prop 계약까지고, 스타일은 플랫폼마다 따로 씁니다.

값이 갈리지 않게 묶는 자리가 contract/ 입니다. 축(ButtonVariant), 공통 props, 치수 표(CONCERT_CARD_BARE_SPEC)를 여기 올리고 양쪽 구현이 그걸 읽습니다.

설치

pnpm add @coldsurfers/surf-ui

peer 는 쓰는 표면만큼만 필요합니다. 전부 optional 이라 웹만 쓰는 소비처는 하나도 안 깝니다.

무엇을 쓰면무엇이 필요한가
전부@emotion/native · react-native
TabBar · AnimatedTabBarreact-native-safe-area-context
AnimatedTabBar · PullToRefreshreact-native-reanimated · react-native-worklets
PullToRefreshreact-native-gesture-handler
Spinner · PullToRefreshreact-native-svg

import 경로

배럴(/native)과 표면별 진입점(/native/TabBar) 둘 다 열려 있습니다.

import { Button, Text } from '@coldsurfers/surf-ui/native'
import { TabBar } from '@coldsurfers/surf-ui/native/TabBar'

무거운 peer 를 무는 표면은 진입점으로 여는 편이 낫습니다. 배럴은 PullToRefresh 까지 끌고 오므로, 탭바만 쓰는 화면도 gesture-handler 를 번들에 들입니다.

색은 훅으로 받는다

RN 에는 CSS 변수가 없습니다. 웹에서 var(--surf-action-primary) 한 줄로 끝나던 색 참조를 useScheme() 이 대신합니다.

const scheme = useScheme()
<View style={{ backgroundColor: scheme.surface }} />

축은 웹부터 늘린다

새 variant 나 size 가 필요하면 웹에서 먼저 엽니다. 여기서 먼저 늘리면 계약이 갈라집니다.

예외는 웹에 짝이 생길 수 없는 표면 하나뿐입니다 — TabBar · AnimatedTabBar · PullToRefresh 셋이 그렇습니다. 하단 탭 크롬과 당겨서 새로고침은 웹에 대응하는 면이 없습니다.

문서의 미리보기는 진짜 RN 코드입니다

이 사이트는 react-native 를 react-native-web 으로 별칭 걸어 native 컴포넌트를 그대로 그립니다. 그래서 그려진다는 것 자체가 그 조합이 실제 앱에서 선다는 증거입니다.

다만 PullToRefresh 와 AnimatedTabBar 는 미리보기가 없습니다 — reanimated 의 워클릿 변환이 babel 플러그인인데, turbopack 은 node_modules 를 babel 대상에서 빼기 때문입니다. 이 사이트가 무는 워클릿은 DS 의 dist 안, 즉 node_modules 에 있습니다 (#119).

On this page