ArtisanPack UI
DocsDesign SystemUpgrading @artisanpack-ui/vue 1.x to 2.0

Upgrading @artisanpack-ui/vue 1.x to 2.0

Design System v1.0.0

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
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

<Button>

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
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

<Input>

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
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
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

<Pagination>

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

<Tooltip>

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.