All Projects → mlturner88 → vue-simple-bem

mlturner88 / vue-simple-bem

Licence: MIT license
A simple Vue.js directive to map BEM CSS class names.

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to vue-simple-bem

The-HTML-and-CSS-Workshop
A New, Interactive Approach to Learning HTML and CSS
Stars: ✭ 65 (+282.35%)
Mutual labels:  bem, bem-css
Gulp Pug Starter
Frontend development with pleasure. Pug + SCSS version
Stars: ✭ 228 (+1241.18%)
Mutual labels:  bem
Rebem
React ❤️ BEM
Stars: ✭ 93 (+447.06%)
Mutual labels:  bem
Synergy
Synergy is a framework for building modular, configurable and scalable UI components for React-DOM projects
Stars: ✭ 146 (+758.82%)
Mutual labels:  bem
Frontie Webpack
Front-end Boilerplate | Gulp 4 + Webpack 4 + Babel + ITCSS Architecture + BEM Methodology + Twig.js
Stars: ✭ 102 (+500%)
Mutual labels:  bem
Blog
这是一个Blog, 如果喜欢可以订阅,是Watch, 不是 Star 哈。。。
Stars: ✭ 161 (+847.06%)
Mutual labels:  bem
Bem Kit
💄 CSS UI kit with BEM convention and SASS
Stars: ✭ 69 (+305.88%)
Mutual labels:  bem
ts-react-boilerplate
A very opinionated (React/TypeScript/Redux/etc) frontend boilerplate
Stars: ✭ 43 (+152.94%)
Mutual labels:  bem
Yandex Ui
Yandex UI Kit build on React and bem-react
Stars: ✭ 229 (+1247.06%)
Mutual labels:  bem
Enb
Tool for building web projects, BEM bundler.
Stars: ✭ 136 (+700%)
Mutual labels:  bem
Skin
Pure CSS framework designed & developed by eBay for a branded, e-commerce marketplace.
Stars: ✭ 126 (+641.18%)
Mutual labels:  bem
Bem Xjst
bem-xjst (eXtensible JavaScript Templates): declarative template engine for the browser and server
Stars: ✭ 115 (+576.47%)
Mutual labels:  bem
Bolt
The Bolt Design System provides robust Twig and Web Component-powered UI components, reusable visual styles, and powerful tooling to help developers, designers, and content authors build, maintain, and scale best of class digital experiences.
Stars: ✭ 186 (+994.12%)
Mutual labels:  bem
Kanbasu
A lightweight CSS framework written in Sass.
Stars: ✭ 94 (+452.94%)
Mutual labels:  bem
bem-react-boilerplate
DEPRECATED! A bare minimum frontend boilerplate based on create-react-app and bem-react-core.
Stars: ✭ 32 (+88.24%)
Mutual labels:  bem
Bemskel
A lightweight CSS framework written in BEM and SASS for building scalable component-based user interfaces
Stars: ✭ 89 (+423.53%)
Mutual labels:  bem
Dress Code
The official style guide and framework for all Zalando Brand Solutions products
Stars: ✭ 123 (+623.53%)
Mutual labels:  bem
Bemify
Sass Mixins to write BEM-style SCSS source
Stars: ✭ 149 (+776.47%)
Mutual labels:  bem
luxe
Luxe is a WordPress starter theme using a modern workflow and best practices.
Stars: ✭ 22 (+29.41%)
Mutual labels:  bem
hyper
🎨 Hyper: A component-first CSS design system.
Stars: ✭ 26 (+52.94%)
Mutual labels:  bem

Vue Simple BEM

Note: The below documentation is for using vue-simple-bem with Vue 3. If you're looking for instructions on using vue-simple-bem with Vue 2, see previous versions of the README.

A simple directive to bring BEM to Vue 3. Less than 1KiB compressed. No external dependencies.

Installation

Install using your package manager of choice.

yarn add vue-simple-bem

npm i --save vue-simple-bem

You can install the directive as a global dependency. The configuration options are optional.

import { createApp } from 'vue';
import VueSimpleBem from 'vue-simple-bem';

const app = createApp({...});
app.use(VueSimpleBem);

You can also import it directly into a component.

<script>
import { bem } from 'vue-simple-bem';

export default {
  name: 'MyComponent',
  directives: { bem }
};
</script>

What is BEM?

Before continuing, you may want to get familiar with BEM and the problem it's solving.

At it's simplest, it is a css naming convention that keeps your selectors flat and expresses an explicit relationship between classes in a component.

Here is some further reading:

Usage

A simple example.

<script>
export default {
  name: 'MyComponent',
};
</script>

<template>
  <div v-bem>
    <div v-bem:sampleText>Example Text</div>
  </div>
</template>
  • The root div will become <div class="my-component">. The Block name is derived from component name.
  • The child element div will become <div class="my-component__sample-text">

Example with modifiers

<script>
export default {
  name: 'MyComponent',
  props: {
    bold: {
      type: Boolean,
      default: true
    },
    italics: {
      type: Boolean,
      default: true
    },
    center: {
      type: Boolean,
      default: false
    }
  }
};
</script>

<template>
  <div v-bem="{ bold, emphasizeText: italics }">
    <div v-bem:sampleText="{ bold, center }">Example Text</div>
  </div>
