Layout`s
packer 2.0

Web layout environment
with modular Dart Sass framework

Powered by unbywyd.

bitbucket
Ungic concept Ungic concept

What`s new?

About active version

The project is still on an unstable version < 1.0 and I'm doing everything possible to stabilize it. What does it mean? It works and fulfills its requirements but the project still requires bugs correction and additions for full work with it.

New features

Sass syntax in internal style tags!

<style sass>
    body {
        h2 {
            font-size: 2em;
        }
    }
</style>

The html plugin will automatically process and compile sass styles in css.

Integration with sass components

Now the rules for the sass components can be written directly in html!

// source/html/index.html

// Create style section in html document
<div class="component">
    <header>
        <a href="">Link</a>
        <style sass="ungic" lid="header">
            a {
                font-size: 1.2em;
                display: block;
                width: 200px;
                text-align: right;
            }
        </style>
    </header>
    <footer>
        <a href="">Link</a>
        <style sass="ungic" lid="footer">
            // Get access to this component
            @use "ungic.components.ungic" as this;
            @use "ungic.components.ungic.theme" as theme;
            a {
                font-size: 1.4em;
                color: theme.color(primary, .6);
            }
        </style>
    </footer>
</div>


// source/scss/components/component/render.scss

// and just include it in your sass component
@use ".core" as this;
@use ".core/theme" as *;
@use "functions" as *;
@use "mixins" as *;

@include this.component {
    header {
       @include meta.load-css("ungic.from-html.header");
    }
    footer {
        @include meta.load-css("ungic.from-html.footer");
    }
}

// Result in the built css file
.component header a {
    font-size: 1.2em;
    display: block;
    width: 200px
}

[dir=ltr] .component header a {
    text-align: right
}

[dir=rtl] .component header a {
    text-align: left
}

.component footer a {
    font-size: 1.4em;
    color: #c4fd98
}

.un-inverse .component footer a {
    color: #3e8209
}

All styles that are transferred to the sass component will be processed as with all the features of the sass framework! Will support RTL, inversion, theming etc.

Note! These styles are passed to the sass plugin and are removed from the html document!

About packer

Ungic packer is the environment for web coder, its purpose is to facilitate the preparation of materials for front-end, but rather, helps to solve the following tasks:

Basic tasks

  • To prepare a structure for the future web template
  • To provide a local server for working with project files
  • To provide live server
  • To provide the necessary tools for web coder

HTML preparation

  • To provide the ability to partition pages to (templates, html parts, markdown and text files) for multiple inclusion in your project.
  • To provide full-fledged work with popular template engines such as: Handlebars, Mustache, Underscore, Pug
  • To provide work with dynamic data for templates (JSON, YAML, QueryString, SCSS options - the possibility of a sass ungic framework)
  • To provide tools for debugging
  • To provide helpers to quickly render icons and include static project files
  • To provide html5 validation
  • To provide AMP page validation
  • To provide release implementation functionality
  • To provide html minification and optimization
  • (New) to provide optimization internal scripts (Merging, processing with babeljs, compressing)
  • (New) optimization internal styles (Merging, processing with postcss and cleancss, compressing)
  • (New) including local external css (link[rel="stylesheet"]) to internal styles (style tag) with replacing url relative to host or relative path.
  • (New) including local js files to internal scripts.
  • (New) full release build relative to html document (A release will be compiled only with those icons and styles that were used in a particular document).
  • (New) internal sass styles in style tags with sass/scss attr.
  • (New) integration of internal sass styles with scss components, see more

Web icons preparation

  • To provide optimization SVG files
  • To provide functionality for packaging icons into web fonts
  • To provide functionality for packaging SVG icons into SVG sprites
  • To provide functionality to image processing and sprite generation
  • To provide functionality to import and export icons
  • To provide release implementation functionality

CSS preparation

