MOOC Utils

Utils like auto assignment solver extension and course notice announcment notification for MOOC courses

UI components

Introduction#

UI library overview for the website: shared primitives, notice-reminders feature components, assignment-solver download UI, and landing sections.

Project structure#

The UI library is organized under website/components/ui with reusable base components and specialized components grouped by feature area:

  • Shared UI primitives: button, input, textarea, card, dialog, alert-dialog, badge
  • Feature-specific components: notice reminders (inbox, subscription manager, user profile), assignment solver (extension download), landing page components (features, product showcase)

Core components#

This section documents the shared UI primitives that form the foundation of the component library.

  • Button

  • Purpose: Primary interactive element with variant and size variants.

  • Props:

  • variant: default, outline, secondary, ghost, destructive, link

  • size: default, xs, sm, lg, icon, icon-xs, icon-sm, icon-lg

  • className: optional tailwind classes

  • Customization: Uses CVA for variant and size tokens; integrates with data-slot attributes for consistent styling.

  • Accessibility: Inherits focus-visible ring and aria-invalid states for form integration.

  • Input

  • Purpose: Text input primitive with consistent focus states and invalid feedback.

  • Props: type, className, plus standard input attributes.

  • Customization: Tailwind classes applied via cn; integrates aria-invalid for form validation.

  • Textarea

  • Purpose: Multi-line text input with consistent focus and invalid states.

  • Props: className, plus standard textarea attributes.

  • Card

  • Purpose: Container with header, title, description, action, content, and footer slots.

  • Props:

  • size: default, sm

  • className

  • Slots: card-header, card-title, card-description, card-action, card-content, card-footer.

  • Dialog

  • Purpose: Modal overlay with trigger, portal, close, overlay, content, header, footer, title, and description.

  • Props:

  • DialogContent: showCloseButton flag

  • DialogFooter: showCloseButton flag

  • size variants for alert-style dialogs

  • Composition: Composes Base UI Dialog with internal Button and XIcon for close.

  • AlertDialog

  • Purpose: Confirmation dialog with action and cancel bindings to Button.

  • Props:

  • size: default, sm

  • AlertDialogAction: Button props

  • AlertDialogCancel: variant, size defaults to outline, default size

  • Badge

  • Purpose: Label or indicator with variant variants.

  • Props:

  • variant: default, secondary, destructive, outline, ghost, link

  • render: optional renderer for advanced composition

  • className

Styling approach

  • Tailwind classes are combined using cn from lib/utils.
  • CVA defines variant and size tokens for Buttons and Badges.
  • Focus-visible rings and aria-invalid states ensure accessible feedback.
  • Responsive breakpoints and spacing tokens are used consistently across components.

Architecture overview#

The UI library follows a composition-first pattern:

  • Primitive components (Button, Input, Card) encapsulate base styling and behavior.
  • Feature components (NotificationInbox, UserProfile, SubscriptionManager) compose primitives to implement domain logic.
  • Landing components (Features, ProductShowcase) build product demos from primitives and links.

Detailed component analysis#

Button component#

  • Variants: default, outline, secondary, ghost, destructive, link
  • Sizes: default, xs, sm, lg, icon, icon-xs, icon-sm, icon-lg
  • Behavior: Uses Base UI Button, adds data-slot, focus-visible ring, aria-invalid support, and pointer-events disabled when disabled.

Input and textarea components#

  • Input: Base input with focus-visible ring, aria-invalid support, and consistent padding.
  • Textarea: Multi-line variant with similar focus and invalid states.

Card component#

  • Slots: header, title, description, action, content, footer
  • Size variants: default, sm
  • Composition: Uses data-size and data-slot attributes for consistent rendering.

Dialog and alertdialog components#

  • Dialog: Root, Trigger, Portal, Close, Overlay, Content, Header, Footer, Title, Description.
  • AlertDialog: Root, Trigger, Portal, Overlay, Content (with size), Header, Footer, Media, Title, Description, Action, Cancel.

Badge component#

  • Variants: default, secondary, destructive, outline, ghost, link
  • Composition: Uses Base UI renderer with data-slot and variant tokens.

Notice reminders components#

NotificationInbox#

  • Fetches notifications via React Query, displays unread count, and allows marking as read.
  • Composes Card, Button, Input, and Badge for a connected inbox experience.

UserProfile#

  • Manages user profile editing, channel listing, and account deletion with confirmations.
  • Uses Input, Label, Card, Badge, and Button for form and profile display.

SubscriptionManager#

  • Lists subscriptions, expands to show course details and recent announcements, and supports deletion.
  • Uses Card, Button, Badge, and Link for navigation.

Assignment solver components#

ExtensionDownload#

  • Promotes browser extension installation via store links and manual steps.
  • Uses Card, Button, and Badge for structured presentation.

Landing page components#

Features#

  • Displays feature highlights for assignment solver and placeholders for notice reminders.
  • Uses Button variants and layout tokens for visual emphasis.

ProductShowcase#

  • Highlights two tools with feature lists and CTAs; one is active, the other marked as coming soon.
  • Uses Button variants and gradient accents.

Dependency analysis#

Component dependencies and coupling:

  • Feature components depend on primitives (Button, Input, Card, Badge) for consistent styling and behavior.
  • Notice reminders components integrate with React Query for data fetching and mutations.
  • Landing components depend on Button variants and layout utilities for visual consistency.

Performance considerations#

  • Prefer variant and size tokens over ad-hoc classes to reduce CSS bloat.
  • Use data-slot attributes to minimize reflows during dynamic updates.
  • Lazy-load heavy feature components (e.g., subscription announcements preview) to defer computation.
  • Keep mutation caches minimal; invalidate only affected query keys to avoid unnecessary refetches.
  • Use CSS containment and transform-based animations sparingly to maintain smooth interactions.

Accessibility compliance#

  • Focus management: All interactive primitives expose focus-visible rings and outline-none where appropriate.
  • ARIA integration: Inputs support aria-invalid for validation feedback; dialogs include sr-only labels for close buttons.
  • Semantic markup: Components render semantic HTML elements (button, input, textarea) with proper roles.
  • Keyboard navigation: Triggers and controls are keyboard accessible via Base UI primitives.
  • Screen reader support: Icons include sr-only text where needed; dialogs provide titles and descriptions.

Responsive design implementation#

  • Breakpoints: Components use responsive utilities (e.g., sm:, md:) to adapt layouts across screen sizes.
  • Typography: Heading and text utilities scale appropriately with container widths.
  • Spacing: Consistent padding and margin tokens ensure readable layouts on mobile and desktop.
  • Grids and flex: Cards and landing sections use grid and flex utilities to stack or align content responsively.

Troubleshooting guide#

Common issues and resolutions:

  • Button disabled state not applying: Verify disabled prop is passed and pointer-events-none is included in variant classes.
  • Dialog close button not visible: Ensure showCloseButton is true and Button variant/size are set correctly.
  • Input focus ring not visible: Confirm focus-visible ring classes are present and not overridden by custom styles.
  • Badge variant mismatch: Check variant prop matches available options and data-slot is set.
  • NotificationInbox not updating after read: Ensure query key invalidation occurs on mutation success.
  • SubscriptionManager expansion not toggling: Verify expandedSub state and toggle handler logic.

Conclusion#

Primitives first, feature components second. Landing and inbox code are the reference compositions.