Box
Box 컴포넌트는 Lynx에서 가장 기초적인 레이아웃 표면을 구성하는 컴포넌트입니다.
레이아웃은 사용 중인 zero-runtime 스타일링 라이브러리로 구성하는 것을 권장해요. 이유와 대체 예제는 Styling 가이드에서 확인하세요.
Installation
Usage
Box는 Lynx 네이티브 <view>를 렌더링합니다. bg, p, borderRadius 같은 스타일 prop은 SEED 토큰을 직접 object style 값으로 변환해 적용합니다.
Props
Prop
Type
bg?(string & {}) | ScopedColorBg | ScopedColorPalette | ScopedColorBanner | undefinedbackground?(string & {}) | ScopedColorBg | ScopedColorPalette | ScopedColorBanner | undefinedcolor?(string & {}) | ScopedColorPalette | ScopedColorFg | undefinedborderColor?(string & {}) | ScopedColorPalette | ScopedColorStroke | undefinedborderWidth?0 | (string & {}) | 1 | undefinedborderTopWidth?0 | (string & {}) | 1 | undefinedborderRightWidth?0 | (string & {}) | 1 | undefinedborderBottomWidth?0 | (string & {}) | 1 | undefinedborderLeftWidth?0 | (string & {}) | 1 | undefinedborderRadius?0 | (string & {}) | "r0_5" | "r1" | "r1_5" | "r2" | "r2_5" | "r3" | "r3_5" | "r4" | "r5" | "r6" | "full" | undefinedborderTopLeftRadius?0 | (string & {}) | "r0_5" | "r1" | "r1_5" | "r2" | "r2_5" | "r3" | "r3_5" | "r4" | "r5" | "r6" | "full" | undefinedborderTopRightRadius?0 | (string & {}) | "r0_5" | "r1" | "r1_5" | "r2" | "r2_5" | "r3" | "r3_5" | "r4" | "r5" | "r6" | "full" | undefinedborderBottomRightRadius?0 | (string & {}) | "r0_5" | "r1" | "r1_5" | "r2" | "r2_5" | "r3" | "r3_5" | "r4" | "r5" | "r6" | "full" | undefinedborderBottomLeftRadius?0 | (string & {}) | "r0_5" | "r1" | "r1_5" | "r2" | "r2_5" | "r3" | "r3_5" | "r4" | "r5" | "r6" | "full" | undefinedwidth?Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full" | undefinedminWidth?Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full" | undefinedmaxWidth?Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full" | undefinedheight?Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full" | undefinedminHeight?Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full" | undefinedmaxHeight?Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | "full" | undefinedtop?0 | (string & {}) | undefinedleft?0 | (string & {}) | undefinedright?0 | (string & {}) | undefinedbottom?0 | (string & {}) | undefinedpadding?0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedp?0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpaddingX?0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpx?0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpaddingY?0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpy?0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpaddingTop?0 | "safeArea" | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpt?0 | "safeArea" | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpaddingRight?0 | "safeArea" | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpr?0 | "safeArea" | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpaddingBottom?0 | "safeArea" | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpb?0 | "safeArea" | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpaddingLeft?0 | "safeArea" | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedpl?0 | "safeArea" | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefineddisplay?(string & {}) | "flex" | "none" | undefinedposition?(string & {}) | "relative" | "absolute" | "fixed" | undefinedoverflowX?"hidden" | (string & {}) | "visible" | undefinedoverflowY?"hidden" | (string & {}) | "visible" | undefinedzIndex?Property.ZIndex | undefinedflexGrow?boolean | Property.FlexGrow | undefinedflexShrink?boolean | Property.FlexShrink | undefinedflexDirection?(string & {}) | "row" | "column" | "rowReverse" | "columnReverse" | undefinedflexWrap?boolean | "nowrap" | "wrap" | undefinedjustifyContent?(string & {}) | "flexStart" | "flexEnd" | "center" | "spaceBetween" | "spaceAround" | undefinedjustifySelf?Property.JustifySelf | undefinedalignItems?(string & {}) | "flexStart" | "flexEnd" | "center" | "stretch" | undefinedalignContent?(string & {}) | "flexStart" | "flexEnd" | "center" | "stretch" | undefinedalignSelf?(string & {}) | "flexStart" | "flexEnd" | "center" | "stretch" | undefinedgap?0 | Dimension | "spacingX.betweenChips" | "spacingX.globalGutter" | "spacingY.componentDefault" | "spacingY.navToTitle" | "spacingY.screenBottom" | "spacingY.betweenText" | (string & {}) | undefinedbleed?BleedValue | undefinedbleedX?BleedValue | undefinedbleedY?BleedValue | undefinedbleedTop?BleedValue | undefinedbleedRight?BleedValue | undefinedbleedBottom?BleedValue | undefinedbleedLeft?BleedValue | undefinedmargin?MarginValue | undefinedm?MarginValue | undefinedmarginX?MarginValue | undefinedmx?MarginValue | undefinedmarginY?MarginValue | undefinedmy?MarginValue | undefinedmarginTop?MarginValue | undefinedmt?MarginValue | undefinedmarginRight?MarginValue | undefinedmr?MarginValue | undefinedmarginBottom?MarginValue | undefinedmb?MarginValue | undefinedmarginLeft?MarginValue | undefinedml?MarginValue | undefinedStyle Props
현재 Box에서 여는 스타일 prop은 Lynx에서 안정적으로 검증한 범위로 제한합니다.
| 분류 | Props |
|---|---|
| 색상 | bg, background, color, borderColor |
| 테두리 | borderWidth, borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth, borderRadius와 corner radius props |
| 크기 | width, minWidth, maxWidth, height, minHeight, maxHeight |
| 패딩 | p, px, py, pt, pr, pb, pl과 longhand padding props |
| 마진 | m, mx, my, mt, mr, mb, ml과 longhand margin props |
| Bleed | bleed, bleedX, bleedY, bleedTop, bleedRight, bleedBottom, bleedLeft |
| Flex | display, flexDirection, flexWrap, flexGrow, flexShrink, alignItems, alignContent, alignSelf, justifyContent, justifySelf, gap |
| 배치 | position, top, right, bottom, left, zIndex, overflowX, overflowY |
명시적인 style prop은 마지막에 merge되므로, 필요한 경우 계산된 스타일을 덮어쓸 수 있습니다.
style prop은 inline style로 적용되므로 같은 속성을 지정한 className utility보다 우선합니다. className으로 지정할 속성은 style prop으로 함께 지정하지 마세요. 예를 들어 px="x3" className="pl-x7"의 왼쪽 패딩은 x3입니다.
pt, pr, pb, pl에 "safeArea"를 지정하면 host가 넘긴 safeAreaInsetTop, safeAreaInsetRight, safeAreaInsetBottom, safeAreaInsetLeft global props를 padding으로 적용합니다. 값이 없거나 음수이면 env(safe-area-inset-*)을 사용합니다. top과 bottom은 값이 0이어도 env()를 사용합니다.
Margin과 Bleed
margin prop은 SEED 토큰, 길이, "auto"를 받습니다. 방향별 prop이 축 prop(mx, my)보다, 축 prop이 m보다 우선합니다.
bleed prop은 음수 margin을 적용해, 요소를 부모의 padding 영역까지 넓힙니다. 값은 "16px" 같은 px 길이, 0, "safeArea"를 받습니다. "safeArea"를 지정하면 같은 방향의 safe area inset만큼 넓힙니다.
margin 계열과 bleed 계열은 모두 margin-*으로 변환되므로 함께 지정할 수 없습니다. 이 제약 때문에 BoxProps, VStackProps, HStackProps는 union 타입입니다. 이 타입을 확장할 때는 interface ... extends 대신 type을 사용하세요.
Native Props
Box는 style prop 외에 루트 <view>의 native 속성(className, id, accessibility-*, bind*·main-thread:* 이벤트, data-* 등)과 ref를 받아 그대로 전달합니다. style prop과 같은 이름의 native 속성은 style prop으로 해석합니다.
웹 버전과의 차이
Lynx Box는 React Box와 다음과 같은 차이가 있습니다.
as,asChild를 지원하지 않습니다. Lynx 컴파일러 제약 때문에 네이티브<view>를 컴포넌트 파일 안에서 직접 렌더링합니다.bgGradient,boxShadow,unstable_transform처럼 아직 Lynx에서 검증하지 않은 StyleProps는 열지 않습니다.- bleed prop은 SEED 토큰(
"x4","spacingX.globalGutter"등)과"asPadding"을 받지 않습니다. 토큰은 CSS 변수로 변환되는데, Lynx는 inline style의calc()안에 있는 CSS 변수를 적용하지 않기 때문입니다. 토큰과 같은 값의 px 길이를 지정하세요. - 반응형 값(
{ base, md }),hideFrom,_active,gridColumn,gridRow를 지원하지 않습니다. 스타일은 CSS 변수가 아니라 object style로 바로 적용됩니다. - 이벤트는 웹의
onClick대신 Lynx의bindtap계열 prop을 사용합니다. 접근성은aria-*대신accessibility-*prop을 사용합니다.
Last updated on