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#
| Property | Type | Default | Description |
|---|---|---|---|
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),
],
),
),
],
)
Related Components#
- ArcaneGlassCard - Glassmorphism card
- ArcaneBox - Simple bordered container
- ArcaneFeatureCard - Feature showcase card