Skip to content

Migration Guide ​

This document records the version evolution, public API adjustments, and breaking change migration guides for BrutxUI to help you smoothly upgrade the component library.


Overview & Version Compatibility ​

BrutxUI is currently in rapid 0.x iteration. To avoid long-term legacy burdens, the public API continues to be streamlined and standardized following first principles.

ModuleNature of ChangeImpact ScopeApplicable / Introduced Version
Public API Contract ConvergenceStructural optimizationExport scope from root entry, subpath import rulesv0.10.0+
Props Type InferenceRecommended practiceComponent Props type definition approachv0.10.0+
Selector Internal HelpersRemoval / EncapsulationInternal functions like useClearableSelectionv0.10.0+
Button Effect (Glitch) ControlBehavioral changeButton effect prop and programmatic playbackv0.9.0+
CLI Source Mode Types PlacementDirectory specificationShared types location in source installation modev0.9.0+
Style & Asset ConsumptionArchitectural noteSubpath imports and CSS stylesheet delivery boundariesAll versions

1. Public API Contract & Standard Imports ​

BrutxUI uses a unified API Contract for module declaration and export projection.

1. Root Entry vs. Subpath Imports ​

  • Root entry (brutx-ui-vue): Exports foundational components (such as Button, Card, Badge, Dialog), shared variants, and headless utilities.
  • Named subpaths (brutx-ui-vue/<module>): Used to load composite components (such as Combobox, TreeSelect, Cascader, DataTable) along with their specialized types and variants, as well as standalone composables (such as brutx-ui-vue/useReducedMotion).
ts
import { Button } from 'brutx-ui-vue'
import { Combobox, type ComboboxOption } from 'brutx-ui-vue/combobox'
import { TreeSelect, type TreeNode, type SelectionMode } from 'brutx-ui-vue/tree-select'
import { Loading, vLoading } from 'brutx-ui-vue/loading'
import { useReducedMotion } from 'brutx-ui-vue/useReducedMotion'

2. Best Practices for Props Type Inference ​

In earlier versions, some components individually exported named types such as ButtonProps. Starting from v0.10.0, to ensure types always remain synchronized with the single source of truth in component implementations, it is recommended to use Vue 3's InstanceType<typeof Component>['$props']:

ts
// Deduce component Props types via InstanceType
type ButtonProps = InstanceType<typeof Button>['$props']
type ComboboxProps = InstanceType<typeof Combobox>['$props']

2. Selector Internal Helpers Convergence ​

Background ​

In earlier versions, the following 4 selector-related helper functions were inadvertently exposed through the root entry or public subpaths:

  • useClearableSelection
  • useSelectableTrigger
  • useSelectionDisplayText
  • useTransferPanelSelection

These functions are internal implementation details tightly coupled to internal component states. Starting in v0.10.0, they have been removed from npm public exports and public subpaths.

Migration & Alternatives ​

Application code should not and does not need to call these internal helpers directly. All selection state management should be performed cleanly via standard v-model, props, slots, and events on the corresponding components (Combobox, Cascader, TreeSelect, Transfer):

ts
// Standard two-way data binding with public options contract
const selectedValue = ref<string>('')
const options: ComboboxOption[] = [
    { label: 'Vue 3', value: 'vue3' },
    { label: 'Tailwind CSS', value: 'tailwind' },
]

const treeSelectionMode: SelectionMode = 'checkbox'
const treeData: TreeNode[] = [
    { id: '1', label: 'Frameworks', children: [{ id: '1-1', label: 'Vue' }] },
]

NOTE

Core business data types like ComboboxOption, CascaderOption, CascaderValue, TreeNode, SelectionMode, and TransferDataItem remain public and should be imported from their respective subpaths.


3. Explicit Button Effect Control & Lifecycle ​

Description ​

Starting with v0.9.0, the Button component enforces strict lifecycle and triggering constraints on the glitch effect:

  1. Explicit Enablement: You must explicitly specify effect="glitch". Under the default effect="none", the effect will not activate even if autoplay is passed or play() is called programmatically via a template ref.
  2. Lifecycle Safeguards: When a button is disabled, loading, when the user's OS has prefers-reduced-motion enabled, or when deactivated inside <KeepAlive>, the effect automatically pauses; unmounting releases all underlying WebGL / Canvas / Audio resources.
ts
// Explicitly enable effects via effect="glitch" (default is "none")
const isPlaying = ref<boolean>(false)
const handleGlitch = (): void => {
    isPlaying.value = true
}

For motion-sensitive environments, pair this with the useReducedMotion composable for graceful degradation:

ts
// useReducedMotion returns a readonly Ref<boolean>
const prefersReducedMotion = useReducedMotion()

4. Shared Types in CLI Source Installation Mode ​

For projects using the CLI (brutx-vue add <component>) to copy source code:

  • Shared tree and option types are installed by default under types/ at the same level as composables (e.g. src/types/tree.ts).
  • If sharedBase is configured in brutx.json, types are placed under that configured directory's types/.
  • When updating source components, use the CLI's diff/update workflow to review upstream updates while preserving your local custom modifications.

5. Style Consumption & Performance Costs ​

BrutxUI delivers styles compiled into a single consolidated stylesheet:

  • Importing via subpaths (e.g. import { Combobox } from 'brutx-ui-vue/combobox') reduces the JavaScript dependency closure of your bundle.
  • However, due to the atomic and utility-driven nature of Neo-Brutalist Tailwind CSS v4 design tokens, the stylesheet should be imported once globally:
    ts
    import 'brutx-ui-vue/style.css'
  • When analyzing bundle cost, measure tree-shaken JavaScript savings and CSS stylesheet size independently.

Brute force builds.