Bridge UI

Default props

Set app-wide default props for Bridge UI components.

Every Bridge UI component ships with library defaults (for example Button uses color="primary", size="md", variant="solid"). Override those defaults once in the provider so every instance inherits them unless you pass a prop.

Configure the provider

Pass components.<Name>.defaultProps to BridgeUIProvider:

<script setup lang="ts">
import { BridgeUIProvider } from "@bridge-ui/vue";
</script>

<template>
  <BridgeUIProvider
    :components="{
      Modal: {
        defaultProps: {
          size: 'lg',
          blur: 'sm',
          transition: 'fade',
        },
      },
      Button: {
        defaultProps: {
          rounded: 'lg',
          color: 'secondary',
          variant: 'outline',
        },
      },
      Snackbar: {
        defaultProps: {
          duration: 4000,
          progressbar: true,
          position: 'top-end',
        },
      },
    }"
  >
    <slot />
  </BridgeUIProvider>
</template>
import { BridgeUIProvider } from "@bridge-ui/react";
import type { PropsWithChildren } from "react";

export default function DefaultProps({ children }: PropsWithChildren) {
  return (
    <BridgeUIProvider
      components={{
        Modal: {
          defaultProps: {
            size: "lg",
            blur: "sm",
            transition: "fade",
          },
        },
        Button: {
          defaultProps: {
            rounded: "lg",
            color: "secondary",
            variant: "outline",
          },
        },
        Snackbar: {
          defaultProps: {
            duration: 4000,
            progressbar: true,
            position: "top-end",
          },
        },
      }}
    >
      {children}
    </BridgeUIProvider>
  );
}

On Vue you can also pass the same shape to createBridgeUI() in your plugin; the provider merges with those options.

Form density defaults

Set global.formDefaults to apply shared size and rounded across form controls—TextField, Select, Checkbox, FileUpload, Slider, Rating, OtpField, Autocomplete, NumberField, PasswordField, Textarea, RichTextEditor, Radio, Switch, ColorField, and the date/time fields (DateField, DateRangeField, DateTimeField, TimeField, TimeRangeField, DateTimeRangeField).

<script setup lang="ts">
import { BridgeUIProvider } from "@bridge-ui/vue";
</script>

<template>
  <BridgeUIProvider :global="{ formDefaults: { size: 'lg', rounded: 'md' } }">
    <slot />
  </BridgeUIProvider>
</template>
import type { PropsWithChildren } from "react";

import { BridgeUIProvider } from "@bridge-ui/react";

export default function FormDefaults({ children }: PropsWithChildren) {
  return (
    <BridgeUIProvider
      global={{
        formDefaults: { size: "lg", rounded: "md" },
      }}
    >
      {children}
    </BridgeUIProvider>
  );
}

Radio and Switch receive size only—their rounded stays shape-driven (full) unless you override it per component via defaultProps or instance props. BaseField and FormControl also ignore rounded from formDefaults.

Default color

Set global.defaultColor to replace the library default color (primary, dark, or secondary) on every colorable component: Button, ButtonGroup, Badge, Alert, Avatar, Link, Tabs, ToggleGroup, Snackbar, Progress, Spinner, Stepper, Pagination, Accordion, Calendar, ActionFooter, form fields, and pickers. Divider and Tooltip keep their neutral defaults.

Use "black" for a monochrome UI instead of repeating color in every components.<Name>.defaultProps. To rebrand primary, change the palette in theme colors instead.

<script setup lang="ts">
import { BridgeUIProvider } from "@bridge-ui/vue";
</script>

<template>
  <BridgeUIProvider
    :global="{ defaultColor: 'black' }"
    :components="{ Alert: { defaultProps: { color: 'info' } } }"
  >
    <slot />
  </BridgeUIProvider>
</template>
import type { PropsWithChildren } from "react";

import { BridgeUIProvider } from "@bridge-ui/react";

export default function DefaultColor({ children }: PropsWithChildren) {
  return (
    <BridgeUIProvider
      global={{ defaultColor: "black" }}
      components={{ Alert: { defaultProps: { color: "info" } } }}
    >
      {children}
    </BridgeUIProvider>
  );
}

Component defaultProps, shared chrome, and instance props still win over defaultColor, and error / invalid states are unaffected. In the example above, every Alert stays info while the rest of the UI turns black.

Shared form chrome

FormField, FormControl, BaseField, and TimePanel are registry keys. Set them once to theme a family; a public entry such as components.TextField still overrides defaultProps. Chrome tokens live on the shared key (components.FormField.tokens, components.BaseField.tokens). Dropdown tokens live on components.Listbox. Set components.Listbox.defaultProps.matchWidth so Select / Autocomplete menus match the field width. Time overlay chrome: components.TimePanel (TimePicker / TimeRangePicker override). Cancel / Apply in pickers and listboxes live on components.ActionFooter.

Prefer public fields and controls in apps. Theme all text-like fields via components.FormField, toggle-row chrome via components.FormControl, and composite chrome (OtpField, Slider) via components.BaseField. Theme Cancel / Apply via components.ActionFooter rather than importing it.

<script setup lang="ts">
import { BridgeUIProvider } from "@bridge-ui/vue";
</script>

