@brrritscold/core-react 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -11
- package/dist/components/badge.js +1 -1
- package/dist/components/button.js +2 -2
- package/dist/components/checkbox.js +1 -1
- package/dist/components/combobox.js +1 -1
- package/dist/components/dropdown-menu.js +1 -1
- package/dist/components/input-group.js +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/radio-group.js +1 -1
- package/dist/components/select.js +1 -1
- package/dist/components/tabs.js +1 -1
- package/dist/components/textarea.js +1 -1
- package/dist/library.snapshot.json +1413 -1503
- package/dist/styles.css +9 -0
- package/dist/tokens.json +30 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -59,6 +59,7 @@ Scripts beyond the contract: `build:styles` (the token half of `build`), `drift:
|
|
|
59
59
|
|
|
60
60
|
- **Primitives** hold raw values: `color.neutral.500`, `space.4`, `size.md`, `font-size.sm`, … A half step is written with a dash, since a token name can't hold a dot: `px-2.5` is `space.2-5`. Each class has one token: `h-9` and `size-9` read `space.9`; `size.*` holds only the container widths `max-w-*` reads.
|
|
61
61
|
- **Semantics** are named exactly as shadcn's CSS variables (`background`, `primary-foreground`, `border`, `ring`, `radius`, …), point at primitives, and are defined in both `light` and `dark`. Colours are only ever semantic in components.
|
|
62
|
+
- **Per-mode fills** are semantics too, for a fill whose alpha changes by mode, so the library can apply it: `input-background` (a form field: `transparent` in light, `input` at 30% in dark), `outline-background` (an outlined control raised on its surface, Button `outline` and the active tab: `background` in light, `input-background` in dark) and `destructive-background` (the tint behind destructive text: `destructive` at 10% in light, 20% in dark). Penpot can't add an alpha to a reference, so an alpha value is an `rgba()` literal of the primitive it tints. A component reads them as `bg-input-background` and so on, never as a `dark:` alpha arm.
|
|
62
63
|
- **`$type`s** follow Penpot's token types, so token sync writes them as they are: `color`, `spacing`, `sizing`, `borderRadius`, `fontFamilies`, `fontSizes`, `fontWeights`, `number` (line height), `letterSpacing`, `shadow`, `opacity`.
|
|
63
64
|
- **`styles.css`**: primitives and light semantics on `:root`, dark semantics on `.dark`, then the `@theme inline` block. It clears Tailwind's default scale for every token type and maps the tokens in their place, so a utility reads its token's variable (`p-4` → `var(--space-4)`) and changing a token changes every class that uses it:
|
|
64
65
|
|
|
@@ -85,7 +86,7 @@ Scripts beyond the contract: `build:styles` (the token half of `build`), `drift:
|
|
|
85
86
|
The CI job `drift` keeps this package and the design system library in Penpot honest, offline and without Penpot credentials:
|
|
86
87
|
|
|
87
88
|
1. `pnpm drift:manifest` writes `code-manifest.json` (gitignored; CI uploads it as the `code-manifest` artifact) from the built `.d.ts`: every export, each prop's literal union, the icon names. Run `build` first.
|
|
88
|
-
2. `pnpm drift:check` checks `design/library.snapshot.json` against the manifest and `tokens/tokens.json` (drift rules 1–
|
|
89
|
+
2. `pnpm drift:check` checks `design/library.snapshot.json` against the manifest and `tokens/tokens.json` (drift rules 1–10 in `@brrritscold/design-core-js`). Library → code mismatches fail; code → library gaps are a warning, except the exports on the allowlist.
|
|
89
90
|
3. Every token the PR's base `tokens.json` has and this one doesn't needs a `design/token-migrations.json` entry, or the job fails (`design-drift migrations`).
|
|
90
91
|
|
|
91
92
|
| File | Holds |
|
|
@@ -100,27 +101,26 @@ Fixing a red check, lockstep PRs and promotion: the personal-ai `design-system`
|
|
|
100
101
|
|
|
101
102
|
Penpot can't say everything a class list says. The library twin keeps every checked attribute on a token and accepts these known differences:
|
|
102
103
|
|
|
103
|
-
- **
|
|
104
|
-
-
|
|
105
|
-
-
|
|
104
|
+
- **A colour at an opacity is a tint layer,** unless a per-mode fill holds it. Applying a colour token resets the fill's opacity to 1, so `Table/Footer`'s `bg-muted/50` is a `Tint` rectangle (fill `muted`, layer opacity `opacity.50`). An `rgba()` token keeps its alpha, so Button and Badge `destructive` fill `destructive-background` directly, 10% in Light and 20% in Dark.
|
|
105
|
+
- **`dark:` overrides that pick another semantic are dropped.** Button `outline`'s `dark:border-input` stays `border` (the same `neutral.800` in Dark today).
|
|
106
|
+
- **Button's 1px border is margin on its label.** A Penpot stroke takes no layout space, so `border border-transparent` is a 1px left and right margin on `Label` (margins aren't checked attributes), and `outline`'s visible border is an inner stroke on top. Penpot sets the `Button` label 1px wider than Chromium does, so a label button is 66px wide against code's 65.
|
|
106
107
|
- **Hover and focus states have no variants**, and neither do the focus and `aria-invalid` rings (`ring-3 ring-*/20`). A state backed by a prop is a variant property named after it, with values `true` / `false`: Checkbox `checked` / `disabled` / `aria-invalid`, Switch `checked` / `disabled`, Input and Textarea `disabled` / `aria-invalid`. Button has none: it was built before the form controls.
|
|
107
108
|
- **A disabled control is the whole twin at `opacity.50`**, as `data-disabled:opacity-50` fades the whole element.
|
|
108
109
|
- **RadioGroup's item has no `checked` variant**, because `RadioGroupItem` has no `checked` prop (the group's `value` picks it). `Components/RadioGroup/Item` holds a hidden `Checked` layer, which a copy shows to draw the selected item.
|
|
109
|
-
- **
|
|
110
|
-
- **Checkbox's corners are `border-radius.sm`** (6px, the `rounded-sm` it is in code), not `radius`, which would make a 16px box nearly round.
|
|
110
|
+
- **Shadowed fields fill with `outline-background`** where code is `bg-input-background`: Input, Textarea, Select's trigger, Combobox's input and chips. A Penpot board with a transparent fill casts its shadow from its children, so `shadow.xs` smeared the placeholder text. In Dark the two tokens are the same; in Light the fill is `background`, which looks the same on a page. Checkbox and RadioGroup's item fill `input-background` as code does.
|
|
111
111
|
- **Field `responsive` looks like `vertical`.** It goes horizontal in a field group 28rem or wider, a container query Penpot can't express.
|
|
112
|
-
- **Toast is the resting toast only.** Stacking, expand-on-hover and swipe have no twin; `Toast` is one toast at the viewport's `max-w-sm` (384px). Its `type` icon is a hidden `Icon` layer (`CircleCheck`) a copy shows and swaps, since `type` is toast data, not a prop. Its
|
|
113
|
-
- **Badge is 2px narrower.** Its `border border-transparent` adds 1px a side in code; the twin draws no transparent stroke. `destructive`
|
|
114
|
-
- **Toggle and ToggleGroup
|
|
112
|
+
- **Toast is the resting toast only.** Stacking, expand-on-hover and swipe have no twin; `Toast` is one toast at the viewport's `max-w-sm` (384px). Its `type` icon is a hidden `Icon` layer (`CircleCheck`) a copy shows and swaps, since `type` is toast data, not a prop. Its text lines are 21px tall against code's 20px, so it stands 2px taller.
|
|
113
|
+
- **Badge is 2px narrower.** Its `border border-transparent` adds 1px a side in code; the twin draws no transparent stroke. `destructive` fills `destructive-background`.
|
|
114
|
+
- **Toggle and ToggleGroup show text labels.** The items show a `Label` text where stories show an icon. `outline` fills with `background` where code is `bg-transparent`, for its shadow, as the shadowed fields do. A joined (`spacing` 0) outline group keeps each item's full border, so its dividers are 2px where code's `border-l-0` makes them 1px.
|
|
115
115
|
- **Alert's action is a hidden `Action` layer** at `top-2.5 right-3`. A copy that shows it applies `space.18` to the right padding, as `has-data-[slot=alert-action]:pr-18` does. `destructive`'s description is `destructive` at full strength, not `/90`: no `opacity.90` token.
|
|
116
116
|
- **Avatar's border ring is a `Ring` ellipse** on top (`after:` overlay, `mix-blend-darken` dropped). `Image` and `Badge` are hidden layers a copy shows; `AvatarGroup` is layout-only (`-space-x-2`) and on the drift allowlist.
|
|
117
117
|
- **Open/active states are hidden layers.** Base UI holds them, not a prop. `Accordion/Item` has a hidden `Content` and its Trigger a hidden `Open` chevron (`ChevronUp`) beside `Closed` (`ChevronDown`). `Tabs/Trigger` has a hidden `Active` pill (`background`, `shadow.sm`) and a hidden `Line` bar for the `line` list. A copy shows them. The bottom border of an accordion item is a 1px `Border` layer, hidden on the last item.
|
|
118
|
-
- **An inactive tab's text is `muted-foreground`,** not `text-foreground/60` (there is no `opacity.60` token).
|
|
118
|
+
- **An inactive tab's text is `muted-foreground`,** not `text-foreground/60` (there is no `opacity.60` token). The active pill fills `outline-background`; dark's active `border-input` has no twin. Vertical `Tabs` turns its `List` copy into a column.
|
|
119
119
|
- **Card's `ring-1 ring-foreground/10` is a `Ring` layer** on top (`foreground` stroke at `opacity.10`). The `sm` variant overrides its parts' padding to `space.4` and the title to `font-size.sm`. `Action` is hidden in `Header`; `Action`, `Content`, `Footer` and `Tabs/Content`, `Accordion/Content` hold `_internal/Slot` placeholders. `BreadcrumbItem` is layout-only and on the drift allowlist. `BreadcrumbList`'s gap is `space.2-5` (`sm:gap-2.5`, the desktop width).
|
|
120
120
|
- **Table's columns are fixed-width cells.** `Table/Head` and `Table/Cell` are 120px boards (a table lays out its columns from content; Penpot can't), so the twin's columns don't stretch to the container's `w-full`. `TableHeader` and `TableBody` are layout-only (`Columns` and `Rows` wrappers) and on the drift allowlist. A row's `border-b` is a 1px `Border` layer, hidden on the last body row and on the footer's row; `data-[state=selected]:bg-muted` is a hidden `Selected` layer a copy shows (no prop). `Table/Footer`'s `bg-muted/50` is a `Tint` layer (`muted` at `opacity.50`); its text is `font-weight.medium` on each cell's copy. Hover (`hover:bg-muted/50`) has no twin.
|
|
121
121
|
- **Pagination's buttons are their own boards, not Button copies.** `Button`'s main holds a `Label` only, and a copy can't add an icon, so `Pagination/Link` (`isActive` `true` → outline, `false` → ghost, `icon` size), `Previous`, `Next`, `Ellipsis`, `DataTableColumnHeader`'s trigger, `DataTableViewOptions` and the toolbar's `Reset` are boards carrying Button's tokens for that variant and size. `PaginationItem` is a bare `<li>`, on the drift allowlist. `Pagination` hugs its content where code is `w-full justify-center`; `DataTablePagination` hugs too, so its pagination sits next to the rows-per-page select instead of pushed right, and Previous / Next show no `aria-disabled` fade (no prop to vary).
|
|
122
122
|
- **The data-table primitives twin their resting look.** `DataTableColumnHeader` has a `sort` variant (`none` / `asc` / `desc`) and draws the sortable trigger; the plain-text header (no `onSortChange`) and the trigger's `-ml-3` have no twin, nor does its menu. `DataTableViewOptions` is the trigger only; its menu is a `DropdownMenu` of checkbox items. `DataTableToolbar`'s `Reset` and `DataTablePagination`'s `Rows per page` group are hidden layers a copy shows; the toolbar's `Actions` is an `_internal/Slot`. The filter input is an `Input` copy at 32px tall with `size.xs` on its width.
|
|
123
|
-
- **Calendar is one month, November 2026, and its day states are copy overrides.** react-day-picker holds today, selected, outside and disabled as modifiers, not props, so `CalendarDayButton` is the resting 32×32 ghost day (`radius`, `font-size.sm`) and `Calendar`'s main draws today (9, `muted` fill), the selected day (12, `primary` fill, `primary-foreground` text) and the outside days (December, `muted-foreground` text) as overridden copies. Range, dropdown captions, week numbers and multiple months have no twin. The nav buttons are boards with Button `ghost`'s tokens at `icon` size, as Pagination's are; the absolute nav over a centred caption is a `space-between` header row. Text lines are 18px against code's 16px for `text-xs` weekdays.
|
|
123
|
+
- **Calendar is one month, November 2026, and its day states are copy overrides.** react-day-picker holds today, selected, outside and disabled as modifiers, not props, so `CalendarDayButton` is the resting 32×32 ghost day (`radius-md`, `font-size.sm`) and `Calendar`'s main draws today (9, `muted` fill), the selected day (12, `primary` fill, `primary-foreground` text) and the outside days (December, `muted-foreground` text) as overridden copies. Range, dropdown captions, week numbers and multiple months have no twin. The nav buttons are boards with Button `ghost`'s tokens at `icon` size, as Pagination's are; the absolute nav over a centred caption is a `space-between` header row. Text lines are 18px against code's 16px for `text-xs` weekdays.
|
|
124
124
|
- **DatePicker is the trigger only,** empty (`Pick a date`, icon and label `muted-foreground`), with a `disabled` variant at `opacity.50`. Its `w-72` width stays raw (no sizing token binds it). The popup is a `Popover/Content` holding a `Calendar` copy on a page design.
|
|
125
125
|
- **The dark-mode switch thumb is wrong.** Code's thumb is `dark:bg-foreground` unchecked and `dark:bg-primary-foreground` checked. The twin keeps `background`, so in Dark an unchecked thumb is near-black on the track.
|
|
126
126
|
- **An icon's stroke stays 2px when resized.** lucide scales the stroke with the icon's size; Penpot scales the paths (constraints `scale`) but not the stroke width. A twin that resizes an icon copy sets the copy's stroke width by hand (Checkbox's 14px check: 2 × 14 / 24 ≈ 1.167).
|
package/dist/components/badge.js
CHANGED
|
@@ -10,7 +10,7 @@ const badgeVariants = cva('group/badge inline-flex h-5 w-fit shrink-0 items-cent
|
|
|
10
10
|
variant: {
|
|
11
11
|
default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80',
|
|
12
12
|
secondary: 'bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80',
|
|
13
|
-
destructive: 'bg-destructive
|
|
13
|
+
destructive: 'bg-destructive-background text-destructive focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20',
|
|
14
14
|
outline: 'border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground',
|
|
15
15
|
ghost: 'hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50',
|
|
16
16
|
link: 'text-primary underline-offset-4 hover:underline',
|
|
@@ -10,10 +10,10 @@ const buttonVariants = cva("group/button inline-flex shrink-0 items-center justi
|
|
|
10
10
|
variants: {
|
|
11
11
|
variant: {
|
|
12
12
|
default: 'bg-primary text-primary-foreground hover:bg-primary/80',
|
|
13
|
-
outline: 'border-border bg-background shadow-xs hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:
|
|
13
|
+
outline: 'border-border bg-outline-background shadow-xs hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:hover:bg-input/50',
|
|
14
14
|
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground',
|
|
15
15
|
ghost: 'hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50',
|
|
16
|
-
destructive: 'bg-destructive
|
|
16
|
+
destructive: 'bg-destructive-background text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40',
|
|
17
17
|
link: 'text-primary underline-offset-4 hover:underline',
|
|
18
18
|
},
|
|
19
19
|
size: {
|
|
@@ -7,6 +7,6 @@ import { Checkbox as CheckboxPrimitive } from '@base-ui/react/checkbox';
|
|
|
7
7
|
import { CheckIcon } from 'lucide-react';
|
|
8
8
|
import { cn } from '../lib/utils.js';
|
|
9
9
|
function Checkbox({ className, ...props }) {
|
|
10
|
-
return (_jsx(CheckboxPrimitive.Root, { "data-slot": "checkbox", className: cn('peer relative flex size-4 shrink-0 items-center justify-center rounded-sm border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 data-disabled:cursor-not-allowed data-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary
|
|
10
|
+
return (_jsx(CheckboxPrimitive.Root, { "data-slot": "checkbox", className: cn('peer relative flex size-4 shrink-0 items-center justify-center rounded-sm border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 data-disabled:cursor-not-allowed data-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary bg-input-background dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground group-has-[:focus-visible]/field-label:data-checked:border-primary dark:data-checked:bg-primary', className), ...props, children: _jsx(CheckboxPrimitive.Indicator, { "data-slot": "checkbox-indicator", className: "grid place-content-center text-current transition-none [&>svg]:size-3.5", children: _jsx(CheckIcon, {}) }) }));
|
|
11
11
|
}
|
|
12
12
|
export { Checkbox };
|
|
@@ -54,7 +54,7 @@ function ComboboxSeparator({ className, ...props }) {
|
|
|
54
54
|
return (_jsx(ComboboxPrimitive.Separator, { "data-slot": "combobox-separator", className: cn('-mx-1 my-1 h-px bg-border', className), ...props }));
|
|
55
55
|
}
|
|
56
56
|
function ComboboxChips({ className, ...props }) {
|
|
57
|
-
return (_jsx(ComboboxPrimitive.Chips, { "data-slot": "combobox-chips", className: cn('flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border border-input bg-
|
|
57
|
+
return (_jsx(ComboboxPrimitive.Chips, { "data-slot": "combobox-chips", className: cn('flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border border-input bg-input-background bg-clip-padding px-2.5 py-1.5 text-sm shadow-xs transition-all focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/50 has-aria-invalid:border-destructive has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 has-data-[slot=combobox-chip]:px-1.5 dark:has-aria-invalid:border-destructive/50 dark:has-aria-invalid:ring-destructive/40', className), ...props }));
|
|
58
58
|
}
|
|
59
59
|
function ComboboxChip({ className, children, showRemove = true, ...props }) {
|
|
60
60
|
return (_jsxs(ComboboxPrimitive.Chip, { "data-slot": "combobox-chip", className: cn('flex h-5.5 w-fit items-center justify-center gap-1 rounded-sm bg-muted px-1.5 text-xs font-medium whitespace-nowrap text-foreground has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0', className), ...props, children: [children, showRemove && (_jsx(ComboboxPrimitive.ChipRemove, { "aria-label": "Remove", render: _jsx(Button, { variant: "ghost", size: "icon-xs" }), className: "-ml-1 opacity-50 hover:opacity-100", "data-slot": "combobox-chip-remove", children: _jsx(XIcon, { className: "pointer-events-none" }) }))] }));
|
|
@@ -27,7 +27,7 @@ function DropdownMenuLabel({ className, inset, ...props }) {
|
|
|
27
27
|
return (_jsx(MenuPrimitive.GroupLabel, { "data-slot": "dropdown-menu-label", "data-inset": inset, className: cn('px-2 py-1.5 text-xs font-medium text-muted-foreground data-inset:pl-8', className), ...props }));
|
|
28
28
|
}
|
|
29
29
|
function DropdownMenuItem({ className, inset, variant = 'default', ...props }) {
|
|
30
|
-
return (_jsx(MenuPrimitive.Item, { "data-slot": "dropdown-menu-item", "data-inset": inset, "data-variant": variant, className: cn("group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive
|
|
30
|
+
return (_jsx(MenuPrimitive.Item, { "data-slot": "dropdown-menu-item", "data-inset": inset, "data-variant": variant, className: cn("group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive-background data-[variant=destructive]:focus:text-destructive data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive", className), ...props }));
|
|
31
31
|
}
|
|
32
32
|
function DropdownMenuSub({ ...props }) {
|
|
33
33
|
return _jsx(MenuPrimitive.SubmenuRoot, { "data-slot": "dropdown-menu-sub", ...props });
|
|
@@ -12,7 +12,7 @@ import { Button } from './button.js';
|
|
|
12
12
|
import { Input } from './input.js';
|
|
13
13
|
import { Textarea } from './textarea.js';
|
|
14
14
|
function InputGroup({ className, ...props }) {
|
|
15
|
-
return (_jsx("div", { "data-slot": "input-group", role: "group", className: cn('group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-all outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto
|
|
15
|
+
return (_jsx("div", { "data-slot": "input-group", role: "group", className: cn('group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-all outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto bg-input-background dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5', className), ...props }));
|
|
16
16
|
}
|
|
17
17
|
const inputGroupAddonVariants = cva("flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-sm [&>svg:not([class*='size-'])]:size-4", {
|
|
18
18
|
variants: {
|
package/dist/components/input.js
CHANGED
|
@@ -5,6 +5,6 @@ import { Input as InputPrimitive } from '@base-ui/react/input';
|
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import { cn } from '../lib/utils.js';
|
|
7
7
|
function Input({ className, type, ...props }) {
|
|
8
|
-
return (_jsx(InputPrimitive, { type: type, "data-slot": "input", className: cn('h-9 w-full min-w-0 rounded-md border border-input bg-
|
|
8
|
+
return (_jsx(InputPrimitive, { type: type, "data-slot": "input", className: cn('h-9 w-full min-w-0 rounded-md border border-input bg-input-background px-2.5 py-1 text-base shadow-xs transition-all outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40', className), ...props }));
|
|
9
9
|
}
|
|
10
10
|
export { Input };
|
|
@@ -10,6 +10,6 @@ function RadioGroup({ className, ...props }) {
|
|
|
10
10
|
return (_jsx(RadioGroupPrimitive, { "data-slot": "radio-group", className: cn('grid w-full gap-3', className), ...props }));
|
|
11
11
|
}
|
|
12
12
|
function RadioGroupItem({ className, ...props }) {
|
|
13
|
-
return (_jsx(RadioPrimitive.Root, { "data-slot": "radio-group-item", className: cn('group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 data-disabled:cursor-not-allowed data-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary
|
|
13
|
+
return (_jsx(RadioPrimitive.Root, { "data-slot": "radio-group-item", className: cn('group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 data-disabled:cursor-not-allowed data-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary bg-input-background dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground group-has-[:focus-visible]/field-label:data-checked:border-primary dark:data-checked:bg-primary', className), ...props, children: _jsx(RadioPrimitive.Indicator, { "data-slot": "radio-group-indicator", className: "flex size-4 items-center justify-center", children: _jsx("span", { className: "absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary-foreground" }) }) }));
|
|
14
14
|
}
|
|
15
15
|
export { RadioGroup, RadioGroupItem };
|
|
@@ -15,7 +15,7 @@ function SelectValue({ className, ...props }) {
|
|
|
15
15
|
return (_jsx(SelectPrimitive.Value, { "data-slot": "select-value", className: cn('flex flex-1 text-left', className), ...props }));
|
|
16
16
|
}
|
|
17
17
|
function SelectTrigger({ className, size = 'default', children, ...props }) {
|
|
18
|
-
return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn("flex w-fit items-center justify-between gap-1.5 rounded-md border border-input bg-
|
|
18
|
+
return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn("flex w-fit items-center justify-between gap-1.5 rounded-md border border-input bg-input-background py-2 pr-2 pl-2.5 text-sm whitespace-nowrap shadow-xs transition-all outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, _jsx(SelectPrimitive.Icon, { render: _jsx(ChevronDownIcon, { className: "pointer-events-none size-4 text-muted-foreground" }) })] }));
|
|
19
19
|
}
|
|
20
20
|
function SelectContent({ className, children, side = 'bottom', sideOffset = 4, align = 'center', alignOffset = 0, alignItemWithTrigger = true, ...props }) {
|
|
21
21
|
return (_jsx(SelectPrimitive.Portal, { children: _jsx(SelectPrimitive.Positioner, { side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset, alignItemWithTrigger: alignItemWithTrigger, className: "isolate z-50", children: _jsxs(SelectPrimitive.Popup, { "data-slot": "select-content", "data-align-trigger": alignItemWithTrigger, className: cn('relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95', className), ...props, children: [_jsx(SelectScrollUpButton, {}), _jsx(SelectPrimitive.List, { children: children }), _jsx(SelectScrollDownButton, {})] }) }) }));
|
package/dist/components/tabs.js
CHANGED
|
@@ -31,7 +31,7 @@ function TabsList({ className, variant = 'default', ...props }) {
|
|
|
31
31
|
return (_jsx(TabsPrimitive.List, { "data-slot": "tabs-list", "data-variant": variant, className: cn(tabsListVariants({ variant }), className), ...props }));
|
|
32
32
|
}
|
|
33
33
|
function TabsTrigger({ className, ...props }) {
|
|
34
|
-
return (_jsx(TabsPrimitive.Tab, { "data-slot": "tabs-trigger", className: cn("relative inline-flex h-full flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", 'group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent', 'data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:
|
|
34
|
+
return (_jsx(TabsPrimitive.Tab, { "data-slot": "tabs-trigger", className: cn("relative inline-flex h-full flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", 'group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent', 'data-active:bg-outline-background data-active:text-foreground dark:data-active:border-input dark:data-active:text-foreground', 'after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:-bottom-1 group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100', className), ...props }));
|
|
35
35
|
}
|
|
36
36
|
function TabsContent({ className, ...props }) {
|
|
37
37
|
return (_jsx(TabsPrimitive.Panel, { "data-slot": "tabs-content", className: cn('flex-1 text-sm outline-none', className), ...props }));
|
|
@@ -4,6 +4,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import { cn } from '../lib/utils.js';
|
|
6
6
|
function Textarea({ className, ...props }) {
|
|
7
|
-
return (_jsx("textarea", { "data-slot": "textarea", className: cn('flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-
|
|
7
|
+
return (_jsx("textarea", { "data-slot": "textarea", className: cn('flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-input-background px-2.5 py-2 text-base shadow-xs transition-all outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40', className), ...props }));
|
|
8
8
|
}
|
|
9
9
|
export { Textarea };
|