Skip to content

Maz-UI v4.0.0 Migration Guide ​

Maz-UI v4.0.0 isn’t just an update — it’s a complete rebuild designed to give developers more flexibility and simplicity.

The library is now split into independent packages, allowing you to install and use only what you need.
The theme system has been redesigned to make customizing and managing multiple themes easier, while the internationalization system offers full control over translations.
Performance has also been significantly improved thanks to optimal tree-shaking, more efficient minification, and a modernized architecture.

Connected to Maz-UI MCP

Follow the MCP guide to connect your AI assistant to Maz-UI's documentation for a smooth migration process.

Why Migrate to v4.0.0? ​

Architectural Revolution ​

v4.0.0 isn't just an update, it's a complete rebuild that transforms Maz-UI into a modern and performant library:

Optimized Tree-Shaking ​

  • Dramatic bundle reduction: 60-90% size reduction
  • Granular imports: Every component, composables, plugins, directive, and utility is individually importable
  • Modern bundlers: Perfect compatibility with Vite, Webpack 5, Rollup

Modular Architecture ​

  • Restructured monorepo: Separation into specialized packages
  • New export structure: Modular exports for better DX
  • Maximum flexibility: Choose exactly what you need

Advanced Theme System ​

  • Predefined presets: mazUi, obsidian, ocean, pristine
  • Dynamic CSS Variables: Automatic CSS variable generation
  • Intelligent dark mode: Configurable strategies for dark mode based on system preferences and user choice stored in cookies

Complete Internationalization ​

  • 9 supported languages by default: EN, FR, DE, ES, IT, PT, JA, ZH-CN
  • Add your own languages: Easy integration of custom translations
  • Translation system: Vue plugin and dedicated composables
  • Automatic fallback: Smart handling of missing translations

New Components or refactored ​

  • MazLink: Modern link component replacing MazBtn variant="link"
  • MazExpandAnimation: CSS Grid expansion animation (replaces MazTransitionExpand)
  • MazDropzone: Complete rewrite without external dependency
  • MazPopover: Versatile overlay component with smart positioning
  • MazSelectCountry: Country/language selector with i18n support

New Packages ​

v4.0.0 separates functionality into specialized packages for better modularity:

Main Packages ​

PackageDescriptionStatus
maz-uiVue components, composables, pluginsRefactored
@maz-ui/themesTheme system and presetsNew
@maz-ui/translationsi18n translationsNew
@maz-ui/utilsJavaScript/TypeScript utilitiesNew
@maz-ui/iconsSVG icons and flags (860+ icons)New
@maz-ui/cliCLI for theme generationRenamed
@maz-ui/nuxtNuxt moduleNew
@maz-ui/mcpMCP server for IA agentNew

Migration Checklist ​

Step 1: Update Dependencies ​

bash
# Uninstall old version
npm uninstall maz-ui

# Install new version
npm install maz-ui@4.0.0

# Optional: Install specialized packages
npm install @maz-ui/themes @maz-ui/translations @maz-ui/utils @maz-ui/icons

# Remove external dependency no longer needed
npm uninstall dropzone

Updated peer dependencies:

  • Vue: ^3.5.0 (was ^3.0.0)
  • unplugin-vue-components: >=28.0.0
  • unplugin-auto-import: >=19.0.0

Vue users - Plugin configuration ​

NEW: v4.0.0 introduces a mandatory Vue plugin for configuration.

Before (v3.x) ​

typescript
// main.ts
import { createApp } from 'vue'
import 'maz-ui/css/main.css'
import App from './App.vue'

createApp(App).mount('#app')

After (v4.0.0) ​

typescript
// main.ts
import { createApp } from 'vue'
import { MazUi } from 'maz-ui/plugins/maz-ui'
import { mazUi } from '@maz-ui/themes/presets'
import { fr } from '@maz-ui/translations'

// Import styles before your CSS
import 'maz-ui/styles'
import './style.css'

import App from './App.vue'

const app = createApp(App)

// NEW: MazUi plugin required
app.use(MazUi, {
  // Theme configuration (optional)
  theme: {
    preset: mazUi, // or 'ocean' | 'pristine' | 'obsidian'
  },
  // Translation configuration (optional)
  translations: {
    locale: 'fr',
    fallbackLocale: 'en',
    messages: {
      fr,
    },
  },
})

