Segmented Control 여러 옵션 중 하나를 선택하여 관련 콘텐츠를 즉시 필터링하거나 전환할 때 사용하는 컴포넌트입니다.
@seed-design/lynx-react@0.6.0, @seed-design/lynx-css@0.10.0
import "./styles" ;
import { useSeedClassName } from "@seed-design/lynx-react" ;
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
return (
< view className = { `${ seedClassName } docs-lynx-segmented-control-root` }>
< view className = "segmented-control-example" >
< SegmentedControl
className = "segmented-control-example__control"
defaultValue = "Hot"
accessibility-label = "Sort by"
>
< SegmentedControlItem value = "Hot" >Hot</ SegmentedControlItem >
< SegmentedControlItem value = "New" >New</ SegmentedControlItem >
</ SegmentedControl >
</ view >
</ view >
);
}
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 {
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.
*/
value?string | undefined
defaultValue?string | undefined
disabled?boolean | undefined
onValueChange?(( value : string ) => void ) | undefined
style?CSSProperties | undefined
children?React.ReactNode
className?string | undefined
notification?boolean | undefined
bindtap?EventHandler < BaseTouchEvent < Target >> | undefined
main-thread:bindtap?EventHandler < BaseTouchEvent < Element >> | undefined
className?string | undefined
disabled?boolean | undefined
childrenstring | number
style?CSSProperties | undefined
valuestring
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 { useSeedClassName } from "@seed-design/lynx-react" ;
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
return (
< view className = { `${ seedClassName } docs-lynx-segmented-control-root` }>
< 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 = "Alfredo" disabled >
Alfredo
</ SegmentedControlItem >
< SegmentedControlItem value = "Pesto" disabled >
Pesto
</ SegmentedControlItem >
< SegmentedControlItem value = "Carbonara" >Carbonara</ SegmentedControlItem >
< SegmentedControlItem value = "Bolognese" >Bolognese</ SegmentedControlItem >
</ SegmentedControl >
</ view >
</ view >
);
}
import "./styles" ;
import { useState } from "@lynx-js/react" ;
import { ActionButton, useSeedClassName } from "@seed-design/lynx-react" ;
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
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 = { `${ seedClassName } docs-lynx-segmented-control-root` }>
< 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 >
</ view >
);
}
import "./styles" ;
import { useSeedClassName } from "@seed-design/lynx-react" ;
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
return (
< view className = { `${ seedClassName } docs-lynx-segmented-control-root` }>
< view className = "segmented-control-example" >
< SegmentedControl defaultValue = "price" accessibility-label = "정렬 기준" >
< SegmentedControlItem value = "price" >가격 높은 순</ SegmentedControlItem >
< SegmentedControlItem value = "discount" >할인율 높은 순</ SegmentedControlItem >
< SegmentedControlItem value = "popular" >인기 많은 순</ SegmentedControlItem >
</ SegmentedControl >
</ view >
</ view >
);
}
SegmentedControl의 style이나 className으로 너비를 지정할 수 있습니다.
import "./styles" ;
import { useSeedClassName } from "@seed-design/lynx-react" ;
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
return (
< view className = { `${ seedClassName } docs-lynx-segmented-control-root` }>
< 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 >
</ view >
);
}
onValueChange로 선택 값 변경을 감지할 수 있습니다. Controlled 모드에서는 value와 함께 사용합니다.
import "./styles" ;
import { useState } from "@lynx-js/react" ;
import { useSeedClassName } from "@seed-design/lynx-react" ;
import { SegmentedControl, SegmentedControlItem } from "@/components/ui/segmented-control" ;
export default function Example () {
const seedClassName = useSeedClassName ({ colorMode: "system" });
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 = { `${ seedClassName } docs-lynx-segmented-control-root` }>
< 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 >
</ view >
);
}
항목 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 상호작용
SegmentedControlItem의 invalid 상태
Lynx Registry와 package는 invalid 상태를 제공하지 않습니다. 이 차이는 의도된 미지원입니다. 오류 상태가 필요하면 앱에서 SegmentedControl 가까이에 오류 문구를 표시하고, accessibility-label에도 오류 내용을 포함하세요.