Lynx

AppBar

화면 상단에서 현재 화면의 제목과 탐색 액션을 보여주는 내비게이션 바 컴포넌트입니다.

Engine ≥ 3.6
사용 가능 버전@seed-design/lynx-react@0.2.0, @seed-design/lynx-css@0.2.0
Lynx 예제를 불러오는 중입니다.

Installation

npx @seed-design/cli add ui:app-bar

Props

AppBar

Prop

Type

style?CSSProperties | undefined
children?ReactNode
className?string | undefined

AppBarLeft

Prop

Type

bindlayoutchange?EventHandler<LayoutChangeDetailEvent<Target>> | undefined
style?CSSProperties | undefined
children?ReactNode
className?string | undefined

AppBarMain

Prop

Type

style?CSSProperties | undefined
children?ReactNode
className?string | undefined

AppBarRight

Prop

Type

bindlayoutchange?EventHandler<LayoutChangeDetailEvent<Target>> | undefined
style?CSSProperties | undefined
children?ReactNode
className?string | undefined

AppBarSlot

Prop

Type

style?CSSProperties | undefined
children?ReactNode
className?string | undefined

AppBarIconButton

Prop

Type

icon?ReactElement<LynxIconElementProps, string | JSXElementConstructor<any>> | undefined
accessibility-label?string | undefined
accessibility-element?boolean | undefined
accessibility-traits?"text" | "image" | "button" | "link" | "header" | "search" | "selected" | "playable" | "keyboard" | "summary" | "disabled" | "updating" | "adjustable" | "tabbar" | "none" | undefined
className?string | undefined
children?ReactNode
bindtap?EventHandler<BaseTouchEvent<Target>> | undefined
main-thread:bindtap?EventHandler<BaseTouchEvent<Element>> | undefined

AppBarBackButton

Prop

Type

icon?ReactElement<LynxIconElementProps, string | JSXElementConstructor<any>> | undefined
className?string | undefined
bindtap?EventHandler<BaseTouchEvent<Target>> | undefined
main-thread:bindtap?EventHandler<BaseTouchEvent<Element>> | undefined
children?ReactNode
accessibility-label?string | undefined
accessibility-element?boolean | undefined
accessibility-traits?"text" | "image" | "button" | "link" | "header" | "search" | "selected" | "playable" | "keyboard" | "summary" | "disabled" | "updating" | "adjustable" | "tabbar" | "none" | undefined

AppBarCloseButton

Prop

Type

icon?ReactElement<LynxIconElementProps, string | JSXElementConstructor<any>> | undefined
children?ReactNode
className?string | undefined
bindtap?EventHandler<BaseTouchEvent<Target>> | undefined
main-thread:bindtap?EventHandler<BaseTouchEvent<Element>> | undefined
accessibility-label?string | undefined
accessibility-element?boolean | undefined
accessibility-traits?"disabled" | "text" | "image" | "button" | "link" | "header" | "search" | "selected" | "playable" | "keyboard" | "summary" | "updating" | "adjustable" | "tabbar" | "none" | undefined

Usage

설치한 snippet은 Root와 주요 슬롯을 AppBar, AppBarLeft, AppBarMain, AppBarRight로 export 합니다. AppBarBackButton, AppBarCloseButton은 기본 아이콘만 제공하며, 실제 이동 로직은 bindtap으로 직접 전달합니다.

import {
  AppBar,
  AppBarBackButton,
  AppBarLeft,
  AppBarMain,
  AppBarRight,
} from "@/components/ui/app-bar";

export function Header({ goBack }: { goBack: () => void }) {
  return (
    <AppBar>
      <AppBarLeft>
        <AppBarBackButton bindtap={goBack} />
      </AppBarLeft>
      <AppBarMain title="동네생활" />
      <AppBarRight />
    </AppBar>
  );
}

Title / Subtitle

AppBarMaintitle, subtitle을 전달하면 내부에서 AppBar.Title, AppBar.Subtitle을 조립합니다. subtitle이 있으면 layout="withSubtitle"가 자동으로 적용됩니다.

