Separator

Visually or semantically separates content.

Examples

Basic

PropDefaultTypeDescription
label-stringThe label content.
Preview
Code

Variant & Color

PropDefaultTypeDescription
separatorsolid-gray{variant}-{color}Set the separator variant and color.
VariantDescription
solidA solid line.
dashedA dashed line.
dottedA dotted line.
Preview
Code

Orientation

PropDefaultTypeDescription
orientationhorizontalhorizontal, verticalSet the separator orientation.
Preview
Code

Position

Allows you to adjust the position of the label content. Here are the available positions and their corresponding orientations:

PropDefaultTypeDescription
separator-positioncentercenter, left, right, top, bottomSet the separator position.
Preview
Code

Size

PropDefaultTypeDescription
size-stringSet the separator size.
Preview
Code

Slots

NamePropsDescription
default-The label content.

Presets

shortcuts/separator.ts
type SeparatorPrefix = 'separator'

export const staticSeparator: Record<`${SeparatorPrefix}-${string}` | SeparatorPrefix, string> = {
  // base
  'separator': 'text-md shrink-0 relative',
  'separator-default-variant': 'separator-solid-gray',
  'separator-content': 'text-0.75em text-muted bg-base absolute flex justify-center items-center',

  // orientation states
  'separator-horizontal': 'h-px my-4 w-full border-t-0.0625em',
  'separator-vertical': 'w-px mx-4 h-full border-l-0.0625em',
  'separator-content-horizontal': 'h-1px py-1 px-2',
  'separator-content-vertical': 'w-1px px-1 py-2',

  // horizontal positions
  'separator-position-left': 'left-6 top-1/2 -translate-y-1/2',
  'separator-position-right': 'right-6 top-1/2 -translate-y-1/2',
  'separator-position-center': 'left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2',

  // vertical positions
  'separator-position-bottom': 'bottom-4 left-1/2 -translate-x-1/2',
  'separator-position-top': 'top-4 left-1/2 -translate-x-1/2',

  // static variants
  'separator-solid-gray': 'border-base',
}

export const dynamicSeparator = [
  // dynamic variants
  [/^separator-solid(-(\S+))?$/, ([, , c = 'gray']) => `border-solid border-${c}-200 dark:border-${c}-700/58`],
  [/^separator-dashed(-(\S+))?$/, ([, , c = 'gray']) => `border-dashed border-${c}-200 dark:border-${c}-700/58`],
  [/^separator-dotted(-(\S+))?$/, ([, , c = 'gray']) => `border-dotted border-${c}-200 dark:border-${c}-700/58`],
]

export const separator = [
  ...dynamicSeparator,
  staticSeparator,
]

Props

types/separator.ts
import type { SeparatorProps } from 'radix-vue'
import type { HTMLAttributes } from 'vue'

type Extensions = SeparatorProps & { class?: HTMLAttributes['class'], label?: string }

export interface NSeparatorProps extends Extensions {
  /**
   * Allows you to add `UnaUI` separator preset properties,
   * Think of it as a shortcut for adding options or variants to the preset if available.
   *
   * @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/separator.ts
   * @example
   * separator="solid-green"
   */
  separator?: HTMLAttributes['class']
  /**
   * Allows you to change the orientation and position of the separator.
   *
   * @default horizontal-center
   */
  separatorPosition?: HTMLAttributes['class']
  /**
   * Allows you to change the size of the separator.
   *
   * @default md
   *
   * @example
   * size="sm" | size="2cm" | size="2rem" | size="2px"
   */
  size?: HTMLAttributes['class']
  /**
   * `UnaUI` preset configuration
   *
   * @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/separator.ts
   */
  una?: {
    separator?: HTMLAttributes['class']
    separatorContent?: HTMLAttributes['class']

    separatorDefaultVariant?: HTMLAttributes['class']
  }
}

Components

Separator.vue
<script setup lang="ts">
import type { NSeparatorProps } from '../../types'
import { Separator } from 'radix-vue'
import { computed } from 'vue'
import { cn, omitProps } from '../../utils'

const props = withDefaults(defineProps<NSeparatorProps>(), {
  orientation: 'horizontal',
})

const delegatedProps = computed(() => {
  const { class: _, ...delegated } = omitProps(props, ['una'])

  return delegated
})
</script>

<template>
  <Separator
    v-bind="omitProps(delegatedProps, ['una', 'separatorPosition'])"
    :class="
      cn(
        'separator',
        props.una?.separatorDefaultVariant || 'separator-default-variant',
        props.class,
        props.una?.separator,
        props.orientation === 'vertical' ? 'separator-vertical' : 'separator-horizontal',
      )
    "
  >
    <span
      v-if="props.label || $slots.default"
      :separator-position="props.separatorPosition || 'center'"
      :class="cn(
        'separator-content',
        props.una?.separatorContent,
        props.orientation === 'vertical' ? 'separator-content-vertical' : 'separator-content-horizontal',
      )"
    >
      <slot>
        {{ props.label }}
      </slot>
    </span>
  </Separator>
</template>