Skip to content

feat: image card clean#700

Merged
nastyastavitskaya merged 11 commits intotest/untitledui-ant-pocfrom
feat/image-card-clean
Dec 17, 2025
Merged

feat: image card clean#700
nastyastavitskaya merged 11 commits intotest/untitledui-ant-pocfrom
feat/image-card-clean

Conversation

@AustinFash
Copy link
Contributor

@AustinFash AustinFash commented Dec 16, 2025

Summary

This PR introduces a new ImageCard component to the Aquarium design system. The ImageCard is a selectable card component that displays an image with optional metadata and interactive states.

Features

  • Selectable state: Click-toggleable selection with visual feedback (beetroot border outline)
  • Selection indicator: Beetroot rounded square with white checkmark icon in top-left corner when selected
  • Optional tag: Displays a colored tag in the bottom-right corner (only visible when selected)
  • Loading state: Shows a spinner overlay when loading
  • Title and description: Displays text metadata below the image using Typography.Text
  • Controlled component: Uses selected prop and onChange callback for parent state management
  • Design system integration: Uses Aquarium design system constants (BorderRadius, Padding, ColorBgBase)
  • Built on Card component: Leverages the existing Card component with cover prop

Component API

interface IImageCardProps {
  src: string                           // Image source URL
  alt?: string                          // Alt text for image
  selected?: boolean                    // Selection state
  onChange?: (selected: boolean) => void // Selection change callback
  tag?: React.ReactNode | string        // Optional tag content
  tagColor?: string                     // Tag color variant
  loading?: boolean                     // Loading state
  size?: number | string                // Card dimensions
  title: string                         // Card title
  description: string                   // Card description
  className?: string                    // Additional CSS classes
  style?: React.CSSProperties           // Inline styles
  onClick?: (e: React.MouseEvent) => void // Click handler
  'data-testid'?: string                // Test identifier
}

Files Added

- src/components/data-display/ImageCard/ImageCard.tsx - Component implementation
- src/components/data-display/ImageCard/ImageCard.stories.tsx - Storybook stories with 8 examples
- Updated src/components/index.ts - Added component export

Testing Plan

- Was this tested locally? Yes
- Tested in Storybook with multiple stories:
  - Primary - Basic card with title/description
  - Selected - Card in selected state with checkmark
  - WithTag - Card with tag badge
  - Loading - Card with loading spinner
  - SelectedWithTag - Combined selected state with tag
  - WithTitle - Card with title only
  - WithTitleAndDescription - Card with both title and description
  - ControlledSelection - Interactive toggle demo
  - MultipleCards - Grid of 6 selectable cards demonstrating multi-select behavior
- Verified proper styling with design system constants
- Tested click interactions and state management
- Verified tag only displays when card is selected

Reference Issue (For mParticle employees only. Ignore if you are an outside contributor)

- Closes https://go.mparticle.com/work/REPLACEME

@AustinFash AustinFash changed the base branch from main to test/untitledui-ant-poc December 16, 2025 20:18
@github-actions
Copy link

github-actions bot commented Dec 16, 2025

PR Preview Action v1.6.3
Preview removed because the pull request was closed.
2025-12-17 04:47 UTC

import { BorderRadiusSm, ColorBgBase, PaddingSm, PaddingXs } from 'src/styles/style'
import { Flex, Typography } from 'antd'

const ColorBeetroot = '#A8203E'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be colorPrimary, or #C20075

import { Spin } from 'src/components/feedback/Spin/Spin'
import { CheckOutlined } from '@ant-design/icons'
import { BorderRadiusSm, ColorBgBase, PaddingSm, PaddingXs } from 'src/styles/style'
import { Flex, Typography } from 'antd'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import from src/components, not from antd

Comment on lines +88 to +107
<div
style={{
position: 'absolute',
top: PaddingSm,
left: PaddingSm,
padding: 2,
borderRadius: BorderRadiusSm,
backgroundColor: ColorBeetroot,
}}>
<div
style={{
width: 12,
height: 12,
padding: 2,
borderRadius: BorderRadiusSm,
backgroundColor: ColorBeetroot,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty sure that can be just one div (or Flex) but ok for poc

@AustinFash AustinFash force-pushed the feat/image-card-clean branch from 8aa27b7 to d5b6e19 Compare December 16, 2025 21:15
AustinFash and others added 6 commits December 16, 2025 16:17
- Update color from #A8203E to #C20075 (colorPrimary)
- Import Flex and Typography from src/components instead of antd
- Apply consistent color to description text

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Keep Primary (basic example)
- Keep ControlledSelection (interactive single card)
- Keep MultipleCards (multi-select grid)
- Remove redundant stories: Selected, WithTag, Loading, SelectedWithTag, WithTitle, WithTitleAndDescription

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fix clickable area to only image/card (not title/description)
- Add padding between image and title using Flex gap
- Increase description font size from 10px to 11px
- Add dot badge to tag (6px circle to the left of text)
- Fix ESLint error: add return type to toggleSelection function

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add pointerEvents: 'none' to title/description Flex to disable clicks
- Constrain title/description width to match card size
- Add flexShrink: 0 to clickable card div
- Add width: 'fit-content' to outer Flex container

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove onClick from outer div
- Add absolute positioned clickable overlay with inset: 0 covering card
- Set overlay zIndex to 1
- Set loading/checkmark/tag zIndex to 2 (above overlay)
- Constrain clickable area to exactly the card dimensions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@nastyastavitskaya nastyastavitskaya merged commit 2591e5d into test/untitledui-ant-poc Dec 17, 2025
8 of 9 checks passed
@nastyastavitskaya nastyastavitskaya deleted the feat/image-card-clean branch December 17, 2025 04:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants