Skip to content

Vue

@ecss/vue-adapter generates typed Vue 3 functional components from @block and @element declarations. The adapter's id is 'vue'.

Installation

sh
npm i -D @ecss/vue-adapter
sh
pnpm add -D @ecss/vue-adapter
sh
yarn add -D @ecss/vue-adapter

Requires vue version 3.3 or higher to be installed.

Setup

The adapter is registered in ecss.config.ts via defineConfig from @ecss/config — the config is not tied to any particular bundler; it is read by the ECSS plugin of your bundler. defaultAdapter sets the adapter applied to .ecss files by default:

ts
// ecss.config.ts
import { defineConfig } from '@ecss/config';
import { vueAdapter } from '@ecss/vue-adapter';

export default defineConfig({
  adapters: [vueAdapter()],
  defaultAdapter: 'vue',
});

Usage

Each @block turns into a Vue 3 functional component that is imported directly from the .ecss file. The component name is formed as {prefix}{BlockName} (the default prefix is E): @block ButtonEButton. Content is passed through the default slot.

vue
<script setup lang="ts">
import { EButton } from './Button.ecss';
</script>

<template>
  <EButton as="button" :params="{ variant: 'primary' }" @click="onClick">
    Click me
  </EButton>
</template>

The params prop

The block's parameters are passed through a single params prop (in the template, via the :params binding). Their types come from the generated {Block}Params interface (for example ButtonParams), so you cannot pass a non-existent @enum value.

params is required if the block has at least one required @param (without ?); if all parameters are optional or there are none at all, the prop can be omitted.

vue
<EButton :params="{ variant: 'primary' }" />
<!-- variant is required -->
<ECard />
<!-- Card has all parameters optional -->

The as prop

By default the component renders as a <div>. The as prop accepts any HTML tag and changes the root element. The component is typed by the chosen tag, so the set of allowed HTML attributes narrows automatically:

vue
<EButton
  as="button"
  type="submit"
  :params="{ variant: 'primary' }"
>Submit</EButton>

<EButton as="a" href="/about" :params="{ variant: 'ghost' }">Link</EButton>

With as="a", href, target, and other <a> attributes are available; with as="button", type, disabled, and so on.

class, style, and attributes

ECSS sets the block's class, the CSS variables from params, and data attributes on the root element. Everything you pass to the component lands on the root element through Vue's standard attribute fall-through:

  • class — your class is added to the block's class without overriding it;
  • style — merged with the CSS variables generated from params;
  • the remaining attributes and handlers (id, aria-*, data-*, @click, …) land on the root element as is.

Sub-components (@element)

If a @block contains @element, they become nested components through static properties of the root and are available in the template via dot notation:

vue
<EButton :params="{ withIcon: true }">
  <EButton.Icon>
    <svg><!-- … --></svg>
  </EButton.Icon>
  <EButton.Text>Click me</EButton.Text>
</EButton>

Sub-components support the same as prop (the default is <div>) but do not accept params.

Options

The factory's only option is componentNamePrefix (the component name prefix, default 'E'): vueAdapter({ componentNamePrefix: 'My' })MyButton. For more details, see the adapters overview.

Requirements

The adapter generates Vue 3 functional components. Vue 3.3 or higher is required — in earlier versions the typing of the polymorphic as prop in templates does not work correctly.

See also