Lynx

Attachment Display Field

외부 소스에서 제공된 미디어를 표시하고 호스트 동작으로 관리하는 컴포넌트입니다.

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

Installation

기본 항목 표시만 필요하면 다음 패키지와 기본 snippet을 설치하세요.

npm install @seed-design/lynx-react @seed-design/lynx-css

Reorderable

항목 순서를 변경해야 하면 native 가로 long-press gesture를 포함한 별도 snippet을 설치하세요.

npx @seed-design/cli@latest add ui:attachment-display-field-reorderable

Lynx AttachmentDisplayField는 미디어 picker나 업로드 API를 직접 호출하지 않습니다. trigger 탭에서 onTriggerTap을 실행하고, 호스트 앱의 media picker가 반환한 AttachmentDisplayEntry[]를 callback의 addEntries에 전달하세요. 문서 예제의 picsum.photos URL은 고정 demo fixture이며, 실제 앱의 native module 이름이나 bridge API를 가정하지 않습니다.

Props

AttachmentDisplayField

Prop

Type

children?React.ReactNode
label?React.ReactNode
labelWeight?"medium" | "bold" | undefined
indicator?React.ReactNode
description?React.ReactNode
errorMessage?React.ReactNode
showRequiredIndicator?boolean | undefined
entries?AttachmentDisplayEntry[] | undefined
defaultEntries?AttachmentDisplayEntry[] | undefined
onEntriesChange?((entries: AttachmentDisplayEntry[]) => void) | undefined
disabled?boolean | undefined
invalid?boolean | undefined
readOnly?boolean | undefined
required?boolean | undefined
maxEntries?number | undefined
onTriggerTap?((helpers: { addEntries: (entries: AttachmentDisplayEntry[]) => void; updateEntryStatus: (id: string, details: AttachmentDisplayStatusDetails) => void; }) => void) | undefined
style?CSSProperties | undefined
className?string | undefined

AttachmentDisplay

Prop

Type

onTriggerTap(helpers: DisplayTriggerHelpers) => void
children?((context: AttachmentDisplayContextValue) => React.ReactNode) | undefined
onRetry?((entry: DisplayEntry, helpers: DisplayRetryHelpers) => void) | undefined

AttachmentDisplayItem

Prop

Type

entryAttachmentDisplayEntry
onRetry?(() => void) | undefined
children?React.ReactNode
style?CSSProperties | undefined
className?string | undefined

Usage

AttachmentDisplayField 안에 AttachmentDisplay를 조합합니다. onTriggerTap은 호스트 미디어 picker를 호출하고 반환된 entries를 addEntries에 전달하는 callback입니다.

<AttachmentDisplayField defaultEntries={[]} maxEntries={10}>
  <AttachmentDisplay
    onTriggerTap={async ({ addEntries }) => {
      const entries = await hostMediaPicker();
      addEntries(entries);
    }}
  />
</AttachmentDisplayField>

hostMediaPicker는 앱이 소유한 adapter입니다. 특정 native module 이름을 snippet이나 문서에서 정하지 않으며, 취소한 경우 []를 반환하도록 구현하세요. Display entry는 URL 기반 모델입니다. id, thumbnailUrl, status를 사용하며 uploading 상태에서는 선택적으로 progress를 전달합니다. AttachmentDisplayFile, Blob을 다루지 않고 파일 유효성 검증도 수행하지 않습니다.

Item 직접 구성하기

AttachmentDisplay의 children은 context render callback입니다. entries의 순서대로 AttachmentDisplayItem을 직접 렌더링할 수 있고, AttachmentDisplayItem에는 native item root props와 dragging variant prop을 전달할 수 있습니다. children을 생략하면 기본 image, uploading progress, retry, remove action 구성이 자동으로 렌더링됩니다.

<AttachmentDisplay onTriggerTap={async ({ addEntries }) => addEntries(await hostMediaPicker())}>
  {({ entries }) => entries.map((entry) => <AttachmentDisplayItem key={entry.id} entry={entry} />)}
</AttachmentDisplay>

Adding Entries

Trigger

