Skip to content

Pending Review

Pending Review from User Experience (UX)

Radio Card Component

Overview

The PWC Radio Card component provides visually rich single-selection functionality with card-based layouts, multiple variants, and enhanced visual styling options. Built on the InputBase foundation, it offers three distinct variants (default, compact, largeIcon), flexible fill styles, and integrated tag support for complex selection interfaces requiring visual hierarchy and contextual information.

Core Capabilities

  • Multiple Card Variants - Default, compact, and largeIcon layouts optimized for different content types and space requirements
  • Visual Fill Styles - Solid and gradient background options providing enhanced visual feedback and design flexibility
  • Integrated Icon Support - Icon integration with size and color variations for visual identification and improved user experience
  • Tag and Label System - Optional tag overlays with variant support for status indicators and additional context information
  • Interactive Card States - Hover, active, and selected states with smooth transitions for enhanced user feedback
  • Flexible Layout System - Responsive card arrangement with wrapping support for optimal space utilization across screen sizes

When to use Radio Card:

  • Visual selection interfaces requiring rich content presentation with icons, labels, and contextual information
  • Product or service selection where visual differentiation enhances user decision-making and reduces cognitive load
  • Configuration panels needing prominent option presentation with clear visual hierarchy and status indicators
  • Onboarding flows where visual cards guide users through important choices with enhanced engagement and clarity

When not to use Radio Card:

  • Simple text-based selections where standard radio buttons provide adequate functionality without visual overhead
  • Space-constrained interfaces where compact radio buttons offer better density and layout efficiency
  • Forms requiring minimal visual distraction where card layouts might overwhelm primary content

Basic Implementation

import { PwcRadioCard } from "@progress-i360/pwc-react";
import { useMemo, useState } from 'react';

function SubscriptionSelector() {
  const [selectedPlan, setSelectedPlan] = useState('standard');

  const planOptions = useMemo(
    () => [
      {
        value: 'basic',
        label: 'Basic Plan',
        hint: 'Essential features for small teams',
        icon: 'user',
        tagLabel: 'Popular',
        tagVariant: 'success'
      },
      {
        value: 'standard',
        label: 'Standard Plan',
        hint: 'Advanced features for growing teams',
        icon: 'users',
        tagLabel: 'Recommended',
        tagVariant: 'info'
      }
    ],
    []
  );

  return (
    <PwcRadioCard
      name="plan"
      label="Choose Your Plan"
      hint="Select the plan that best fits your needs"
      options={planOptions}
      variant="default"
      fillStyle="solid"
      value={selectedPlan}
      required
      onChange={(event) => setSelectedPlan(event.detail)}
    />
  );
}
import { useEffect, useMemo, useRef, useState } from 'react';
import '@progress-i360/progress-web-components/button';
import '@progress-i360/progress-web-components/form';
import '@progress-i360/progress-web-components/radio-card';

type RadioCardOption = {
  value: string;
  label: string;
  hint?: string;
  icon?: string;
  tagLabel?: string;
  tagVariant?: string;
};

type RadioCardElement = HTMLElement & {
  options?: RadioCardOption[];
  value?: string;
  disabled?: boolean;
  fillStyle?: string;
};

type PwcSubmitDetail = {
  payload: Record<string, unknown>;
  success: () => void;
};

function ProjectSetupWizard() {
  const formRef = useRef<HTMLElement | null>(null);
  const radioCardRef = useRef<RadioCardElement | null>(null);

  const deploymentOptions = useMemo<RadioCardOption[]>(
    () => [
      {
        value: 'cloud',
        label: 'Cloud Native',
        hint: 'Fully managed cloud infrastructure',
        icon: 'cloud',
        tagLabel: 'Recommended',
        tagVariant: 'success'
      },
      {
        value: 'onpremise',
        label: 'On-Premises',
        hint: 'Complete control over infrastructure',
        icon: 'building'
      }
    ],
    []
  );

  const [deployment, setDeployment] = useState('cloud');
  const [isSubmitting, setIsSubmitting] = useState(false);

  useEffect(() => {
    const radioElement = radioCardRef.current;
    if (!radioElement) {
      return;
    }

    radioElement.options = deploymentOptions;
    radioElement.value = deployment;
    radioElement.disabled = isSubmitting;
    radioElement.fillStyle = 'gradient';

    const handleChange = (event: Event) => {
      const detail = (event as CustomEvent<string>).detail;
      setDeployment(detail);
    };

    radioElement.addEventListener('pwc-change', handleChange);
    return () => {
      radioElement.removeEventListener('pwc-change', handleChange);
    };
  }, [deploymentOptions, deployment, isSubmitting]);

  useEffect(() => {
    const formElement = formRef.current;
    if (!formElement) {
      return;
    }

    const handleSubmit = (event: Event) => {
      const submitDetail = (event as CustomEvent<PwcSubmitDetail>).detail;
      if (!submitDetail || isSubmitting) {
        return;
      }

      setIsSubmitting(true);
      setTimeout(() => {
        submitDetail.success();
        setIsSubmitting(false);
      }, 2000);
    };

    formElement.addEventListener('pwc-submit', handleSubmit as EventListener);
    return () => {
      formElement.removeEventListener('pwc-submit', handleSubmit as EventListener);
    };
  }, [isSubmitting]);

  return (
    <pwc-form ref={formRef}>
      <pwc-radio-card
        ref={radioCardRef}
        name="deployment"
        label="Deployment Strategy"
        hint="Choose your preferred deployment method"
        variant="default"
        required
      ></pwc-radio-card>

      <pwc-button
        type="submit"
        variant="primary"
        label={isSubmitting ? 'Creating...' : 'Create Project'}
        disabled={isSubmitting}
        style={{ marginTop: '16px' }}
      ></pwc-button>
    </pwc-form>
  );
}
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import "@progress-i360/progress-web-components/radio-card";

