@flusys/ng-layout 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +150 -11
  2. package/assets/layout/base/_brand.scss +44 -0
  3. package/assets/layout/{_core.scss → base/_core.scss} +8 -1
  4. package/assets/layout/{_footer.scss → base/_footer.scss} +1 -1
  5. package/assets/layout/{_forms.scss → base/_forms.scss} +3 -3
  6. package/assets/layout/base/_menu.scss +52 -0
  7. package/assets/layout/base/_rtl.scss +230 -0
  8. package/assets/layout/base/_topbar.scss +132 -0
  9. package/assets/layout/base/variables/_common.scss +62 -0
  10. package/assets/layout/classic/_main.scss +14 -0
  11. package/assets/layout/classic/_menu.scss +77 -0
  12. package/assets/layout/classic/_responsive.scss +101 -0
  13. package/assets/layout/classic/_rtl.scss +26 -0
  14. package/assets/layout/classic/_topbar.scss +46 -0
  15. package/assets/layout/{_topbar_nav.scss → classic/_topbar_nav.scss} +31 -15
  16. package/assets/layout/classic/classic.scss +6 -0
  17. package/assets/layout/layout.scss +18 -16
  18. package/assets/layout/modern/_menu.scss +98 -0
  19. package/assets/layout/modern/_responsive.scss +93 -0
  20. package/assets/layout/modern/_rtl.scss +24 -0
  21. package/assets/layout/modern/_shell.scss +59 -0
  22. package/assets/layout/modern/_sidebar.scss +101 -0
  23. package/assets/layout/modern/_topbar.scss +37 -0
  24. package/assets/layout/modern/_variables.scss +114 -0
  25. package/assets/layout/modern/modern.scss +7 -0
  26. package/fesm2022/flusys-ng-layout.mjs +1315 -939
  27. package/fesm2022/flusys-ng-layout.mjs.map +1 -1
  28. package/package.json +4 -4
  29. package/types/flusys-ng-layout.d.ts +171 -64
  30. package/assets/layout/_main.scss +0 -13
  31. package/assets/layout/_menu.scss +0 -188
  32. package/assets/layout/_responsive.scss +0 -128
  33. package/assets/layout/_rtl.scss +0 -482
  34. package/assets/layout/_topbar.scss +0 -215
  35. package/assets/layout/variables/_common.scss +0 -20
  36. /package/assets/layout/{_mixins.scss → base/_mixins.scss} +0 -0
  37. /package/assets/layout/{_preloading.scss → base/_preloading.scss} +0 -0
  38. /package/assets/layout/{_typography.scss → base/_typography.scss} +0 -0
  39. /package/assets/layout/{_utils.scss → base/_utils.scss} +0 -0
  40. /package/assets/layout/{variables → base/variables}/_dark.scss +0 -0
  41. /package/assets/layout/{variables → base/variables}/_light.scss +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @flusys/ng-layout
2
2
 
