Skip to content

@mgremy ng‐primitives

Miguel Gremy edited this page Jun 19, 2026 · 3 revisions

@mgremy/ng-primitives is a library containing multiple wrappers around the ng-primitives library. Its goal is to provide stylable UI components using TailwindCSS.

Terminology

A primitive provides a functionality (e.g, button, accordion, checkbox).

A directive is a part of a primitive (e.g, accordion-content, accordion-trigger), providing styling capabilities and sometimes parameters (e.g, size, color).

Each directive provides a data attribute indicating its type with the following pattern: data-mgnp-<directive>.

Each directive provides 2 classes, one is directly used to apply CSS on it, the other one can be used for external CSS modification. The patterns are mgnp-<directive> and mgnp-c-<directive>. Each primitive has its own CSS file inside _theme directory.

How to create a directive

In the ng-primitives library, create a new secondary entry point with the same structure as the others:

📦<primitive>
 ┣ 📂src
 ┃ ┣ 📂lib
 ┃ ┃ ┣ 📂mgnp-<directive>
 ┃ ┃ ┃ ┗ mgnp-<directive>.ts
 ┃ ┗ index.ts
 ┣ README.md
 ┗ ng-package.json

Style convention

Define directive style

When creating a new primitive, we need to create its own CSS file inside _theme directory. It must contain all theme definitions for each directive it includes.

Here is the base structure of a CSS:

@layer components {
  .mgnp-<directive> {
    @apply some-tailwind-utilities;
  }
}

Dynamic styling

Directive setup

When a directive style depends on user inputs, the value is provided by the directive to CSS using data attributes:

@Directive({
  /*...*/
  host: {
    /*...*/
    'data-mgnp-<directive>': '',
    '[attr.data-mgnp-<directive>-color]': 'color()',
  },
})

CSS setup

When a style depends on user input, a CSS file is created for each input in a folder with the same name as the directive's CSS file (e.g., for the directive's color, we create the _theme/<directive>/color.css file).

In it, we create dedicated TailwindCSS utilities using @utility keyword, with the following pattern: mgnp-<directive>-<input>-<value>. For example, for the color input, we will create the following utilities:

@utility mgnp-<directive>-color-ui {/*...*/}
@utility mgnp-<directive>-color-primary {/*...*/}
@utility mgnp-<directive>-color-secondary {/*...*/}
/*...*/

It will then be called in the base CSS file using the following syntax:

@layer components {
  .mgnp-accordion {
    /*...*/
    @apply data-[mgnp-<directive>-color=ui]:mgnp-<directive>-color-ui;
    @apply data-[mgnp-<directive>-color=primary]:mgnp-<directive>-color-primary;
    @apply data-[mgnp-<directive>-color=secondary]:mgnp-<directive>-color-secondary;
    /*...*/
  }
}

It's then called at the top of the directive CSS file with the @import rule @import './<directive>/<input>.css';

Clone this wiki locally