2.0 is rebuilt on the ArtisanPack UI design system. The components keep their purpose, and three things change underneath them: - DaisyUI is gone...
@artisanpack-ui/react 2.0 is rebuilt on the ArtisanPack UI design system. The components keep their purpose, and three things change underneath them:
- DaisyUI is gone. Components are styled by
@artisanpack-ui/css: plain CSS in cascade layers, driven by design tokens. Tailwind is optional.
- One API across Livewire, React and Vue. Some components, props and events were renamed to match. Most 1.x exports still work in 2.0, marked
@deprecated, so an app keeps building while you migrate, but they go in the next major.
- Theming is tokens.
@artisanpack-ui/tokens 2.0 replaces the DaisyUI color maps with presets built on the tokens.
The codemod does the mechanical part. This guide covers it and what is left for you.
How long the old version is supported
The previous major gets security fixes only for 12 months after the new one ships. No features or component fixes are backported. Each repository's SECURITY.md carries the end date from launch day.
The old and new majors can't be mixed in one app: the new CSS replaces DaisyUI, and the two style the same components differently. Upgrade a whole app at once, on a branch.
1. Update the packages
Commit your work first, then:
npm install @artisanpack-ui/react@^2 @artisanpack-ui/css
npm uninstall daisyui
2. Run the codemod
Preview the changes:
npx @artisanpack-ui/codemods react src --dry-run
The dry run prints a diff of every file it would change and writes nothing. Run it without --dry-run to apply them:
npx @artisanpack-ui/codemods react src
| Option |
What it does |
| paths |
Files or directories to migrate. Default: src |
--dry-run |
Show the changes as a diff without writing |
--no-classes |
Leave raw DaisyUI classes out of the report |
--json |
Print the report as JSON |
It reads .tsx, .jsx, .ts and .js files and skips node_modules, build output and dot-directories. It edits in place and keeps your formatting and comments; run your formatter afterwards if a rewritten line runs long.
What it rewrites. Imports from @artisanpack-ui/react and its entry points (/form, /layout, …), with every reference to a renamed component and its Props type; renamed props and events on JSX elements; flags that became values (vertical to orientation="vertical"); values that changed with the name (position="left" to placement="start"); and per-part class props, merged into classes. It follows aliases (Modal as Sheet) and namespace imports (UI.Modal).
What it reports and leaves alone. Each line of the report has the file, line and column:
| Label |
Meaning |
manual |
A prop, event or component with no automatic replacement. The message says what to do |
review |
A change that was made and deserves a look: a renamed event whose payload changed, or a dynamic value the codemod couldn't read |
removed |
A prop that was deleted because 2.0 has no equivalent |
class |
A raw DaisyUI class, theme variable or DaisyUI configuration. See step 3 |
It can't see through a spread (<Modal {...props} />) or a dynamic value (vertical={isTall}); both are reported. You can run the codemod again after you fix things by hand: migrated code has nothing left for it to rewrite. The exception is a 1.x name that 2.0 reuses with a new meaning, such as label on Code. Preview a second run with --dry-run.
3. Remove DaisyUI and adopt the new CSS
Load the CSS once. Without Tailwind, import it in your app's entry:
import '@artisanpack-ui/css';
With Tailwind v4, import it from your Tailwind entry stylesheet instead. Declare the layer order first, so Preflight never restyles a component and a utility on a component still wins. The last import is optional: it adds utilities generated from the tokens (bg-surface-page, text-muted, rounded-control).
@layer theme, base, apui, components, utilities;
@import 'tailwindcss';
@import '@artisanpack-ui/css';
@import '@artisanpack-ui/css/tailwind';
Then delete @plugin "daisyui"; and any @plugin "daisyui/theme" block from your CSS.
To bring your own styles, import @artisanpack-ui/css/headless instead: the same markup, ARIA and behavior with no component CSS.
Replace raw DaisyUI classes
Markup that used DaisyUI classes directly (btn, card, badge, bg-base-200) has no styles once DaisyUI is gone. The upgrade tool lists every one with its file and line and never rewrites them, because the right replacement depends on the element. For each:
| You have |
Use instead |
A component class: btn, badge, card, alert, tab, modal, tooltip, … |
The component. <a class="btn btn-primary"> is a Button with href. Where you need the bare markup, the apui- class and data attributes: class="apui-button" data-color="primary" |
A size or color modifier: btn-sm, badge-success, alert-warning |
The component's size and color props (data-size, data-color on bare markup) |
input, select, textarea, checkbox, toggle, label on native controls |
The form components, which draw the label, hint and error too |
bg-base-100 |
bg-surface-default with the Tailwind preset, or background: var(--apui-surface-default) |
bg-base-200 |
bg-surface-sunken · var(--apui-surface-sunken) |
bg-base-300, border-base-300 |
border-default · var(--apui-border-default); as a background, bg-surface-sunken |
text-base-content |
text-default · var(--apui-text-default) |
text-base-content/70, /60, /50 |
text-muted · var(--apui-text-muted). text-subtle for the faintest text. Opacity on text is gone: the tokens are checked for contrast, an opacity isn't |
text-primary-content, text-error-content, … |
The color's own foreground: text-primary-foreground, text-error-foreground · var(--apui-color-primary-foreground), var(--apui-color-error-foreground) |
bg-primary, text-error, border-success |
Unchanged with the Tailwind preset. Without Tailwind, the color's own token: var(--apui-color-primary), var(--apui-color-error), var(--apui-color-success) |
rounded-box, rounded-btn |
rounded-surface, rounded-control · var(--apui-radius-surface), var(--apui-radius-control) |
The tool marks names such as input, table, link and label as "may be": they are DaisyUI classes and also common class names of your own. Check each.
Left and right are logical now. Use ms-*, me-*, ps-*, pe-*, start-* and end-* next to components so layouts mirror in right-to-left languages.
4. Migrate your theme
@artisanpack-ui/tokens 1.x shipped DaisyUI color maps, cn(), resolveColor(), glass helpers and a Tailwind plugin. 2.0 replaces all of them with the design tokens as --apui-* custom properties, which @artisanpack-ui/css already includes. Remove the 1.x Tailwind plugin from your config and any imports of those helpers.
A brand is a preset. The generator ships with the tokens package, so install it, then generate a preset from your colors:
npm install --save-dev @artisanpack-ui/tokens@^2
npx apui-generate-preset --name acme --primary "#7c3aed" > acme.css
The generator refuses a preset that fails WCAG 2.2 AA contrast in any theme. Import the file after @artisanpack-ui/css and switch it on with <html data-preset="acme">.
The theme lives in data-theme on <html>. ThemeToggle sets and stores it and reports a change as onValueChange; its modes prop is now choices. Render ThemeScript in the document head to apply the stored theme before first paint.
Repoint theme variables
DaisyUI's custom properties are gone, and nothing aliases them. The tool lists each reference:
| DaisyUI |
Token |
--color-base-100 |
--apui-surface-default |
--color-base-200 |
--apui-surface-sunken |
--color-base-300 |
--apui-border-default |
--color-base-content |
--apui-text-default |
--color-primary, --color-error, … |
--apui-color-primary, --apui-color-error, … |
--color-primary-content |
--apui-color-primary-foreground |
--radius-box |
--apui-radius-surface |
--radius-field |
--apui-radius-field |
--radius-selector |
--apui-radius-control |
var(--p), var(--b1), var(--bc) (DaisyUI 4) |
The same tokens as above |
--color-* is also a Tailwind theme namespace, so some of these may be yours and not DaisyUI's. The tool can't tell; you can.
Themes and presets
| Before |
Now |
data-theme="light" or a DaisyUI theme name |
data-theme="light", "dark" or "high-contrast". With no attribute the page follows the system setting |
| A custom DaisyUI theme, or a generated theme file |
A preset: a named set of token values switched with data-preset. ledger and harbor ship with the CSS |
| Glass props with tints and opacities |
surface="glass" on the component; the look comes from the glass tokens |
| Per-component color overrides |
Tokens. Set --apui-color-primary and the rest once, in a preset |
Theme, preset and density (data-density="compact") combine, and any element can set them for its subtree.
5. Renamed and consolidated components
| 1.x |
Now |
Notes |
<Dropdown> |
<DropdownMenu> |
|
<DropdownItem> |
By hand |
Use DropdownMenuItem, which needs a value; the menu reports the choice through onSelect. |
<Editor> |
<CodeEditor> |
|
<ErrorDisplay> |
<ErrorState> |
|
<Modal> |
<Dialog> |
|
<Radio> |
<RadioGroup> |
|
<Sidebar> |
By hand |
Use AppShell, the whole page frame, with a Menu in its sidebar slot. |
<SpotlightSearch> |
<Spotlight> |
|
<StatGroup> |
<Grid> |
|
<ToastMessage> |
By hand |
Use Toast, which takes title, description and color instead of a toast object. |
<ToastProvider> |
By hand |
Render one <Toaster /> instead of wrapping the app, and create toasts with toast.create(). |
6. Changes by component
Every 1.x prop and event that changed. "Automatic" says whether the codemod makes the change for you.
<Accordion>
| 1.x |
2.0 |
Automatic |
openIndices |
Now value. |
Yes |
defaultOpenIndices |
Now defaultValue. |
Yes |
join |
Remove join. If it was join={false} (separate panels), use variant="separated". |
By hand |
onOpenChange |
The onOpenChange event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
<Alert>
| 1.x |
2.0 |
Automatic |
visible |
Removed. Alert dismisses itself; listen to open-change. |
Yes |
onDismiss |
Now onOpenChange. Check the handler: the payload is boolean. |
Yes, to review |
<Avatar>
| 1.x |
2.0 |
Automatic |
image |
Now src. |
Yes |
placeholder |
Now name. |
Yes |
ring |
Removed. Avatar has no ring in 2.0. |
Yes |
online |
Now status="online". |
Yes |
offline |
Now status="offline". |
Yes |
subtitle |
Avatar no longer renders a title or subtitle. Render the text beside it, for example in a ListItem (title, description, leading). |
By hand |
<Badge>
| 1.x |
2.0 |
Automatic |
outline |
Now variant="outline". |
Yes |
| 1.x |
2.0 |
Automatic |
label |
Pass the text as children instead of label. |
By hand |
link |
Now href. |
Yes |
external |
Set target="_blank" and rel="noopener noreferrer" alongside href. |
By hand |
badge |
Render a Badge inside the button's children. |
By hand |
badgeClasses |
Button has no badge part. Style it with class, or a classes key: root, icon, iconEnd, label, spinner. |
By hand |
responsive |
Removed. The label is no longer hidden on small screens; use iconOnly with an aria-label for an icon-only button. |
Yes |
tooltip |
Wrap the button in <Tooltip content="…">. |
By hand |
tooltipPosition |
Set placement on the wrapping Tooltip (logical values such as top, bottom, start, end). |
By hand |
iconRight |
Now iconEnd. |
Yes |
<Calendar>
| 1.x |
2.0 |
Automatic |
value |
Now date. |
Yes |
weekStartsOnSunday |
Now weekStartsOn. |
Yes |
highlightWeekends |
Removed. |
Yes |
highlightToday |
Removed. Today is always marked. |
Yes |
minDate |
Remove it: the calendar no longer limits dates (the prop is still accepted but ignored). |
By hand |
maxDate |
Remove it: the calendar no longer limits dates (the prop is still accepted but ignored). |
By hand |
color |
Set color on each entry in events instead (the prop is still accepted but ignored). |
By hand |
renderDay |
Removed, with no replacement. |
By hand |
<Carousel>
| 1.x |
2.0 |
Automatic |
showIndicators |
Removed. |
Yes |
showArrows |
Removed. |
Yes |
<Chart>
| 1.x |
2.0 |
Automatic |
data |
Now series. |
Yes |
color |
Remove it: Chart has no color prop; series colors come from the theme. |
By hand |
options |
Removed, with no replacement. |
By hand |
showLegend |
Removed. The legend shows for two or more series. |
Yes |
animated |
Removed. Chart draws its own SVG and has no animation switch. |
Yes |
<Checkbox>
| 1.x |
2.0 |
Automatic |
right |
Removed. The label position is fixed by the design system. |
Yes |
hint |
Now description. |
Yes |
color |
Remove it: Checkbox has no color prop in 2.0. |
By hand |
card |
A single Checkbox has no card layout. Use CheckboxGroup with variant="cards". |
By hand |
cardClass |
Gone with card. With CheckboxGroup variant="cards", style the cards through classes. |
By hand |
<Clipboard>
| 1.x |
2.0 |
Automatic |
text |
Now value. |
Yes |
successLabel |
Now copiedLabel. |
Yes |
successDuration |
Now timeout. |
Yes |
color |
Removed, with no replacement. |
By hand |
onCopy |
Now onCopied. onCopied; onCopy stays a deprecated alias. |
Yes, to review |
<Code>
| 1.x |
2.0 |
Automatic |
label |
Now fileName. |
Yes |
hint |
Remove it and render the text under the code block yourself. |
By hand |
showLineNumbers |
Now numbered. |
Yes |
maxHeight |
Removed, with no replacement. |
By hand |
<Collapse>
| 1.x |
2.0 |
Automatic |
icon |
Remove it: the indicator icon is fixed. Style it through classes.icon. |
By hand |
name |
Removed, with no replacement. |
By hand |
bordered |
Removed. The look comes from variant (section or read-more). |
Yes |
title |
Now label. |
Yes |
<ColorPicker>
| 1.x |
2.0 |
Automatic |
clearable |
Removed. There is no clear button in 2.0. |
Yes |
random |
Removed. There is no random-color button in 2.0. |
Yes |
icon |
Remove it: the field shows its own swatch trigger. |
By hand |
iconRight |
Remove it: the field has no trailing icon. |
By hand |
randomIcon |
Remove it: the random-color button is gone. |
By hand |
onClear |
The onClear event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
onRandomColor |
The onRandomColor event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
<DatePicker>
| 1.x |
2.0 |
Automatic |
inline |
Removed. The floating/inline label is gone; the label sits above the field. |
Yes |
dateType |
dateType="datetime-local" becomes the time prop; for time, month and week use <Input type="…">; date is the default, so remove it. |
By hand |
icon |
Remove it: DatePicker has no icon props. |
By hand |
iconRight |
Remove it: DatePicker has no icon props. |
By hand |
<Diff>
| 1.x |
2.0 |
Automatic |
oldLabel |
Removed, with no replacement. |
By hand |
newLabel |
Removed, with no replacement. |
By hand |
mode |
Use view (unified · split). |
By hand |
<Divider>
| 1.x |
2.0 |
Automatic |
vertical |
Now orientation="vertical". |
Yes |
color |
Use strength. |
By hand |
labelPosition |
Now align. |
Yes |
<Drawer>
| 1.x |
2.0 |
Automatic |
end |
Now side="end". |
Yes |
persistent |
No equivalent: Escape and the backdrop always close the drawer. hideClose only hides the close button. |
By hand |
onClose |
Now onOpenChange. Check the handler: the payload is boolean. |
Yes, to review |
| 1.x |
2.0 |
Automatic |
label |
Unchanged. Still the trigger's text. |
Yes |
end |
Now align="end". |
Yes |
top |
Remove it: DropdownMenu has no prop to open above the trigger. |
By hand |
hover |
Removed. The menu opens on click and from the keyboard only. |
Yes |
trigger |
DropdownMenu renders its own trigger button. Pass the trigger's content as label. |
By hand |
<EmptyState>
| 1.x |
2.0 |
Automatic |
heading |
Now title. |
Yes |
headingAs |
Now headingLevel. |
Yes |
action |
Now actions. |
Yes |
<ErrorDisplay> → <ErrorState>
| 1.x |
2.0 |
Automatic |
message |
Now description. |
Yes |
retryLabel |
Render the retry button yourself in actions, for example actions={<Button onClick={retry}>Try again</Button>}. |
By hand |
onRetry |
The onRetry event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
<File>
| 1.x |
2.0 |
Automatic |
withDragDrop |
Removed. The drop zone is always on. Use variant="compact" for the plain row. |
Yes |
dragDropText |
Now title. |
Yes |
dragDropClass |
Use classes={{ dropzone: "…" }}. |
By hand |
progress |
Progress is per file: set progress on the entries you pass in value. |
By hand |
hideProgress |
Removed. A progress bar shows only for value entries that have progress. |
Yes |
onFilesSelected |
The onFilesSelected event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
<Grid>
| 1.x |
2.0 |
Automatic |
cols |
Now columns. |
Yes |
colsSm |
Use minItemWidth for responsive columns. |
By hand |
colsMd |
Use minItemWidth. |
By hand |
colsLg |
Use minItemWidth. |
By hand |
colsXl |
Use minItemWidth. |
By hand |
gapX |
One gap step. |
By hand |
gapY |
One gap step. |
By hand |
<Icon>
| 1.x |
2.0 |
Automatic |
path |
Removed, with no replacement. |
By hand |
viewBox |
Removed, with no replacement. |
By hand |
| 1.x |
2.0 |
Automatic |
clearable |
Removed. Input has no clear button in 2.0. If you need one, render your own. |
Yes |
inline |
Removed. The floating/inline label is gone; the label sits above the field. |
Yes |
iconRight |
Now iconEnd. |
Yes |
onClear |
The onClear event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
<Markdown>
| 1.x |
2.0 |
Automatic |
renderMarkdown |
Removed, with no replacement. |
By hand |
| 1.x |
2.0 |
Automatic |
activeKey |
Mark the active item with current (on the items entry or on MenuItem). Sub-menus holding it open by default. |
By hand |
horizontal |
Not in the 2.0 API (planned as orientation). Remove it, or check the component's docs for what replaces it. |
By hand |
color |
Remove it: Menu has no color prop in 2.0. |
By hand |
size |
Remove it: Menu has no size prop in 2.0. |
By hand |
compact |
Removed. Menu spacing follows the design system. |
Yes |
<Modal> → <Dialog>
| 1.x |
2.0 |
Automatic |
subtitle |
Now description. |
Yes |
persistent |
No single equivalent: role="alertdialog" stops backdrop clicks closing it and hideClose hides the close button, but Escape still closes it. |
By hand |
glass |
Now surface="glass". |
Yes |
bottom |
Dialog has no bottom-sheet mode. Use Drawer with side="bottom". |
By hand |
actions |
Now footer. |
Yes |
onClose |
Now onOpenChange. Check the handler: the payload is boolean. |
Yes, to review |
<Navbar>
| 1.x |
2.0 |
Automatic |
glass |
Now surface="glass". |
Yes |
start |
Now brand. |
Yes |
center |
Pass the links as links or NavbarItem children; a search field goes in search. |
By hand |
end |
Now actions. |
Yes |
| 1.x |
2.0 |
Automatic |
currentPage |
Now page. |
Yes |
totalPages |
Now pageCount. |
Yes |
size |
Remove it: Pagination has no size prop in 2.0. |
By hand |
<Password>
| 1.x |
2.0 |
Automatic |
inline |
Removed. The floating/inline label is gone; the label sits above the field. |
Yes |
clearable |
Removed. Password has no clear button in 2.0. |
Yes |
hideToggle |
The reveal button is always shown in 2.0. Use Input type="password" if you need a field without it. |
By hand |
hiddenIcon |
Remove it: the reveal button's icons are built in. |
By hand |
visibleIcon |
Remove it: the reveal button's icons are built in. |
By hand |
onClear |
The onClear event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
<Pin>
| 1.x |
2.0 |
Automatic |
numeric |
Now type="numeric". |
Yes |
hide |
Now mask. |
Yes |
color |
Remove it: Pin has no color prop in 2.0. |
By hand |
onIncomplete |
The onIncomplete event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
<Popover>
| 1.x |
2.0 |
Automatic |
triggerMode |
Popover opens on click; hover is Tooltip's job. |
By hand |
position |
Now placement. Values: left is now start, right is now end. left and right are now start and end. |
Yes |
showDelay |
Removed, with no replacement. |
By hand |
hideDelay |
Removed, with no replacement. |
By hand |
persistent |
Removed. |
Yes |
<Progress>
| 1.x |
2.0 |
Automatic |
showValue |
Removed. Use label and valueText. |
Yes |
<Radio> → <RadioGroup>
| 1.x |
2.0 |
Automatic |
color |
Remove it: RadioGroup has no color prop. |
By hand |
optionValue |
Map your options to { value, label, description } objects; the key props are gone. |
By hand |
optionLabel |
Map your options to { value, label, description } objects; the key props are gone. |
By hand |
optionHint |
Map your options to { value, label, description } objects; the hint is each option's description. |
By hand |
inline |
Now orientation="horizontal". |
Yes |
card |
Now variant="cards". |
Yes |
cardClass |
Use classes={{ item: "…" }} with variant="cards". |
By hand |
<RichTextEditor>
| 1.x |
2.0 |
Automatic |
minHeight |
Remove it: minHeight is gone. Set a min-height in CSS through classes if you need one. |
By hand |
<Select>
| 1.x |
2.0 |
Automatic |
placeholderValue |
Remove it: the placeholder option always has an empty value. |
By hand |
inline |
Removed. The inline label is gone; the label sits above the field. |
Yes |
optionValue |
Map your options to { value, label } objects (or strings); the key props are gone. |
By hand |
optionLabel |
Map your options to { value, label } objects (or strings); the key props are gone. |
By hand |
iconRight |
Remove it: Select only takes a leading icon; the end holds the built-in indicator. |
By hand |
<Skeleton>
| 1.x |
2.0 |
Automatic |
circle |
Now shape="circle". |
Yes |
<Sparkline>
| 1.x |
2.0 |
Automatic |
type |
Now variant. |
Yes |
color |
Remove it: Sparkline has no color prop; style it through classes or CSS. |
By hand |
strokeWidth |
Remove it: the stroke width is set by the design system. |
By hand |
curve |
Removed. Lines are drawn by the shared geometry; there is no curve switch. |
Yes |
fillOpacity |
Remove it: use variant="area" for a fill; its opacity is set by the design system. |
By hand |
showTooltip |
Removed. Sparkline has no hover tooltip; it is described by label. |
Yes |
<SpotlightSearch> → <Spotlight>
| 1.x |
2.0 |
Automatic |
items |
Use groups: wrap the items as [{ label, items }] and rename item fields to the SpotlightResult shape (label, description, href, icon, keywords). |
By hand |
filterFn |
No custom filter. Set remote, track the query with search/onSearchChange, and pass already-filtered groups. |
By hand |
maxResults |
Remove it: there is no result cap. Limit the items you pass (with remote if you filter yourself). |
By hand |
emptyMessage |
Now emptyLabel. |
Yes |
onClose |
Now onOpenChange. Check the handler: the payload is boolean. |
Yes, to review |
<Stack>
| 1.x |
2.0 |
Automatic |
direction |
Now orientation. |
Yes |
<Stat>
| 1.x |
2.0 |
Automatic |
changeLabel |
Now description. |
Yes |
sparklineData |
Use KpiCard's sparkline. |
By hand |
sparklineType |
Removed, with no replacement. |
By hand |
sparklineColor |
Removed, with no replacement. |
By hand |
title |
Now label. |
Yes |
actions |
Remove it: Stat has no actions area. Put the controls beside the Stat, for example in a Card. |
By hand |
<StatGroup> → <Grid>
| 1.x |
2.0 |
Automatic |
horizontal |
Removed. React StatGroup: a row of stats is a Grid with columns. |
Yes |
<Steps>
| 1.x |
2.0 |
Automatic |
currentStep |
Use value, which counts from 1: currentStep={n} becomes value={n + 1}. |
By hand |
vertical |
Now orientation="vertical". |
Yes |
color |
Remove it: Steps has no color prop. Use a step's state for an error step. |
By hand |
size |
Remove it: Steps has no size prop in 2.0. |
By hand |
<Table>
| 1.x |
2.0 |
Automatic |
striped |
Removed. |
Yes |
hoverable |
Removed. |
Yes |
compact |
Now density="compact". |
Yes |
size |
Use density (compact, default or comfortable). size is still accepted but ignored. |
By hand |
noHeaders |
Now hideHeaders. |
Yes |
selectedKeys |
Now value. |
Yes |
selectableKey |
Now keyBy. |
Yes |
expandableKey |
Now keyBy. |
Yes |
containerClassName |
Now the root key of classes. |
Yes |
onSort |
Now onSortChange. Check the handler: the payload is { column: string; direction: 'asc' | 'desc' }. |
Yes, to review |
onSelectionChange |
Now onValueChange. Check the handler: the payload is Array<string | number>. |
Yes, to review |
<Tabs>
| 1.x |
2.0 |
Automatic |
activeTab |
Now value. |
Yes |
defaultTab |
Now defaultValue. |
Yes |
vertical |
Now orientation="vertical". |
Yes |
verticalRight |
Removed. Covered by orientation and logical placement. |
Yes |
color |
Remove it: Tabs has no color prop. Choose the look with variant (segmented or underline). |
By hand |
tabListClassName |
Now the list key of classes. |
Yes |
panelClassName |
Now the content key of classes. |
Yes |
activeTabClassName |
Tabs has no activeTab part. Style it with class, or a classes key: root, list, trigger, icon, count, content. |
By hand |
onChange |
Now onValueChange. Check the handler: the payload is string. |
Yes, to review |
<Textarea>
| 1.x |
2.0 |
Automatic |
inline |
Removed. The inline label is gone; the label sits above the field. |
Yes |
<ThemeToggle>
| 1.x |
2.0 |
Automatic |
modes |
Now choices. |
Yes |
<Timeline>
| 1.x |
2.0 |
Automatic |
vertical |
Removed. Timelines are vertical. |
Yes |
compact |
Removed. |
Yes |
snap |
Removed. |
Yes |
<Toggle>
| 1.x |
2.0 |
Automatic |
right |
Removed. The label position is fixed by the design system. |
Yes |
hint |
Now description. |
Yes |
| 1.x |
2.0 |
Automatic |
tip |
Now content. |
Yes |
position |
Now placement. Values: left is now start, right is now end. left and right are now start and end. |
Yes |
color |
Tooltips use the inverse surface; tooltip-<color> is removed. |
By hand |
7. After the codemod
- Work through the
manual lines of the report, then the class lines.
- Events. Value and open changes are
onValueChange and onOpenChange. The codemod renames handlers and marks each for review, because the payload is now the value and not a DOM event.
- Toasts.
ToastProvider no longer wraps the app. Render one Toaster and create toasts with toast.create().
- Left and right. Placement and side props take
start and end, so layouts mirror in right-to-left languages.
- Run the type checker: every prop the codemod left behind is a type error that points at the line.
- Look at each page in light, dark and high-contrast themes.