Brand

Corner ticks

The L-shaped corner marks the brand frames things with.

stablev0.1.0 Chromium 103 ui-scale safe

Install

Copies the file into components/ds/, with its registry dependencies and npm packages. See Installation for the one-time setup.
bunx shadcn@3 add @fastrp/corner-ticks

Examples

Default

Open alone
Dört köşe
Öne çıkan
Küçük

API

<CornerTicks />

The L-shaped corner ticks the brand frames things with instead of a full border. Drawn with borders sized by `--tick-size` / `--tick-thickness`, never inline pixels, so the FiveM webview's ui-scale pass sizes them with everything else. The parent must be positioned.

PropTypeDefaultNotes
classNamestring—
cornersCorner[]['top-left', 'top-right', 'bottom-left', 'bottom-right']
size"sm" | "md" | "lg"—
tone"primary" | "line" | "foreground"—

Dependencies

npm

  • class-variance-authority@^0.7.1

Registry

  • @fastrp/utils

Source

components/ds/corner-ticks.tsxShow
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';

// @fast-ds [email protected]

export type Corner = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';

const CORNER_CLASS: Record<Corner, string> = {
  'top-left':
    'left-0 top-0 [border-left-width:var(--tick-thickness)] [border-top-width:var(--tick-thickness)]',
  'top-right':
    'right-0 top-0 [border-right-width:var(--tick-thickness)] [border-top-width:var(--tick-thickness)]',
  'bottom-left':
    'bottom-0 left-0 [border-bottom-width:var(--tick-thickness)] [border-left-width:var(--tick-thickness)]',
  'bottom-right':
    'bottom-0 right-0 [border-bottom-width:var(--tick-thickness)] [border-right-width:var(--tick-thickness)]',
};

const ticksVariants = cva('pointer-events-none absolute inset-0', {
  variants: {
    size: {
      sm: '[--tick-size:5px]',
      md: '',
      lg: '[--tick-size:12px] [--tick-thickness:2px]',
    },
    tone: {
      line: '[--tick-color:var(--line-border)]',
      primary: '[--tick-color:var(--primary)]',
      foreground: '[--tick-color:var(--foreground)]',
    },
  },
  defaultVariants: { size: 'md', tone: 'line' },
});

export type CornerTicksProps = VariantProps<typeof ticksVariants> & {
  corners?: Corner[];
  className?: string;
};

const ALL: Corner[] = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];

/**
 * The L-shaped corner ticks the brand frames things with instead of a full border. Drawn with
 * borders sized by `--tick-size` / `--tick-thickness`, never inline pixels, so the FiveM webview's
 * ui-scale pass sizes them with everything else. The parent must be positioned.
 */
export function CornerTicks({ corners = ALL, size, tone, className }: CornerTicksProps) {
  return (
    <span aria-hidden className={cn(ticksVariants({ size, tone }), className)}>
      {corners.map((corner) => (
        <span
          key={corner}
          className={cn(
            'absolute size-[var(--tick-size)] border-0 border-solid border-[hsl(var(--tick-color))]',
            CORNER_CLASS[corner],
          )}
        />
      ))}
    </span>
  );
}