기본 AttachmentDisplay는 trigger와 항목 목록을 함께 제공합니다. trigger를 탭하면 onTriggerTap({ addEntries, updateEntryStatus })가 호출됩니다. 피커 결과를 addEntries에 전달하면 maxEntries 상한과 single-mode(maxEntries={1}) 치환이 적용됩니다.

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

Listening to Entry Changes

entriesonEntriesChange로 목록을 controlled 방식으로 관리할 수 있습니다. trigger로 추가하거나 삭제 action을 탭한 결과 모두 onEntriesChange로 전달됩니다. value-changes 예제는 added/removed 값을 누적하여 보여줍니다.

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

Managing Item Status

항목의 status는 pending, uploading, success, error 중 하나입니다. 호스트 앱의 업로드 작업은 updateEntryStatus로 진행률과 최종 상태를 갱신하세요.

  • uploading: ProgressCircle이 표시되며 progress가 있으면 해당 값(0–100)을 표시합니다.
  • error: onRetry가 제공된 경우 재시도 action이 표시됩니다. 재시도 callback에서 같은 id를 uploading으로 되돌린 뒤 업로드를 다시 시작하세요.
  • success: 완료된 thumbnail을 표시합니다.

예제는 uploading(0 → 25 → 60) → success 전이와 error 항목의 retry 전이를 모두 보여줍니다. 이 전이는 demo fixture를 위한 동기 callback이며 실제 앱에서는 호스트 업로드 결과로 갱신하세요.

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

Reordering Entries

React의 dnd-kit 의존성은 Lynx에서 사용하지 않습니다. AttachmentDisplayReorderable은 별도 snippet에서 native 가로 long-press gesture를 사용하며, gesture가 끝나면 reorderEntry(fromIndex, toIndex)를 호출하여 목록 순서를 바꿉니다. disabledreadOnly에서는 정렬 gesture가 차단됩니다.

별도 snippet의 SortableAttachmentDisplayItemindex를 필수로 받습니다. 기본 항목 map도 명시적인 SortableAttachmentDisplayItem을 사용하며, custom children callback을 사용할 때도 각 항목을 해당 컴포넌트로 직접 구성하세요. callback 결과를 Children.toArray로 다시 해석하거나 index로 clone하지 않습니다.

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

Examples

Disabled

disabled는 trigger 추가와 정렬 gesture를 막지만, 기존 항목의 remove action은 허용합니다.

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

Read Only

readOnly는 trigger, remove, 정렬 gesture를 모두 막습니다. 외부에서 entries를 갱신하거나 초기 목록을 hydrate하는 것은 허용됩니다.

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

Controlled

entriesonEntriesChange를 사용하여 외부에서 아이템 목록을 제어할 수 있습니다. 외부 reset은 setEntries([])처럼 앱 state를 갱신하여 수행합니다.

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

Custom Inset

실제 horizontal scroll-view를 감싸는 layout에서 --seed-attachment-input-extend-x CSS 변수를 사용하면 목록을 global gutter 바깥으로 확장할 수 있습니다. 예제는 400px 회색 외곽과 안쪽 TextField/AttachmentDisplay를 포함합니다.

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

Field Integration

label, indicator, description, errorMessage, showRequiredIndicator를 Field 슬롯과 함께 사용할 수 있습니다. 예제는 목록이 비었을 때 invalid와 error footer를 표시합니다.

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

Customizing Items

기본 item 구성이 아닌 경우 SeedAttachmentDisplay.Item compound slots를 사용하여 badge, progress, retry, remove action을 직접 구성할 수 있습니다. 예제의 첫 번째 fixture에는 대표사진 badge가 있습니다.

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

State and accessibility

label, description, errorMessage, indicator, showRequiredIndicator는 Field 슬롯으로 렌더링됩니다. 기본 trigger와 remove action에는 접근성 label이 제공되며, custom action을 구성할 때는 의미를 설명하는 accessibility-label을 지정하세요.

Lynx 미지원 기능

  • 브라우저 drag-and-drop 및 React dnd-kit: native long-press reorder snippet으로 대체하세요.
  • HTML <input type="file">, File, Blob, object URL: 호스트 media picker가 URL 기반 AttachmentDisplayEntry를 반환하도록 연결하세요.
  • HTML form 제출 및 react-hook-form: 앱 state와 submit/controller adapter로 대체하세요.

Last updated on

목차