Lynx
Segmented Control
여러 옵션 중 하나를 선택하여 관련 콘텐츠를 즉시 필터링하거나 전환할 때 사용하는 컴포넌트입니다.
사용 가능 버전@seed-design/[email protected], @seed-design/[email protected]
Lynx 예제를 불러오는 중입니다.
import "./styles";
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control";
export default function Example() {
return (
<SegmentedControl defaultValue="Hot" accessibility-label="Sort by">
<SegmentedControlItem value="Hot">Hot</SegmentedControlItem>
<SegmentedControlItem value="New">New</SegmentedControlItem>
</SegmentedControl>
);
}Installation
npx @seed-design/cli add ui:segmented-controlpnpm dlx @seed-design/cli add ui:segmented-controlyarn dlx @seed-design/cli add ui:segmented-controlbun x @seed-design/cli add ui:segmented-control의존성 설치
npm install @seed-design/lynx-reactyarn add @seed-design/lynx-reactpnpm add @seed-design/lynx-reactbun add @seed-design/lynx-react아래 코드를 복사 후 붙여넣고 사용하세요
/**
* @file ui:segmented-control
* @requires @seed-design/lynx-react@^1.0.0
* @requires @seed-design/lynx-css@^1.0.0
**/
import * as React from "@lynx-js/react";
import {
NotificationBadge,
NotificationBadgePositioner,
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 Omit<SeedSegmentedControl.ItemProps, "notification"> {
notification?: boolean;
}
/**
* @see https://seed-design.io/lynx/components/segmented-control#segmentedcontrolitem
*/
export const SegmentedControlItem = React.forwardRef<unknown, SegmentedControlItemProps>(
({ children, notification, ...otherProps }, ref) => {
return (
<SeedSegmentedControl.Item
ref={ref}
{...otherProps}
notification={
notification ? (
<NotificationBadgePositioner size="small" attach="text">
<NotificationBadge />
</NotificationBadgePositioner>
) : undefined
}
>
{children}
</SeedSegmentedControl.Item>
);
},
);
SegmentedControlItem.displayName = "SegmentedControlItem";
/**
* 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.
*/
Props
SegmentedControl
value와 defaultValue 중 적어도 하나를 제공해야 선택된 항목과 Indicator를 표시할 수 있습니다.
Prop
Type
onValueChange?((value: string) => void) | undefinedSegmentedControlItem
Prop
Type
notification?boolean | undefinedchildrenstring | numbervaluestringdisabled?boolean | undefinedUsage
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>
);
}Examples
Disabled
SegmentedControl의 disabled는 전체 항목을 비활성화합니다. 각 SegmentedControlItem도 따로 비활성화할 수 있습니다.
Lynx 예제를 불러오는 중입니다.
import "./styles";
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control";
export default function Example() {
return (
<view className="segmented-control-example">
<SegmentedControl defaultValue="Hot" disabled accessibility-label="Sort by">
<SegmentedControlItem value="Hot">Hot</SegmentedControlItem>
<SegmentedControlItem value="New">New</SegmentedControlItem>
</SegmentedControl>
<SegmentedControl defaultValue="Marinara" accessibility-label="Pasta">
<SegmentedControlItem value="Marinara">Marinara</SegmentedControlItem>
<SegmentedControlItem value="Pesto" disabled>
Pesto
</SegmentedControlItem>
<SegmentedControlItem value="Carbonara">Carbonara</SegmentedControlItem>
</SegmentedControl>
</view>
);
}Notification
Lynx 예제를 불러오는 중입니다.
import "./styles";
import { useState } from "@lynx-js/react";
import { ActionButton } from "@seed-design/lynx-react";
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control";
export default function Example() {
const [sortBy, setSortBy] = useState("monthly");
const [hasSeenAnnual, setHasSeenAnnual] = useState(false);
function handleValueChange(value: string) {
"background only";
setSortBy(value);
if (value === "annual") setHasSeenAnnual(true);
}
function handleResetNotification() {
"background only";
setHasSeenAnnual(false);
}
return (
<view className="segmented-control-example">
<SegmentedControl
accessibility-label="Billing Method"
value={sortBy}
onValueChange={handleValueChange}
>
<SegmentedControlItem value="monthly">Monthly</SegmentedControlItem>
<SegmentedControlItem value="annual" notification={!hasSeenAnnual}>
Annual
</SegmentedControlItem>
<SegmentedControlItem value="enterprise">Enterprise Custom</SegmentedControlItem>
</SegmentedControl>
<ActionButton
size="xsmall"
variant="neutralSolid"
disabled={!hasSeenAnnual}
bindtap={handleResetNotification}
>
Reset Notification
</ActionButton>
</view>
);
}Long Label
Lynx 예제를 불러오는 중입니다.
import "./styles";
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control";
export default function Example() {
return (
<SegmentedControl defaultValue="price" accessibility-label="정렬 기준">
<SegmentedControlItem value="price">가격 높은 순</SegmentedControlItem>
<SegmentedControlItem value="discount">할인율 높은 순</SegmentedControlItem>
<SegmentedControlItem value="popular">인기 많은 순</SegmentedControlItem>
</SegmentedControl>
);
}Fixed Width
SegmentedControl의 style이나 className으로 너비를 지정할 수 있습니다.
Lynx 예제를 불러오는 중입니다.
import "./styles";
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control";
export default function Example() {
return (
<view className="segmented-control-example">
<SegmentedControl
className="segmented-control-example__fixed-wide"
defaultValue="new"
accessibility-label="Sort by"
>
<SegmentedControlItem value="new">New</SegmentedControlItem>
<SegmentedControlItem value="hot">Hot</SegmentedControlItem>
</SegmentedControl>
<SegmentedControl
className="segmented-control-example__fixed-narrow"
defaultValue="oneway"
accessibility-label="Trip Type"
>
<SegmentedControlItem value="oneway">One Way Trip</SegmentedControlItem>
<SegmentedControlItem notification value="round">
Round Trip
</SegmentedControlItem>
<SegmentedControlItem notification value="multi">
Multi-City Journey
</SegmentedControlItem>
</SegmentedControl>
</view>
);
}Listening to Value Changes
onValueChange로 선택 값 변경을 감지할 수 있습니다. Controlled 모드에서는 value와 함께 사용합니다.
Lynx 예제를 불러오는 중입니다.
import "./styles";
import { useState } from "@lynx-js/react";
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control";
export default function Example() {
const [count, setCount] = useState(0);
const [lastValue, setLastValue] = useState<string | null>(null);
function handleValueChange(nextValue: string) {
"background only";
setCount((previous) => previous + 1);
setLastValue(nextValue);
}
return (
<view className="segmented-control-example">
<SegmentedControl
defaultValue="hot"
onValueChange={handleValueChange}
accessibility-label="Sort by"
>
<SegmentedControlItem value="hot">Hot</SegmentedControlItem>
<SegmentedControlItem value="new">New</SegmentedControlItem>
</SegmentedControl>
<text className="segmented-control-example__status">
onValueChange called: {count} times, last value: {lastValue ?? "-"}
</text>
</view>
);
}웹 버전과의 차이
- 선택 이벤트는 input change 대신
bindtap과onValueChange로 받습니다. - 접근성은 ARIA 대신 Lynx의
accessibility-*속성을 사용합니다.
Lynx 미지원 기능
- HTML form 제출을 위한
ItemHiddenInput,name,form,inputProps - 키보드 focus와 focus-visible 상호작용
SegmentedControlItem의invalid상태. 오류 문구는 컴포넌트 가까이에 표시하고accessibility-label에도 포함하세요.
Last updated on