app.mount('#app')

Nuxt users - Module Configuration ​

NEW: Dedicated Nuxt module with simplified API.

Before (v3.x) ​

typescript
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['maz-ui/nuxt'],
  mazUi: {
    // v3 configuration
  }
})

After (v4.0.0) ​

typescript
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@maz-ui/nuxt'], // New package
  mazUi: {
    // New configuration API
    theme: {
      preset: 'maz-ui',
      strategy: 'hybrid',
      darkModeStrategy: 'class',
    },
    translations: {
      locale: 'fr',
      fallbackLocale: 'en',
    },
    plugins: {
      aos: true,
      dialog: true,
      toast: true,
      wait: true,
    },
    directives: {
      vTooltip: true,
      vLazyImg: true,
      vClickOutside: true,
    },
  }
})

Import Migration ​

MAJOR CHANGE: New modular import structure.

Components ​

NOTE: Component imports haven't changed - they work the same way as in v3.x.

typescript
// ✅ SAME AS v3.x - Still works
import MazBtn from 'maz-ui/components/MazBtn'
import MazInput from 'maz-ui/components/MazInput'

// ✅ NEW - Batch imports for convenience
import { MazBtn, MazInput } from 'maz-ui/components'

Plugins ​

typescript
// ❌ BEFORE (v3.x)
import { installToaster, ToastHandler } from 'maz-ui'

// ✅ AFTER (v4.0.0)
import { ToastPlugin, ToastHandler } from 'maz-ui/plugins'
// or for maximum tree-shaking
import { ToastPlugin, ToastHandler } from 'maz-ui/plugins/toast'

Directives ​

typescript
// ❌ BEFORE (v3.x)
import { vClickOutside, vTooltip } from 'maz-ui'

// ✅ AFTER (v4.0.0)
import { vClickOutside, vTooltip } from 'maz-ui/directives'
// or for maximum tree-shaking
import { vClickOutside } from 'maz-ui/directives/vClickOutside'
import { vTooltip } from 'maz-ui/directives/vTooltip'

Composables ​

typescript
// ❌ BEFORE (v3.x)
import { useTimer, useToast } from 'maz-ui'

// ✅ AFTER (v4.0.0)
import { useTimer, useToast } from 'maz-ui/composables'
// or for maximum tree-shaking
import { useTimer } from 'maz-ui/composables/useTimer'
import { useToast } from 'maz-ui/composables/useToast'

Utilities ​

typescript
// ❌ BEFORE (v3.x)
import { currency, date } from 'maz-ui'

// ✅ AFTER (v4.0.0)
import { formatCurrency, formatDate } from 'maz-ui'
// or for better performance
import { formatCurrency, formatDate } from '@maz-ui/utils'

Component Changes ​

MazBtn - Major Changes ​

html
<!-- ❌ BEFORE (v3.x) -->
<MazBtn variant="link" href="/path">
  Link
</MazBtn>

<!-- ✅ AFTER (v4.0.0) - Use MazLink -->
<MazLink href="/path">
  Link
</MazLink>

<!-- Action with click -->
<MazLink @click="handleClick">
  Action
</MazLink>

Prop Changes ​

html
<!-- CHANGED PROPS -->
<MazBtn
  outlined            <!-- ✅ NEW: was 'outline' -->
  justify="space-between"  <!-- 🆕 NEW: Content alignment -->
  :padding="false"         <!-- 🆕 NEW: Padding control -->
  rounded-size="full"      <!-- 🆕 NEW: Border radius size -->
>
  Button
</MazBtn>

Replaces MazBtn variant="link" with a richer API:

html
<!-- ✅ NEW COMPONENT -->
<MazLink
  href="/path"
  :auto-external="true"           <!-- 🆕 NEW: Automatic external icon -->
  :underline-hover="true"         <!-- 🆕 NEW: Underline on hover -->
  left-icon="home"                <!-- 🆕 NEW: Left icon -->
  right-icon="arrow-right"        <!-- 🆕 NEW: Right icon -->
  color="primary"                 <!-- 🆕 NEW: Custom color -->
  as="router-link"               <!-- 🆕 NEW: Custom component -->
>
  Link with icons
</MazLink>

MazPicker --> MazDatePicker ​

MazPicker has been renamed to MazDatePicker.

Props have been changed:

  • no-header --> hide-header
  • input-date-style --> input-date-format