To work with css, i developed a sophisticated framework that allows you to write components quickly and use them in your projects, each component can interact with another component using its functionality, in addition to components, there are other features, the features of the framework will be listed below

  • Based on Dart Sass
  • Modularity concept and component implementation
  • Styling a project and inheriting components of project styles
  • Functionality for color inversion and automatic theme inversion
  • Implementing themes and supporting multiple themes
  • Full RTL support
  • Postcss handling (Autoprefix, cleancss, rtl-css, ungic plugins to export themes)
  • Export scss options to JSON and directly to html plugin for template generation
  • Integration with an icon plugin (There are two virtual components sprites and font-icons which can be included in sass components)
  • Release implementation
  • (New) now, with the build of the release, it is possible to take out not only additional themes in separate files, but also inversions styles for them!

See more and demo of features

Get started

  1. First, install the global library using npm npm install ungic -g.
  2. Create an empty directory, go to the directory itself and perform the initial installation with ungic init command:
    > mkdir mydir
    > cd mydir
    > ungic init
    

    But first, it is recommended to initialize the npm (optional)
    > mkdir mydir
    > cd mydir
    > npm init
    > ungic init
    
    After initialization, the ungic packer will generate the necessary directory and file structure, you can get to work!
  3. To get started you should run the development environment with ungic run command

After the above actions, the server is successfully started and ready to accept any changes made in the source directory and after starting, the command line has access to commands for managing plugins

Commands list:

Global commands

  • ungic --help - It will returns the project version
  • ungic --version - It will returns the packer version
  • ungic --log, -l - Enable or disable logging to the console
  • ungic --mode, -m - Providing the mode configuration. Manipulates NODE_ENV environment variable. [default: "development"]

Commands after running a project

  • --help - It will returns the help about the active menu
  • exit - Action back or exit
  • html - Switch to html plugin menu
    • valid <path> - Check page from the dist directory using validator.w3.org
    • amp_valid <path> - Check page from the dist directory using amp-validator
    • create <name> - Create New Page
    • release - Create release
    • pages - Show list of pages
    • unwatch - Skip file changes for this plugin
    • watch - To watch file changes for this plugin
    • remove <name> - Remove page
  • scss - switch to scss plugin menu
    • create <cid> - Create sass component
    • release [name] - Assemble components in a release
    • components - Show list of existing components
    • remove <name> - Remove component
    • unwatch
    • watch
  • icons - switch to icons plugin menu
    • export - Export svg icons to json file
    • import - Import svg icons from exported file
    • release - Create release
    • unwatch
    • watch
  • other - switch to other menu
    • install_demo - Install demo content
    • create_config - Generate a configuration file if the project was initialized

Friendship with Webpack

Ungic packer is very suitable for working with webpackor rather, it closes the part that is not quite suitable for the webpack.

I believe that the webpack is good to use for working with JS but for working with styles (css), html and icons still better to use the ungic packer, since it was created just for this, it allows you to start working after entering only one ungic run command, and you get:

  • Live server and you don't need webpack-dev-server! Just add watch: true option to your webpack configuration and configure file output to dist directory of the ungic packer. Live server of ungic can determine when to reload the page, and when to update files without reloading.
  • A complete style environment: SASS preprocessor, postcss postprocessor, postcss plugins as autoprefixer, rtl-css, clean-css and ungic sass framework features (Project concept, modularity, components, color inversion, themes and more).
  • Automatic processing of svg files and conversion to web icons (sprites or fonts)
  • Automatic image processing and conversion to sprites
  • Full integration between icons and sass (There are modules that you can include to sass components)
  • Almost any job with html and with template engines (It is possible to work with temporary data such as JSON or YAML)
  • Full integration with sass framework, inclusion of components to the page, receiving data from sass directly to template engines
  • Release and Package Management (You can to pack different sass components with different themes, you can to pack only specific icons and more.)
  • And many other features, see here.

