Aura Border

A dynamic border component with rotation, blur, and glow effects for highlighting content.

aura-border-preview.jsx

import AuraBorderContainer, { AuraBorder } from "@/components/visual-effects/aura-border/aura-border";

const AuraBorderPreview = () => {
  return (
    // Use AuraBorderContainer only when AuraBorder’s glow/border is hidden or not rendering correctly due to stacking context issues.
    <AuraBorderContainer      
      style={{
        width: "320px",
      }}
    >
      <AuraBorder
        colors={[
          "#60A5FA",
          "#A78BFA",
          "#F472B6",
          "#38BDF8",
          "#60A5FA",
        ]}
        style={cardStyles}
      >
        {/* Add your content here */}
        <ChartIcon style={iconStyles} />
        <h2>AI-Powered Insights</h2>
        <p>Instantly analyze complex datasets with advanced AI algorithms, turning raw information into actionable insights that help you make smarter, faster, and more accurate decisions every single day.</p>
      </AuraBorder>
    </AuraBorderContainer>
  )
};

const cardStyles = {
  borderRadius: "16px",
  background: "var(--layer-secondary)",
  padding: "16px",
};

const iconStyles = {
  width: "32px",
  height: "32px",
  display: "inline-block",
  marginBottom: "8px",
};

const ChartIcon = (props) => {
  const {
    style,
  } = props;
  return (  
    <svg style={style} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
      <path fill="currentColor" d="M5 20q-.425 0-.712-.288T4 19V9q0-.425.288-.712T5 8h2q.425 0 .713.288T8 9v10q0 .425-.288.713T7 20zm5 0q-.425 0-.712-.288T9 19v-5q0-.425.288-.712T10 13h2q.425 0 .713.288T13 14v5q0 .425-.288.713T12 20zm7 0q-.425 0-.712-.288T16 19V5q0-.425.288-.712T17 4h2q.425 0 .713.288T20 5v14q0 .425-.288.713T19 20z" />
    </svg>
  )
};

export default AuraBorderPreview;

Installation

Run the command from your project root directory (the folder that contains package.json).

Terminal / Console

npx mosaicui-cli@latest visual-effects/aura-border

1. Copy the component file

Create a new file called aura-border.jsx in your reusable components folder (for example /src/components/) and paste the following code into it.

aura-border.jsx

import { memo, useLayoutEffect, useMemo, useRef } from "react";
import styles from "./aura-border.module.css";

const AuraBorderContainer = (props) => {
  const {
    children,
    tagName = "div",
    className,
    ...restProps
  } = props;

  const Component = tagName || "div";

  return (
    <Component
      {...restProps}
      className={[
        styles["aura-border-container"],
        className,
      ].join(" ")}
    >
      {children}
    </Component>
  );
};

export const AuraBorder = memo((props) => {
  const {
    children,
    colors = ["rgba(127, 127, 127, 1)"],
    width = 1,
    speed = 0.5,
    intensity = 0.5,
    tagName = "div",
    className,
    style,
    ...restProps
  } = props;

  const Component = tagName || "div";

  const ref = useRef();

  const _width = useMemo(() => (
    Math.max(0, width)
  ), [width]);

  const _speed = useMemo(() => (
    Math.min(1, Math.max(0, speed))
  ), [speed]);

  const _intensity = useMemo(() => (
    20 * Math.min(1, Math.max(0, intensity))
  ), [intensity]);

  const gradient = useMemo(() => (
    `conic-gradient(from var(--conic-angle), ${colors.join()})`
  ), [colors]);

  useLayoutEffect(() => {
    let rafId = null;
    let conicAngle = 0;
    const updateConicAngle = () => {
      conicAngle += (_speed * 2);
      conicAngle = conicAngle % 360;
      ref.current.style.setProperty("--conic-angle", `${conicAngle}deg`);
      rafId = requestAnimationFrame(updateConicAngle);
    };
    rafId = requestAnimationFrame(updateConicAngle);
    return () => {
      cancelAnimationFrame(rafId);
    };
  }, [_speed]);

  return (
    <Component
      {...restProps}
      ref={ref}
      className={[
        styles["aura-border"],
        className,
      ].join(" ")}
      style={{
        ...style,
        "--gradient": gradient,
        "--width": `${_width}px`,
        "--intensity": `${_intensity}px`,
      }}
    >
      {children}
    </Component>
  );
});

