Coder Social home page Coder Social logo

sulu / web-js Goto Github PK

View Code? Open in Web Editor NEW
21.0 17.0 11.0 126 KB

A js library for controlling your components from your templating engine like twig.

License: MIT License

JavaScript 80.08% SCSS 19.92%
component-library javascript component hacktoberfest

web-js's Introduction

Github CI npm Size Install Size

Web JS

The web-js in connection with web component twig extension gives you simple and efficient way to handle your javascript components over twig.

Installation

NPM

# NPM:
npm install @sulu/web

# Yarn
yarn add @sulu/web

# pnpm
pnpm add @sulu/web

Usage

Create your first component

A component can be created using different JS patterns:

Class Component

// js/components/test-class.js
export default class Test {
    constructor(el, options) {
        this.text = options.text;
        el.onclick = this.say;
    }

    say() {
        alert(this.text);
    }
}

Function Component

// js/components/test-function.js
export default function(el, options) {
    el.onclick = function() {
        alert(options.text);
    };
}

Create your first service

Sometimes you want just run js code which is not binded to a dom element for this services where created. Typically usages are running tracking code functions.

// js/services/log.js

module.exports = {
   log: function(text) {
       console.log(text);
   }
};

Initialize web.js and registering your components and services

import web from '@sulu/web';
import Test from './components/test-class'
import more from './components/test-function'
import Log from './services/log';

// components
web.registerComponent('test', Test);
web.registerComponent('more', more, { defaultOption: 'defaultValue' });

// services
web.registerService('logger', Log);

Embedding in template

For efficient handling it's recommended to use it with a template engine like twig.

Twig

For twig embedding see the web component twig extension.

<button id="{{ prepare_component('test') }}">
    Say Hello
</button>

<button id="{{ prepare_component('test') }}">
    Say Bye
</button>

{% do prepare_service('logger', 'log', ['Hello']) %}

<script src="js/main.js"></script>
<script>
    web.startComponents({{ get_components() }});
    web.callServices({{ get_services() }});
</script>

HTML

You can also use without a template engine and by calling the startComponents and callServices.

<button id="test-1">
    Say Hello
</button>

<button id="test-2">
    Say Bye
</button>

<script src="js/main.js"></script>
<script>
    web.startComponents([
        {name: 'test', id: 'test-1', { text: 'Hello' }}, 
        {name: 'test', id: 'test-2', { text: 'Bye' }},
    ]);
    
    web.callServices([
        {name: 'logger', func: 'log', args: ['Hello']},
    ]);
</script>

The @sulu/web-js provides some components and services which can be registered in your container and be used.

Content Security Policy

If you want to work with CSP and avoid inline scripts you can just write the components into a data attribute and read it from there. E.g.:

<script id="app" data-components="[
        {name: 'test', id: 'test-1', { text: 'Hello' }}, 
        {name: 'test', id: 'test-2', { text: 'Bye' }},
    ]"

    data-services="[
        {name: 'logger', func: 'log', args: ['Hello']},
    ]"
    
    src="js/main.js"></script>

Then the data attribute can be read in the main.js and the components started there.

Web CSS

Beside the js the @sulu/web-js is also shipped with some scss tools to make also creating css easier. They can be found in the scss directory.

Version Update & Publish to NPM (docs for maintainers)

1. Create release on github

Update package.json version on master branch:

git checkout master
git pull origin master
npm version [ major | minor | patch ] --no-git-tag-version
# update version in changelog
git add .
git commit -m "Release <version>"
git push origin master

Generate changelog:

github_changelog_generator --future-release <version>

Copy the text of the last release into github release description and create new release.

2. Publish release

git fetch --tags
git checkout <version>
# Test which files get packed by npm
npm pack --dry-run
# Publish package
npm publish

web-js's People

Contributors

alexander-schranz avatar c00n84 avatar chirimoya avatar dmetzler1988 avatar luca-rath avatar martinlagler avatar popoplanter avatar prokyonn avatar quentinhaettel avatar wachterjohannes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

web-js's Issues

Refactor components with modifiers

Components which toggle modifier classes on some elements should be refactored to make them also work, if the element doesn't have a class. The following code snippet does exactly that. Maybe this can be extracted into a utils.js file

appendModifier = (className: string | undefined, modifier: string): string => {
    if (!className) {
        return modifier;
    }

    return className + '--' + modifier;
};

getFirstClass = (element: HTMLElement): string | undefined => {
    return element.classList[0];
};

It can the be used like this

const containerOpenClass = this.appendModifier(this.getFirstClass(this.container), 'open');
this.container.classList.toggle(containerOpenClass);

Split expand in expand and overlay component

Currently the expand is used for 2 usecases, overlays and things to be open or add a class to it. It is controlled currently over the closeOnEsc if it should be closed. The closeOnEsc is currently not correclty implemented when having multiple overlays open at once or a stack of overlays as this is more complex overlay and the closeOnEsc behaviour should be open moved into an own component. Another way would be moving the EscapeStack into an service.

Split core-js into component-registry and service-registry

Currently services and components are handled in the core.js. As services are only used when you try to set informations like api tokens from the backend to them it would maybe make sense to split this 2 parts of the core.js to keep the build for the website as small as possible.

Get rid of jquery in core.js

Instead of getting a jquery object in the initialize method you should get a pure DOM Document.

If you still need a jQuery object you can wrap the dom document with it:

initialize(el) {
    this.$el = $(el);
}

Its also better to know which components need jquery and which does not as every component itself need to import jquery correctly.

That the core.js is 100% clean of jquery the $.extend need to be replace: https://github.com/massiveart/web-js/blob/783b208d2a5208c409f1a75df613eb9474bb4272/src/core.js#L194

Add ability to set defaultOptions when registering a new component

Add ability to set defaultOptions when registering a new component

e.g.:

web.registerComponent('example', Example, { default: option });

The default options will be merged with the given options and can be overwritten this make it easier to create reusable components.

Add container link scss implementation

Sometimes a whole container should be linked this can be done by adding the following mixin to our toolset:

@mixin containerLink() {
    &::after {
        content: '';
        position: absolute;
        height: 100%;
        left: 0;
        top: 0;
        width: 100%;
    }
}

Usage: (https://jsfiddle.net/p9zcoqm5/10/)

<article class="test">
     <img src="http://placehold.it/200x100" alt="test">
 
     <h3>Title</h3>

     <a href="/test" class="test__link">
            Link
     </a>

     <a class="test__author"  href="/author">
            Author
     </a>
</article>
.test {
    position: relative;
    background: red;
    width: 200px;
}

.test__link {
    @include containerLink();
}

.test__author {
     position: relative;
     z-index: 10; // not needed when element is after link
}

Add passive event listener patcher / forcer

function forcePassiveEventListeners(eventNames) {
    const func = EventTarget.prototype.addEventListener;
    EventTarget.prototype.addEventListener = function(...args) {
        if (eventNames.includes(args[0])) {
            args[2] = passiveEvents ? {
                passive: false,
            } : false;
        }

        func.call(this, ...args);
    };
}
forcePassiveEventListeners(['scroll', 'touchmove', 'touchstart']);

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.