Webpack it`s a wonderful thing but ungic complements it. You can use them together!

Documentation

Describing all the functionality is a very difficult job, which is sometimes not worth the time spent, so it was decided to make demo content that comes bundled, to install the demo go to the other menu and call demo command


However, there are some subtleties about which I write below

How to configure plugins of project

After clean installation without npm initialization, ungic.config.json configuration file will be generated in the project directory, but if the installation was made after npm init then you have to create the file yourself or use the other > create_config command in the cli menu after the project starts.

Configuration works by JSON schema and ajv, so you can see what options can be taken from configuration schemes:

Sass framework documentation

See the documentation for the sass framework

Sass framework

Ungic sass framework based on Dart sass which allows you to immerse yourself in the process of modular development.

Ungic sass framework is a platform for writing your own components and styles, this framework does not contain ready-made components, but soon I will try to process my existing components and transfer them to this framework and then share them.


The main features of this framework can be read here, below I will describe the principles of its work, also see examples in demo installation package. Scss framework consists of the following parts:

Each of the above listed parts will be described in detail below. And also you can familiarize yourself with the algorithms of the framework:

Demo of main features:

I made themes for this site very fast and not perfect, but you can really appreciate it on my site (switch to night and look carefully at all the pictures on the site).


Project

The project must be configured before starting the development of components. The project consists of the following parts:

Themes

This directory is in the project directory and containing the sass files, each file is a theme configuration file, see example file. All components in the development environment are generated based on the selected theme, by default is the default.scss theme. You can change this by configuring the build configuration file.

When creating a release, you can generate a specific component or set of components with any number of themes, each theme can be separated into a separate file, to connect a theme, you just need to set the class name of the theme with the name of the parent DOM element (Recommended set to body or html tag). In addition, an invert version will also be generated for each theme!. Example for using:

<body class="un-invert un-theme-godard">
    <div class="mycomponent">
        Hi!
    </div>
</body>

Each theme consists of colors ($colors) and configurations ($conifg) that are responsible for the functionality of the theme.

What is Theme, a bit of theory

Css rules in the sass framework are generated exclusively with components, the render file is responsible for this. All properties that contain color should use the theme functionality. When making rules, all properties that contain color should use the theming functionality and should not be specified directly, example:

// components/mycomponent.render.scss
@use ".core" as this;
@use ".core/theme" as theme;

@include this.component {
  color: theme.color(text-color); // It is right
  border-color: #FFF; // It is not right!
}

The framework has a very powerful functionality for working with color, each theme consists of a set of colors, you can darken or lighten these colors, you can pre-create palettes for each color, examples:

// components/mycomponent.render.scss
@use ".core" as this;
@use ".core/theme" as theme;

@include this.component {
  /*
  *   Lighten the color by 50% relative to the darkest color of the theme,
  *   provided that the active theme is light or darken by 50% the color relative
  *   to the darkest color of the theme, provided that the active theme is dark
  */
  color: theme.color(text-color, .5);

  /*
  *   Get gray color. Will be calculated automatically relative to
  *   the lightest and darkest color of the theme
  */
  color: theme.gray();

  /*
  *   Get gray color with offset
  *   90% lighter if the theme is light and vice versa
  */
  color: theme.gray(.9);
}

// project/themes/default.scss
$palettes: (
    primary: (
        lighten: #e8f2c7,
        darken: #4c5d15
    )
);

// components/mycomponent.render.scss
@use ".core" as this;
@use ".core/theme" as theme;

@include this.component {
    /*
    *   Get tint of palette for text-color relative to theme type (light or dark)
    */
    color: theme.color(primary, theme.subs(darken, lighten));

    /*
    *   If the tint exists, otherwise lighten / darken (Depends on the type of theme)
    */

    $darken: -.5;
    @if theme.has-palette(primary, 'darken') {
        $darken: 'darken';
    }
    $lighten: .5;
    @if theme.has-palette(primary, 'lighten') {
        $lighten: 'lighten';
    }
    border-color: theme.color(primary, subs($lighten, $darken));

    /*
    *   Check relative to theme name and theme type
    *   If the active theme is the default then if the active theme is light it will return darken and for dark - lighten,
    *   for any other theme will return .5,
    *   for a light theme, it brightens the color by 50% and for dark vice versa
    */
    border-color: theme.color(primary, subs-theme(default, subs(darken, lighten), .5));
}

In addition, you can control the inversion of colors.

Using themes in components

Each component has its own core, which includes functionality for working with the theme of the project, just include the theme in the component:

// Render file
@use ".core/theme" as theme;
or
@use ".core/theme" as *;

After that, get access to all theme functions and mixins:

// Render file
@use ".core" as this;
@use ".core/theme" as theme;

// Get config theme
$config: theme.config();

// Use color function
@include this.component {
    color: theme.color(text-color);
    &-title {
        color: theme.color(text-color, .2); // 20% lighter
    }
}

Note! When inversion, the color function changes the direction of light when lightening or darkening


You can manage colors relative to theme type, for the dark and light version using the subs function of theme module

// Render file
@use ".core/theme" as theme;
@debug theme.get(theme-type); // Light

.mycomponent {
    color: theme.color(theme.subs(white, black)); // Set colors relative to theme type
}
Colors / Palettes and Tints
Colors

Each theme consists of a set of required colors, which are set in theme of project, each color can be modified using smart algorithm. This algorithm allows you to darken or lighten colors with a shade of hue, as well as relative to the light between the main colors of the theme (The text color of the light theme is the darkest color then background color of the light theme is the lightest, with the inversion the opposite)

Theme functions using this algorithm:

  • lightness($color, $percent) - Lightens and darkens color without changing hue
  • brightness($color, $percent, $hue-offset: null) - Lightens and darkens the color changing hue

Note! The second argument to the color function uses the brightness method

// Render file
.mycomponent {
    color: theme.color(primary, .9); // 90% lighter if the theme is light and 90% darker at inverted
}
Palettes and Tints

When you need a specific hue for a particular color, relying on percentages is very difficult, so you can create a palette for it and place all its tints

// Customize themes in the configuration file
$palettes: (
    primary: (
        lighten: #e4ffb5,
        darken: #263211
    )
);

// And use in render file
@use ".core/theme" as theme;
.mycomponent {
    color: theme.color(primary, theme.subs(lighten, darken)); // Get specific tint relative to theme type
}

Note! All rules which should return the css, must be written in render file your component

Configuration

Here may be any configuration options that can be used throughout the project.

// Render file
@use ".core" as *;
@debug project-config();

Styling properties

File with css properties, initially contains a whole list of all properties with a default value. Properties are used to style the component. Each component in the project inherits these properties. The component also has personal properties that overlap project properties. There are special functions for working with properties:

  • border
  • padding
  • margin
  • font
  • background
  • list-style
  • list-style
  • overflow

These functions partially imitate the subtraction of single properties. To use a specific property when writing rules, there is a prop($prop, $args...), this function supports all of the above functions and also returns any other properties.

Note! All properties are inherited from the project to components, and components can redefine them with personal properties, methods for working with properties return the combined properties of the project + component

// project/properties.scss
$margin-bottom:15px;
$margin-left:5px;
$margin-right:0;
$margin-top:0;

// components/mycomponent/properties.scss
$margin-right:10px;
$margin-left:10px;

// components/mycomponent/render.scss
@use ".core" as *;
@debug prop(margin); // 0 10px 15px

Note! The personal properties of components can be redefined in reassignment project file.

Reassignment

This file is used to override the personal configuration and properties of each components.

$cid: null !default;
$config: () !default;
$properties: () !default;

@if($cid == helloworld) {
    $config: map.merge($config, (...));
}

As you can see, this file receives three parameters programmatically:

$cid: null !default;
$config: () !default;
$properties: () !default;

After that, this file returns already processed $config and $properties variables (Programmatically, this is not visible in the file). The challenge is to change the incoming data regarding the component identifier.


System core of the framework

There are two system modules in the framework.

  • meta
  • utils

Meta

This module contains various functions and mixins for working with the fremvork.

I would like to note such an important function as export($cid, $oid, $data) this function is responsible for exporting data from sass

// components/mycomponent/once.scss
@use "ungic.meta" as un-meta;
$export: un-meta.export($component_id, $option_id, $data);

Note! You should not use this function from your components, since each component has its own export function!

// components/mycomponent/once.scss
@use ".core" as *;
$export: export('myoptions', (color: #FFF, andmap: (name: Artem)));

Utils

Contains some pretty useful tools.

Using system modules
@use "ungic.meta" as un-meta;
@use "ungic.utils" as un-utils;

Components

The component consists of the following parts:

  • Core
    • Configuration
    • Theme
    • Functions
    • Mixins
  • Functions (Optional)
  • Mixins (Optional
  • Properties
  • Configuration
  • Render
  • Once

Core

Core of component

Core of component consists of the main functionality of the framework, the core is configured in the software part when rendering components. The core is the system part of the component and you do not need to change it!

Note! The core component is a system part, it should not be changed!

The core should be included at the beginning of the component files as a module using @use: @use ".core" as this

Configuration

The core configuration, this is the configuration of the component, to get options, use the .config() method of module as function:

@use ".core" as this;
$config: this.config();

The component core also has access to the project and its configuration:

@use ".core" as this;
$project: this.$project;
$project-config: this.project-config();
Theme

The framework has project themes with which all components are generated, each component has access to the functionality of the active rendering theme.

Note! In ungic sass framework, components should not use free colors, everything related to colors should go through themes.

The functionality of the theme is part of the core and is included as a separate module:

@use ".core" as this;
@use ".core/theme" as theme;

@include this.component {
    color: theme.color(primary, .9); // Darken 90% of the primary color relative to darkest color of active theme
}

See also Using themes in components.

Functions / Mixins

All core functions and mixins can be seen from the source code of the modules for functions and for mixins.

Personal functions and mixins

If your component has functionality, and you have functions or mixins they must be in their own directories (functions, mixins), hierarchy can be any, as well as the number of files but they should all be forwarded from the index file!

Each component has access to the functions and mixins of any component for this you can include them as a module @use "ungic.components.CID.functions" as *; and @use "ungic.components.CID.mixins" as *;

// I have two components buttons and cards

// components/cards/render.scss
@use "ungic.components.buttons" as buttons; // Get core of component
@use "ungic.components.buttons.mixins" as btnsMixins;

@use ".core" as this;
@use "mixins" as *;

@include this.component {
    .btn {
        /*
        *   Any component has exist() method, even if it does not exist in the project
        *   required to avoid sass rendering errors if component is not exist in the project
        */
        @if buttons.exist() {
            @include btnsMixins.buttonsRender(); // Render buttons from buttons component
        } @else {
            @include buttonsRender();  // Otherwise own render method
        }
    }
}

Personal styling properties

See styling properties of project, personal properties of a component override project properties.

Configuration

Any personal variables or configuration data required by the component. The configuration for the component is specified in a personal config.scss file, or it can be forwarded out of it. The configuration file is not included directly as a module!

Note! config.scss personal file of component should not be used as a module! Only by using .config() core method.

In order to get the config of component you need to use the config() method from its core. The fact is that this allows the project to intercept all configurations of each component and, if necessary, redefine them, see Reassignment

// components/mycomponent/render.scss

@use ".core" as *;
$config: config();

Render

This file is responsible for rendering the component, it is this file that should return all the rules of the component, for all rules from render file, themes are generated, as well as theme inversions (if required).

The following helpers exist to write the rules:

  • component mixin core
  • this mixin core
  • wrap mixin core
  • and mixin core
  • nest mixin core
Using

Using the helpers listed above, it is possible to write rules regarding an element selector without leaving it. The mixin component creates a selector with a class named component and accepts the @content:

@use ".core" as this;

// components/mycomponent/render.scss
@include this.component {
    color: color(text-color);
    // rules
}

// output.css
.mycomponent {
    color: #000
}

There are three helpers that allow you to stay in this construction.

  • wrap
  • and
  • nest

They allow you to go outside, create sister selectors, and more.

@use ".core" as *;
// components/mycomponent/render.scss

@include component {
    &-title {
        @debug &; // .mycomponent-test
    }
    &-big {
        @debug &; // .mycomponent-big
    }
    &.method {
        @debug &; // .mycomponent.method
    }
    &-body {
        @include this {
            @debug &; // .mycomponent-body .mycomponent

            &-title {
                @debug &; // .mycomponent-body .mycomponent-title

                // Go back?
                @include wrap('.un-inverse') {
                    @debug &; // .un-inverse .mycomponent-body .mycomponent-title
                }

                // If has a method .mycomponent.mycomponent-big ?
                @include wrap('-big') { // or without addition this.wrap(this(-big), false)
                    @debug &; // .mycomponent-big .mycomponent-body .mycomponent-title
                }

                // Several selectors?
                @include wrap('.un-inverse, .un-theme-allora') {
                    @debug &; // .un-inverse .mycomponent-body .mycomponent-title,  .un-theme-allora .mycomponent-body .mycomponent-title
                }


            }
        }
    }

    .button {
        @debug &; // .mycomponent .button
        ....
        // If there is a method
        @include and(-big) {
            @debug &; // .mycomponent-big .button
            span {
                @debug &; // .mycomponent-big .button span
            }
        }
        // Same
        span {
            @include and(-big) {
                @debug &; // .mycomponent-big .button span
            }
        }

        @include and('-big, -small, .small, .big') {
            @debug &; // .mycomponent-big .button, .mycomponent-small .button, .mycomponent.big .button, .mycomponent.small .button
        }
    }
    &-button {
        @include and('.method') {
            @debug &; // .mycomponent.method-button
        }
        @include and('-method') {
            @debug &; // .mycomponent-method-button
        }
    }
    .alert {
        @include and(':hover,:focus') {
            @debug &;  // .mycomponent:hover .alert, .mycomponent:focus .alert
        }
    }
    &-alert {
        .button {
            @include wrap(':hover,:focus') {
                @debug &;  // .mycomponent:hover .mycomponent-alert .button, .mycomponent:focus .mycomponent-alert .button
            }
        }
    }

    .title {
        @include nest('+' + cid(true)) {
            @debug &; // .mycomponent + .mycomponent .title
        }

        @include nest(h3) {
            @debug &; // .mycomponent h3 .title
        }
    }
    @include nest('+') {
        @include this {
            .title {
                @debug &; // .mycomponent + .mycomponent .title
            }
        }
    }
}

Once

Serves to perform operations that will be performed only once. This is where you should export arbitrary data from sass using export() core method


Component theming

All theming goes through the functionality of the theming. The theme must be configured in the project and used in components. Each theme can be generated in a separate file for each component, in addition, each theme supports automatic inversion. Theme to the development environment is only one, but with the release, you can select any number and set one of them as the default theme.


About Inversion

One of the main features of the sass framework is the theming and automatic theme inversion. The theme may be light or may be dark, this calculates the framework relative to the text and background colors. Each theme consists of colors, palettes and tints, in the sass framework all work with colors goes through the theme functionality, that is why the inversion is very smooth. In addition, there is a functionality that allows you to control colors for a dark or light theme, as well as for inversion. How it works? Rendering takes place in two stages:

  • The first stage - rendering with default theme settings
  • The second stage - at the software level, the settings are changed in the opposite direction

After that, with the help of postсss plug-ins, all properties that are not related to colors are cut out and class .un-inverse added before each selector. What does it mean? We get two versions in one file at once and can control the inversion by adding a .un-inverse class, for example, to a body element of your html document. When rendering with several themes, we get a wrapper with the name of the theme example:

// components/mycomponent/render.scss

.mycomponent {
    .title {
        color: color(text-color);
    }
}

// We get
.mycomponent .title {
    color: #000
}
.un-inverse .mycomponent .title {
    color: #FFF
}

// With themes

.mycomponent .title {
    color: #000
}
.un-theme-mytheme .mycomponent .title {
    color: #444
}
.un-theme-mytheme.un-inverse .mycomponent .title {
    color: #fafafa
}

In the case of inversion, as well as with the temization, property values that are not related to color will not be duplicated except those properties that have a value other than color, for example inherit or transparent, also the same colors will not be duplicated!

The following inversion tools are available:

color()

theme.color($color-name, $offset, $hue-offset); - function, the $offset argument controls the light color of the selected color, when inverted, this argument also changes direction

// components/mycomponent/render.scss

@use ".core/theme" as theme;
.mycomponent {
    /*
    *   For a light theme, it will darken the color on 90%
    *   But for the dark, it will lighten the color on 90%
    */
    color: theme.color(text-color, .9);
}

You can make rules considering various factors, you can do the following:

  • You can make css rules regarding a light or dark type of theme
  • You can make css rules exclusively for dark or light type of theme
  • You can make css rules exclusively for inversion type of theme
  • You can make css rules exclusively for specific theme

See methods below to implement these features.

is-inverse, ignore-inverse, is, subs-theme, subs, is-theme, is-type, is-light, is-dark

You can control inverse with the following mixins:

is-inverse

Apply any rules for inversion only!

// components/mycomponent/render.scss

@use ".core/theme" as theme;
.mycomponent {
    @include theme.is-inverse {
        display:none;
        color: color(primary, .5);
    }
}
ignore-inverse

Ignore any rules for inversion

// components/mycomponent/render.scss

@use ".core/theme" as theme;
.mycomponent {
    @include theme.ignore-inverse {
        color: color(primary, .5);
    }
}

The control of classes is naturally carried out manually with the help of javascript

subs($if_light, $if_dark) function

subs() function returns values relatively light and dark theme theme.subs($if_light, $if_dark)

// components/mycomponent/render.scss

@use ".core/theme" as *;
.mycomponent {
    color: color(subs(primary, secondary));
    background-color: gray(subs(.4, .8));
}
subs-theme($theme_name, $value, $default: null) function

You can set specific value relative to theme

// components/mycomponent/render.scss

@use ".core/theme" as *;
.mycomponent {
    // Set primary color for allora theme and secondary for any other
    color: color(subs-theme(allora, primary, secondary));
}
is-type($type) mixin

To generate rules exclusively for theme type (dark or light)

// components/mycomponent/render.scss

@use ".core/theme" as *;
.mycomponent {
    @include is-type(light) {
        display:none;
    }
}

You can also use is-light() and is-dark() mixins for this

Note! To control the inverse of the theme, there is a class .un-inverse it should be specified to the top element on your page, default it is HTML tag, it can be configured in build_schemes.json file

is-theme($theme-name)

To generate rules exclusively for specific theme

// components/mycomponent/render.scss

@use ".core/theme" as *;
.mycomponent {
    display: block;
    color: color(primary, .5);
    @include is-theme(default) {
        display:inline-block;
    }
}
is($prefix)

Ignores the theming and inversion and will add an arbitrary prefix before the selector. Useful for controlling manually the type of theme, example:

// components/mycomponent/render.scss
@use ".core/theme" as *;

.visible-only-dark,  .visible-only-light {
    display: none !important;
}
@include is('.un-dark') {
    .visible-only-dark {
        display: block !important;
    }
}
@include is('.un-light') {
    .visible-only-light {
        display: block !important;
    }
}
                        

Build configuration

To configure the assembly of sass components in a dev environment or during release, you need to configure the build_schemes.json configuration file which located by default in source/scss directory

See its JSON scheme from source code.

//Example
{
    "single_theme_prefix": false,
    "dev": {
        "config": {
            "theme_mode": "external",
            "inverse": true,
            "autoprefixer": true,
            "direction": "ltr",
            "opposite_direction": true
        },
        "default_theme": "default"
    },
    "release": {
        "config": {
            "default": {
                "theme_mode": "external",
                "inverse": true,
                "autoprefixer": true,
                "direction": "ltr",
                "opposite_direction": true
            }
        },
        "build": {
            "main": {
                "config": "default",
                "components": "*",
                "default_theme": "default",
                "version": "0.0.1"
            }
        }
    }
}

In this file you can register any number of Build release schemes and when release through the command line, specify the identifier from the scheme, from the example above, there is only one type of scheme with the main name


Generate multiple themes for project

Ungic sass framework can generate projects with an unlimited number of themes but not in dev environment, in a dev environment, each component generates its own css file with one default theme. The default theme is assigned in the build_schemes.json file.

Also, when creating a release from the command line, you can select any existing themes, in addition, you can control the making of css rules relative to themes

Read more


Icon Integration

The framework has two sass modules that can be included in the sass components, provided that the Icon Plugin generates this type of icon

  • 1. sprites
  • 2. font-icons
@use "ungic.sprites" as sprites;
@use "ungic.font-icons" as ficons;

@if mixin-exists(render, sprites) {
    @include sprites.render();
}

@if mixin-exists(render, ficons) {
    @include ficons.render();
}

Including a component in another component

You can use the functionality of each component in another component, you can even include rules of another component using the load-css method:

// components/cid1/render.scss

@use "ungic.components" as cids;
@use "ungic.components.cid2.functions" as functions_of_cid2;  // Get personal functions of component
@use "ungic.components.cid2.mixins" as mixins_of_cid2; // Get personal mixins of component
@use "ungic.components.cid2" as cid2; // Get core of component
@debug cids.$cids; // Get all components id
@debug cid2.cid(); // cid2
@debug cid2.config(); // Get config
@debug cid2.prop('padding'); // Get padding property of cid2 component

.mycomponent {
    @include meta.load-css('ungic.components.cid2.render'); // Include component rules
}


Export data from sass

Ungic sass framework exports data from sass to json, this is necessary for the following:

  • Data is transmitted to the html plugin, and it generates templates based on this data.
  • Saves to a json file for later use

By default, sass framework exports the configuration of each component and of project to a sass-options.json file in dist directory.

Any data can be exported from components, the export method is used for this

// components/mycomponent/once.scss

@use ".core" as this;

$colors: (#FFF, #000);
$config: this.export('mydata', (color: #FFF, asList: $colors, asMap:(
    name: 'Artem'
)));

Note! Exporting data preferably from once.scss file, this file is compiled only once.

You can export anything you like, all the data will appear in the sass-options.json file, besides that, you can use this exported option directly in html plugin, just use include handlebars helper with sass attribute and indicate the component id in it, to filter and get specific options, you can specify a more accurate path using dot.

// source/html/index.html
....
<body>
// Get all data of sass mycomponent
{{{include "templates/template.hbs" sass="mycomponent"}}}

// Get specific data option of sass mycomponent
{{{include "templates/template.hbs" sass="mycomponent.mydata"}}}

// templates/template.hbs
{{{debug}}} // See data
</body>
...

It works without any hitches, no need to restart the project, no need to wait, it all works in real time! All data is tracked for changes and reassemble all templates that use any data that has been changed!

You can enable multiple options at once

// source/html/index.html
{{{include "template.hbs" sass="mycomponent.mydata, mycomponent2.otherData"}}}

Html integration

In addition to data integration for template generation, there is also an automatic inclusion of CSS styles of components in the development environment to html pages.

To include a generated component styles use un-pine tag

// source/html/index.html

<head>
    <un-pipe css="base, normalizer, buttons, grid"></un-pipe>
</head>

RTL tools

RTL support is provided using postss processing with postcss-rtl plugin. There are several functions of utils module to make it easier to write styles with RTL support:

  • dir($ltr, $rtl) set LTR and RTL values
  • rtli($val) or rtl-ignore($val) RTL ignore
  • rtl-prepend($ltr, $rtl-prepend, $sep:' ') Prepend method to RTL
  • rtl-append($ltr, $rtl-append, $sep: ' ') Append method to RTL

Examples:

// components/mycomponent/render.scss

.mycomponent {
    text-align: left;
}

// We get
.mycomponent {
    text-align: left
}
[dir="rtl"] .mycomponent {
    text-align: right;
}

// Ignore tools
@use "ungic.utils" as *;

.mycomponent {
    text-align: rtli(left);
}
// We get only
.mycomponent {
    text-align: left
}

.mycomponent {
    font-family: utils.rtl-prepend('-apple-system, BlinkMacSystemFont, "Segoe UI", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"', 'Heebo', ',');
}

// We get
.mycomponent {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
[dir="rtl"] .mycomponent {
    font-family: Heebo, -apple-system, BlinkMacSystemFont, "Segoe UI", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

You can configure the rendering of RTL in the build configuration.

Reviews

If you like my project, or maybe you don’t understand it, but you still like it, or you don’t understand anything at all and don’t know if you like it, in any case, click Like)

But if you are in the subject and know what to say, then leave your review, thanks