export default memo(AuraBorderContainer);

2. Copy the CSS module file

In the same folder, create a file called aura-border.module.css and paste the following CSS.

aura-border.module.css

.aura-border-container {
  isolation: isolate;
}

.aura-border {
  --conic-angle: 0deg;
  --width: 1px;
  --intensity: 2px;

  position: relative;

  &:before,
  &:after {
    content: "";
    position: absolute;
    z-index: -1;
    background: var(--gradient);
    border-radius: inherit;
    transition: background 100ms linear;
  }

  &:before {
    inset: calc(var(--width) * -1);
  }

  &:after {
    inset: 0;
    filter: blur(var(--intensity));
  }
}

Examples

Discover how supported props transform components to match your needs.

Border Width

AI-Powered Insights

Instantly analyze complex datasets with advanced AI algorithms, turning raw information into actionable insights that help you make smarter, faster, and more accurate decisions every single day.

aura-border

import AuraBorderContainer, { AuraBorder } from "@/components/visual-effects/aura-border/aura-border";

const AuraBorderWidthPreview = () => {
  return (
    // Use AuraBorderContainer only when AuraBorder’s glow/border is hidden or not rendering correctly due to stacking context issues.
    <AuraBorderContainer
      style={{
        margin: "32px 0",
        width: "320px",
      }}
    >
      <AuraBorder
        colors={[
          "#60A5FA",
          "#A78BFA",
          "#F472B6",
          "#38BDF8",
          "#60A5FA",
        ]}
        width={5}
        style={cardStyles}
      >
        {/* Add your content here */}
        <ChartIcon style={iconStyles} />
        <h2>AI-Powered Insights</h2>
        <p>Instantly analyze complex datasets with advanced AI algorithms, turning raw information into actionable insights that help you make smarter, faster, and more accurate decisions every single day.</p>
      </AuraBorder>
    </AuraBorderContainer>
  )
};

const cardStyles = {
  borderRadius: "16px",
  background: "var(--layer-secondary)",
  padding: "16px",
};

const iconStyles = {
  width: "32px",
  height: "32px",
  display: "inline-block",
  marginBottom: "8px",
};

const ChartIcon = (props) => {
  const {
    style,
  } = props;
  return (  
    <svg style={style} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
      <path fill="currentColor" d="M5 20q-.425 0-.712-.288T4 19V9q0-.425.288-.712T5 8h2q.425 0 .713.288T8 9v10q0 .425-.288.713T7 20zm5 0q-.425 0-.712-.288T9 19v-5q0-.425.288-.712T10 13h2q.425 0 .713.288T13 14v5q0 .425-.288.713T12 20zm7 0q-.425 0-.712-.288T16 19V5q0-.425.288-.712T17 4h2q.425 0 .713.288T20 5v14q0 .425-.288.713T19 20z" />
    </svg>
  )
};

export default AuraBorderWidthPreview;

Intensity

AI-Powered Insights

Instantly analyze complex datasets with advanced AI algorithms, turning raw information into actionable insights that help you make smarter, faster, and more accurate decisions every single day.

aura-border

import AuraBorderContainer, { AuraBorder } from "@/components/visual-effects/aura-border/aura-border";

const AuraBorderIntensityPreview = () => {
  return (
    // Use AuraBorderContainer only when AuraBorder’s glow/border is hidden or not rendering correctly due to stacking context issues.
    <AuraBorderContainer
      style={{
        margin: "32px 0",
        width: "320px",
      }}
    >
      <AuraBorder
        colors={[
          "#60A5FA",
          "#A78BFA",
          "#F472B6",
          "#38BDF8",
          "#60A5FA",
        ]}
        intensity={0.9}
        style={cardStyles}
      >
        {/* Add your content here */}
        <ChartIcon style={iconStyles} />
        <h2>AI-Powered Insights</h2>
        <p>Instantly analyze complex datasets with advanced AI algorithms, turning raw information into actionable insights that help you make smarter, faster, and more accurate decisions every single day.</p>
      </AuraBorder>
    </AuraBorderContainer>
  )
};

const cardStyles = {
  borderRadius: "16px",
  background: "var(--layer-secondary)",
  padding: "16px",
};

