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/vue 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/vue@^2 @artisanpack-ui/css
npm uninstall daisyui
2. Run the codemod
Preview the changes:
npx @artisanpack-ui/codemods vue 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 vue 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 |
--global |
Also migrate tags of components registered globally, which no file imports |
--json |
Print the report as JSON |
It reads .vue, .ts, .js, .tsx and .jsx 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. In <script>, imports from @artisanpack-ui/vue and every reference to a renamed component, including a components option. In <template>, tags in PascalCase or kebab-case, props (bound or not, in the case you wrote them), events, v-model arguments and slots. 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) are rewritten too. Only tags a file imports from the package are touched, unless you pass --global.
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 v-bind="props" or a dynamic value (:vertical="isTall"); both are reported. Templates in other languages, such as Pug, are not rewritten. 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 update:modelValue. 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 select. |
<Editor> |
<CodeEditor> |
|
<ErrorDisplay> |
<ErrorState> |
|
<FileUpload> |
<File> |
|
<Modal> |
<Dialog> |
|
<Radio> |
<RadioGroup> |
|
<Sidebar> |
By hand |
Use AppShell, the whole page frame, with a Menu in its sidebar slot. |
<SpotlightSearch> |
<Spotlight> |
|
<ToastMessage> |
By hand |
Use Toast; timed toasts come from toast.create() and render in a Toaster. |
<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, slot and event that changed. "Automatic" says whether the codemod makes the change for you.
<Accordion>
| 1.x |
2.0 |
Automatic |
open-indices |
Now model-value. |
Yes |
default-open-indices |
Use v-model. |
By hand |
join |
Remove it: panels share one container by default. If you passed :join="false", use variant="separated" instead. |
By hand |
@update:openIndices |
Now @update:modelValue. Check the handler: the payload is string[]. |
Yes, to review |
<Alert>
| 1.x |
2.0 |
Automatic |
visible |
Removed. Alert dismisses itself; listen to open-change. |
Yes |
@dismiss |
Now @open-change. Check the handler: the payload is boolean. |
Yes, to review |
<Avatar>
| 1.x |
2.0 |
Automatic |
online |
Now status="online". |
Yes |
offline |
Now status="offline". |
Yes |
ring |
Removed: Avatar has no ring. Delete it, or draw the ring with your own class on the avatar. |
By hand |
<Badge>
| 1.x |
2.0 |
Automatic |
outline |
Now variant="outline". |
Yes |
ghost |
Now variant="ghost". |
Yes |
<Breadcrumbs>
| 1.x |
2.0 |
Automatic |
#item |
The item slot is gone. Use the scoped link slot ({ item, href, attrs }, bind attrs) to render a router link, or compose BreadcrumbsItem children. |
By hand |
| 1.x |
2.0 |
Automatic |
label |
Move the text into the default slot: <Button>Save</Button>. |
By hand |
link |
Now href. |
Yes |
external |
Removed. Pass target="_blank" and rel="noopener noreferrer" as attributes; they go to the anchor that href renders. |
By hand |
badge |
Removed. Put a Badge inside the button's default slot. |
By hand |
badge-color |
Removed with badge. Set color on the Badge you put in the default slot. |
By hand |
badge-classes |
Button has no badge part. Style it with class, or a classes key: root, icon, iconEnd, label, spinner. |
By hand |
responsive |
Removed. Hide the label at small widths with your own responsive class on the slot content, or use iconOnly with an aria-label. |
By hand |
tooltip |
Removed. Wrap the button in <Tooltip content="…">. |
By hand |
tooltip-position |
Removed. Set placement (top, bottom, start, end) on the Tooltip you wrap the button in; left is start and right is end. |
By hand |
#iconRight |
Now #iconEnd. |
Yes |
<Calendar>
| 1.x |
2.0 |
Automatic |
model-value |
Now date. |
Yes |
week-start |
Now week-starts-on. |
Yes |
min-date |
Still accepted but ignored: the calendar no longer limits dates. Remove it. |
By hand |
max-date |
Still accepted but ignored: the calendar no longer limits dates. Remove it. |
By hand |
class-name |
Now class. |
Yes |
@update:modelValue |
Now @date-change. Check the handler: the payload is string. |
Yes, to review |
@date-click |
The date-click event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
@month-change |
The month-change event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
<Card>
| 1.x |
2.0 |
Automatic |
subtitle |
Now description. |
Yes |
figure-position |
Removed: media always sits edge to edge above the header. Lay out a side or bottom image yourself in the default slot. |
By hand |
no-shadow |
Removed. Elevation is chosen with surface (default, raised, sunken or glass). |
Yes |
bordered |
Removed. There is no border option; the look comes from its surface. |
Yes |
compact |
Removed: there is no compact padding option. Delete it, or adjust padding with classes.body / classes.header. |
By hand |
glass |
Now surface="glass". |
Yes |
link |
Now href. |
Yes |
external |
Removed: the card link (href) opens in the same tab. For a new-tab link, put your own anchor in the title slot. |
By hand |
#figure |
Now #media. |
Yes |
#header |
The header slot is gone. Split its content across the title, description and actions slots. |
By hand |
#menu |
Now #actions. |
Yes |
<Carousel>
| 1.x |
2.0 |
Automatic |
show-arrows |
Removed. |
Yes |
show-indicators |
Removed. |
Yes |
model-value |
Now index. |
Yes |
@update:modelValue |
Now @update:index. |
Yes |
<Chart>
| 1.x |
2.0 |
Automatic |
data |
Now series. |
Yes |
color |
Removed: series take the --apui-chart-1 to --apui-chart-6 tokens in order. Override those CSS variables to recolor. |
By hand |
options |
Removed, with no replacement. |
By hand |
show-legend |
Removed. The legend shows for two or more series. |
Yes |
animated |
Removed. The chart is a static SVG with no animation option. |
Yes |
class-name |
Now class. |
Yes |
<Checkbox>
| 1.x |
2.0 |
Automatic |
right |
Removed. There is no option to move the label to the other side. |
Yes |
hint |
Now description. |
Yes |
color |
Removed: a checked box uses the primary color. Delete it. |
By hand |
card |
Removed from Checkbox. For card-style options use CheckboxGroup with variant="cards". |
By hand |
card-class |
Checkbox has no card part. Style it with class, or a classes key: root, box, control, indicator, label, description, error. |
By hand |
<Clipboard>
| 1.x |
2.0 |
Automatic |
text |
Now model-value. |
Yes |
success-label |
Now copied-label. |
Yes |
success-duration |
Now timeout. |
Yes |
color |
Removed: the copy button has no color option. Delete it. |
By hand |
class-name |
Now class. |
Yes |
#success |
The success slot is gone. Set the after-copy text with copiedLabel. |
By hand |
@copy |
Now @copied. copy is still emitted, deprecated. |
Yes, to review |
<Code>
| 1.x |
2.0 |
Automatic |
line-numbers |
Now numbered. |
Yes |
class-name |
Now class. |
Yes |
@copy-failed |
The copy-failed event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
<ColorPicker>
| 1.x |
2.0 |
Automatic |
clearable |
Removed. There is no clear button. Clear the value through v-model. |
Yes |
random |
Removed. There is no random-color button. Offer presets with swatches. |
Yes |
default-value |
Removed with clearable (it was the color used on clear). Set the starting color through v-model. |
By hand |
#icon |
The icon slot is gone: the field shows its color swatch trigger instead. Remove it. |
By hand |
#iconRight |
The iconRight slot is gone. Remove it. |
By hand |
#randomIcon |
The randomIcon slot is gone with the random button. Remove it. |
By hand |
@clear |
The clear event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
@randomColor |
The randomColor 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 label always sits above the field. |
Yes |
date-type |
Removed. date is the default; for datetime-local add time. time, month and week have no equivalent: use <Input type="…">. |
By hand |
#icon |
The icon slot is gone: the field has a built-in calendar button. Remove it. |
By hand |
#iconRight |
The iconRight slot is gone: the field has a built-in calendar button. Remove it. |
By hand |
<Diff>
| 1.x |
2.0 |
Automatic |
before |
Now old-content. |
Yes |
after |
Now new-content. |
Yes |
before-label |
Removed: the header shows one fileName and the change counts, not per-side labels. |
By hand |
after-label |
Removed: the header shows one fileName and the change counts, not per-side labels. |
By hand |
mode |
Now view. Values: side-by-side is now split, inline is now unified. |
Yes |
line-numbers |
Removed. Line numbers always show. |
Yes |
<Divider>
| 1.x |
2.0 |
Automatic |
vertical |
Now orientation="vertical". |
Yes |
color |
Use strength. |
By hand |
label-position |
Now align. |
Yes |
<Drawer>
| 1.x |
2.0 |
Automatic |
end |
Now side="end". |
Yes |
persistent |
Removed: Escape and the backdrop always close the drawer. To keep it open, bind v-model:open and ignore the close; hideClose hides the close button. |
By hand |
aria-label |
No longer a prop. Pass aria-label as a plain kebab-case attribute; it names the panel when there is no title. |
By hand |
aria-labelledby |
Removed: the panel is labelled by its own title. Use title (or the title slot), or an aria-label attribute. |
By hand |
| 1.x |
2.0 |
Automatic |
#trigger |
Now #label. |
Yes |
<EmptyState>
| 1.x |
2.0 |
Automatic |
heading |
Now title. |
Yes |
heading-as |
Now heading-level. |
Yes |
#action |
Now #actions. |
Yes |
<ErrorDisplay> → <ErrorState>
| 1.x |
2.0 |
Automatic |
message |
Now description. |
Yes |
retryable |
Removed. Put your own retry Button in the actions slot and handle its click; ErrorState emits no retry event. |
By hand |
retry-label |
Removed with retryable. It becomes the text of the Button you put in the actions slot. |
By hand |
@retry |
The retry event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
<FileUpload> → <File>
| 1.x |
2.0 |
Automatic |
with-drag-drop |
Now variant="dropzone". |
Yes |
drag-drop-text |
Now title. |
Yes |
drag-drop-class |
Now the dropzone key of classes. |
Yes |
progress |
Removed. Bind v-model to the file list and set progress (0 to 100) on each entry. |
By hand |
hide-progress |
Removed. A bar shows only for entries that carry progress. |
Yes |
@filesSelected |
The filesSelected 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 |
cols-sm |
Use minItemWidth for responsive columns. |
By hand |
cols-md |
Use minItemWidth. |
By hand |
cols-lg |
Use minItemWidth. |
By hand |
cols-xl |
Use minItemWidth. |
By hand |
gap-x |
One gap step. |
By hand |
gap-y |
One gap step. |
By hand |
<Icon>
| 1.x |
2.0 |
Automatic |
aria-label |
Now label. |
Yes |
class-name |
Now class. |
Yes |
| 1.x |
2.0 |
Automatic |
clearable |
Removed: there is no built-in clear button. Use type="search" for the native one, or add your own button. |
By hand |
inline |
Removed. The label always sits above the control. |
Yes |
#iconRight |
Now #iconEnd. |
Yes |
@clear |
The clear event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
<Loading>
| 1.x |
2.0 |
Automatic |
aria-label |
Now label. |
Yes |
<Markdown>
| 1.x |
2.0 |
Automatic |
content |
Now source. |
Yes |
| 1.x |
2.0 |
Automatic |
horizontal |
Not in the 2.0 API (planned as orientation). Remove it, or check the component's docs for what replaces it. |
By hand |
size |
Removed: the menu has one size. Delete it, or restyle with classes. |
By hand |
color |
Removed: the current item uses the theme's tokens. Delete it. |
By hand |
#item |
The scoped item slot is gone. Compose MenuItem, MenuSub, MenuTitle and MenuSeparator children in the default slot for custom items. |
By hand |
<Modal> → <Dialog>
| 1.x |
2.0 |
Automatic |
title |
Unchanged. Still the heading and the accessible name. |
Yes |
subtitle |
Now description. |
Yes |
persistent |
No direct equivalent. role="alertdialog" stops the backdrop from closing it, but Escape still closes; hideClose hides the close button. |
By hand |
glass |
Now surface="glass". |
Yes |
bottom |
Removed from Dialog. For a bottom sheet use Drawer with side="bottom". |
By hand |
aria-label |
No longer a prop. Pass aria-label as a plain kebab-case attribute; it names the dialog when there is no title. |
By hand |
#actions |
Now #footer. |
Yes |
<Navbar>
| 1.x |
2.0 |
Automatic |
color |
Removed: the bar has no color option. Use surface (default or glass) or your own class. |
By hand |
glass |
Now surface="glass". |
Yes |
#center |
The center slot is gone. Put links in the default slot as NavbarItem children (or the links prop); a search field goes in the search slot. |
By hand |
#end |
Now #actions. |
Yes |
#start |
Now #brand. |
Yes |
| 1.x |
2.0 |
Automatic |
current-page |
Now page. |
Yes |
total-pages |
Now page-count. |
Yes |
sibling-count |
Now siblings. |
Yes |
size |
Removed: pagination has one size. Delete it. |
By hand |
@update:currentPage |
Now @update:page. |
Yes |
<Password>
| 1.x |
2.0 |
Automatic |
inline |
Removed. The label always sits above the control. |
Yes |
clearable |
Removed: there is no clear button. Delete it. |
By hand |
hide-toggle |
Removed: the reveal button always shows. For a field without it, use <Input type="password">. |
By hand |
#hiddenIcon |
The hiddenIcon slot is gone: the reveal button draws its own icons. Remove it. |
By hand |
#visibleIcon |
The visibleIcon slot is gone: the reveal button draws its own icons. Remove it. |
By hand |
@clear |
The clear 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 |
Removed: the cells have no color option. Delete it. |
By hand |
@incomplete |
The incomplete event is not in the 2.0 API. Check the component's docs for what replaces it. |
By hand |
@valueChange |
Now @update:modelValue. Check the handler: the payload is string. |
Yes, to review |
<Popover>
| 1.x |
2.0 |
Automatic |
position |
Now placement. Values: left is now start, right is now end. left and right are now start and end. |
Yes |
<Progress>
| 1.x |
2.0 |
Automatic |
show-value |
Removed. Use label and valueText. |
Yes |
aria-label |
No longer a prop. Pass aria-label as a plain kebab-case attribute (it lands on the progressbar), or use label for a visible name. |
By hand |
<Radio> → <RadioGroup>
| 1.x |
2.0 |
Automatic |
color |
Removed: radios use the primary color. Delete it. |
By hand |
option-value |
Removed. Options must be strings or { value, label, description } objects; map your data to that shape (1.x defaulted to id). |
By hand |
option-label |
Removed. Options must be strings or { value, label, description } objects; map your data to that shape (1.x defaulted to name). |
By hand |
option-hint |
Removed. Put each option's hint in its description key. |
By hand |
inline |
Now orientation="horizontal". |
Yes |
card |
Now variant="cards". |
Yes |
card-class |
Now the item key of classes. |
Yes |
<RichTextEditor>
| 1.x |
2.0 |
Automatic |
min-height |
Removed. Set a min-height in CSS on the editable area, for example through classes.content. |
By hand |
<Select>
| 1.x |
2.0 |
Automatic |
placeholder-value |
Removed: the placeholder option always has an empty value. Delete it and treat '' as no selection. |
By hand |
inline |
Removed. The label always sits above the control. |
Yes |
option-value |
Removed. Options must be strings, { value, label, disabled } objects or { label, options } groups; map your data to that shape (1.x defaulted to id). |
By hand |
option-label |
Removed. Options must be strings, { value, label, disabled } objects or { label, options } groups; map your data to that shape (1.x defaulted to name). |
By hand |
#iconRight |
The iconRight slot is gone: the end of a native select holds its chevron. Use the icon slot (before the value) or remove it. |
By hand |
<Skeleton>
| 1.x |
2.0 |
Automatic |
circle |
Now shape="circle". |
Yes |
<Sparkline>
| 1.x |
2.0 |
Automatic |
type |
Now variant. |
Yes |
color |
Removed: the line uses the theme's tokens. Recolor it in CSS through classes.line / classes.area. |
By hand |
stroke-width |
Removed: the stroke is fixed. Override it in CSS through classes.line if you must. |
By hand |
curve |
Removed. There is no curve option. |
Yes |
fill-opacity |
Removed: use variant="area" for the fill and style it through classes.area. |
By hand |
show-tooltip |
Removed. Sparkline has no tooltip; label describes the trend for assistive technology. |
Yes |
<SpotlightSearch> → <Spotlight>
| 1.x |
2.0 |
Automatic |
#item |
The scoped item slot is gone. Results render from groups; set each item's label, description, icon, color and shortcut instead. |
By hand |
<Stack>
| 1.x |
2.0 |
Automatic |
direction |
Now orientation. |
Yes |
<Stat>
| 1.x |
2.0 |
Automatic |
title |
Now label. |
Yes |
change-direction |
Now trend. Values: up is now up, down is now down, neutral is now flat. |
Yes |
#actions |
The actions slot is gone. Place the controls next to the Stat, or use KpiCard. |
By hand |
#figure |
The figure slot is gone. An icon goes in the icon slot (or the icon prop); other content has no place in a Stat. |
By hand |
<Steps>
| 1.x |
2.0 |
Automatic |
current-step |
Use v-model (modelValue), which counts from 1: pass currentStep + 1. Steps before it are complete; the current one is no longer marked complete. |
By hand |
vertical |
Now orientation="vertical". |
Yes |
color |
Removed: step colors come from each step's state. Delete it; use a step's state (error) to flag one. |
By hand |
#step |
The scoped step slot is gone. Compose Step children in the default slot; each one's default slot is its title. |
By hand |
<Table>
| 1.x |
2.0 |
Automatic |
columns |
Now headers. |
Yes |
striped |
Removed. |
Yes |
compact |
Now density="compact". |
Yes |
hoverable |
Removed. |
Yes |
pin-rows |
Removed. |
Yes |
pin-cols |
Removed. |
Yes |
sort |
key becomes column. |
By hand |
empty-message |
Now empty-text. |
Yes |
@sort |
key becomes column. |
By hand |
<Tabs>
| 1.x |
2.0 |
Automatic |
active-tab |
Now model-value. |
Yes |
default-tab |
Not in the 2.0 API (planned as defaultValue). Remove it, or check the component's docs for what replaces it. |
By hand |
vertical |
Now orientation="vertical". |
Yes |
vertical-right |
Removed. Covered by orientation and logical placement. |
Yes |
color |
Removed: the selected tab uses the theme's tokens. Delete it; pick the look with variant (segmented or underline). |
By hand |
tab-list-class-name |
Use :classes="{ list: '…' }". |
By hand |
panel-class-name |
Use :classes="{ content: '…' }" (the panel is the content part). |
By hand |
active-tab-class-name |
Removed. Style the selected trigger in CSS with [data-part="trigger"][data-selected], or add a class to all triggers through classes.trigger. |
By hand |
@update:activeTab |
Now @update:modelValue. |
Yes |
<Textarea>
| 1.x |
2.0 |
Automatic |
inline |
Removed. The label always sits above the box. |
Yes |
<ThemeToggle>
| 1.x |
2.0 |
Automatic |
class-name |
Now class. |
Yes |
<Timeline>
| 1.x |
2.0 |
Automatic |
vertical |
Removed. Timelines are vertical. |
Yes |
snap |
Removed. |
Yes |
compact |
Removed. |
Yes |
#item |
The scoped item slot is gone. Compose TimelineItem children: the default slot is the head and the card slot the box under it. |
By hand |
#marker |
The marker slot is gone: markers are decorative. Set each item's icon and color, or use variant="dot". |
By hand |
<Toggle>
| 1.x |
2.0 |
Automatic |
right |
Removed. There is no option to move the label to the other side. |
Yes |
hint |
Now description. |
Yes |
| 1.x |
2.0 |
Automatic |
text |
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 |
force-open |
Now open. |
Yes |
7. After the codemod
- Work through the
manual lines of the report, then the class lines.
- Events. Value and open changes are
update:modelValue and update:open, so v-model and v-model:open cover them. 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.