Files
basecoat/migration-tracker.md
T

47 lines
16 KiB
Markdown

# Basecoat Style Migration Tracker
Track migration of Basecoat components against the latest shadcn/ui v4 component source and all eight style packs.
Upstream source root: `../_sandbox/shadcn-ui`
Upstream style files: `apps/v4/registry/styles/style-{vega,nova,maia,lyra,mira,luma,sera,rhea}.css`
Legend:
- `pending`: not started
- `in-progress`: actively being migrated
- `done`: style-pack coverage implemented for current scope
- `deferred`: intentionally postponed
| Component | Status | Basecoat CSS | Upstream Base | Upstream Styles | Notes |
| --- | --- | --- | --- | --- | --- |
| alert | done | `src/css/components/alert.css` | `apps/v4/registry/bases/base/ui/alert.tsx` | all 8 `style-*.css` | Shared CSS now keeps alert structure only. All eight style files map upstream alert, title, description, action, and destructive/default variants onto Basecoat selectors. Docs include action, custom colors, and RTL. |
| badge | done | `src/css/components/badge.css` | `apps/v4/registry/bases/base/ui/badge.tsx` | all 8 `style-*.css` | Shared CSS now keeps badge structure only. All eight style files map upstream default, secondary, destructive, outline, ghost, and link variants. Docs include custom colors and RTL directional icon guidance. |
| button | done | `src/css/components/button.css` | `apps/v4/registry/bases/base/ui/button.tsx` | all 8 `style-*.css` | Standalone button rules are mapped across all eight styles, including xs sizing and icon-aware padding. Icon-aware padding now uses logical `ps`/`pe` utilities for RTL. Drift fixed: Maia base radius now uses upstream `rounded-4xl`. Docs include RTL guidance; directional icons must opt into `rtl:rotate-180`. |
| button-group | done | `src/css/components/button-group.css` | `apps/v4/registry/bases/base/ui/button-group.tsx` | all 8 `style-*.css` | Shared orientation/focus/adjacency structure remains in component CSS. Horizontal adjacency uses logical start/end border and radius rules for RTL. Style files cover grouped edge radius, nested group gap, text segment styling, separators, and Luma/Sera/Rhea outline input/select border coupling mapped to Basecoat selectors. Docs aligned with upstream sections where applicable and include RTL guidance. |
| card | done | `src/css/components/card.css` | `apps/v4/registry/bases/base/ui/card.tsx` | all 8 `style-*.css` | Shared CSS now keeps semantic card structure. All eight style files map upstream card root, header, title, description, content, footer, image, and `data-size="sm"` styling onto Basecoat selectors. Intentional divergence: card overflow remains visible because Basecoat overlays are inline rather than portalled like shadcn/Radix. Docs include size and RTL. |
| checkbox | done | `src/css/components/checkbox.css` | `apps/v4/registry/bases/base/ui/checkbox.tsx` | all 8 `style-*.css` | Shared CSS now keeps native checkbox structure and masked checkmark only. All eight style files map upstream checkbox root and indicator visuals onto Basecoat native checkbox selectors using `:checked` instead of shadcn `data-checked`. Docs aligned with upstream sections: checked state, invalid, basic, description, disabled, group, table, and RTL. |
| collapsible | deferred | `src/css/components/collapsible.css` | `apps/v4/registry/bases/base/ui/collapsible.tsx` | n/a | Basecoat already ships native `details`/`summary` enhancement CSS. Do not port shadcn/ui Collapsible as a JS component unless a real controlled-state need appears. TODO: add a `Disclosure` docs page for the native pattern with default, open, icon, accordion/group, and RTL examples. |
| combobox | done | `src/css/components/combobox.css` | `apps/v4/registry/bases/base/ui/combobox.tsx` | all 8 `style-*.css` | Added dedicated input-first Combobox CSS, JS, Nunjucks macro, and Jinja macro. All eight style files map upstream combobox content, list, empty state, labels, items, active state, separators, chips, chip remove, and trigger/input visuals onto Basecoat selectors. Intentional divergence: Basecoat uses raw semantic HTML and vanilla JS instead of Base UI Combobox primitives; single selection stores text in the visible input while options can render custom HTML via `data-label`; multiple selection uses chips plus a real input and stores a JSON array in the hidden input. Docs include basic, multiple, groups, custom items, invalid, disabled, auto-highlight, top side, and RTL. |
| command | done | `src/css/components/command.css` | `apps/v4/registry/bases/base/ui/command.tsx` | all 8 `style-*.css` | Shared CSS now keeps command/dialog structure, filtering visibility, empty state, shortcut/indicator slots, and active item behavior only. All eight style files map upstream command root, dialog, input wrapper, input, list, empty state, group, heading, separator, item, active state, and shortcut visuals onto Basecoat selectors. Intentional divergence: Basecoat implements command behavior with vanilla JS and native `<dialog>` rather than `cmdk` and portalled shadcn/ui Dialog. Docs aligned with upstream sections: about, composition, basic, shortcuts, groups, scrollable, RTL, and API guidance. |
| dialog | done | `src/css/components/dialog.css` | `apps/v4/registry/bases/base/ui/dialog.tsx` | all 8 `style-*.css` | Shared CSS now keeps native dialog mechanics, backdrop/open transitions, centered content layout, structural header/body/footer, and close-button structure only. All eight style files map upstream overlay, content, close position, header, footer, title, and description visuals onto Basecoat `.dialog` selectors. Intentional divergence: Basecoat uses the native `<dialog>` element and `showModal()` instead of shadcn/ui's portalled Base UI Dialog. Docs aligned with upstream sections: composition, custom close button, no close button, sticky footer, scrollable content, RTL, and API guidance. |
| dropdown-menu | done | `src/css/components/dropdown-menu.css` | `apps/v4/registry/bases/base/ui/dropdown-menu.tsx` | all 8 `style-*.css` | Shared CSS now keeps structure, roles, disabled states, shortcut/indicator slots, and fallback hover only. All eight style files map upstream content, item, checkbox/radio item, indicator, label, separator, shortcut, destructive, and inset visuals onto Basecoat role/data selectors. Intentional divergence: Basecoat dropdown content remains inline-positioned and does not implement upstream submenus/avatar/complex nested examples yet. Docs aligned with upstream sections for basic, shortcuts, icons, checkboxes, radio, destructive, RTL, and API guidance. |
| empty | done | `src/css/components/empty.css` | `apps/v4/registry/bases/base/ui/empty.tsx` | all 8 `style-*.css` | Added lightweight `.empty` root API using semantic `header`, `figure`, `section`, and `footer` children instead of shadcn slot classes. All eight style files map upstream empty root, header, media/icon, title, description, and content visuals onto Basecoat selectors. Docs now treat Empty as a real Basecoat component and include outline, avatar, avatar group, input group, and RTL examples. |
| field | done | `src/css/components/field.css` | `apps/v4/registry/bases/base/ui/field.tsx` | all 8 `style-*.css` | Shared CSS now covers field, fieldset, semantic field groups, field-description, field-error, and field-separator structure. All eight style files map upstream field visuals onto existing Basecoat selectors, including `cn-field-label` checked/card behavior via `.field > label` and `label:has(> .field)`. Docs include semantic field groups, separator, choice card, responsive layout, and RTL. |
| input | done | `src/css/components/input.css` | `apps/v4/registry/bases/base/ui/input.tsx` | all 8 `style-*.css` | Shared CSS now keeps structural input behavior only. All eight style files map upstream input visuals onto Basecoat `.input` and `.field` selectors. Docs aligned with upstream sections where applicable: basic, field, field group, disabled, invalid, file, inline, grid, required, badge, input group, button group, and form. RTL is supported through native direction handling and logical utility usage in examples. |
| input-group | done | `src/css/components/input-group.css` | `apps/v4/styles/base-*/ui/input-group.tsx` | all 8 `style-*.css` | Added lightweight `.input-group` root API. Children remain semantic native controls and elements; optional `data-align="inline-start|inline-end|block-start|block-end"` maps upstream addon placement without shadcn slot classes. `data-control` is the escape hatch for custom non-native controls. |
| item | done | `src/css/components/item.css` | `apps/v4/registry/bases/base/ui/item.tsx` | all 8 `style-*.css` | Added lightweight `.item` and `.item-group` APIs using semantic `figure`, `section`, `aside`, `header`, and `footer` children instead of shadcn slot classes. All eight style files map upstream item variants, sizes, media, content, title, description, actions, header/footer, group, and separator visuals onto Basecoat selectors. Docs now use the component API and include variants, sizes, icon, avatar, image, group, header, link, and RTL examples. |
| kbd | done | `src/css/components/kbd.css` | `apps/v4/registry/bases/base/ui/kbd.tsx` | all 8 `style-*.css` | Added `kbd-group` and mapped upstream kbd/kbd-group styles across all eight style files. Docs include button, input-group, and RTL examples. |
| label | done | `src/css/components/label.css` | `apps/v4/registry/bases/base/ui/label.tsx` | all 8 `style-*.css` | Shared CSS now keeps label structure and disabled behavior. All eight style files map upstream label visuals. Sera control-label exceptions are mapped with Basecoat native input selectors instead of shadcn peer data-slot selectors. Docs include RTL. |
| native-select | done | `src/css/components/native-select.css` | `apps/v4/registry/bases/base/ui/native-select.tsx` | all 8 `style-*.css` | Shared CSS now keeps native select structure only. All eight style files map upstream native select visuals onto Basecoat `select.select` and `.field select`, using a CSS background chevron instead of upstream's wrapper icon element. Intentional divergence: direct selects stay `w-fit` by default because Basecoat has no `w-fit` wrapper; width utilities remain supported. Docs split Native Select from custom Select and include groups, disabled, invalid, size, RTL, and API guidance. |
| popover | done | `src/css/components/popover.css` | `apps/v4/registry/bases/base/ui/popover.tsx` | all 8 `style-*.css` | Shared CSS now keeps positioning, visibility, side, and align behavior only. All eight style files map upstream popover content/header/title/description visuals onto Basecoat `[data-popover]` and semantic header selectors. Intentional divergence: Basecoat popover remains inline-positioned relative to `.popover` rather than portalled through Base UI; animation utilities from upstream are omitted because this Tailwind setup does not include shadcn animation utilities. Docs aligned with upstream sections: composition, basic, align, form, RTL, and API guidance. |
| radio | done | `src/css/components/radio.css` | `apps/v4/registry/bases/base/ui/radio-group.tsx` | all 8 `style-*.css` | Shared CSS now keeps native radio structure and checked dot only. All eight style files map upstream radio group/item/indicator visuals onto Basecoat native radio selectors using `:checked` instead of shadcn `data-checked`. Docs aligned with upstream sections: checked state, invalid, basic, description, choice card, fieldset, disabled, invalid, and RTL. |
| range | done | `src/css/components/range.css` + `src/js/range.js` | `apps/v4/registry/bases/base/ui/slider.tsx` | all 8 `style-*.css` | Shared CSS keeps native range structure and gradient fill. Added `range.js` to sync `--slider-value`. All eight style files map upstream slider track/thumb visuals onto native range pseudo-elements. Intentional divergence: Basecoat uses native single-thumb range inputs, so upstream multi-thumb and vertical slider examples are not supported. Docs updated with default, controlled label, disabled, RTL, and divergence note. |
| select | done | `src/css/components/select.css` | `apps/v4/registry/bases/base/ui/select.tsx` | all 8 `style-*.css` | Shared CSS now keeps custom select structure, listbox behavior selectors, selected checkmark background, and empty state only. All eight style files map upstream trigger, value, content, label, group, item, active state, and separator visuals onto Basecoat selectors. Intentional divergences: Basecoat keeps inline popover positioning below the trigger rather than shadcn/ui's selected-item-over-trigger alignment and retains multiselect as Basecoat API surface. Combobox-specific search-header support has been removed from Select and moved to the dedicated Combobox component. Docs aligned with upstream sections where applicable: align, groups, scrollable, disabled, invalid, RTL, plus Basecoat multiselect. |
| sidebar | done | `src/css/components/sidebar.css` | `apps/v4/registry/bases/base/ui/sidebar.tsx` | `style-*.css` | Mapped upstream sidebar visuals onto Basecoat's simpler semantic sidebar. Intentional differences: no React provider, rail, inset/floating variants, icon-only collapse, menu actions, badges, or sidebar skeleton API. |
| skeleton | done | `src/css/components/skeleton.css` | `apps/v4/registry/bases/base/ui/skeleton.tsx` | all 8 `style-*.css` | Added dedicated `skeleton` class. All eight style files map upstream skeleton visuals. Docs now use `skeleton` instead of raw utility-only examples and include avatar, card, text, form, table, and RTL examples. |
| switch | done | `src/css/components/switch.css` | `apps/v4/registry/bases/base/ui/switch.tsx` | all 8 `style-*.css` | Shared CSS now keeps native checkbox-as-switch structure and pseudo-thumb only. All eight style files map upstream switch track/thumb visuals onto Basecoat native switch selectors using `:checked`, `data-size`, and explicit `:dir(rtl)` thumb transforms. Docs aligned with upstream sections: checked state, invalid, basic, description, choice card, disabled, invalid, size, and RTL. |
| table | done | `src/css/components/table.css` | `apps/v4/registry/bases/base/ui/table.tsx` | all 8 `style-*.css` | Added `table-container` and mapped upstream table root, header, body, footer, row, cell, head, and caption styles across all eight style files using logical alignment. Docs include footer, actions, and RTL. |
| tabs | done | `src/css/components/tabs.css` | `apps/v4/registry/bases/base/ui/tabs.tsx` | all 8 `style-*.css` | Shared CSS now keeps tabs layout, role structure, and panel structure only. All eight style files map upstream default and line variants, horizontal/vertical orientation, active state, icon sizing, and content text styles onto Basecoat role selectors. JS now skips disabled tabs and supports vertical ArrowUp/ArrowDown navigation. Docs aligned with upstream sections: composition, line, vertical, disabled, icons, RTL, and API guidance. |
| textarea | done | `src/css/components/textarea.css` | `apps/v4/registry/bases/base/ui/textarea.tsx` | all 8 `style-*.css` | Shared CSS now keeps structural textarea behavior only. All eight style files map upstream textarea visuals onto Basecoat `.textarea` and `.field` selectors. Docs aligned with upstream sections where applicable: field, disabled, invalid, button, and form. RTL is supported through native direction handling. |
| toast | done | `src/css/components/toast.css` | `apps/v4/registry/bases/base/ui/sonner.tsx` | all 8 `style-*.css` | Shared CSS keeps toaster positioning, toast lifecycle layout, icons/content/footer structure, and hide animation. All eight style files map upstream Sonner toast radius onto Basecoat `.toast-content`. Intentional divergence: Basecoat keeps its vanilla JS toast API and does not depend on Sonner. |
| tooltip | done | `src/css/components/tooltip.css` | `apps/v4/registry/bases/base/ui/tooltip.tsx` | all 8 `style-*.css` | Shared CSS keeps CSS-only tooltip trigger, positioning, visibility, side, align, and logical inline side behavior. All eight style files map upstream tooltip content radius/spacing/typography and optional arrow radius onto Basecoat `data-tooltip` selectors. Intentional divergence: Basecoat tooltips are text-only CSS tooltips and are not portalled composed content like upstream. Docs updated with sides, disabled trigger wrapper, link, icon button, RTL, and divergence note. |