const iconStyles = {
  width: "32px",
  height: "32px",
  display: "inline-block",
  marginBottom: "8px",
};

const ChartIcon = (props) => {
  const {
    style,
  } = props;
  return (  
    <svg style={style} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
      <path fill="currentColor" d="M5 20q-.425 0-.712-.288T4 19V9q0-.425.288-.712T5 8h2q.425 0 .713.288T8 9v10q0 .425-.288.713T7 20zm5 0q-.425 0-.712-.288T9 19v-5q0-.425.288-.712T10 13h2q.425 0 .713.288T13 14v5q0 .425-.288.713T12 20zm7 0q-.425 0-.712-.288T16 19V5q0-.425.288-.712T17 4h2q.425 0 .713.288T20 5v14q0 .425-.288.713T19 20z" />
    </svg>
  )
};

export default AuraBorderIntensityPreview;

Speed

AI-Powered Insights

Instantly analyze complex datasets with advanced AI algorithms, turning raw information into actionable insights that help you make smarter, faster, and more accurate decisions every single day.

aura-border

import AuraBorderContainer, { AuraBorder } from "@/components/visual-effects/aura-border/aura-border";

const AuraBorderSpeedPreview = () => {
  return (
    // Use AuraBorderContainer only when AuraBorder’s glow/border is hidden or not rendering correctly due to stacking context issues.
    <AuraBorderContainer
      style={{
        margin: "32px 0",
        width: "320px",
      }}
    >
      <AuraBorder
        colors={[
          "#60A5FA",
          "#A78BFA",
          "#F472B6",
          "#38BDF8",
          "#60A5FA",
        ]}
        speed={0.9}
        style={cardStyles}
      >
        {/* Add your content here */}
        <ChartIcon style={iconStyles} />
        <h2>AI-Powered Insights</h2>
        <p>Instantly analyze complex datasets with advanced AI algorithms, turning raw information into actionable insights that help you make smarter, faster, and more accurate decisions every single day.</p>
      </AuraBorder>
    </AuraBorderContainer>
  )
};

const cardStyles = {
  borderRadius: "16px",
  background: "var(--layer-secondary)",
  padding: "16px",
};

const iconStyles = {
  width: "32px",
  height: "32px",
  display: "inline-block",
  marginBottom: "8px",
};

const ChartIcon = (props) => {
  const {
    style,
  } = props;
  return (  
    <svg style={style} xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
      <path fill="currentColor" d="M5 20q-.425 0-.712-.288T4 19V9q0-.425.288-.712T5 8h2q.425 0 .713.288T8 9v10q0 .425-.288.713T7 20zm5 0q-.425 0-.712-.288T9 19v-5q0-.425.288-.712T10 13h2q.425 0 .713.288T13 14v5q0 .425-.288.713T12 20zm7 0q-.425 0-.712-.288T16 19V5q0-.425.288-.712T17 4h2q.425 0 .713.288T20 5v14q0 .425-.288.713T19 20z" />
    </svg>
  )
};

export default AuraBorderSpeedPreview;

Props

Configure the component with the following props:


Use AuraBorderContainer only if you encounter stacking or z-index issues with AuraBorder. It creates a dedicated stacking context to ensure your glow and border render correctly.


AuraBorderContainer Props

PropTypeRequiredDefaultDescription
childrenReactNodeYesThe content to be wrapped inside the container.
tagNamestringNodivHTML tag or React element type to use as the wrapper container.
classNamestringNoAdditional CSS class names to apply to the wrapper for custom styling.
styleReact.CSSPropertiesNoInline styles to apply directly to the wrapper container.


AuraBorder Props

PropTypeRequiredDefaultDescription
childrenReactNodeYesThe content to be wrapped inside the AuraBorder.
colorsstring[]No["rgba(127, 127, 127, 1)"]Array of colors or gradients for the border glow. Accepts any valid CSS color.
widthnumberNo1Width of the border in pixels. Minimum value: 0.
speednumberNo0.5Speed of rotation. Value between 0 (no rotation) and 1 (fastest).
intensitynumberNo0.5Glow intensity. Value between 0 (no glow) and 1 (maximum glow).
tagNamestringNodivHTML tag or React element type used as the wrapper container.
classNamestringNoAdditional CSS class names applied to the wrapper.
styleReact.CSSPropertiesNoInline styles applied directly to the wrapper container.