Nexus DSdocs

Radius overrides

Use the appearance corners setting to choose a radius preset for the whole theme. For a smaller area, set data-radius on a wrapper. To change the radius used by buttons within that area, override --nx-radius-base.

Button currently uses nx:rounded-base, which reads --nx-radius-base. Input and SelectTrigger use nx:rounded-md, which reads --nx-radius-md. The generic base name describes a token, not permanent ownership by Button: any consumer of that token inside the scope receives the override.

Some components render Button with their own radius class, which replaces rounded-base. These ignore the override:

  • InputGroupButton at sizes xs, icon-xs (rounded-sm) and sm (rounded-md). Size icon-sm follows the override.
  • Carousel previous and next buttons (rounded-full).
  • DatePicker selected days: rounded-md at a range start and end, rounded-none in the middle of a range, and rounded-l-md or rounded-r-md on the outer side of any selected day at a week edge. A single selected day away from a week edge, unselected days and the month navigation buttons follow the override.

Rounded buttons, unchanged inputs

Under round, both base and medium radii start at 12px. This example changes base to 9999px, leaving medium at 12px.

Use the component import paths from your installation. The local style type accepts this custom property without changing React's global types.

import type { CSSProperties } from 'react';

import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Select, SelectTrigger, SelectValue } from '@/components/ui/select';

type RadiusStyle = CSSProperties & { '--nx-radius-base': string };
const pillButtons: RadiusStyle = { '--nx-radius-base': '9999px' };

export function RoundedActions() {
  return (
    <div data-radius="round" style={pillButtons}>
      <Button>Save changes</Button>
      <Input aria-label="Name" />
      <Select>
        <SelectTrigger aria-label="Category">
          <SelectValue placeholder="Choose a category" />
        </SelectTrigger>
      </Select>
    </div>
  );
}

The example demonstrates the closed Select trigger; add SelectContent and SelectItem when providing choices. For one Button, put style={pillButtons} on that Button instead. Existing className and style customization remains available. Removing the override restores the inherited preset value.

Nested scopes and precedence

PlacementResult
Override on a wrapperDescendant consumers inherit it; siblings outside the wrapper do not.
Nested wrapper without a preset or overrideKeeps inheriting the outer override.
Nested wrapper with its own overrideIts descendants receive the nested value.
Nested data-radius="smooth"Declares fresh preset values, replacing an inherited override; Button returns to 8px.
data-radius="round" and an inline base override on the same wrapperThe inline override wins over the preset's normal selector declaration. Medium remains 12px.

These scopes follow the actual DOM ancestry. Content rendered into a portal outside the wrapper does not inherit the wrapper's variables.

ButtonGroup still removes the touching corners of adjacent children, in both horizontal and vertical groups. In a group of only Buttons, the override rounds the outside corners while the joining edges stay square. ButtonGroupText, Input and SelectTrigger keep rounded-md, so a group mixing them with Buttons shows different outside corners at each end. Button rendered with asChild passes its styling to the child element as usual.

For the overall appearance model, see Appearance. The Tokens / Radius overrides / Scope And Precedence Storybook story checks the computed corners for these examples, including unchanged Input and SelectTrigger corners.