New Props:

  • min-max-auto: Control behavior when the date is in the range of min and max.
html
<MazDatePicker />

MazPopover - New Component ​

Versatile overlay component with smart positioning:

html
<!-- NEW COMPONENT -->
<MazPopover
  trigger="click"                 <!-- 🆕 NEW: Trigger mode -->
  position="bottom-start"         <!-- 🆕 NEW: Smart positioning -->
  :persistent="true"              <!-- 🆕 NEW: Keep open for interactions -->
  role="dialog"                   <!-- 🆕 NEW: Accessibility role -->
>
  <template #trigger>
    <MazBtn>Open Popover</MazBtn>
  </template>

  <template #default>
    <div class="p-4">
      Popover content
    </div>
  </template>
</MazPopover>

MazSelectCountry - New Component ​

Country/language selector with i18n support:

html
<!-- ✅ NEW COMPONENT -->
<MazSelectCountry
  v-model="selectedCountry"
  :preferred-codes="['US', 'FR']"  <!-- 🆕 NEW: Preferred countries -->
  :locale="'fr'"                   <!-- 🆕 NEW: Localization -->
  :hide-flags="false"              <!-- 🆕 NEW: Flag display -->
  :display-code="false"            <!-- 🆕 NEW: Show codes -->
/>

MazInputPhoneNumber - Renamed ​

html
<!-- ❌ BEFORE (v3.x) -->
<MazPhoneNumberInput
  v-model="phone"
  v-model:country-code="country"
  :preferred-countries="['FR', 'US']"
  @update="handleUpdate"
/>

<!-- ✅ AFTER (v4.0.0) -->
<MazInputPhoneNumber
  v-model="phone"
  v-model:country-code="country"
  :preferred-countries="['FR', 'US']"
  @data="handleData"            <!-- 🔄 CHANGED: @update → @data -->
/>

MazExpandAnimation - Replaces MazTransitionExpand ​

html
<!-- ❌ BEFORE (v3.x) -->
<MazTransitionExpand animation-duration="500ms">
  <div v-show="isOpen">Content</div>
</MazTransitionExpand>

<!-- ✅ AFTER (v4.0.0) -->
<MazExpandAnimation
  v-model="isOpen"                <!-- 🆕 NEW: v-model for state control -->
  duration="500ms"               <!-- 🔄 CHANGED: duration instead of animation-duration -->
  timing-function="ease-in-out"  <!-- 🆕 NEW: Timing function -->
>
  <div>Content</div>
</MazExpandAnimation>

MazDropzone - Complete Rewrite ​

External dependency removed:

bash
# ❌ BEFORE (v3.x) - External dependency required
npm install dropzone

# ✅ AFTER (v4.0.0) - No external dependency
npm uninstall dropzone

New Features:

html
<!-- ✅ NEW FEATURES -->
<MazDropzone
  v-model="files"
  :auto-upload="'single'"          <!-- 🆕 NEW: Automatic upload -->
  url="/api/upload"                <!-- 🆕 NEW: Upload URL -->
  :request-options="{ ... }"       <!-- 🆕 NEW: Request options -->
  :transform-body="transformFn"    <!-- 🆕 NEW: Body transformation -->
  :min-file-size="0.1"            <!-- 🆕 NEW: Min size in MB -->
  @upload-success="onSuccess"      <!-- 🆕 NEW: Success event -->
  @upload-error="onError"          <!-- 🆕 NEW: Error event -->
/>

MazDropdown & MazSelect - Position API ​

html
<!-- ❌ BEFORE (v3.x) -->
<MazDropdown position="bottom right" />
<MazSelect position="bottom right" />

<!-- ✅ AFTER (v4.0.0) -->
<MazDropdown position="bottom-end" />
<MazSelect position="bottom-end" />

New position type:

typescript
type MazPopoverPosition = 'auto' | 'top' | 'bottom' | 'left' | 'right' |
  'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' |
  'left-start' | 'left-end' | 'right-start' | 'right-end'

MazDialogConfirm - Renamed ​

typescript
// ❌ BEFORE (v3.x)
import { MazDialogPromise } from 'maz-ui'

// ✅ AFTER (v4.0.0)
import { MazDialogConfirm } from 'maz-ui'

Composable Changes ​

useDialog - API Changes ​