3
- Application shell for the FLUSYS Angular platform — topbar, sidebar, menu, and signal-based layout state management.
3
+ Application shell for the FLUSYS Angular platform — topbar, sidebar, menu, and signal-based layout state management. Ships two interchangeable layout skins (**classic** and **modern**) that share the same services, menu and topbar components.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@flusys/ng-layout.svg)](https://www.npmjs.com/package/@flusys/ng-layout)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -21,21 +21,21 @@ Use `AppLayout` as the parent route component. All authenticated pages become ch
21
21
 
22
22
  ```typescript
23
23
  // app.routes.ts
24
- import { Routes } from '@angular/router';
25
- import { AppLayout } from '@flusys/ng-layout';
24
+ import { Routes } from "@angular/router";
25
+ import { AppLayout } from "@flusys/ng-layout";
26
26
 
27
27
  export const routes: Routes = [
28
28
  {
29
- path: '',
29
+ path: "",
30
30
  component: AppLayout,
31
31
  children: [
32
- { path: 'dashboard', loadComponent: () => import('./pages/dashboard.component') },
33
- { path: 'products', loadComponent: () => import('./pages/product-list.component') },
32
+ { path: "dashboard", loadComponent: () => import("./pages/dashboard.component") },
33
+ { path: "products", loadComponent: () => import("./pages/product-list.component") },
34
34
  ],
35
35
  },
36
36
  {
37
- path: 'auth',
38
- loadChildren: () => import('./pages/auth/auth.routes'),
37
+ path: "auth",
38
+ loadChildren: () => import("./pages/auth/auth.routes"),
39
39
  },
40
40
  ];
41
41
  ```
@@ -64,7 +64,146 @@ To push user/company profile into the topbar (done automatically by `ng-auth`'s
64
64
 
65
65
  ---
66
66
 
67
- ## 3. Integration Tokens — Auth, Notifications, Language
67
+ ## 3. Layout Skins
68
+
69
+ `AppLayout` renders the skin selected by `LayoutConfig.layoutTheme`. Both skins share every
70
+ service and topbar component — only the shell markup and styling differ, so switching costs
71
+ nothing but a config value.
72
+
73
+ | Skin | Shell | Menu modes |
74
+ | --------- | ---------------------------------------------------------------------------------- | ----------------------- |
75
+ | `classic` | Fixed topbar across the top, sidebar below it, page content in the remaining space | static, overlay, topbar |
76
+ | `modern` | Gradient canvas, transparent sidebar, page content in an elevated rounded card | static, overlay |
77
+
78
+ Set the default in `APP_CONFIG`:
79
+
80
+ ```typescript
81
+ export const environment: IAppConfig = {
82
+ layoutConfig: {
83
+ layoutTheme: "modern", // 'classic' (default) | 'modern'
84
+ menuMode: "static",
85
+ },
86
+ // ...
87
+ };
88
+ ```
89
+
90
+ Users can switch skins at runtime from the theme configurator; the choice is persisted with the
91
+ rest of the layout config unless `isMemorable: false`. Read it back through the service:
92
+
93
+ ```typescript
94
+ readonly theme = this.layout.layoutTheme; // Signal<'classic' | 'modern'>
95
+ readonly isModern = this.layout.isModernLayout; // Signal<boolean>
96
+ ```
97
+
98
+ `menuMode: 'topbar'` renders a horizontal nav, which only the classic skin provides — the modern
99
+ skin falls back to its static sidebar.
100
+
101
+ Every skin renders exactly one menu toggle, and `LayoutService.onMenuToggle()` decides what it
102
+ acts on from the current mode and viewport:
103
+
104
+ | Mode | What the toggle does |
105
+ | ------------------- | ------------------------------------------------------------- |
106
+ | any mode, mobile | Opens/closes the sidebar drawer over a mask |
107
+ | `static`, desktop | Collapses/restores the sidebar in place |
108
+ | `overlay`, desktop | Slides the sidebar in/out over the content |
109
+ | `topbar`, desktop | Shows/hides the horizontal nav row (`topbarMenuVisible`) |
110
+
111
+ ### Source layout
112
+
113
+ ```
114
+ components/
115
+ app.layout.ts # skin switcher — the component you route to
116
+ shared/ # used by every skin
117
+ layout-shell.base.ts # shared open/close, outside-click and body-scroll behaviour
118
+ app.brand-logo.ts # logo + company name home link
119
+ app.menu.ts # menu tree, configurator, footer
120
+ top-bar/
121
+ app.topbar-actions.ts # the whole trailing action rail (search, theme, widgets)
122
+ layouts/classic/ # classic shell — bar, brand block, horizontal nav, sidebar
123
+ layouts/modern/ # modern shell — bar, brand block, page title, sidebar
124
+
125
+ assets/layout/
126
+ base/ # tokens, core, typography, forms, brand, topbar, menu, footer, rtl, utils
127
+ classic/ # classic skin styling
128
+ modern/ # modern skin styling
129
+ ```
130
+
131
+ A skin owns only the parts that actually differ. The brand block, the topbar action rail and
132
+ the menu tree are one component and one stylesheet each, shared by every skin; `base/_topbar.scss`
133
+ and `base/_menu.scss` hold their structure and read the tokens below, and a skin retunes them by
134
+ overriding a token on its own shell class rather than restating the rules.
135
+
136
+ Every colour in both skins resolves from the active `@flusys/ng-ui` theme variables, so preset,
137
+ primary, surface and dark-mode changes repaint the shell automatically.
138
+
139
+ ### Preset-driven chrome
140
+
141
+ A `@flusys/ng-ui` preset (Aura / Lara / Nora) publishes structural tokens alongside its colours,
142
+ and both skins read them — so switching preset restyles the shell, not just the components inside
143
+ it. The classic skin uses them directly; the modern skin clamps each one into its own range with
144
+ `min()` / `max()`, so its card and rows stay softer than a classic sidebar's while a square preset
145
+ still squares them.
146
+
147
+ | Preset token | Classic | Modern |
148
+ | ----------------------------------- | ---------------------------------- | ----------------------------------------------------------------------- |
149
+ | `--f-card-border-radius` | components inside the page | `--layout-modern-radius` — the content card, its topbar and its content |
150
+ | `--f-menuitem-active-radius` | active menu row radius | `--layout-modern-item-radius` — capped at the skin's own `0.625rem` |
151
+ | `--f-menuitem-active-border-width` | accent bar on the active row | same accent bar, drawn in the row's own ink |
152
+ | `--f-topbar-border-width` | topbar bottom border | `--layout-modern-topbar-border-width` — floored at a hairline |
153
+ | `--f-topbar-shadow` | topbar shadow | topbar shadow |
154
+ | `--f-sidebar-border-width` | sidebar trailing border | `--layout-modern-divider-width` — the sidebar footer's divider |
155
+ | `--f-sidebar-radius` / `-shadow` | sidebar corner and shadow | — (this skin's sidebar is transparent on the canvas) |
156
+ | `--f-border-radius-lg` | components inside the page | `--layout-modern-control-radius` — the drawer's collapse button |
157
+
158
+ Every length a preset publishes carries a unit (`0px`, never `0`), because a bare `0` is a
159
+ `<number>` inside `min()` / `max()` / `calc()` and would invalidate the whole expression.
160
+
161
+ A neutral primary — the `noir` swatch, and Nora's signature colour — resolves the primary ramp to
162
+ the surface greys, which would leave the modern skin's canvas too pale for the white ink on top.
163
+ `applyPrimaryPalette` marks the root with `f-primary-noir` for exactly this case (CSS cannot branch
164
+ on a custom property's value), and the skin anchors its canvas in the dark end of the ramp instead.
165
+
166
+ ### Shell geometry tokens
167
+
168
+ Both skins size themselves from one set of CSS variables declared in
169
+ `assets/layout/base/variables/_common.scss` — nothing hardcodes a width, height or z-index, so
170
+ overriding a token in your own stylesheet resizes the shell in both skins at once.
171
+
172
+ | Token | Default | Used for |
173
+ | ------------------------------ | ------------------------ | ---------------------------------------------------------------------------------------------------------- |
174
+ | `--layout-viewport-height` | `100dvh` | Full-height shells — a fixed sidebar always fills exactly 100% |
175
+ | `--layout-topbar-height` | `4rem` | Topbar height, sidebar offset, content padding, dropdown top |
176
+ | `--layout-topbar-inline-padding` | `--layout-content-padding` | Topbar gutters, and where the compact widget menu hangs from |
177
+ | `--layout-topbar-actions-gap` | `1rem` | Space between the action rail's groups |
178
+ | `--layout-topbar-group-gap` | `1rem` | Space inside a group (theme controls, widget menu) |
179
+ | `--layout-topbar-action-size` | `2.5rem` | Diameter of a round topbar action button |
180
+ | `--layout-topbar-action-icon-size` | `1.25rem` | Icon size inside those buttons |
181
+ | `--layout-sidebar-width` | `19rem` | Sidebar width and the content margin that clears it |
182
+ | `--layout-content-padding` | `2rem` | Page gutters |
183
+ | `--layout-shell-topbar-bottom` | `--layout-topbar-height` | Where the topbar ends — shared widgets pin full-width overlays here (the modern skin adds its card margin) |
184
+ | `--layout-content-viewport-height` | `viewport − topbar-bottom` | The space left under the topbar — the classic sidebar, pinned below the topbar, fills exactly this |
185
+ | `--layout-topbar-z` | `997` | Stacking order: topbar under mask under sidebar |
186
+ | `--layout-mask-z` | `998` | |
187
+ | `--layout-sidebar-z` | `999` | |
188
+
189
+ ```css
190
+ :root {
191
+ --layout-sidebar-width: 18rem; /* narrower sidebar, everything else follows */
192
+ }
193
+ ```
194
+
195
+ The modern skin overrides the topbar tokens on `.layout-modern` (a taller bar, tighter gaps,
196
+ smaller icons) and adds its own `--layout-modern-*` tokens for the pieces that have no shared
197
+ equivalent — gradient canvas, card radius, its narrower sidebar. Everything else it inherits.
198
+
199
+ Both skins' shells are written with CSS logical properties, so RTL needs no mirrored copy of the
200
+ layout rules; `classic/_rtl.scss` and `modern/_rtl.scss` only flip the drawer `transform`, which
201
+ has no logical equivalent, and `base/_rtl.scss` carries the component-library corrections that
202
+ are not tied to a skin.
203
+
204
+ ---
205
+
206
+ ## 4. Integration Tokens — Auth, Notifications, Language
68
207
 
69
208
  Connect feature packages to the layout via injection tokens. Register them in `app.config.ts`.
70
209
 
@@ -86,10 +225,10 @@ The layout reads these tokens to render topbar slots without directly importing
86
225
 
87
226
  ---
88
227
 
89
- ## 4. Clear Persisted Layout
228
+ ## 5. Clear Persisted Layout
90
229
 
91
230
  ```typescript
92
- import { LayoutPersistenceService } from '@flusys/ng-layout';
231
+ import { LayoutPersistenceService } from "@flusys/ng-layout";
93
232
 
94
233
  inject(LayoutPersistenceService).clear(); // removes flusys.layout.config from localStorage
95
234
  ```
@@ -0,0 +1,44 @@
1
+ @use 'mixins' as *;
2
+
3
+ // Shared <app-brand-logo> markup. The host is `display: contents`, so the anchor
4
+ // below is the flex item of whichever bar renders it. Every skin gets the same
5
+ // treatment — a full-size mark next to a slightly oversized name, which still reads
6
+ // as the brand on its own when no logo is configured.
7
+ .layout-brand-logo {
8
+ display: inline-flex;
9
+ align-items: center;
10
+ gap: 0.5rem;
11
+ min-width: 0;
12
+ flex-shrink: 0;
13
+ color: var(--text-color);
14
+ border-radius: var(--content-border-radius);
15
+ font-size: 1.5rem;
16
+ font-weight: 500;
17
+
18
+ .logo-image {
19
+ height: 2.5rem;
20
+ width: auto;
21
+ max-width: 3rem;
22
+ object-fit: contain;
23
+ flex-shrink: 0;
24
+ }
25
+
26
+ // The name is the first thing to give up room on a narrow bar; skins that keep a
27
+ // full-width brand row (the modern drawer) reveal it again.
28
+ span {
29
+ display: none;
30
+ overflow: hidden;
31
+ text-overflow: ellipsis;
32
+ white-space: nowrap;
33
+ }
34
+
35
+ &:focus-visible {
36
+ @include focused();
37
+ }
38
+ }
39
+
40
+ @media (min-width: 640px) {
41
+ .layout-brand-logo span {
42
+ display: inline;
43
+ }
44
+ }
@@ -20,7 +20,14 @@ a {
20
20
  }
21
21
 
22
22
  .layout-wrapper {
23
- min-height: 100vh;
23
+ min-height: var(--layout-viewport-height);
24
+ }
25
+
26
+ /* Set by LayoutShellBase while a mobile drawer is open — shared by every skin. */
27
+ @media (max-width: 991px) {
28
+ .blocked-scroll {
29
+ overflow: hidden;
30
+ }
24
31
  }
25
32
 
26
33
  @keyframes scalein {
@@ -4,7 +4,7 @@
4
4
  justify-content: center;
5
5
  padding: 1rem 0;
6
6
  gap: 0.5rem;
7
- border-top: 1px solid var(--surface-border);
7
+ border-top: var(--f-border-width, 1px) solid var(--surface-border);
8
8
 
9
9
  .logo-image {
10
10
  height: 2rem;
@@ -5,12 +5,12 @@
5
5
  /* Native select element */
6
6
  select.ui-select {
7
7
  width: 100%;
8
- padding: 0.5rem 2.5rem 0.5rem 0.75rem;
8
+ padding: var(--f-field-padding-y, 0.5rem) 2.5rem var(--f-field-padding-y, 0.5rem) var(--f-field-padding-x, 0.75rem);
9
9
  font-size: 1rem;
10
10
  font-family: inherit;
11
11
  background: var(--f-form-field-background, #ffffff);
12
- border: 1px solid var(--f-form-field-border-color, #d1d5db);
13
- border-radius: var(--f-border-radius-md, 6px);
12
+ border: var(--f-border-width, 1px) solid var(--f-form-field-border-color, #d1d5db);
13
+ border-radius: var(--f-field-border-radius, 6px);
14
14
  color: var(--f-text-color, #374151);
15
15
  transition: border-color 0.2s, box-shadow 0.2s;
16
16
  appearance: none;
@@ -0,0 +1,52 @@
1
+ // Structure of the shared <app-menu> markup — list reset and row layout. Every skin
2
+ // renders this same tree, so only the look (colours, padding, indentation) belongs in
3
+ // a skin file.
4
+ // Written with logical properties throughout, which is what keeps the menu correct
5
+ // in RTL without a mirrored copy of these rules.
6
+ .layout-menu {
7
+ margin: 0;
8
+ padding: 0;
9
+ list-style-type: none;
10
+
11
+ a {
12
+ user-select: none;
13
+ }
14
+
15
+ ul {
16
+ margin: 0;
17
+ padding: 0;
18
+ list-style-type: none;
19
+
20
+ a {
21
+ display: flex;
22
+ align-items: center;
23
+ position: relative;
24
+ outline: 0 none;
25
+ color: var(--text-color);
26
+ cursor: pointer;
27
+ transition:
28
+ background-color var(--element-transition-duration),
29
+ box-shadow var(--element-transition-duration);
30
+
31
+ .layout-menuitem-icon {
32
+ margin-inline-end: 0.5rem;
33
+ }
34
+
35
+ .layout-submenu-toggler {
36
+ font-size: 75%;
37
+ margin-inline-start: auto;
38
+ transition: transform var(--element-transition-duration);
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ // An expanded submenu flips its chevron. Shared by every skin whose menu is a
45
+ // vertical list — a new skin joins the selector list. The classic horizontal nav is
46
+ // deliberately left out: it opens submenus on hover and its chevron points sideways.
47
+ .layout-sidebar .layout-menu,
48
+ .layout-modern-sidebar .layout-menu {
49
+ li.active-menuitem > a .layout-submenu-toggler {
50
+ transform: rotate(-180deg);
51
+ }
52
+ }
@@ -0,0 +1,230 @@
1
+ // RTL corrections that are not tied to a layout skin — component library widgets and
2
+ // the utility classes pages use directly. Anything the shell itself needs is written
3
+ // with logical properties instead, so it mirrors without a rule here.
4
+ html[dir='rtl'] {
5
+ // Flip navigation arrows
6
+ .pi-chevron-left::before {
7
+ content: '\e901'; // pi-chevron-right icon code
8
+ }
9
+
10
+ .pi-chevron-right::before {
11
+ content: '\e900'; // pi-chevron-left icon code
12
+ }
13
+
14
+ // Calendar grid direction
15
+ .calendar-month .grid,
16
+ .calendar-week .grid,
17
+ .calendar-day {
18
+ direction: rtl;
19
+ }
20
+
21
+ // Calendar day - time column should align left in RTL (visually on right side)
22
+ .calendar-day .pr-2 {
23
+ padding-right: 0 !important;
24
+ padding-left: 0.5rem !important;
25
+ }
26
+
27
+ .calendar-day .border-r {
28
+ border-right: none !important;
29
+ border-left: var(--f-border-width, 1px) solid var(--surface-border) !important;
30
+ }
31
+
32
+ // Form labels and inputs
33
+ .p-float-label > label {
34
+ left: auto;
35
+ right: 0.75rem;
36
+ }
37
+
38
+ // Checkbox/radio alignment
39
+ .p-checkbox,
40
+ .p-radiobutton {
41
+ margin-right: 0;
42
+ margin-left: 0.5rem;
43
+ }
44
+
45
+ // Button icons
46
+ .p-button-icon-left {
47
+ margin-right: 0;
48
+ margin-left: 0.5rem;
49
+ }
50
+
51
+ .p-button-icon-right {
52
+ margin-left: 0;
53
+ margin-right: 0.5rem;
54
+ }
55
+
56
+ // Table - full RTL support
57
+ .p-datatable {
58
+ direction: rtl;
59
+
60
+ .p-datatable-thead > tr > th,
61
+ .p-datatable-tbody > tr > td {
62
+ text-align: right;
63
+ }
64
+
65
+ // Actions column (usually last) should be left-aligned
66
+ .p-datatable-thead > tr > th:last-child,
67
+ .p-datatable-tbody > tr > td:last-child {
68
+ text-align: left;
69
+ }
70
+
71
+ // Paginator - rotate navigation icons
72
+ .p-paginator {
73
+ .p-paginator-first,
74
+ .p-paginator-prev,
75
+ .p-paginator-next,
76
+ .p-paginator-last {
77
+ transform: rotate(180deg);
78
+ }
79
+ }
80
+ }
81
+
82
+ // Toast positioning
83
+ .p-toast {
84
+ &.p-toast-top-right,
85
+ &.p-toast-bottom-right {
86
+ right: auto;
87
+ left: 20px;
88
+ }
89
+
90
+ &.p-toast-top-left,
91
+ &.p-toast-bottom-left {
92
+ left: auto;
93
+ right: 20px;
94
+ }
95
+ }
96
+
97
+ // Breadcrumb separator - rotate arrow
98
+ .p-breadcrumb .p-menuitem-separator {
99
+ transform: rotate(180deg);
100
+ }
101
+
102
+ // Steps
103
+ .p-steps .p-steps-item::before {
104
+ left: auto;
105
+ right: 50%;
106
+ }
107
+
108
+ // Dialog - swap margins only
109
+ .p-dialog .p-dialog-header-icons {
110
+ margin-left: 0;
111
+ margin-right: auto;
112
+ }
113
+
114
+ // Sidebar panel
115
+ .p-sidebar-left {
116
+ left: auto !important;
117
+ right: 0 !important;
118
+ }
119
+
120
+ .p-sidebar-right {
121
+ right: auto !important;
122
+ left: 0 !important;
123
+ }
124
+
125
+ // Card actions - swap margin
126
+ .card-actions {
127
+ margin-left: 0;
128
+ margin-right: auto;
129
+ }
130
+
131
+ // Tag/Badge positioning
132
+ .p-tag,
133
+ .p-badge {
134
+ margin-left: 0;
135
+ margin-right: 0.5rem;
136
+ }
137
+
138
+ // Menu items with icons - swap icon margin for RTL
139
+ .p-menuitem-link .p-menuitem-icon {
140
+ margin-right: 0;
141
+ margin-left: 0.5rem;
142
+ }
143
+
144
+ // Accordion - swap toggle icon margin
145
+ .p-accordion .p-accordion-toggle-icon {
146
+ margin-left: 0;
147
+ margin-right: auto;
148
+ }
149
+
150
+ // Tree/TreeTable - swap toggler margin
151
+ .p-tree .p-tree-toggler,
152
+ .p-treetable .p-treetable-toggler {
153
+ margin-right: 0;
154
+ margin-left: 0.5rem;
155
+ }
156
+
157
+ // Text alignment
158
+ .text-left {
159
+ text-align: right !important;
160
+ }
161
+
162
+ .text-right {
163
+ text-align: left !important;
164
+ }
165
+
166
+ // Border utilities
167
+ .border-l {
168
+ border-left: none !important;
169
+ border-right: var(--f-border-width, 1px) solid var(--surface-border) !important;
170
+ }
171
+
172
+ .border-r {
173
+ border-right: none !important;
174
+ border-left: var(--f-border-width, 1px) solid var(--surface-border) !important;
175
+ }
176
+
177
+ // Margin/padding utilities
178
+ .ml-auto {
179
+ margin-left: 0 !important;
180
+ margin-right: auto !important;
181
+ }
182
+
183
+ .mr-auto {
184
+ margin-right: 0 !important;
185
+ margin-left: auto !important;
186
+ }
187
+
188
+ .ml-2 {
189
+ margin-left: 0 !important;
190
+ margin-right: 0.5rem !important;
191
+ }
192
+
193
+ .mr-2 {
194
+ margin-right: 0 !important;
195
+ margin-left: 0.5rem !important;
196
+ }
197
+
198
+ .pl-2 {
199
+ padding-left: 0 !important;
200
+ padding-right: 0.5rem !important;
201
+ }
202
+
203
+ .pr-2 {
204
+ padding-right: 0 !important;
205
+ padding-left: 0.5rem !important;
206
+ }
207
+
208
+ // Justify content
209
+ .justify-start {
210
+ justify-content: flex-end !important;
211
+ }
212
+
213
+ .justify-end {
214
+ justify-content: flex-start !important;
215
+ }
216
+
217
+ // Items alignment in flex
218
+ .items-start {
219
+ align-items: flex-start;
220
+ }
221
+
222
+ // Scroll container
223
+ .overflow-x-auto {
224
+ direction: rtl;
225
+
226
+ > * {
227
+ direction: rtl;
228
+ }
229
+ }
230
+ }