GithubHelp home page GithubHelp logo

houd1ni / fela-vue Goto Github PK

View Code? Open in Web Editor NEW
7.0 3.0 3.0 1.52 MB

Fela mixin for Vue designed for flexibility yet team-oriented.

Home Page: https://houd1ni.github.io/fela-vue/

License: MIT License

JavaScript 22.81% TypeScript 76.70% HTML 0.50%
vue vuejs fela css-in-js styles css styling strongly-typed

fela-vue's Introduction

fela-vue

Fela toolkit for Vue designed for flexibility yet team-oriented. website wip.

Build Status codecov bundlephobia npm Deps DevDeps (tree-shaking friendly!)

Fela does the great job, but it has no idea how to cook it with Vue. This is what I've created after combining vue's :style and :class attributes to make apps dynamically configured and easiest to write and maintain.

Included as deps:

The plugins are a lite most useful part of fela-preset-web.

USAGE

More about plugins. Several basic are already built in here!

More about enhancers.

In the options object below you can also add other Renderer options

Detailed API Docs are in separate markdowns below

// All of the options are optional.
const options = {
  // Default styles to mix. Does not mix if omitted.
  // Have a look at the example below to see it in action.
  // Either pass a function (then key would be `fdef`):
  defStyles: (componentInstance) => ({ colors: { cyan: 'cyan' }, bold: { fontWeight: 'bold' } }),
  // ... Or an object with your own key:
  defStyles: {
    key: 'fdef',
    value: (componentInstance) => ({ colors: { cyan: 'cyan' } })
  },
  // Modifiers to classes when assigned from templates. See examples below.
  // Each modifier is a condition that is being called with provided class name and context object.
  modifiers: {},
  // Name of styling method. Defaults to `f`.
  method: 'f',
  // Additional fela plugins.
  plugins: [],
  // Additional fela enhancers.
  enhancers: [],
  // Preset configurations.
  preset: {
    // Config for fela-plugin-unit. Same defaults ('px', {}).
    unit: ['em', { margin: '%' }]
  },
  // SSR status.
  ssr: false
}

const renderer = new Renderer(options)

// If Options API. To use globally:
Vue.mixin(renderer.mixin)
// or createApp(App).mixin(stylesRenderer.mixin)

// ... Or per module
export default {
  mixins: [ renderer.mixin ],
  // ...
}

EXAMPLES

** same options object as above **

// main.js
import Vue from 'vue'
import { Renderer } from 'fela-vue'

const renderer = new Renderer({
  ...options,
  modifiers: {
    // Too simple but short c:
    mobile: () => window.clientWidth < 600
  }
})

// Not required.
// Search for documentation link by "DOM helpers" here above.
renderer.setClasses(css`
  .html, .body {
    margin 0
    padding 0
    font-size 18px
  }
`)

// if Options API.
// Vue 2:
Vue.mixin( renderer.mixin )
// Vue 3:
// createApp(App)
//   .mixin((new Renderer(options)).mixin)
//   .mount('#app')

Component example

MyComponent.vue

<template>
  <div :class="f('wrapper')">
    <span :class="f('one')"> It's green! </span>
    <span :class="f('two')"> It's cyan! </span>
    <span :class="f('mobile&one !mobile.two localModifier.bold')">
      It's green when mobile modifier is true and cyan when false. `.` equals to `&` on your taste.
      For Options API the local modifiers named styleMods in mixins (see below in JS)
      For Composition API search for "with Vue Composition API" doc link above.
    </span>
    <span :class="f('three', {color: 'white'})"> you don't see me! </span>
    <span :class="f({color: 'yellow'})"> I do it by myself! </span>
    <span :class="f('one two, bold')"> Combined classes by commas and spaces </span>
    <span :class="f('bold my-kebab')"> And kebab-case! </span>
    <span :class="f('bold myKebab')"> The same! </span>
    <span :class="f('button one')">
      If class is not in local style(), it will be taken from defaults (defStyles), if present.
      Here's button could be taken from there, then merged with `one`
      where is `one` is in priority: right to left principle.
    </span>
    <div v-for="i in [0,1,2]">
      <span
        :class="f((i) => ({color: ['green', 'blue', 'yellow'][i]}))"
      > This way is OK too. </span>
    </div>
  </div>
</template>

<script>
// Uncomment to use literal css: css`...`
// import { css } from 'fela-vue'
import { defineComponent } from 'vue'

export default defineComponent({
  computed: {
    style() {
      // Not required. Use with arbitrary key by `options.defStyles.key`.
      const { colors } = this.fdef

      // Also, it's recommended to return one css`...` with all classes included.
      // Search for a "lit-css" documentation link above.
      // Also search for a "Vue Composition API" to use along it.
      return {
        one: { color: 'green' },
        two: { color: colors.cyan },
        three: ({color}) => {
          fontWeight: 'bold',
          color
        },
        bold: () => ({ fontWeight: 'bold' }),
        // 'my-kebab' is also valid if the same in the template.
        myKebab: { color: 'purple' },
        anotherClass: css`
          background: grey
        `,
        ...css`
          .other-class {
            margin-top: 44; // still ok for fela. will be 44px.
            // you can comment a whole line,
            margin-left: 22 // this's OK too.
            /* block comments are also supported. */
            :hover {
              // no colons and semicolons are ok.
              background grey
            }
          }
          .anotherOne {
            padding: 15
          }
        `
      }
    },
    styleMods() {
      return {
        localModifier: (name, context) => true
      }
    }
  }
})
</script>

It's better to make this computed in the end of a component definition or make a const variable at the bottom and return it from the computed prop.

Also, It's very handy to make snippets for adding style() {} to computed.

fela-vue's People

Contributors

dependabot[bot] avatar houd1ni avatar olegzavrazhindecathlon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

fela-vue's Issues

lit-css ,\n support.

now we can do just .one, .two, .three {} but no

.one,
.two,
.three {}

as many like more that placing them into a line.

Problem with displaying pseudo-elements

.socials {
  position relative

  &:before {
    content ''
    position absolute
  }

  &:after {
    content ''
    position absolute
  }
}

Describe the bug
Pseudo-elements don't display after sources build (minification)

To Reproduce
Steps to reproduce the behavior:

  1. Computed style()
  2. Add a "selector" with pseudo-elements
  3. See the result
  4. Pseudo-elements don't display

Expected behavior
Pseudo-elements display

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):
everywhere

Smartphone (please complete the following information):
everywhere

Additional context
I'll create PR with additional tests later

lit-css bad rule parsing

cssmargin-left: ${0} doesn't emit.
Should omit rule only if value is null or undefined.
Zero value should emit zero.

2.5.0

  • Add class fallback to default classes, if not present in current style() computed.

Compilation-time parser.

Should compile css... in objects when compiling to be able to:

  • Shake some by minifiers
  • Drop runtime parser
  • Make it even faster

Probably should be done in a different project or a major-branch hence it will be a webpack/rollup plugin.

Dependabot updates

Upgrade packages versions
All info in "Pull requests" tab.

Check for security alarms
Add any other context about the problem here.

lit-css typing bug

Using lit-css in typescript may cause the type error:

Argument of type 'TemplateStringsArray' is not assignable to parameter of type 'string[]'.

Lit-css improvements

should support this:

.cls: {
   .red, .green: {
     padding: 5
  }
}

Hence, should support , and spaces as a class name.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.