@madj2k/fe-frontend-kit 2.0.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.
- package/index.js +7 -0
- package/index.scss +6 -0
- package/menus/flyout-menu/flyout-menu-2.0.0.js +331 -0
- package/menus/flyout-menu/flyout-menu-2.0.0.scss +47 -0
- package/menus/flyout-menu/index.js +2 -0
- package/menus/flyout-menu/index.scss +1 -0
- package/menus/pulldown-menu/index.js +2 -0
- package/menus/pulldown-menu/index.scss +1 -0
- package/menus/pulldown-menu/pulldown-menu-2.0.0.js +196 -0
- package/menus/pulldown-menu/pulldown-menu-2.0.0.scss +33 -0
- package/package.json +31 -0
- package/readme.md +218 -0
- package/sass/bootstrap-5.3.0/00_mixins/_accessibility.scss +42 -0
- package/sass/bootstrap-5.3.0/00_mixins/_colors.scss +99 -0
- package/sass/bootstrap-5.3.0/00_mixins/_effects.scss +45 -0
- package/sass/bootstrap-5.3.0/00_mixins/_flex-box.scss +104 -0
- package/sass/bootstrap-5.3.0/00_mixins/_form.scss +164 -0
- package/sass/bootstrap-5.3.0/00_mixins/_format.scss +208 -0
- package/sass/bootstrap-5.3.0/00_mixins/_icons.scss +129 -0
- package/sass/bootstrap-5.3.0/00_mixins/_nav.scss +327 -0
- package/sass/bootstrap-5.3.0/00_mixins/_page.scss +261 -0
- package/sass/bootstrap-5.3.0/00_mixins/_section.scss +111 -0
- package/sass/bootstrap-5.3.0/00_mixins/_toggle-list.scss +133 -0
- package/sass/bootstrap-5.3.0/00_mixins/_unit.scss +51 -0
- package/sass/bootstrap-5.3.0/10_config/_colors.scss +17 -0
- package/sass/bootstrap-5.3.0/10_config/_font.scss +228 -0
- package/sass/bootstrap-5.3.0/10_config/_maps.scss +51 -0
- package/sass/bootstrap-5.3.0/index.scss +20 -0
- package/tools/owl/index.js +2 -0
- package/tools/owl/index.scss +1 -0
- package/tools/owl/owl-thumbnail-2.0.0.js +355 -0
- package/tools/owl/owl-thumbnail-2.0.0.scss +0 -0
- package/tools/resize-end/index.js +2 -0
- package/tools/resize-end/index.scss +1 -0
- package/tools/resize-end/resize-end-2.0.0.js +108 -0
- package/tools/resize-end/resize-end-2.0.0.scss +10 -0
- package/tools/scrolling/index.js +2 -0
- package/tools/scrolling/index.scss +1 -0
- package/tools/scrolling/scrolling-2.0.0.js +244 -0
- package/tools/scrolling/scrolling-2.0.0.scss +10 -0
package/readme.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# @madj2k/frontend-kit
|
|
2
|
+
Reusable frontend toolkit including SCSS mixins and menu components (JS/SCSS).
|
|
3
|
+
|
|
4
|
+
# # Installation
|
|
5
|
+
```
|
|
6
|
+
npm install @madj2k/frontend-kit
|
|
7
|
+
```
|
|
8
|
+
Requirements:
|
|
9
|
+
For SCSS mixins: Bootstrap SCSS (your project needs to install bootstrap and include it in the build)
|
|
10
|
+
For menu components: none
|
|
11
|
+
|
|
12
|
+
## Contains
|
|
13
|
+
* SASS mixins (using Bootstrap 5.3 functions/mixins)
|
|
14
|
+
* Menu components (JS + SCSS), Bootstrap-independent
|
|
15
|
+
* Several JS-Tools
|
|
16
|
+
|
|
17
|
+
## Usage in your project
|
|
18
|
+
### SCSS Mixins
|
|
19
|
+
```
|
|
20
|
+
@use '@madj2k/frontend-kit' as *;
|
|
21
|
+
```
|
|
22
|
+
Or import individual mixins:
|
|
23
|
+
```
|
|
24
|
+
@use '@madj2k/frontend-kit/sass/00_mixins/colors' as *;
|
|
25
|
+
```
|
|
26
|
+
### Menu components (JS and SCSS):
|
|
27
|
+
Each menu component can be used separately.
|
|
28
|
+
|
|
29
|
+
# JS: Resize-End
|
|
30
|
+
A lightweight helper class that triggers a debounced 'madj2k-resize-end' event
|
|
31
|
+
when the user finishes resizing the browser window.
|
|
32
|
+
|
|
33
|
+
It also manages a scrolling detection state (via body attribute) to avoid triggering
|
|
34
|
+
resize-end during user scrolling, and respects active input fields (useful on mobile).
|
|
35
|
+
|
|
36
|
+
# JS: Scrolling
|
|
37
|
+
A lightweight scrolling helper class that enables:
|
|
38
|
+
1. Body classes based on scroll direction (scroll-up / scroll-down)
|
|
39
|
+
2. Smooth anchor scrolling with optional offset
|
|
40
|
+
3. Automatic scrolling when collapsible elements (like Bootstrap .collapse) open
|
|
41
|
+
4. Appear-on-scroll animations for elements
|
|
42
|
+
|
|
43
|
+
The class is fully configurable via options and is designed to be used in CMS contexts
|
|
44
|
+
where elements can be added, removed or re-ordered dynamically.
|
|
45
|
+
|
|
46
|
+
# JS: OWL-Thumbnails
|
|
47
|
+
A JavaScript helper class to create a main OWL carousel with a synchronized thumbnail navigation carousel.
|
|
48
|
+
|
|
49
|
+
Supports flexible configurations for both the main and the thumbnail carousels,
|
|
50
|
+
including:
|
|
51
|
+
- Custom navigation
|
|
52
|
+
- Syncing main carousel to clicked thumbnails
|
|
53
|
+
- Syncing thumbnails to main carousel changes
|
|
54
|
+
- Optionally equalizing thumbnail heights
|
|
55
|
+
- Optionally preventing the centered thumbnail stage shift (for designs where thumbs should stay left aligned)
|
|
56
|
+
- Responsive and CMS-friendly (works with dynamic content)
|
|
57
|
+
|
|
58
|
+
This is especially useful for image galleries or product carousels in CMS setups (e.g. TYPO3, WordPress, etc.)
|
|
59
|
+
where content may change dynamically.
|
|
60
|
+
|
|
61
|
+
# Flyout-Navigation
|
|
62
|
+
## Usage
|
|
63
|
+
Integrate the CSS- and JS-file into your project. Make sure jQuery is included.
|
|
64
|
+
Then init the menu with
|
|
65
|
+
```
|
|
66
|
+
import { Madj2kFlyoutMenu } from '@madj2k/frontend-kit/menus/flyout-menu';
|
|
67
|
+
document.querySelectorAll('.js-flyout-toggle').forEach((el) => {
|
|
68
|
+
new Madj2kFlyoutMenu(el, { animationDuration: 800 });
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
CSS:
|
|
72
|
+
```
|
|
73
|
+
@use '@madj2k/frontend-kit/menus/flyout-menu' as *;
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Basic HTML
|
|
77
|
+
```
|
|
78
|
+
<div class="siteheader" id="siteheader">
|
|
79
|
+
|
|
80
|
+
[...]
|
|
81
|
+
|
|
82
|
+
<nav>
|
|
83
|
+
<button class="js-flyout-toggle"
|
|
84
|
+
aria-label="Open menu"
|
|
85
|
+
aria-controls="nav-mobile"
|
|
86
|
+
aria-haspopup="true"
|
|
87
|
+
aria-expanded="false">
|
|
88
|
+
<span class="icon-bars"></span>
|
|
89
|
+
</button>
|
|
90
|
+
<div class="flyout js-flyout"
|
|
91
|
+
id="nav-mobile"
|
|
92
|
+
data-position-ref="siteheader">
|
|
93
|
+
<div class="flyout-container js-flyout-container">
|
|
94
|
+
<div class="nav-mobile-inner js-flyout-inner">
|
|
95
|
+
CONTENT HERE
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</nav>
|
|
100
|
+
</div>
|
|
101
|
+
```
|
|
102
|
+
IMPORTANT: If the siteheader is positioned with ```position:fixed```, you have to switch that to ```position:absolute``` when the menu is opened.
|
|
103
|
+
Otherwise in the opened menu the scrolling won't work.
|
|
104
|
+
```
|
|
105
|
+
.flyout-open {
|
|
106
|
+
.siteheader {
|
|
107
|
+
position:absolute;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
## Special: blur/gray effect for background
|
|
112
|
+
* In order to achieve a blur/gray-effect for the background we add the following DIV to the main-content section:
|
|
113
|
+
```
|
|
114
|
+
<div class="background-blur"></div>
|
|
115
|
+
```
|
|
116
|
+
Then we deactivate the fullHeight of the flyout menu and make the blurry background clickable
|
|
117
|
+
```
|
|
118
|
+
import { Madj2kFlyoutdownMenu } from '@madj2k/frontend-kit/menus/flyout-menu';
|
|
119
|
+
document.querySelectorAll('.js-flyout-toggle').forEach((el) => {
|
|
120
|
+
new Madj2kFlyoutMenu(el, { fullHeight: false });
|
|
121
|
+
});
|
|
122
|
+
document.querySelector('.js-background-blur').addEventListener('click', function() {
|
|
123
|
+
document.dispatchEvent(new CustomEvent('madj2k-flyoutmenu-close'));
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
* And we need this additional CSS:
|
|
127
|
+
```
|
|
128
|
+
/**
|
|
129
|
+
* Prevent jumping because of scrollbar
|
|
130
|
+
*/
|
|
131
|
+
html,body {
|
|
132
|
+
min-height: 100.1%;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* background-blur for opened flyout
|
|
137
|
+
*/
|
|
138
|
+
.background-blur {
|
|
139
|
+
position:fixed;
|
|
140
|
+
top:0;
|
|
141
|
+
left:0;
|
|
142
|
+
width: 100%;
|
|
143
|
+
height: 100%;
|
|
144
|
+
backdrop-filter: blur(1px) grayscale(100%);
|
|
145
|
+
background-color: rgba(255, 255, 255, 0.7);
|
|
146
|
+
transition: opacity 0.3s ease-in-out;
|
|
147
|
+
opacity:0;
|
|
148
|
+
z-index:-1;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.flyout-open,
|
|
152
|
+
.flyout-closing {
|
|
153
|
+
.background-blur {
|
|
154
|
+
z-index:90;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.flyout-open{
|
|
159
|
+
.background-blur {
|
|
160
|
+
opacity:1;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
# Pulldown-Navigation
|
|
168
|
+
## Usage
|
|
169
|
+
Integrate the CSS- and JS-file into your project. Make sure jQuery is included.
|
|
170
|
+
Then init the menu with
|
|
171
|
+
```
|
|
172
|
+
import { Madj2kPulldownMenu } from '@madj2k/frontend-kit/menus/pulldown-menu';
|
|
173
|
+
document.querySelectorAll('.js-pulldown-toggle').forEach((el) => {
|
|
174
|
+
new Madj2kPulldownMenu(el);
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
CSS:
|
|
178
|
+
```
|
|
179
|
+
@use '@madj2k/frontend-kit/menus/pulldown-menu' as *;
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Basic HTML
|
|
183
|
+
```
|
|
184
|
+
<div class="siteheader">
|
|
185
|
+
|
|
186
|
+
[...]
|
|
187
|
+
|
|
188
|
+
<nav class="pulldown-wrap js-pulldown-wrap">
|
|
189
|
+
<button class="pulldown-toggle js-pulldown-toggle"
|
|
190
|
+
aria-label="Open Menu"
|
|
191
|
+
aria-controls="nav-language"
|
|
192
|
+
aria-haspopup="true"
|
|
193
|
+
aria-expanded="false">
|
|
194
|
+
<span>Menu-Item Level 1</span>
|
|
195
|
+
</button>
|
|
196
|
+
|
|
197
|
+
<div class="pulldown js-pulldown" id="nav-language">
|
|
198
|
+
<div class="pulldown-inner">
|
|
199
|
+
<ul>
|
|
200
|
+
<!-- used to have the right padding-top of the pulldown -->
|
|
201
|
+
<li class="pulldown-hide">
|
|
202
|
+
<a href="#" tabIndex="-1"><span>Menu-Item Level 1</span></a>
|
|
203
|
+
</li>
|
|
204
|
+
<li>
|
|
205
|
+
<a href="#"><span>Menu-Item I Level 2</span></a>
|
|
206
|
+
</li>
|
|
207
|
+
<li>
|
|
208
|
+
<a href="#"><span>Menu-Item II Level 2</span></a>
|
|
209
|
+
</li>
|
|
210
|
+
<li>
|
|
211
|
+
...
|
|
212
|
+
</li>
|
|
213
|
+
</ul>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
</nav>
|
|
217
|
+
</div>
|
|
218
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/* ==================================================
|
|
2
|
+
* Accessibility
|
|
3
|
+
* ================================================== */
|
|
4
|
+
/// Adds a visible and accessible focus outline for interactive elements.
|
|
5
|
+
///
|
|
6
|
+
/// Ensures that keyboard users can visually identify focused elements
|
|
7
|
+
/// (e.g., buttons, links, inputs) with a strong outline for accessibility.
|
|
8
|
+
/// This mixin is meant to be used on elements that need clear focus styles
|
|
9
|
+
/// without relying on default browser outlines.
|
|
10
|
+
///
|
|
11
|
+
/// @group Accessibility
|
|
12
|
+
///
|
|
13
|
+
/// @param {Color} $color - Outline color for focused state. Defaults to `$color-outline`.
|
|
14
|
+
/// @param {Length} $width - Outline width. Defaults to `3px`.
|
|
15
|
+
///
|
|
16
|
+
/// @example scss
|
|
17
|
+
/// button,
|
|
18
|
+
/// a {
|
|
19
|
+
/// @include accessibility-outline();
|
|
20
|
+
/// }
|
|
21
|
+
///
|
|
22
|
+
/// @example scss
|
|
23
|
+
/// .custom-button {
|
|
24
|
+
/// @include accessibility-outline($color: #005fcc, $width: 2px);
|
|
25
|
+
/// }
|
|
26
|
+
///
|
|
27
|
+
/// @author Steffen Kroggel <developer@steffenkroggel>
|
|
28
|
+
/// @license GNU General Public License v3.0 https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
29
|
+
///
|
|
30
|
+
@mixin accessibility-outline ($color: $color-outline, $width: 3px) {
|
|
31
|
+
|
|
32
|
+
&:focus,
|
|
33
|
+
&:focus-within {
|
|
34
|
+
outline: 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&:has(input:focus-visible),
|
|
38
|
+
&:focus-visible {
|
|
39
|
+
outline: rem-calc($width) solid $color;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/// Generates utility classes for background colors based on a Sass map.
|
|
2
|
+
///
|
|
3
|
+
/// For each key–value pair in the provided map, a class with a suffix of `-<key>`
|
|
4
|
+
/// is created, setting `background-color` to the mapped value.
|
|
5
|
+
///
|
|
6
|
+
/// Typically used in component systems or design tokens to expose theme colors.
|
|
7
|
+
///
|
|
8
|
+
/// @group Utilities
|
|
9
|
+
///
|
|
10
|
+
/// @param {Map} $map - A Sass map of color names and values (e.g. `("primary": #005fcc, "secondary": #999)`). Defaults to `$color-map`.
|
|
11
|
+
///
|
|
12
|
+
/// @example scss
|
|
13
|
+
/// @include background-color-classes((
|
|
14
|
+
/// "primary": #005fcc,
|
|
15
|
+
/// "secondary": #999,
|
|
16
|
+
/// "light": #f5f5f5
|
|
17
|
+
/// ));
|
|
18
|
+
///
|
|
19
|
+
/// @example css
|
|
20
|
+
/// .bg-primary { background-color: #005fcc; }
|
|
21
|
+
/// .bg-secondary { background-color: #999; }
|
|
22
|
+
///
|
|
23
|
+
/// @author Steffen Kroggel <developer@steffenkroggel>
|
|
24
|
+
/// @license GNU General Public License v3.0 https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
25
|
+
///
|
|
26
|
+
@mixin background-color-classes($map: $color-map) {
|
|
27
|
+
@each $key, $value in $map {
|
|
28
|
+
&-#{$key} {
|
|
29
|
+
background-color: $value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@each $breakpoint, $size in $grid-breakpoints {
|
|
33
|
+
@media (min-width: $size) {
|
|
34
|
+
&-#{$breakpoint}-#{$key} {
|
|
35
|
+
background-color: $value;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&-#{$breakpoint}-none {
|
|
39
|
+
background-color: transparent;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/// Generates utility classes for text color based on a Sass map.
|
|
47
|
+
///
|
|
48
|
+
/// For each key–value pair in the provided map, a class with a suffix of `-<key>`
|
|
49
|
+
/// is created, setting the `color` of the element and its immediate children to the mapped value.
|
|
50
|
+
///
|
|
51
|
+
/// Adds `!important` to ensure style application even when overridden.
|
|
52
|
+
///
|
|
53
|
+
/// @group Utilities
|
|
54
|
+
///
|
|
55
|
+
/// @param {Map} $map - A Sass map of color names and values. Defaults to `$color-map`.
|
|
56
|
+
///
|
|
57
|
+
/// @example scss
|
|
58
|
+
/// @include font-color-classes((
|
|
59
|
+
/// "danger": #e00,
|
|
60
|
+
/// "success": #0a0
|
|
61
|
+
/// ));
|
|
62
|
+
///
|
|
63
|
+
/// @example css
|
|
64
|
+
/// .text-danger { color: #e00 !important; }
|
|
65
|
+
/// .text-danger > * { color: #e00 !important; }
|
|
66
|
+
///
|
|
67
|
+
/// @author Steffen Kroggel <developer@steffenkroggel>
|
|
68
|
+
/// @license GNU General Public License v3.0 https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
69
|
+
///
|
|
70
|
+
@mixin font-color-classes($map: $color-map) {
|
|
71
|
+
@each $key, $value in $map {
|
|
72
|
+
&-#{$key} {
|
|
73
|
+
color: $value !important;
|
|
74
|
+
|
|
75
|
+
& > * {
|
|
76
|
+
color: $value !important;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
@each $breakpoint, $size in $grid-breakpoints {
|
|
80
|
+
@media (min-width: $size) {
|
|
81
|
+
&-#{$breakpoint}-#{$key} {
|
|
82
|
+
color: $value !important;
|
|
83
|
+
|
|
84
|
+
& > * {
|
|
85
|
+
color: $value !important;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&-#{$breakpoint}-none {
|
|
90
|
+
color: inherit !important;
|
|
91
|
+
|
|
92
|
+
& > * {
|
|
93
|
+
color: inherit !important;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/// Adds a custom underline to text elements using a pseudo-element.
|
|
2
|
+
///
|
|
3
|
+
/// This mixin creates a visual underline using `::after`, which allows
|
|
4
|
+
/// for more control than `text-decoration`. It supports customizable
|
|
5
|
+
/// color and thickness, and adjusts vertical spacing responsively.
|
|
6
|
+
///
|
|
7
|
+
/// Useful for link-like text styling or emphasis elements.
|
|
8
|
+
///
|
|
9
|
+
/// @group Effects
|
|
10
|
+
///
|
|
11
|
+
/// @param {Color} $color - The underline color. Default: `$color-primary`.
|
|
12
|
+
/// @param {Length} $width - Thickness of the underline (in px, converted to `rem`). Default: `2px`.
|
|
13
|
+
///
|
|
14
|
+
/// @example scss
|
|
15
|
+
/// .highlighted-text {
|
|
16
|
+
/// @include underline($color-tertiary, 3px);
|
|
17
|
+
/// }
|
|
18
|
+
///
|
|
19
|
+
/// @example css
|
|
20
|
+
/// .highlighted-text::after {
|
|
21
|
+
/// border-bottom: 0.1875rem solid #cc0000;
|
|
22
|
+
/// bottom: -0.09em;
|
|
23
|
+
/// }
|
|
24
|
+
///
|
|
25
|
+
/// @author Steffen Kroggel <developer@steffenkroggel>
|
|
26
|
+
/// @license GNU General Public License v3.0 https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
27
|
+
///
|
|
28
|
+
@mixin underline ($color: $color-primary, $width: 2px) {
|
|
29
|
+
|
|
30
|
+
position: relative;
|
|
31
|
+
display: inline-block;
|
|
32
|
+
|
|
33
|
+
&::after {
|
|
34
|
+
content: '';
|
|
35
|
+
position: absolute;
|
|
36
|
+
left: 0;
|
|
37
|
+
right: 0;
|
|
38
|
+
bottom: -0.09em;
|
|
39
|
+
border-bottom: rem-calc($width) solid $color;
|
|
40
|
+
|
|
41
|
+
@include media-breakpoint-up(xl) {
|
|
42
|
+
bottom: -0.15em;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/// Calculates `flex-basis` for a given number of columns while accounting for CSS `gap`.
|
|
2
|
+
///
|
|
3
|
+
/// This mixin ensures that items within a flex container evenly divide available width,
|
|
4
|
+
/// **including** the horizontal `gap` spacing between them.
|
|
5
|
+
/// Ideal for grid-like layouts using `display: flex` and `gap`.
|
|
6
|
+
///
|
|
7
|
+
/// Based on: https://stackoverflow.com/questions/72116170/account-for-gap-when-calculating-flex-basis
|
|
8
|
+
///
|
|
9
|
+
/// @group Layout
|
|
10
|
+
///
|
|
11
|
+
/// @param {Number} $cols - Number of columns (flex items per row). Default: `2`.
|
|
12
|
+
/// @param {Length} $gap - Horizontal gap between items. Default: `16px`.
|
|
13
|
+
/// @return {Declaration} - Sets `flex-basis` using a `calc()` formula.
|
|
14
|
+
///
|
|
15
|
+
/// @example scss
|
|
16
|
+
/// .grid-item {
|
|
17
|
+
/// @include flex-basis(3, 24px);
|
|
18
|
+
/// }
|
|
19
|
+
///
|
|
20
|
+
/// @example css
|
|
21
|
+
/// flex-basis: calc(100% / 3 - 24px / 3 * (3 - 1));
|
|
22
|
+
///
|
|
23
|
+
/// @author Steffen Kroggel <developer@steffenkroggel>
|
|
24
|
+
/// @license GNU General Public License v3.0 https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
25
|
+
///
|
|
26
|
+
@mixin flex-basis($cols: 2, $gap: 16px) {
|
|
27
|
+
flex-basis: calc(100% / #{$cols} - #{$gap} / #{$cols} * (#{$cols} - 1));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/// Flexbox Item Width Generator
|
|
32
|
+
///
|
|
33
|
+
/// Dynamically generates responsive flex item widths based on the number
|
|
34
|
+
/// of items in a container and a column-count configuration map.
|
|
35
|
+
///
|
|
36
|
+
/// This mixin assumes that item widths are calculated using a helper mixin
|
|
37
|
+
/// like `@include flex-basis($columns, $gap)` which distributes space based
|
|
38
|
+
/// on a total column count per row, adjusted for a given gap.
|
|
39
|
+
///
|
|
40
|
+
/// @param {Map} $config - A map where:
|
|
41
|
+
/// - Keys are the total number of items in a row (e.g., 4, 5, 6)
|
|
42
|
+
/// - Values are either:
|
|
43
|
+
/// - A single number: the number of columns for that layout
|
|
44
|
+
/// - A map of item index ranges (e.g., `'1-3'`, `'4-5'`) where each
|
|
45
|
+
/// range defines how many columns those items span in that row
|
|
46
|
+
///
|
|
47
|
+
/// @param {Length} $gap - Optional spacing between columns (default: `0`)
|
|
48
|
+
///
|
|
49
|
+
/// @param {String} $counterClassPrefix - The base class prefix for the container,
|
|
50
|
+
/// e.g. '.items' or '.grid--cols' (default: '.items').
|
|
51
|
+
///
|
|
52
|
+
/// @param {String} $className - The selector for each item (default: '.item')
|
|
53
|
+
///
|
|
54
|
+
/// @example scss - Uniform layout
|
|
55
|
+
/// $layout: (
|
|
56
|
+
/// 4: 2, // All 4 items arranged in 2 columns (2 per row)
|
|
57
|
+
/// 6: 3 // All 6 items in 3 columns
|
|
58
|
+
/// );
|
|
59
|
+
///
|
|
60
|
+
/// @example scss - Mixed layout with row-specific splits
|
|
61
|
+
/// $layout: (
|
|
62
|
+
/// 5: (
|
|
63
|
+
/// '1-3': 3, // First row: 3 columns (items 1–3)
|
|
64
|
+
/// '4-5': 2 // Second row: 2 columns (items 4–5)
|
|
65
|
+
/// )
|
|
66
|
+
/// );
|
|
67
|
+
///
|
|
68
|
+
/// @output
|
|
69
|
+
/// Generates selectors like `.items-5 .item:nth-child(...)` with flex-basis
|
|
70
|
+
/// calculated using the number of columns and the provided gap.
|
|
71
|
+
///
|
|
72
|
+
/// @note
|
|
73
|
+
/// This mixin requires a `flex-basis($columns, $gap)` helper mixin or function
|
|
74
|
+
/// that performs the actual width calculation (e.g., using `calc(...)`)
|
|
75
|
+
///
|
|
76
|
+
/// @author Steffen Kroggel <developer@steffenkroggel>
|
|
77
|
+
/// @license GNU General Public License v3.0 https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
78
|
+
///
|
|
79
|
+
@mixin flex-basis-dynamically($config, $gap: 0, $counterClassPrefix: '.count', $className: '.item') {
|
|
80
|
+
@each $count, $value in $config {
|
|
81
|
+
@if type-of($value) == "map" {
|
|
82
|
+
@each $range, $columns in $value {
|
|
83
|
+
$start: null;
|
|
84
|
+
$end: null;
|
|
85
|
+
|
|
86
|
+
@if str-index($range, '-') != null {
|
|
87
|
+
$start: str-slice($range, 1, str-index($range, '-') - 1);
|
|
88
|
+
$end: str-slice($range, str-index($range, '-') + 1);
|
|
89
|
+
} @else {
|
|
90
|
+
$start: $range;
|
|
91
|
+
$end: $range;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
#{$counterClassPrefix}-#{$count} #{$className}:nth-child(n+#{$start}):nth-child(-n+#{$end}) {
|
|
95
|
+
@include flex-basis($columns, $gap);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} @else {
|
|
99
|
+
#{$counterClassPrefix}-#{$count} #{$className} {
|
|
100
|
+
@include flex-basis($value, $gap);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**! ==================================================
|
|
2
|
+
* Mixin form fields
|
|
3
|
+
* ================================================== */
|
|
4
|
+
@use 'sass:math';
|
|
5
|
+
|
|
6
|
+
/// Styles a custom checkbox input field with accessible markup and visual feedback.
|
|
7
|
+
///
|
|
8
|
+
/// Adds support for background and border color customization, as well as custom icons for
|
|
9
|
+
/// default and active states.
|
|
10
|
+
///
|
|
11
|
+
/// @group Form Fields
|
|
12
|
+
///
|
|
13
|
+
/// @param {Length} $size - The visual size of the checkbox element. Default: `16px`.
|
|
14
|
+
/// @param {Color} $default-bg-color - Background color for default state.
|
|
15
|
+
/// @param {Color} $default-border-color - Border color for default state.
|
|
16
|
+
/// @param {String} $default-icon - Icon shown in default state (optional).
|
|
17
|
+
/// @param {Color} $active-bg-color - Background color for checked/active state.
|
|
18
|
+
/// @param {Color} $active-border-color - Border color for checked/active state.
|
|
19
|
+
/// @param {String} $active-icon - Icon shown when checkbox is checked.
|
|
20
|
+
///
|
|
21
|
+
/// @example scss
|
|
22
|
+
/// .form-check-field:has(input[type="checkbox"]) {
|
|
23
|
+
/// @include checkbox();
|
|
24
|
+
/// }
|
|
25
|
+
///
|
|
26
|
+
/// @example html
|
|
27
|
+
/// <label class="form-check-label" for="element-1">
|
|
28
|
+
/// <span class="form-check-field">
|
|
29
|
+
/// <input class="checkbox" id="element-1" type="checkbox" name="" value="1">
|
|
30
|
+
/// </span>
|
|
31
|
+
/// <span>Label</span>
|
|
32
|
+
/// </label>
|
|
33
|
+
///
|
|
34
|
+
/// @author
|
|
35
|
+
/// Steffen Kroggel <developer@steffenkroggel>
|
|
36
|
+
///
|
|
37
|
+
/// @license
|
|
38
|
+
/// GNU General Public License v3.0 https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
39
|
+
///
|
|
40
|
+
@mixin checkbox(
|
|
41
|
+
$size: 16px,
|
|
42
|
+
$default-bg-color: $color-white,
|
|
43
|
+
$default-border-color: $color-secondary,
|
|
44
|
+
$default-icon: null,
|
|
45
|
+
$active-bg-color: $color-primary,
|
|
46
|
+
$active-border-color: $color-primary,
|
|
47
|
+
$active-icon: '../Images/input-checkbox-active.svg'
|
|
48
|
+
) {
|
|
49
|
+
position: relative;
|
|
50
|
+
display: inline;
|
|
51
|
+
padding-left: rem-calc(math.ceil(strip-unit($size) * 2 * 0.8));
|
|
52
|
+
|
|
53
|
+
input {
|
|
54
|
+
position: absolute;
|
|
55
|
+
width: 1em;
|
|
56
|
+
height: 1em;
|
|
57
|
+
left: 0;
|
|
58
|
+
opacity: 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@include accessibility-outline();
|
|
62
|
+
|
|
63
|
+
&::before {
|
|
64
|
+
content: "";
|
|
65
|
+
position: absolute;
|
|
66
|
+
left: rem-calc(0);
|
|
67
|
+
display: inline-block;
|
|
68
|
+
width: rem-calc($size);
|
|
69
|
+
height: rem-calc($size);
|
|
70
|
+
border: rem-calc(1) solid $default-border-color;
|
|
71
|
+
margin-top: rem-calc(-3);
|
|
72
|
+
margin-right: rem-calc(10);
|
|
73
|
+
background-color: $default-bg-color;
|
|
74
|
+
background-size: 100%;
|
|
75
|
+
transform: translateY(4px);
|
|
76
|
+
border-radius: rem-calc(4);
|
|
77
|
+
|
|
78
|
+
@if $default-icon != null {
|
|
79
|
+
background-image: url(#{$default-icon});
|
|
80
|
+
background-repeat: no-repeat;
|
|
81
|
+
background-position: center;
|
|
82
|
+
background-size: rem-calc(math.ceil(strip-unit($size) * 0.75));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
&:has(input:checked),
|
|
87
|
+
&[aria-selected="true"] {
|
|
88
|
+
&::before {
|
|
89
|
+
background-color: $active-bg-color;
|
|
90
|
+
border-color: $active-border-color;
|
|
91
|
+
background-image: url(#{$active-icon});
|
|
92
|
+
background-repeat: no-repeat;
|
|
93
|
+
background-position: center;
|
|
94
|
+
background-size: rem-calc(math.ceil(strip-unit($size) * 0.75));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
/// Styles a custom radio input field based on the checkbox mixin.
|
|
101
|
+
///
|
|
102
|
+
/// Builds on the `checkbox()` structure, but renders a circular selection element.
|
|
103
|
+
/// Supports separate border/background/icon definitions for both default and checked state.
|
|
104
|
+
///
|
|
105
|
+
/// @group Form Fields
|
|
106
|
+
///
|
|
107
|
+
/// @param {Length} $size - The visual size of the radio element. Default: `16px`.
|
|
108
|
+
/// @param {Color} $default-bg-color - Background color for default state.
|
|
109
|
+
/// @param {Color} $default-border-color - Border color for default state.
|
|
110
|
+
/// @param {String} $default-icon - Icon shown when radio is not selected (optional).
|
|
111
|
+
/// @param {Color} $active-bg-color - Background color for selected state.
|
|
112
|
+
/// @param {Color} $active-border-color - Border color for selected state.
|
|
113
|
+
/// @param {String} $active-icon - Icon shown when radio is selected.
|
|
114
|
+
///
|
|
115
|
+
/// @example scss
|
|
116
|
+
/// .form-check-field:has(input[type="radio"]) {
|
|
117
|
+
/// @include radio();
|
|
118
|
+
/// }
|
|
119
|
+
///
|
|
120
|
+
/// @example html
|
|
121
|
+
/// <label class="form-check-label" for="element-2">
|
|
122
|
+
/// <span class="form-check-field">
|
|
123
|
+
/// <input class="radio" id="element-2" type="radio" name="options" value="2">
|
|
124
|
+
/// </span>
|
|
125
|
+
/// <span>Label</span>
|
|
126
|
+
/// </label>
|
|
127
|
+
///
|
|
128
|
+
/// @author
|
|
129
|
+
/// Steffen Kroggel <developer@steffenkroggel>
|
|
130
|
+
///
|
|
131
|
+
/// @license
|
|
132
|
+
/// GNU General Public License v3.0 https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
133
|
+
///
|
|
134
|
+
@mixin radio(
|
|
135
|
+
$size: 16px,
|
|
136
|
+
$default-bg-color: $color-white,
|
|
137
|
+
$default-border-color: $color-secondary,
|
|
138
|
+
$default-icon: null,
|
|
139
|
+
$active-bg-color: $color-primary,
|
|
140
|
+
$active-border-color: $color-primary,
|
|
141
|
+
$active-icon: '../Images/input-radio-active.svg'
|
|
142
|
+
) {
|
|
143
|
+
@include checkbox(
|
|
144
|
+
$size,
|
|
145
|
+
$default-bg-color,
|
|
146
|
+
$default-border-color,
|
|
147
|
+
$default-icon,
|
|
148
|
+
$active-bg-color,
|
|
149
|
+
$active-border-color,
|
|
150
|
+
$active-icon
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
&::before {
|
|
154
|
+
border-radius: rem-calc($size); // circular shape
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
&:has(input:checked),
|
|
158
|
+
&[aria-selected="true"] {
|
|
159
|
+
&::before {
|
|
160
|
+
border: 0;
|
|
161
|
+
background-size: rem-calc(math.ceil(strip-unit($size) * 0.5));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|