Skip to content

Run 2: Foundation Components

Run 2 implements Wave 1 of the image upload component set — five leaf-level components that have no dependencies on other new components from this project. All work is committed to the shared feature branch in a single worktree, and the five tasks are independent of each other within this run.

Repository: ux-prototype (Arda-cards/ux-prototype) Base branch: jmpicnic/item-image-upload-components (branched from main) Parallelism: Tasks 2.1 through 2.5 may run concurrently across 2-3 agents, each in its own worktree and task branch, merging back to the base branch at the end of the wave.


Before any work in this run begins, both of the following must be satisfied:

  1. Run 1 exit gate passed — execute bash run-1-infrastructure/validate-exit.sh and the script must exit 0.
  2. Base branch up-to-datejmpicnic/item-image-upload-components contains all Run 1 commits.

Each task below produces five files. The naming pattern is consistent across all components: <ComponentName>.tsx, <ComponentName>.test.tsx, <ComponentName>.stories.tsx, <ComponentName>.mdx, and index.ts.

Task 2.1 — CopyrightAcknowledgment (atom)

Section titled “Task 2.1 — CopyrightAcknowledgment (atom)”

Location: src/components/canary/atoms/copyright-acknowledgment/

ArtifactDescription
CopyrightAcknowledgment.tsxCheckbox + label that surfaces the copyright agreement required before image submission.
CopyrightAcknowledgment.test.tsx7 unit tests covering checked/unchecked state, disabled state, label text, onChange propagation, and accessibility attributes.
CopyrightAcknowledgment.stories.tsx5 stories: Unchecked (default), Checked, Disabled, WithLongLabel, Controlled.
CopyrightAcknowledgment.mdxProse overview, Canvas embeds for each story, props table.
index.tsBarrel export of CopyrightAcknowledgment and its props type.

Dependencies (from Run 1): ShadCN checkbox primitive.

Acceptance criteria: All 7 unit tests pass; all 5 stories render without console errors in Storybook.


Location: src/components/canary/molecules/image-display/

ArtifactDescription
ImageDisplay.tsxRenders an item image in four visual states: loaded, loading (skeleton), error (Badge overlay), and no-image (placeholder).
ImageDisplay.test.tsx9 unit tests covering each of the four states, alt text, error message text, skeleton presence, and aspect-ratio container dimensions.
ImageDisplay.stories.tsx8 stories: Loaded, Loading, Error, NoImage, SmallSize, LargeSize, WithCaption, InteractiveSizeVariants.
ImageDisplay.mdxProse overview, Canvas embeds, props table including state enum values.
index.tsBarrel export of ImageDisplay and its props type.

Dependencies (from Run 1): ShadCN skeleton primitive; Badge component with the error-overlay variant; getInitials utility from src/types/canary/utilities/.

Acceptance criteria: All 9 unit tests pass; all 4 display states (loaded, loading, error, no-image) render correctly in Storybook stories.


Location: src/components/canary/molecules/image-drop-zone/

ArtifactDescription
ImageDropZone.tsxAccepts image files via drag-and-drop, URL text input, and clipboard paste. Validates MIME type and file size against ImageFieldConfig.
ImageDropZone.test.tsx10 unit tests covering drag-enter/drag-leave visual state, file-drop acceptance, URL input submission, paste event handling, rejection of invalid MIME types, and rejection of oversized files.
ImageDropZone.stories.tsx6 stories: Default, DragActive, WithUrlInput, WithPasteHint, Disabled, CompactVariant.
ImageDropZone.mdxProse overview, Canvas embeds, props table including ImageFieldConfig shape.
index.tsBarrel export of ImageDropZone and its props type.

Dependencies (from Run 1): react-dropzone library (installed in Run 1); ImageFieldConfig type from src/types/canary/utilities/.

Acceptance criteria: All 10 unit tests pass; drag-drop, URL, and paste input paths are exercised and visually correct in stories.


Task 2.4 — ImagePreviewEditor (molecule)

Section titled “Task 2.4 — ImagePreviewEditor (molecule)”

Location: src/components/canary/molecules/image-preview-editor/

ArtifactDescription
ImagePreviewEditor.tsxInline crop/zoom/rotate editor wrapping react-easy-crop. Exposes crop area, zoom level, and rotation as controlled props.
ImagePreviewEditor.test.tsx6 unit tests covering initial render, zoom slider value propagation, rotation button increments, crop area change callback, aspect-ratio locking, and reset-to-defaults behavior.
ImagePreviewEditor.stories.tsx7 stories: Default, Zoomed, Rotated, SquareCrop, FreeformCrop, Disabled, WithResetButton.
ImagePreviewEditor.mdxProse overview, Canvas embeds, props table including crop-area geometry type.
index.tsBarrel export of ImagePreviewEditor and its props type.

Dependencies (from Run 1): react-easy-crop library (installed in Run 1); ShadCN slider primitive.