</template>
  • The root div will become <div class="my-component my-component--bold my-component--emphasize-text">
  • The child element div will become <div class="my-component__sample-text my-component__sample-text--bold">

Example with simplified modifiers

If a modifier isn't dynamic then you can use this syntax.

<script>
export default {
  name: 'MyComponent'
};
</script>

<template>
  <div v-bem.floatLeft>
    <div v-bem:sampleText.italics>Example Text</div>
  </div>
</template>
  • The root div will become <div class="my-component my-component--float-left">
  • The child element div will become <div class="my-component__sample-text my-component__sample-text--italics">

Example using both simple modifiers and dynamic modifiers

You can use both together as well.

<script>
export default {
  name: 'MyComponent',
  props: {
    bold: {
      type: Boolean,
      default: true
    }
  }
};
</script>

<template>
  <div v-bem.floatLeft>
    <div v-bem:sampleText.italics="{ bold }">Example Text</div>
  </div>
</template>
  • The root div will become <div class="my-component my-component--float-left">
  • The child element div will become <div class="my-component__sample-text my-component__sample-text--bold my-component__sample-text--italics">

API

Block

The BEM block will automatically use the name of the component. If the component does not have a name then it will fallback to using the component's tag that Vue uses (which is usually what you registered the component as in the parent). If neither of these are available, it will attempt to use the uuid assigned to the component by the vue framework. If for some reason, even this field is undefined (I'm not sure if that is actually possible) it defaults to bem-block.

The component's name may be either pascal cased or kebab cased. The name will be converted into kebab casing either way for the CSS class name. For example, if the component's name is SomeComponent then the CSS block class name will be some-component. If the component's name is another-component then the CSS block class name will be the same.

Block Modifiers

If you bind an object with properties to the directive then anything that evaluates as truthy will be converted to kebab casing and used as a block modifier. It is also possible to add a block modifier onto a child component's context. The below example will add the following CSS classes.

  • my-component
  • my-component--bold-text
  • my-component--italics
<script>
export default {
  name: 'MyComponent'
  setup() {
    const someConditional = ref(false);
    return { someConditional };
  }
};
</script>

<template>
  <div v-bem="{ boldText: true, underline: false, italics: true, someConditional }">
    Some Text
  </div>
</template>

If a modifier is permanent and does not need to be evaluated then you may use the below syntax. The classes will be the same as above.

<script>
export default {
  name: 'MyComponent'
};
</script>

<template>
  <div v-bem.boldText.italics>
    Some Text
  </div>
</template>

You can also mix these two syntaxes together. The result will be the same. The object values inside of the quotations will take precedence.

<script>
export default {
  name: 'MyComponent'
};
</script>

<template>
  <div v-bem.boldText.italics="{ underline: false }">
    Some Text
  </div>
</template>

Element

You may add an element CSS class using the below syntax. The block portion will still use the component's name. The below example will generate CSS element classes called my-component__some-elem and my-component__text respectively.

<script>
export default {
  name: 'MyComponent'
};
</script>

<template>
  <div v-bem>
    <span v-bem:someElem>Some Text</span>
    <span v-bem:text>More Text</span>
  </div>
</template>

Element Modifiers

The syntax remains the same for element modifiers as it does for block modifiers. The below example will generate the following classes.

  • my-component__some-elem--bold
  • my-component__some-elem--underline
  • my-component__text--underline
<script>
export default {
  name: 'MyComponent'
};
</script>

<template>
  <div v-bem>
    <span v-bem:someElem="{ bold: true, underline: true, center: false }">Some Text</span>
    <span v-bem:text="{ bold: false, underline: true }">More Text</span>
  </div>
</template>

Here is that example again using the alternative syntax if the modifiers do not need to be evaluated.

<script>
export default {
  name: 'MyComponent'
};
</script>

<template>
  <div v-bem>
    <span v-bem:someElem.bold.underline>Some Text</span>
    <span v-bem:text.underline>More Text</span>
  </div>
</template>

Once again with the combined syntaxes.

<script>
export default {
  name: 'MyComponent'
};
</script>

<template>
  <div v-bem>
    <span v-bem:someElem.bold.underline="{ center: false }">Some Text</span>
    <span v-bem:text.underline="{ bold: false }">More Text</span>
  </div>
</template>

Block Mod in Child Component Context

If you have a BEM class mod defined in the styles of a reusable component, but you want to trigger that mod in the context of the consuming component (the parent), then you can specify the directive argument as self. The child component's name or tag will be used to determine the block and the mod will be determined like normal. The example below will generate the following CSS classes for the child component and add them to the child component CSS class list.

  • child-component--bold
  • child-component--underline
<script>
import ChildComponent from './ChildComponent';

export default {
  name: 'ParentComponent',
  components: { ChildComponent }
};
</script>

<template>
  <div v-bem>
    <child-component v-bem:self.bold="{ underline: true, strikeout: false }" />
  </div>
</template>

Plugin Configuration

Name

default: 'bem'

This changes the name the directive is globally registered as by the plugin. This will change the directive in your template. The below example shows adding a block after changing the name to 'css'.

<template>
  <div v-css>Example Text</div>
</template>

Planned Work

  • Add ability to apply BEM mod to child component
  • Add option to manually specify component property that indicates the BEM block instead of using name
  • Add option to configure whether names are kebab cased or not
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].