Segmented Control
여러 옵션 중 하나를 선택하여 관련 콘텐츠를 즉시 필터링하거나 전환할 때 사용하는 컴포넌트입니다.
@seed-design/lynx-react@0.6.0, @seed-design/lynx-css@0.10.0
import "./styles";
import { root } from "@lynx-js/react";
import { useSeedClassName } from "@seed-design/lynx-react";
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control";
function Root() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<page className={seedClassName}>
<view className="segmented-control-example">
<SegmentedControl
className="segmented-control-example__control"
defaultValue="hot"
accessibility-label="정렬 기준"
>
<SegmentedControlItem value="hot">인기순</SegmentedControlItem>
<SegmentedControlItem value="new">최신순</SegmentedControlItem>
</SegmentedControl>
</view>
</page>
);
}
root.render(<Root />);
npx @seed-design/cli add ui:segmented-control
pnpm dlx @seed-design/cli add ui:segmented-control
yarn dlx @seed-design/cli add ui:segmented-control
bun x @seed-design/cli add ui:segmented-control
의존성 설치
npm install @seed-design/lynx-react
yarn add @seed-design/lynx-react
pnpm add @seed-design/lynx-react
bun add @seed-design/lynx-react
아래 코드를 복사 후 붙여넣고 사용하세요
/**
* @file ui:segmented-control
* @requires @seed-design/lynx-react@>=0.6.0 <1.0.0
* @requires @seed-design/lynx-css@>=0.10.0 <1.0.0
**/
import * as React from "@lynx-js/react";
import { SegmentedControl as SeedSegmentedControl } from "@seed-design/lynx-react";
export interface SegmentedControlProps extends SeedSegmentedControl.RootProps {}
/**
* @see https://seed-design.io/lynx/components/segmented-control
*/
export const SegmentedControl = React.forwardRef<unknown, SegmentedControlProps>(
({ children, ...otherProps }, ref) => {
return (
<SeedSegmentedControl.Root ref={ref} {...otherProps}>
{children}
<SeedSegmentedControl.Indicator />
</SeedSegmentedControl.Root>
);
},
);
SegmentedControl.displayName = "SegmentedControl";
export interface SegmentedControlItemProps extends SeedSegmentedControl.ItemProps {}
/**
* @see https://seed-design.io/lynx/components/segmented-control#segmentedcontrolitem
*/
export const SegmentedControlItem = SeedSegmentedControl.Item;
/**
* This file is a snippet from SEED Design, helping you get started quickly with @seed-design/* packages.
* You can extend this snippet however you want.
*/
value?string | undefined
defaultValue?string | undefined
disabled?boolean | undefined
onValueChange?((value: string) => void) | undefined
style?CSSProperties | undefined
children?React.ReactNode
className?string | undefined
childrenstring | number
valuestring
disabled?boolean | undefined
className?string | undefined
style?CSSProperties | undefined
bindtap?EventHandler<BaseTouchEvent<Target>> | undefined
main-thread:bindtap?EventHandler<BaseTouchEvent<Element>> | undefined
import {
SegmentedControl,
SegmentedControlItem,
} from "@/components/ui/segmented-control";
export function App() {
return (
<SegmentedControl defaultValue="hot" accessibility-label="정렬 기준">
<SegmentedControlItem value="hot">인기순</SegmentedControlItem>
<SegmentedControlItem value="new">최신순</SegmentedControlItem>
</SegmentedControl>
);
}
Registry의 SegmentedControl은 선택 Indicator를 자동으로 추가합니다.
SegmentedControl의 disabled는 전체 항목을 비활성화합니다. 각 SegmentedControlItem도 따로 비활성화할 수 있습니다.
import "./styles";
import { root } from "@lynx-js/react";
import { useSeedClassName } from "@seed-design/lynx-react";
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control";
function Root() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<page className={seedClassName}>
<view className="segmented-control-example">
<SegmentedControl defaultValue="hot" disabled accessibility-label="전체 비활성화">
<SegmentedControlItem value="hot">인기순</SegmentedControlItem>
<SegmentedControlItem value="new">최신순</SegmentedControlItem>
</SegmentedControl>
<SegmentedControl defaultValue="hot" accessibility-label="일부 비활성화">
<SegmentedControlItem value="hot">인기순</SegmentedControlItem>
<SegmentedControlItem value="new" disabled>
최신순
</SegmentedControlItem>
</SegmentedControl>
</view>
</page>
);
}
root.render(<Root />);
import "./styles";
import { root } from "@lynx-js/react";
import { useSeedClassName } from "@seed-design/lynx-react";
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control";
function Root() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<page className={seedClassName}>
<view className="segmented-control-example">
<SegmentedControl defaultValue="price" accessibility-label="정렬 기준">
<SegmentedControlItem value="price">가격 높은 순</SegmentedControlItem>
<SegmentedControlItem value="discount">할인율 높은 순</SegmentedControlItem>
<SegmentedControlItem value="popular">인기 많은 순</SegmentedControlItem>
</SegmentedControl>
</view>
</page>
);
}
root.render(<Root />);
SegmentedControl의 style이나 className으로 너비를 지정할 수 있습니다.
import "./styles";
import { root } from "@lynx-js/react";
import { useSeedClassName } from "@seed-design/lynx-react";
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control";
function Root() {
const seedClassName = useSeedClassName({ colorMode: "system" });
return (
<page className={seedClassName}>
<view className="segmented-control-example">
<SegmentedControl
className="segmented-control-example__fixed"
defaultValue="oneway"
accessibility-label="Trip Type"
>
<SegmentedControlItem value="oneway">One Way Trip</SegmentedControlItem>
<SegmentedControlItem value="round">Round Trip</SegmentedControlItem>
<SegmentedControlItem value="multi">Multi-City Journey</SegmentedControlItem>
</SegmentedControl>
</view>
</page>
);
}
root.render(<Root />);
onValueChange로 선택 값 변경을 감지할 수 있습니다. Controlled 모드에서는 value와 함께 사용합니다.
import "./styles";
import { root, useState } from "@lynx-js/react";
import { useSeedClassName } from "@seed-design/lynx-react";
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control";
function Root() {
const seedClassName = useSeedClassName({ colorMode: "system" });
const [value, setValue] = useState("hot");
function handleValueChange(nextValue: string) {
"background only";
setValue(nextValue);
}
return (
<page className={seedClassName}>
<view className="segmented-control-example">
<SegmentedControl
value={value}
onValueChange={handleValueChange}
accessibility-label="정렬 기준"
>
<SegmentedControlItem value="hot">인기순</SegmentedControlItem>
<SegmentedControlItem value="new">최신순</SegmentedControlItem>
</SegmentedControl>
<text className="segmented-control-example__status">선택값: {value}</text>
</view>
</page>
);
}
root.render(<Root />);
| 항목 | React Web | Lynx |
|---|
| 렌더링 요소 | HTML label, input | 네이티브 view, text |
| 선택 이벤트 | input change | bindtap, 공개 상태 이벤트는 onValueChange |
| 접근성 | ARIA radiogroup, radio | Lynx accessibility-* 속성 |
| Indicator | CSS grid와 custom property | Grid layout과 custom property |
- HTML form 제출을 위한
ItemHiddenInput, name, form, inputProps
- 키보드 focus와 focus-visible 상호작용
- Registry
SegmentedControlItem의 notification prop
Lynx에는 대응하는 Notification Badge 컴포넌트가 없어 notification prop을 제공하지 않습니다. 항목 레이블은 문자열이나 숫자로 전달합니다.