Acceptance criteria: All 6 unit tests pass; crop, zoom, and rotate controls respond correctly in Storybook stories.


Location: src/components/canary/atoms/avatar/ (existing component)

ArtifactDescription
Avatar.tsx (modified)Import getInitials from src/types/canary/utilities/ instead of the inline implementation; keep external API identical.
Avatar.test.tsx (augmented)4 new unit tests added: getInitials delegation verified, initials derived correctly for single-word names, initials capped at two characters, and existing snapshot test still passes.
Avatar.stories.tsx (augmented)5 new stories added: SingleWordName, LongNameTwoInitials, NumericFallback, WithImageAndInitialsFallback, SizesShowcase.
Avatar.mdx (updated)Add section documenting the getInitials integration and updated props table if any prop signatures changed.
index.tsUnchanged — re-export is already present.

Dependencies (from Run 1): getInitials utility from src/types/canary/utilities/.

Acceptance criteria: The 4 new unit tests pass; all pre-existing Avatar tests remain green (no regressions); the 5 new stories render without errors.


#TaskLocationUnit TestsStoriesDepends On
2.1CopyrightAcknowledgment atomatoms/copyright-acknowledgment/75Run 1: checkbox primitive
2.2ImageDisplay moleculemolecules/image-display/98Run 1: skeleton, Badge error-overlay, getInitials
2.3ImageDropZone moleculemolecules/image-drop-zone/106Run 1: react-dropzone, ImageFieldConfig
2.4ImagePreviewEditor moleculemolecules/image-preview-editor/67Run 1: react-easy-crop, slider primitive
2.5Avatar modificationatoms/avatar/4 new5 newRun 1: getInitials
Total3631

All five tasks in Run 2 are fully independent of each other. They share only the Run 1 outputs and may be executed concurrently.

Run 1 outputs
(checkbox, skeleton, Badge error-overlay,
getInitials, react-dropzone, ImageFieldConfig,
react-easy-crop, slider)
|
+---> Task 2.1 CopyrightAcknowledgment
|
+---> Task 2.2 ImageDisplay
|
+---> Task 2.3 ImageDropZone
|
+---> Task 2.4 ImagePreviewEditor
|
+---> Task 2.5 Avatar (modification)

Recommended agent grouping when running with parallel agents:

  • Agent A: Tasks 2.1 and 2.5 (smallest by test count; natural pairing of atom-level work).
  • Agent B: Task 2.2 (ImageDisplay — 9 tests, 8 stories; medium complexity).
  • Agent C: Tasks 2.3 and 2.4 (both depend on external library integration; natural pairing).

All of the following must be satisfied before handing off to Run 3:

  1. npm run lint exits 0 in the worktree (zero errors, zero warnings).
  2. npm run build-storybook exits 0 (Storybook bundle produced without errors).
  3. npm run test exits 0 (all Vitest suites pass).
  4. 36 new unit tests pass: 7 (2.1) + 9 (2.2) + 10 (2.3) + 6 (2.4) + 4 (2.5).
  5. 31 new or updated stories render: 5 (2.1) + 8 (2.2) + 6 (2.3) + 7 (2.4)
    • 5 (2.5).
  6. All 5 components export correctly from their respective index.ts files: CopyrightAcknowledgment, ImageDisplay, ImageDropZone, ImagePreviewEditor, and the updated Avatar.
  7. No pre-existing test regressions — the full test suite count for Avatar increases by exactly 4; no previously passing tests are red.

A validate-exit.sh script in this directory encodes checks 1-3 as an automated gate. Checks 4-7 are verified by inspecting test output.


ArtifactProduced ByConsumed By Task
ShadCN checkbox primitiveRun 12.1 CopyrightAcknowledgment
ShadCN skeleton primitiveRun 12.2 ImageDisplay
Badge component with error-overlay variantRun 12.2 ImageDisplay
getInitials utility (src/types/canary/utilities/)Run 12.2 ImageDisplay, 2.5 Avatar
react-dropzone npm packageRun 12.3 ImageDropZone
ImageFieldConfig type (src/types/canary/utilities/)Run 12.3 ImageDropZone
react-easy-crop npm packageRun 12.4 ImagePreviewEditor
ShadCN slider primitiveRun 12.4 ImagePreviewEditor
ArtifactConsumed By
ImageDisplay moleculeRun 3 (ImageHoverPreview, ImageComparisonLayout, ImageFormField), Run 4 (ImageCellDisplay)
ImageDropZone moleculeRun 4 (ImageUploadDialog)
ImagePreviewEditor moleculeRun 4 (ImageUploadDialog via ImageComparisonLayout)
CopyrightAcknowledgment atomRun 4 (ImageUploadDialog)
Avatar modificationNo downstream consumers in this project — modification is a housekeeping improvement only.


Copyright: (c) Arda Systems 2025-2026, All rights reserved