<template>
  <BridgeUIProvider
    :components="{
      FormField: {
        defaultProps: {
          variant: 'filled',
          color: 'secondary',
        },
      },
      TextField: {
        defaultProps: { variant: 'outline' },
      },
      BaseField: {
        tokens: {
          size: { md: { text: 'text-base', group: 'gap-3' } },
        },
      },
    }"
  >
    <slot />
  </BridgeUIProvider>
</template>
import { BridgeUIProvider } from "@bridge-ui/react";
import type { PropsWithChildren } from "react";

export default function SharedChrome({ children }: PropsWithChildren) {
  return (
    <BridgeUIProvider
      components={{
        TextField: {
          defaultProps: { variant: "outline" },
        },
        BaseField: {
          tokens: {
            size: { md: { group: "gap-3", text: "text-base" } },
          },
        },
        FormField: {
          defaultProps: {
            variant: "filled",
            color: "secondary",
          },
        },
      }}
    >
      {children}
    </BridgeUIProvider>
  );
}

Set components.Listbox.defaultProps.matchWidth so Select / Autocomplete menus match the field:

<script setup lang="ts">
import { BridgeUIProvider } from "@bridge-ui/vue";
</script>

<template>
  <BridgeUIProvider
    :components="{
      Listbox: {
        defaultProps: { matchWidth: true },
      },
    }"
  >
    <slot />
  </BridgeUIProvider>
</template>
import { BridgeUIProvider } from "@bridge-ui/react";
import type { PropsWithChildren } from "react";

export default function ListboxMatchWidth({ children }: PropsWithChildren) {
  return (
    <BridgeUIProvider
      components={{
        Listbox: {
          defaultProps: { matchWidth: true },
        },
      }}
    >
      {children}
    </BridgeUIProvider>
  );
}

ActionFooter is a registry key for the Cancel / Apply pair inside pickers and listboxes — the same idea as FormField for field chrome. Set components.ActionFooter.defaultProps once; nested hosts inherit those tokens. Instance customProps.applyButton / customProps.cancelButton still win, including a per-button color.

The typed defaults are applyVariant, cancelVariant, and color. Both buttons share one color; the variants set their hierarchy.

Inside pickers, listboxes, and the RichTextEditor link editor, the footer follows the host color (<DateField color="success" showFooter /> gets a green footer). There, components.ActionFooter.defaultProps.color does not apply — set color on the host (or global.defaultColor) instead.

<script setup lang="ts">
import { BridgeUIProvider } from "@bridge-ui/vue";
</script>

<template>
  <BridgeUIProvider
    :components="{
      ActionFooter: {
        defaultProps: {
          applyVariant: 'solid',
          cancelVariant: 'outline',
        },
      },
    }"
  >
    <slot />
  </BridgeUIProvider>
</template>
import { BridgeUIProvider } from "@bridge-ui/react";
import type { PropsWithChildren } from "react";

export default function ActionFooterDefaults({ children }: PropsWithChildren) {
  return (
    <BridgeUIProvider
      components={{
        ActionFooter: {
          defaultProps: {
            applyVariant: "solid",
            cancelVariant: "outline",
          },
        },
      }}
    >
      {children}
    </BridgeUIProvider>
  );
}

Merge order

For each prop, Bridge UI merges (later wins):

  1. Library defaults

    Hard-coded in the component.

  2. defaultColor

    From global.defaultColor — colorable components only.

  3. formDefaults

    From global.formDefaults — form controls only.

  4. Shared chrome

    From components.FormField, FormControl, BaseField, or TimePanel — form chrome families only.

  5. defaultProps

    From components on the provider (and Vue plugin). Public entries such as TextField override chrome.

  6. Instance props

    What you pass on <Button /> / <Button> (wins).

// Library → defaultColor → formDefaults → chrome (FormField) → components.TextField.defaultProps → instance
// Provider sets formDefaults.size="lg" and TextField defaultProps.variant="filled"
<TextField label="Name" />
{/* Uses lg + filled */}
<TextField label="Email" size="sm" variant="outline" />
{/* Uses sm + outline */}

Global options

global configures shared app settings (not visual tokens):

Key Type Default Description
dates DateAdapter — Date adapter (Dates). Each provider creates its own native adapter when this is omitted.
defaultColor BridgeUIDefaultColor — Default color for every colorable component, replacing the library default. See Default color.
direction "ltr" | "rtl" "ltr" Text direction
formDefaults BridgeUIFormDefaults — Shared size / rounded for form controls
i18n I18nAdapter — i18n adapter (i18n)
icons IconAdapter — Icon adapter (Icons)
locale string "en-US" Locale. setLocale also calls optional i18n.setLocale and dates.setLocale.
mobileBreakpoint string "sm" Threshold used by overlay="auto" and useBreakpoint().mobile
theme string "light" Theme name
timeZone string system IANA zone Default zone for pickers. setTimeZone updates it and calls optional dates.setTimeZone. The value Date stays a UTC instant.
<BridgeUIProvider
  components={{}}
  global={{
    locale: "pt-BR",
    direction: "rtl",
    formDefaults: { size: "lg", rounded: "md" },
  }}
>
  {children}
</BridgeUIProvider>

Which keys are available?

Each component exposes a typed subset under defaultProps (for example Button: color, density, rounded, size, variant). See each component API table for the full list, or Type overrides for how Framework packages refine those types.

Next steps

  • Classes — shared class slots from the provider
  • Tokens — add new token values you can set as defaults
  • Type overrides — stronger typing for defaultProps