No longer Promise-based to avoid JS console errors:

typescript
// ❌ BEFORE (v3.x)
const dialog = useDialog()

try {
  const result = await dialog.confirm({
    title: 'Confirm',
    message: 'Are you sure?',
    confirmText: 'Yes',
    cancelText: 'No'
  })
  // Handle confirm
} catch (error) {
  // Handle cancel
}
typescript
// ✅ AFTER (v4.0.0)
const dialog = useDialog()

dialog.confirm({
  title: 'Confirm',
  message: 'Are you sure?',
  buttons: {                      // 🔄 CHANGED: buttons instead of confirmText/cancelText
    confirm: 'Yes',
    cancel: 'No'
  },
  onAccept: () => {              // 🆕 NEW: Accept callback
    // Handle confirm
  },
  onReject: () => {              // 🆕 NEW: Reject callback
    // Handle cancel
  },
  onClose: () => {               // 🆕 NEW: Close callback (finally)
    // Handle close
  }
})

useDisplayNames - Renamed ​

typescript
// ❌ BEFORE (v3.x)
import { useLanguageDisplayNames } from 'maz-ui'

const { getDisplayName } = useLanguageDisplayNames()

// ✅ AFTER (v4.0.0)
import { useDisplayNames } from 'maz-ui/composables'

const { getDisplayName } = useDisplayNames()

📖 Complete documentation: useDisplayNames Guide

Helpers to Composables ​

🔄 MAJOR CHANGE: Several helpers are now Vue composables and must be used within Vue context.

useIdleTimeout ​

typescript
// ❌ BEFORE (v3.x)
import { idleTimeout } from 'maz-ui'

const controller = idleTimeout({
  timeout: 5000,
  onTimeout: () => console.log('timeout'),
  onActivity: () => console.log('activity')
})

// ✅ AFTER (v4.0.0)
import { useIdleTimeout } from 'maz-ui/composables'

// In a Vue component
const { isIdle } = useIdleTimeout({
  timeout: 5000,
  onTimeout: () => console.log('timeout'),
  onActivity: () => console.log('activity')
})

Color System Changes ​

Color Removals and Replacements ​

typescript
// ❌ REMOVED COLORS
color="theme"     // ✅ REPLACED BY: color="contrast"
color="white"     // ❌ REMOVED
color="black"     // ❌ REMOVED
color="danger"    // ✅ REPLACED BY: color="destructive"

🆕 New Color System ​

Available colors in v4.0.0:

typescript
type MazColor = 'primary' | 'secondary' | 'accent' | 'info' | 'success' |
  'warning' | 'destructive' | 'contrast' | 'transparent'

Migration examples:

html
<!-- ❌ BEFORE (v3.x) -->
<MazBtn color="theme">Theme Button</MazBtn>
<MazBtn color="danger">Danger Button</MazBtn>

<!-- ✅ AFTER (v4.0.0) -->
<MazBtn color="contrast">Contrast Button</MazBtn>
<MazBtn color="destructive">Destructive Button</MazBtn>

Removed Features ​

Removed Directive ​

html
<!-- ❌ REMOVED - v-closable directive -->
<div v-closable="handler">Content</div>

<!-- ✅ ALTERNATIVE - Use v-click-outside -->
<div v-click-outside="handler">Content</div>

Removed Utility Names ​

typescript
// ❌ BEFORE (v3.x)
import { currency, date } from 'maz-ui'

// ✅ AFTER (v4.0.0)
import { formatCurrency, formatDate } from 'maz-ui'

TypeScript Changes ​

Type Prefixing ​

All component types are now prefixed with Maz:

typescript
// ❌ BEFORE (v3.x)
import type { Props } from 'maz-ui/components/MazBtn'
import type { ButtonsRadioOption, Row, Color, Size } from 'maz-ui'

// ✅ AFTER (v4.0.0)
import type { MazBtnProps } from 'maz-ui/components/MazBtn'
import type { MazRadioButtonsOption, MazTableRow, MazColor, MazSize } from 'maz-ui'

Type Import Changes ​

typescript
// ❌ BEFORE (v3.x)
import type { Color, Size } from 'maz-ui'

// ✅ AFTER (v4.0.0)
import type { MazColor, MazSize } from 'maz-ui'

Theme System ​

Basic Configuration ​