@Component({
  selector: 'radio-card-demo',
  template: `
    <pwc-radio-card 
      label="Select Plan" 
      name="plan"
      [options]="planOptions"
      [value]="selectedPlan"
      variant="default"
      fillStyle="solid"
      hint="Choose the plan that best fits your needs"
      required
      (pwc-change)="selectPlan($event)">
    </pwc-radio-card>

    <pwc-radio-card 
      label="Integration Type" 
      name="integration"
      [options]="integrationOptions"
      [value]="selectedIntegration"
      variant="largeIcon"
      fillStyle="gradient"
      (pwc-change)="selectIntegration($event)">
    </pwc-radio-card>

    <pwc-radio-card 
      label="Support Level" 
      name="support"
      [options]="supportOptions"
      [value]="selectedSupport"
      variant="compact"
      [disabled]="!hasValidPlan"
      (pwc-change)="selectSupport($event)">
    </pwc-radio-card>

    <div class="selection-summary" *ngIf="showSummary">
      <p>Selected: {{ selectedPlan }} plan, {{ selectedIntegration }} integration, {{ selectedSupport }} support</p>
    </div>
  `,
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class RadioCardDemo {
  selectedPlan = '';
  selectedIntegration = 'api';
  selectedSupport = 'standard';

  planOptions = [
    { 
      label: 'Starter', 
      value: 'starter',
      icon: 'play',
      hint: 'Perfect for small teams',
      tagLabel: 'Popular',
      tagVariant: 'success'
    },
    { 
      label: 'Professional', 
      value: 'professional',
      icon: 'briefcase',
      hint: 'Best for growing businesses'
    },
    { 
      label: 'Enterprise', 
      value: 'enterprise',
      icon: 'building',
      hint: 'For large organizations',
      tagLabel: 'Recommended',
      tagVariant: 'info'
    }
  ];

  integrationOptions = [
    { 
      label: 'API Integration', 
      value: 'api',
      icon: 'code',
      hint: 'RESTful API access'
    },
    { 
      label: 'Webhook', 
      value: 'webhook',
      icon: 'link',
      hint: 'Real-time notifications'
    }
  ];

  supportOptions = [
    { 
      label: 'Standard', 
      value: 'standard',
      hint: 'Email support'
    },
    { 
      label: 'Premium', 
      value: 'premium',
      hint: '24/7 phone & email'
    }
  ];

  get hasValidPlan() {
    return this.selectedPlan !== '';
  }

  get showSummary() {
    return this.selectedPlan && this.selectedIntegration && this.selectedSupport;
  }

  selectPlan(event: CustomEvent<string>) {
    this.selectedPlan = event.detail;
  }

  selectIntegration(event: CustomEvent<string>) {
    this.selectedIntegration = event.detail;
  }

  selectSupport(event: CustomEvent<string>) {
    this.selectedSupport = event.detail;
  }
}
import '@progress-i360/progress-web-components/radio-card';

// Create radio card group with visual options
const radioCard = document.createElement('pwc-radio-card');
radioCard.setAttribute('label', 'Subscription Plan');
radioCard.setAttribute('name', 'plan');
radioCard.setAttribute('variant', 'default');
radioCard.fillStyle = 'solid';

// Define card options with icons and hints
const options = [
  { label: 'Basic Plan', value: 'basic', icon: 'package', hint: '$10/month - Essential features' },
  { label: 'Premium Plan', value: 'premium', icon: 'star', hint: '$25/month - All features', tagLabel: 'Popular', tagVariant: 'info' },
  { label: 'Enterprise', value: 'enterprise', icon: 'enterprise', hint: 'Custom pricing - Contact sales' }
];
radioCard.options = options;

// Handle card selection
function handlePlanSelection(selectedPlan) {
  console.log('Selected plan:', selectedPlan);
}

radioCard.addEventListener('pwc-change', (event) => {
  handlePlanSelection(event.detail);
});

document.body.appendChild(radioCard);

Usage Patterns

  • Product and Service Selection - E-commerce product variants, subscription plans, and service tiers requiring visual differentiation and rich content presentation
  • Configuration Wizards - Multi-step setup processes with prominent option presentation and visual hierarchy for complex decision flows
  • Onboarding Experiences - User preference collection and initial setup with engaging visual cards that guide choice selection
  • Dashboard Customization - Layout options, theme selection, and feature toggles requiring immediate visual feedback and clear option comparison

Best Practices

Content Strategy Guidelines

  • Clear Visual Hierarchy - Use appropriate variant types (default for detailed content, compact for efficiency, largeIcon for brand focus) based on content needs
  • Meaningful Icon Selection - Choose icons that clearly represent options and enhance recognition rather than decorative elements that add visual noise
  • Strategic Tag Usage - Reserve tags for important status indicators like "Recommended", "Popular", or "New" rather than redundant labeling
  • Concise Hint Text - Provide helpful context that aids decision-making without overwhelming the visual design or creating cognitive overload

Performance Optimization

  • Efficient Rendering - Use appropriate variant selection to minimize DOM complexity while maintaining visual effectiveness and user experience
  • Icon Loading Strategy - Ensure icons are properly loaded and cached to prevent layout shifts and visual inconsistencies during rendering
  • Card State Management - Optimize hover and selection state transitions for smooth user interactions and professional visual feedback
  • Responsive Layout Planning - Consider card wrapping behavior and responsive design patterns for consistent experience across screen sizes

Integration Architecture

  • Form Context Coordination - Integrate seamlessly with PWC form systems for validation, submission, and error handling workflows
  • Fill Style Selection - Choose solid fill for professional interfaces and gradient fill for more dynamic, engaging experiences based on brand requirements
  • Accessibility Standards - Ensure proper ARIA attributes, keyboard navigation, and screen reader compatibility for inclusive card-based selection interfaces
  • Design Token Usage - Leverage PWC design tokens for consistent styling, spacing, and color usage across radio card implementations

Common Use Cases

Data Table Headers

  • View mode selection with rich visual cards showing table, grid, and chart preview options for data presentation control
  • Filter preset cards with icons and descriptions for complex filtering scenarios requiring visual identification and quick selection
  • Export format selection with detailed cards showing file types, size estimates, and feature compatibility information

Search Result Sections

  • Result type filtering with visual cards representing documents, images, videos, and other content types for focused search experiences
  • Sort method selection with cards explaining different sorting algorithms and their impact on result ordering and relevance
  • Time range filtering with visual period cards showing relative timeframes and data availability for temporal search refinement

Dashboard Widget Headers

  • Widget type selection with preview cards showing chart types, data visualizations, and layout options for dashboard customization
  • Data source cards with connection status, update frequency, and data quality indicators for informed source selection
  • Refresh interval selection with cards showing frequency options, performance impact, and real-time data availability

Troubleshooting

Common Issues

Actions Not Triggering

Symptoms: Radio card selection doesn't update values or change events don't fire when cards are clicked

Solutions:

  • Verify that radio cards share the same name attribute for proper group behavior and mutual exclusion functionality

  • Check that onChange handlers are properly bound and contain valid function references for event processing and state updates

  • Ensure disabled states don't prevent legitimate user interactions or interfere with card selection and visual feedback

Actions Not Visible

Symptoms: Radio cards don't render properly or appear with missing icons, labels, or styling elements

Solutions:

  • Confirm that icon resources are loaded and available in your icon system configuration and library setup

  • Check that card variants render correctly with appropriate layout, spacing, and content organization for the selected variant type

  • Verify that tag components display properly when tagLabel and tagVariant properties are provided with valid values

Layout Issues

Symptoms: Radio cards appear with incorrect sizing, alignment, or spacing in form layouts and responsive designs

Solutions:

  • Use appropriate variant selection (default for flexible width, compact for uniform height, largeIcon for fixed dimensions) based on content requirements

  • Check that container styling accommodates card wrapping behavior and provides adequate spacing for visual clarity and touch targets

  • Ensure responsive design patterns work correctly across different screen sizes and device orientations for consistent user experience

Icon Problems

Symptoms: Icons don't display correctly, appear with wrong sizes, or don't match the expected visual style and branding

Solutions:

  • Verify that icon keys match available icons in your icon library and are properly configured for the selected variant type

  • Check that icon sizes and colors adjust correctly for disabled states and provide appropriate visual feedback for user interactions

  • Ensure brand icons work correctly with largeIcon variant and display with proper proportions and visual quality

Implementation Support

  • Variant Selection Guidance - Best practices for choosing appropriate card variants based on content complexity, space constraints, and user experience goals
  • Accessibility Compliance - WCAG guidelines implementation, keyboard navigation patterns, and screen reader optimization for card-based selection interfaces
  • Visual Design Integration - Fill style selection strategies, icon usage patterns, and tag implementation for cohesive visual design and brand consistency

Resources

Storybook Documentation

For comprehensive API documentation, interactive examples, and testing tools: 📖 View Complete API Documentation in Storybook →


This guide provides high-level implementation guidance. For detailed API specifications and interactive examples, visit our Storybook documentation.