Lynx 예제를 불러오는 중입니다.

직접 슬롯을 조립하고 싶다면 AppBarMain의 children으로 compound 컴포넌트를 전달합니다.

import { AppBar, AppBarMain } from "@/components/ui/app-bar";
import { AppBar as SeedAppBar } from "@seed-design/lynx-react";

export function Header() {
  return (
    <AppBar>
      <AppBarMain layout="withSubtitle">
        <SeedAppBar.Title>제목</SeedAppBar.Title>
        <SeedAppBar.Subtitle>부제목</SeedAppBar.Subtitle>
      </AppBarMain>
    </AppBar>
  );
}

Left / Right Action

왼쪽과 오른쪽에는 icon button 또는 custom slot을 배치할 수 있습니다. Cupertino theme에서는 좌우 슬롯 폭을 읽어 가운데 title이 치우치지 않도록 padding을 보정합니다.

AppBarLeftAppBarRight 모두 첫 번째 자식이 아이콘 버튼이면 왼쪽, 마지막 자식이 아이콘 버튼이면 오른쪽 여백을 보정합니다. 버튼 하나만 있으면 양쪽을 모두 보정합니다. 44px 터치 영역과 24px 아이콘 사이의 여백만큼 음수 margin을 적용해, 터치 영역을 유지하면서 화면 가장자리와 제목 쪽 간격을 React의 슬롯 보정 규칙에 맞춥니다.

슬롯이 가장자리 위치를 Context로 전달하므로 AppBarBackButton / AppBarCloseButton과 직접 만든 AppBarIconButton에 자동으로 적용됩니다. Fragment와 조건부 자식을 지원하며, AppBarSlot이나 native 레이아웃 박스 내부에는 자동 보정을 전달하지 않습니다. edge="leading" | "trailing" | "both"를 명시하면 자동 보정 방향을 덮어쓸 수 있습니다.

Lynx 예제를 불러오는 중입니다.

AppBarBackButton / AppBarCloseButton 외에 다른 아이콘을 쓰고 싶다면 AppBarIconButtonicon prop에 Lynx 아이콘을 전달해 직접 구성합니다. 가장자리에 놓이면 위와 동일하게 자동으로 정렬됩니다.

import IconBellLine from "@karrotmarket/lynx-monochrome-icon/IconBellLine";
import {
  AppBar,
  AppBarBackButton,
  AppBarIconButton,
  AppBarLeft,
  AppBarMain,
  AppBarRight,
} from "@/components/ui/app-bar";

export function Header({ goBack }: { goBack: () => void }) {
  return (
    <AppBar>
      <AppBarLeft>
        <AppBarBackButton bindtap={goBack} />
      </AppBarLeft>
      <AppBarMain title="동네생활" />
      <AppBarRight>
        <AppBarIconButton accessibility-label="알림" icon={<IconBellLine />} />
      </AppBarRight>
    </AppBar>
  );
}

Multiple / Conditional Actions

슬롯에 여러 버튼을 넣으면 첫 번째와 마지막 버튼에만 가장자리 여백 보정이 적용됩니다. 가운데 버튼의 터치 영역은 그대로 유지됩니다. 조건부 렌더링으로 버튼이 하나만 남으면 양쪽 여백 보정으로 자동 변경됩니다.

아래 예제에서 검색·닫기를 숨기거나 다시 표시해도 제목은 가운데에 유지됩니다. 각 아이콘 버튼을 눌러 마지막 액션도 확인할 수 있습니다.

Lynx 예제를 불러오는 중입니다.

Custom Slot / Explicit Edge

직접 만든 레이아웃 박스나 AppBarSlot 안의 버튼에는 가장자리 보정을 자동 적용하지 않습니다. 내부 배치를 직접 관리할 때만 edge로 방향을 지정하세요. 일반적인 AppBarLeft / AppBarRight의 버튼에는 지정할 필요가 없습니다.