typescript
// main.ts
import { MazUi } from 'maz-ui/plugins/maz-ui'
import { mazUi } from '@maz-ui/themes/presets'

app.use(MazUi, {
  theme: {
    preset: mazUi, // or 'ocean' | 'pristine' | 'obsidian'
  },
})

Custom Theme ​

typescript
import { definePreset } from '@maz-ui/themes'
import { mazUi } from '@maz-ui/themes/presets'

const customTheme = definePreset({
  base: mazUi,
  name: 'custom-theme',
  colors: {
    light: {
      primary: '220 100% 50%',
      secondary: '220 14% 96%',
    },
    dark: {
      primary: '220 100% 70%',
      secondary: '220 14% 4%',
    }
  }
})

app.use(MazUi, {
  theme: {
    preset: customTheme,
  },
})

useTheme Composable ​

vue
<script setup>
import { useTheme } from 'maz-ui/composables'

const { isDark, toggleDarkMode, setTheme } = useTheme()

// Change theme
setTheme('ocean')

// Toggle dark mode
toggleDarkMode()
</script>

<template>
  <button @click="toggleDarkMode">
    {{ isDark ? '☀️' : '🌙' }}
  </button>
</template>

📖 Complete documentation: Theme Guide

Translation System ​

Configuration ​

typescript
// main.ts
import { MazUi } from 'maz-ui/plugins/maz-ui'
import { fr, en } from '@maz-ui/translations'

app.use(MazUi, {
  translations: {
    locale: 'fr',
    fallbackLocale: 'en',
    messages: {
      fr,
      en,
    },
  },
})

useTranslations Composable ​

vue
<script setup>
import { useTranslations } from 'maz-ui/composables'

const { t, locale, setLocale } = useTranslations()

// Change language
setLocale('fr')
</script>

<template>
  <p>{{ t('button.cancel') }}</p>
</template>

📖 Complete documentation: Translation Guide

Common Errors and Solutions ​

"idleTimeout is not a function" ​

typescript
// ❌ Old way
import { idleTimeout } from 'maz-ui'

// ✅ New way
import { useIdleTimeout } from 'maz-ui/composables'

// In a Vue component
const { isIdle } = useIdleTimeout({ timeout: 5000 })

❌ "MazTransitionExpand is not exported" ​

vue
<!-- ❌ Removed component -->
<MazTransitionExpand>
  <div v-show="isOpen">Content</div>
</MazTransitionExpand>

<!-- ✅ New component -->
<MazExpandAnimation v-model="isOpen">
  <div>Content</div>
</MazExpandAnimation>

❌ "Module not found: Can't resolve 'dropzone'" ​

bash
# ❌ Remove old dependency
npm uninstall dropzone

# ✅ MazDropzone has no external dependency

❌ "useTheme must be used within MazUi plugin" ​

typescript
// ❌ Missing plugin
import { createApp } from 'vue'

// ✅ Add MazUi plugin
import { MazUi } from 'maz-ui/plugins/maz-ui'

app.use(MazUi)

❌ "Property 'outline' does not exist" ​

html
<!-- ❌ Old prop name -->
<MazBtn outline>Button</MazBtn>

<!-- ✅ New prop name -->
<MazBtn outlined>Button</MazBtn>

Migration Benefits ​

Performance ​

Metricv3.xv4.0.0Improvement
Bundle Size~500KB~50-200KB60-90%
Tree-shaking❌ Limited✅ OptimalPerfect
Lazy Loading❌ Basic✅ AdvancedIntelligent
TypeScript✅ Good✅ ExcellentStrict

Developer Experience ​

  • Auto-imports: Resolvers for unplugin-vue-components
  • TypeScript: Strict types and perfect auto-completion
  • DevTools: Nuxt DevTools integration
  • Documentation: Interactive guides and examples

Maintenance ​

  • Modularity: Separate packages for better maintenance
  • Versioning: Semantic versioning for each package
  • Stability: Mature and tested architecture

Complete Migration Checklist ​

Dependencies ​

Configuration ​

Imports ​

Components ​

API Changes ​

Helpers to Composables ​

TypeScript ​

Testing and Validation ​

Additional Resources ​

Need Help? ​

Migration seems complex? We're here to help:


🎉 Congratulations! You now have all the tools to migrate to Maz-UI v4.0.0 and enjoy an exceptional developer experience with optimized performance!