Vue component APIs now use logical direction names (start/end/blockStart/blockEnd) instead of physical names (left/right/top/bottom/alpha/omega). Backward-compatible, with ESLint rule and migration script.
start, end, blockStart, blockEnd.left, right, top, bottom, alpha, omega) still work. This is not a breaking change.#icon slot on dt-button. See below.start means the inline-start edge regardless of locale.margin-inline-start, padding-block-end) that Dialtone already uses internally.Before
<dt-badge>
<template #leftIcon>...</template>
</dt-badge>
<dt-item-layout>
<template #left>...</template>
<template #right>...</template>
<template #bottom>...</template>
</dt-item-layout>
<dt-split-button>
<template #alphaIcon>...</template>
<template #omegaIcon>...</template>
</dt-split-button>
After
<dt-badge>
<template #startIcon>...</template>
</dt-badge>
<dt-item-layout>
<template #start>...</template>
<template #end>...</template>
<template #blockEnd>...</template>
</dt-item-layout>
<dt-split-button>
<template #startIcon>...</template>
<template #endIcon>...</template>
</dt-split-button>
Before
<dt-item-layout
left-class="d-bgc-critical"
right-class="d-bgc-warning"
bottom-class="d-bgc-info"
/>
<dt-split-button
alpha-active
alpha-aria-label="Call"
omega-disabled
/>
After
<dt-item-layout
start-class="d-bgc-critical"
end-class="d-bgc-warning"
block-end-class="d-bgc-info"
/>
<dt-split-button
start-active
start-aria-label="Call"
end-disabled
/>
Before
<dt-button icon-position="left">
...
</dt-button>
<dt-root-layout sidebar-position="right" />
After
<dt-button icon-position="start">
...
</dt-button>
<dt-root-layout sidebar-position="end" />
Before
<dt-split-button
@alpha-clicked="onPrimary"
@omega-clicked="onSecondary"
/>
After
<dt-split-button
@start-clicked="onPrimary"
@end-clicked="onSecondary"
/>
The #icon slot on dt-button is ambiguous: its position depends on the iconPosition prop. The migration tools skip this case. Replace #icon with the slot matching your intended position:
| iconPosition value | Replacement slot |
|---|---|
start (default) | #startIcon |
end | #endIcon |
blockStart | #blockStartIcon |
blockEnd | #blockEndIcon |
Before
<dt-button icon-position="start">
<template #icon>
<dt-icon name="phone" />
</template>
Call
</dt-button>
After
<dt-button icon-position="start">
<template #startIcon>
<dt-icon name="phone" />
</template>
Call
</dt-button>
Components: DtBadge, DtButton, DtInput, DtTab, DtSplitButton, DtItemLayout, DtRootLayout
Recipes: Callbox, Contact Centers Row, General Row, Top Banner Info, Grouped Chip
deprecated-physical-naming flags all deprecated physical slot, prop, prop value, and event usage on Dialtone components.
Add to your ESLint config:
// eslint.config.js (flat config)
import dialtone from '@dialpad/eslint-plugin-dialtone';
export default [
{
plugins: { dialtone },
rules: {
'dialtone/deprecated-physical-naming': 'warn',
},
},
];
Run the migration helper from your project root:
npx dialtone-migration-helper --cwd ./src
Select "physical-to-logical" from the config list. This renames all unambiguous physical names to their logical equivalents across .vue, .md, .html, .js, .ts, .jsx, and .tsx files.
To apply changes without interactive confirmation:
npx dialtone-migration-helper --cwd ./src --force
The script handles: slot directives, prop names, prop values, and event listeners for all affected components.
Skipped: The #icon slot on dt-button (ambiguous), dynamic bindings, and script-block references.
Migrating to Logical Naming for Slots, Props, and Events documentation last updated Friday, September 4, 2026
fix/popover-modal-zindex-scope