ArcaneJaspr Codex
Documentation
ArcaneCard
Versatile card container with shadow and styling
Live Demo
Card content

ArcaneCard#

A container component styled as a card with background, border, shadow, and optional interactive states.

Basic Usage#

// Single child
ArcaneCard(
  child: ArcaneText('Card content'),
)

// Multiple children (convenience)
ArcaneCard(
  children: [
    ArcaneHeading(text: 'Title'),
    ArcaneText('Description here'),
  ],
)

Properties#

PropertyTypeDefaultDescription
child Component? null Card content (single)
children List<Component>? null Card content (multiple)
padding PaddingPreset? md Internal padding
shadow Shadow? sm Shadow depth
borderRadius Radius? lg Corner radius
isClickable bool false Enable hover effects
onTap / onClick VoidCallback? null Click handler (aliases)
styles ArcaneStyleData? null Additional styling

Note: Provide either child or children. The onClick parameter is an alias for onTap.

Shadow Levels#

// No shadow
ArcaneCard(
  shadow: Shadow.none,
  child: ArcaneText('Flat card'),
)

// Small shadow (default)
ArcaneCard(
  shadow: Shadow.sm,
  child: ArcaneText('Subtle shadow'),
)

// Medium shadow
ArcaneCard(
  shadow: Shadow.md,
  child: ArcaneText('Medium shadow'),
)

// Large shadow
ArcaneCard(
  shadow: Shadow.lg,
  child: ArcaneText('Prominent shadow'),
)

// Extra large shadow
ArcaneCard(
  shadow: Shadow.xl,
  child: ArcaneText('Elevated card'),
)

Clickable Card#

ArcaneCard(
  isClickable: true,
  onPressed: () => navigateToDetail(),
  child: ArcaneColumn(
    gap: Gap.sm,
    children: [
      ArcaneHeading(text: 'Click Me'),
      ArcaneText('Hover to see effect'),
    ],
  ),
)

Examples#

Feature Card#

ArcaneCard(
  padding: PaddingPreset.lg,
  child: ArcaneColumn(
    crossAxisAlignment: AlignItems.start,
    gap: Gap.md,
    children: [
      ArcaneDiv(
        styles: const ArcaneStyleData(
          widthCustom: '48px',
          heightCustom: '48px',
          borderRadius: Radius.lg,
          background: Background.accent,
          display: Display.flex,
          justifyContent: JustifyContent.center,
          alignItems: AlignItems.center,
        ),
        children: [span([text('⚡')])],
      ),
      ArcaneHeading(text: 'Fast Performance'),
      ArcaneText('Optimized for speed with minimal bundle size.'),
    ],
  ),
)

Product Card#

ArcaneCard(
  padding: PaddingPreset.none,
  isClickable: true,
  onPressed: () => viewProduct(product),
  child: ArcaneColumn(
    children: [
      ArcaneDiv(
        styles: const ArcaneStyleData(
          heightCustom: '200px',
          borderRadius: Radius.lgTop,
          overflow: Overflow.hidden,
        ),
        children: [
          ArcaneImage(src: product.image, fit: ImageFit.cover),
        ],
      ),
      ArcanePadding(
        padding: PaddingPreset.md,
        child: ArcaneColumn(
          crossAxisAlignment: AlignItems.start,
          gap: Gap.xs,
          children: [
            ArcaneText(product.name),
            ArcaneRow(
              mainAxisAlignment: JustifyContent.spaceBetween,
              children: [
                ArcaneText('\$${product.price}'),
                ArcaneRatingStars(rating: product.rating),
              ],
            ),
          ],
        ),
      ),
    ],
  ),
)

Stats Card#

ArcaneCard(
  child: ArcaneColumn(
    gap: Gap.sm,
    children: [
      ArcaneRow(
        mainAxisAlignment: JustifyContent.spaceBetween,
        children: [
          ArcaneText('Total Revenue'),
          ArcaneIconButton(
            icon: span([text('⋮')]),
            size: IconButtonSize.small,
            onPressed: () {},
          ),
        ],
      ),
      ArcaneHeading(text: '\$45,231.89'),
      ArcaneRow(
        gap: Gap.xs,
        children: [
          ArcaneBadge(label: '+20.1%', variant: BadgeVariant.success),
          ArcaneText('from last month'),
        ],
      ),
    ],
  ),
)

User Card#

ArcaneCard(
  child: ArcaneRow(
    gap: Gap.md,
    children: [
      ArcaneAvatar(
        imageUrl: user.avatar,
        size: AvatarSize.large,
      ),
      ArcaneExpanded(
        child: ArcaneColumn(
          crossAxisAlignment: AlignItems.start,
          gap: Gap.xs,
          children: [
            ArcaneHeading(text: user.name),
            ArcaneText(user.email),
            ArcaneFlow(
              gap: Gap.xs,
              children: [
                for (var role in user.roles)
                  ArcaneBadge(label: role),
              ],
            ),
          ],
        ),
      ),
      ArcaneIconButton(
        icon: span([text('✏')]),
        onPressed: () => editUser(user),
      ),
    ],
  ),
)

Pricing Card#

ArcaneCard(
  padding: PaddingPreset.xl,
  styles: const ArcaneStyleData(
    border: Border.accent,
  ),
  child: ArcaneColumn(
    crossAxisAlignment: AlignItems.center,
    gap: Gap.lg,
    children: [
      ArcaneBadge(label: 'Popular'),
      ArcaneHeading(text: 'Pro'),
      ArcaneRow(
        crossAxisAlignment: AlignItems.end,
        gap: Gap.xs,
        children: [
          ArcaneHeadline(text: '\$29'),
          ArcaneText('/month'),
        ],
      ),
      ArcaneDivider(),
      ArcaneColumn(
        gap: Gap.sm,
        children: [
          ArcaneRow(gap: Gap.sm, children: [span([text('✓')]), ArcaneText('Unlimited projects')]),
          ArcaneRow(gap: Gap.sm, children: [span([text('✓')]), ArcaneText('Priority support')]),
          ArcaneRow(gap: Gap.sm, children: [span([text('✓')]), ArcaneText('Custom domains')]),
        ],
      ),
      ArcaneButton.primary(
        label: 'Get Started',
        isFullWidth: true,
        onPressed: () {},
      ),
    ],
  ),
)

Card Grid#

ArcaneDiv(
  styles: const ArcaneStyleData(
    display: Display.grid,
    gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
    gap: Gap.lg,
  ),
  children: [
    for (var item in items)
      ArcaneCard(
        isClickable: true,
        onPressed: () => viewItem(item),
        child: ArcaneColumn(
          crossAxisAlignment: AlignItems.start,
          gap: Gap.sm,
          children: [
            ArcaneHeading(text: item.title),
            ArcaneText(item.description),
          ],
        ),
      ),
  ],
)