<AppBarRight>
  <AppBarSlot>
    <AppBarCloseButton edge="trailing" bindtap={close} />
  </AppBarSlot>
</AppBarRight>

leading은 왼쪽, trailing은 오른쪽, both는 양쪽 여백을 보정합니다. 명시한 값은 자동 보정보다 우선하며, 버튼의 터치 영역 크기는 바뀌지 않습니다.

Tone

기본값인 tone="layer"는 레이어 배경을 표시합니다. tone="transparent"는 배경을 투명하게 하고 제목과 아이콘에 밝은 색상을 적용하므로 사진이나 어두운 배경 위에서 사용하세요. 배경과 스크롤에 따른 tone 전환은 호출부에서 관리합니다.

Lynx 예제를 불러오는 중입니다.

Accessibility

Lynx에서는 HTML ARIA 속성 대신 Lynx native 접근성 속성을 사용합니다. AppBarIconButton은 기본적으로 accessibility-element={true}accessibility-traits="button"을 적용하며, 아이콘만으로 의미를 알 수 없는 버튼에는 accessibility-label을 전달해야 합니다.

import IconBellLine from "@karrotmarket/lynx-monochrome-icon/IconBellLine";

<AppBarIconButton accessibility-label="알림" icon={<IconBellLine />} />

AppBarBackButton, AppBarCloseButton은 각각 "뒤로", "닫기" 라벨을 기본값으로 제공합니다.

Theme

theme"cupertino" 또는 "android"를 사용할 수 있습니다. 명시하지 않으면 AppBar 내부에서 SystemInfo.platform을 읽어 Android에서는 "android", 그 외 플랫폼이나 값이 없을 때는 "cupertino"를 사용합니다.

<AppBar>
  <AppBarMain title="자동 theme" />
</AppBar>

수동으로 지정한 theme은 platform 기본값보다 우선합니다.

Lynx 예제를 불러오는 중입니다.

Web Version Differences

Lynx AppBar는 React AppBar와 같은 역할과 variant 이름을 제공하지만, 플랫폼별 Recipe와 화면 전환 책임은 다릅니다.

  • 이벤트 핸들링: onClick 대신 Lynx 이벤트인 bindtap을 전달합니다.
  • 렌더링 요소: HTML 요소 대신 네이티브 <view> / <text> 요소를 렌더링합니다.
  • 접근성 라벨링: aria-label 대신 Lynx native accessibility-label을 사용합니다.
  • platform theme: 웹처럼 data-* selector에 의존하지 않고, recipe variant className으로 "cupertino" / "android" 디자인을 적용합니다.
  • navigation 책임: AppBarBackButtonAppBarCloseButton은 이동을 자동 실행하지 않습니다. Stackflow pop() 같은 동작은 호출부에서 연결합니다.
  • 가장자리 아이콘 정렬: 웹은 iconButton:first-child / :last-child selector로 bleed를 보정하지만, Lynx는 해당 가상 클래스를 지원하지 않아 AppBarLeft / AppBarRight가 가장자리 위치를 Context로 전달하고 아이콘 버튼의 Recipe class로 보정합니다. 다중 버튼·custom slot에서도 가장자리 아이콘 버튼에만 정확히 적용됩니다.

Unsupported Lynx Features

현재 Lynx AppBar는 순수 UI 컴포넌트로 제공되며 다음 기능은 포함하지 않습니다.

기능웹 대응대체 방법
Stackflow activity 연동useActivity, useActions 기반 back/close 처리bindtap에서 앱의 navigation 함수를 직접 호출
swipe-back 전환 애니메이션Stackflow screen transition화면 전환을 소유한 navigation 계층에서 처리
data-* selector 기반 상태 스타일웹 recipe selectortheme, tone variant className 사용
HTML button 속성type, DOM click eventLynx <view> 기반 AppBarIconButtonbindtap 사용
HTML ARIA 라벨aria-labelLynx native accessibility-label 사용

Last updated on

목차