Vivid Logo Vivid

ESLint Plugin

The ESLint plugin provides rules for building and maintaining projects with Vivid. At the moment, only code written with Vivid Vue is supported.

About

Most projects already use ESLint to enforce code quality and style. The Vivid ESLint plugin extends ESLint to catch issues specific to Vivid projects.

The plugin can help to:

  • Catch issues like accessibility violations.
  • Guide towards best practices and correct usage.
  • Detect use of deprecated APIs and provide automated fixes.

Getting Started (Vue)

Prerequisites

The plugin is intended to be used in addition to the popular eslint-plugin-vue.

Follow the eslint-plugin-vue installation instructions to install the plugin and set up your environment, if you haven't already.

Installation

Add the NPM package to your repository:

npm install --save-dev @vonage/eslint-plugin-vivid
yarn add -D @vonage/eslint-plugin-vivid
pnpm add -D @vonage/eslint-plugin-vivid

Use the vue preset by adding the following configuration to your ESLint configuration file:

{
	// ...
	"extends": [
		// ...
+		"plugin:@vonage/vivid/vue"
	]
}
// ...
+ import pluginVivid from '@vonage/eslint-plugin-vivid';

export default [
  // ...
+ ...pluginVivid.configs['flat/vue'],
];

Customizing Rules

The plugin provides a set of rules that can be extended or overridden. To customize the rules, add them to the rules key of your ESLint configuration file:

{
	// ...
	"rules": {
+		"@vonage/vivid/no-deprecated-apis": "warn"
	}
}
// ...
export default [
	// ...,
+	{
+		rules: {
+			'@vonage/vivid/no-deprecated-apis': 'warn',
+		},
+	},
]

Rules

no-deprecated-apis

This rule warns about the usage of deprecated APIs. If possible, it will also provide a fix to migrate the code to a new API.

Example

The clickable prop of VSelectableBox has been deprecated in favor of clickable-box.

<!-- ❌ BAD -->
<VSelectableBox clickable></VSelectableBox>

<!-- ✅ GOOD --> <VSelectableBox clickable-box></VSelectableBox>

accessible-names

This rule enforces the presence of an accessible name for components that require it.

An accessible name is a short text alternative that describes the purpose of a component. It provides users of assistive technologies with a label for the component.

You can provide an accessible name with the aria-label attribute.

If the component is purely decorative, you can alternatively use aria-hidden="true" to hide it from screen readers completely.

Example

Without the accessible name, screen readers will announce the component as "button" and the user will be unable to understand its purpose.

<!-- ❌ BAD -->
<VButton icon="save-line"></VButton>

<!-- ✅ GOOD --> <VButton icon="save-line" aria-label="Save"></VButton>

no-inaccessible-events

This rule bans specific event usages that are accessibility concerns.

Example

Badge is a non-interactive component meant to display information only. The @click event handler is therefore an accessibility concern because it cannot be activated by keyboard users and has incorrect semantics for screen readers.

Instead, use a different component that supports user interaction, such as button.

<!-- ❌ BAD -->
<VBadge text="Badge" @click="onClick"></VBadge>

no-anchor-attribute

Anchored components, like tooltip, can reference their anchor in different ways.

This rule disallows the usage of the anchor attribute to reference an anchor by ID. Instead, the anchor slot should be used. The slot is preferred because it does not require the use of global IDs and ensures correct DOM order for accessibility.

The rule provides an automatic fix if the anchor is immediately preceding the anchored component.

Example

<!-- ❌ BAD -->
<VButton id="anchor" label="Save"></VButton>
<VTooltip anchor="anchor" text="Tooltip text"></VTooltip>

<!-- ✅ GOOD --> <VTooltip text="Tooltip text"> <template #anchor><VButton label="Save"></VButton></template> </VTooltip>

no-slot-attribute

This rule enforces the use of the Vue slot syntax (<template #slotname>) instead of the slot attribute (slot="slotname") for named slots of Vivid components. This syntax should be preferred for consistency with slots of regular Vue components.

The rule provides a fix to convert the syntax automatically.

Example

<!-- ❌ BAD -->
<VTextField label="Search">
	<VButton slot="action-items" label="Clear" />
</VTextField>

<!-- ✅ GOOD --> <VTextField label="Search"> <template #action-items><VButton label="Clear" /></template> </VTextField>

no-value-attribute

This rule forbids the usage of the value and checked attributes of Vivid input elements. The attributes should not be used because of inconsistent behaviour between different versions of Vue:

  • Vue 2: Sets the initial value.
  • Vue 3: Sets the current value.

Instead, use modelValue to set the current value or initialValue or defaultChecked to set the initial value.

Example

<!-- ❌ BAD -->
<VTextField :value="value"></VTextField>

<!-- ✅ GOOD --> <VTextField :model-value="value"></VTextField> <!-- or --> <VTextField :initial-value="value"></VTextField>

no-current-value-attribute

This rule forbids the usage of currentValue, currentChecked, currentStart and currentEnd attributes of Vivid input elements. You should use modelValue instead for consistency and compatibility between different versions of Vivid.

The rule provides a fix to update code to use modelValue instead.

Example

<!-- ❌ BAD -->
<VTextField :current-value="value"></VTextField>

<!-- ✅ GOOD --> <VTextField :model-value="value"></VTextField>