Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

Summary

Propose a new BorderBeam component in antd 6.4.0.

BorderBeam is a decorative wrapper component that renders a moving beam along the border of a container. It is intended for high-attention areas such as login panels, recommendation cards, AI modules, and highlighted CTA blocks.

Its role is different from Wave:

  • Wave is interaction feedback.
  • BorderBeam is a persistent surface effect.

This capability is exposed as an explicit compositional component:

<BorderBeam>
  <Card />
</BorderBeam>

instead of a global switch or a demo-only pattern.

Motivation

In recent years, “Border Beam” has become a recognizable UI pattern across multiple component ecosystems including React, Vue, and Svelte. It is commonly used for:

  • Login panels, invite cards, pricing cards, upgrade prompts
  • AI assistants, automation workflows, recommendation modules
  • Panels that need stronger “active”, “running”, or “recommended” perception

There are already multiple community implementations with the same or highly similar concept, such as:

  • Magic UI
  • UI Thing
  • Inspira UI
  • Olova UI
  • Svelte Magic UI
  • NGXUI

This indicates that:

  1. The pattern is already well established.
  2. Developers expect it to be a reusable component instead of a one-off CSS demo.

At the same time, many community implementations are still demo-oriented rather than design-system-oriented:

  • They often depend on Tailwind or a specific motion runtime
  • They usually lack token integration, dark theme support, semantic DOM, and reduced-motion handling
  • Their API boundaries are often loose and easy to overgrow

Within antd, this pattern fits better as a composable decorative component than as a site demo or a private prop on a single component.

Goals

  • Provide a clear, reusable, explicit border-beam component
  • Integrate with antd design tokens by default
  • Support common container scenarios such as Card, login panels, and custom blocks
  • Keep the API sufficient but bounded
  • Support semantic classNames / styles
  • Provide a reasonable reduced-motion fallback
  • Keep the implementation aligned with antd and rc-component infrastructure without introducing extra runtime dependencies

Why Component Instead of Card Prop

BorderBeam should be a standalone component rather than a Card prop like:

<Card borderBeam />

because:

  • It is not a Card-only requirement
  • The visual emphasis is stronger than a normal appearance prop
  • The same effect should be usable with Flex, custom panels, login forms, and other wrappers
  • A wrapper component gives a more stable composition model and clearer extension boundary

API

Common props such as className, rootClassName, and style follow the antd common props contract.

SemanticDOM includes:

  • root
  • beam
Property Description Type Default
borderWidth Width of the beam ring number 1
children Wrapped content ReactNode -
classNames Semantic class names for root and beam, supports object or function form Record<SemanticDOM, string> | (info: { props }) => Record<SemanticDOM, string> -
color Shortcut for using a single beam color string -
colorFrom Beam start color string #1677ff
colorTo Beam end color string #4096ff
delay Animation delay in seconds number 0
disabled Hide the beam effect boolean false
duration Animation duration in seconds number 6
offset Initial beam offset in percentage number 0
pathRadius Beam track radius. Does not change the wrapped content radius React.CSSProperties['borderRadius'] -
paused Pause the animation boolean false
reverse Reverse the beam direction boolean false
size Beam size in px number 60
styles Semantic inline styles for root and beam, supports object or function form Record<SemanticDOM, CSSProperties> | (info: { props }) => Record<SemanticDOM, CSSProperties> -

Usage Examples

Basic

import React from 'react';
import { BorderBeam, Card } from 'antd';

export default () => (
  <BorderBeam>
    <Card title="Workspace" variant="borderless">
      Review task status, deployment health, and recent automation activity in one panel.
    </Card>
  </BorderBeam>
);

Custom Colors

import React from 'react';
import { BorderBeam, Card } from 'antd';

export default () => (
  <BorderBeam colorFrom="#1677ff" colorTo="#36cfc9" duration={5} size={72}>
    <Card title="AI Assistant" variant="borderless">
      Let agents summarize information, review code, and handle repetitive work.
    </Card>
  </BorderBeam>
);

Rounded Login Panel

import React from 'react';
import { BorderBeam, Button, Flex, Input } from 'antd';

const radius = 24;

export default () => (
  <BorderBeam borderWidth={2} pathRadius={radius} size={88}>
    <Flex
      vertical
      gap={16}
      style={{
        width: 360,
        padding: 24,
        borderRadius: radius,
        background: 'var(--ant-color-bg-container)',
      }}
    >
      <Input placeholder="Email" />
      <Input.Password placeholder="Password" />
      <Button type="primary" block>
        Continue
      </Button>
    </Flex>
  </BorderBeam>
);

Detailed Design

DOM Structure

<div className={`${prefixCls}`}>
  {children}
  <div className={`${prefixCls}-beam`} aria-hidden />
</div>

Public semantic slots:

  • root
  • beam

Styling Model

BorderBeam follows antd design tokens by default.

Component tokens:

  • beamColorFrom
  • beamColorTo
  • borderBeamWidth

Default mappings:

  • beamColorFrom -> token.colorPrimary
  • beamColorTo -> token.colorPrimaryHover
  • borderBeamWidth -> token.lineWidth

Per-instance props still take precedence over component tokens.

Radius Model

pathRadius controls the beam track radius only. It does not write radius styles back to the wrapped content.

When pathRadius is omitted, the component may use the following sources as track configuration fallback:

  • style.borderRadius
  • semantic root styles.root.borderRadius
  • the computed border radius of the first child element

For stable and predictable usage across different wrapped components, passing pathRadius explicitly is recommended.

Motion Model

Implementation follows an antd-style CSS-in-JS approach:

  • The root element is relatively positioned
  • The beam layer is absolutely positioned over the border area
  • mask is used to keep only the border ring visible
  • A fixed-size gradient beam is animated along a rectangular offset-path
  • CSS offset-path and offset-distance drive the motion
  • offset-anchor is used to keep the visible beam aligned with the track more naturally
  • Internal motion smoothing may be applied to the running path so large beams remain visually stable on tight or non-uniform corners

This keeps the implementation aligned with the current antd stack and avoids introducing an additional motion runtime.

Accessibility

The beam layer is purely decorative:

  • aria-hidden
  • pointer-events: none
  • Must not replace focus rings
  • Must not replace validation or status borders

When prefers-reduced-motion: reduce is active, the beam effect is hidden.

Performance Constraints

Because this is a persistent motion effect, the component intentionally keeps a narrow scope:

  • Single beam only
  • No frame-by-frame JavaScript layout animation
  • No multi-track or multi-layer glow system
  • Designed for common rectangular and rounded-rectangle containers
  • Child-radius measurement is only used as a fallback path when no explicit track radius is provided

Initial Demo Set

  • basic.tsx
  • customized-color.tsx
  • radius.tsx
  • non-uniform-radius.tsx
  • controlled.tsx
  • component-token.tsx

References

You must be logged in to vote

Replies: 1 comment

Comment options

先只留
children
className
style
classNames
styles
colorFrom
colorTo
pathRadius
这些api

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
1 participant
Morty Proxy This is a proxified and sanitized view of the page, visit original site.