nk_jtb 0.18.0 → 0.19.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.
@@ -0,0 +1,126 @@
1
+ # SCSS Directory Structure
2
+
3
+ ## Current Structure
4
+
5
+ ```bash
6
+ scss/
7
+ ├── functions/ # Pure, reusable utility functions
8
+ ├── mixins/ # Pure, reusable mixins
9
+ └── systems/ # Complete workflows (functions + mixins together)
10
+ ```
11
+
12
+ ### functions/
13
+ Pure utility functions that can be used anywhere. These are standalone functions that
14
+ don't depend on specific mixins or configurations.
15
+
16
+ **Examples:** String manipulation, math helpers, validation functions, resolvers.
17
+
18
+ ### mixins/
19
+ Reusable mixins for common styling patterns. These are general-purpose tools that work
20
+ independently.
21
+
22
+ **Examples:** Media query mixins, layout helpers, generic styling patterns.
23
+
24
+ ### systems/
25
+ Complete workflows where functions and mixins work together as a cohesive unit. These are
26
+ feature-complete modules that combine related functionality.
27
+
28
+ **Examples:** Spacing systems, typography systems, color systems.
29
+
30
+
31
+ ## _resolvers.scss
32
+
33
+ ### Resolver Functions
34
+ These functions conditionally resolve values based on configuration modes. They ensure
35
+ valid lists or values are returned, preserving original values when the mode is disabled.
36
+
37
+ **resolve-breakpoints():** Resolves breakpoints based on responsive mode.
38
+
39
+ **Examples:**
40
+ - `resolve-breakpoints(true, null)` → `('sm', 'md', 'lg', 'xl')`
41
+ - `resolve-breakpoints(false, ('lg'))` → `('lg')`
42
+ - `resolve-breakpoints(false, null)` → `null`
43
+
44
+ ### Getter Functions
45
+ These functions return default values when none are provided, ensuring consistent data
46
+ access.
47
+
48
+
49
+
50
+ <!-- scss/
51
+ ├── components/ # UI component styles
52
+ ├── config/ # Configuration maps and design tokens
53
+ │ ├── _colors.scss # Color palettes and variants
54
+ │ ├── _layout.scss # Display, position, alignment maps
55
+ │ ├── _spacing.scss # Margin, padding, border values
56
+ │ ├── _typography.scss # Font weights, sizes, families
57
+ │ └── _index.scss # Forwards all config files
58
+ ├── utilities/ # Utility class generation and configs
59
+ ├── _base.scss # Base styles, typography, root
60
+ └── _properties.scss # Property maps for utility generation -->
61
+ <!--
62
+ ### base/
63
+ Foundation styles including CSS resets, base typography, root variables, and fundamental
64
+ styling that applies globally.
65
+
66
+ ### components/
67
+ Styles for specific UI components. These are complete styling solutions for individual
68
+ interface elements.
69
+
70
+ **Examples:** Buttons, cards, modals, navigation components.
71
+
72
+ ### config/
73
+ Configuration maps and design tokens split by domain. Each file focuses on a specific area
74
+ of configuration, keeping files manageable and easy to navigate.
75
+
76
+ **Files:** Colors, layout properties, spacing values, typography scales.
77
+
78
+
79
+
80
+ ### properties/
81
+ Property maps that define how utility classes are generated. Contains the configuration
82
+ that connects design tokens to CSS utility classes.
83
+
84
+
85
+
86
+ ### utilities/
87
+ Utility class generation and related configurations. This is where utility classes are
88
+ actually created and applied.
89
+
90
+ **Examples:** Generated spacing utilities, color utilities, typography utilities. -->
91
+
92
+ ---
93
+
94
+ ## Alternative Flat Structure
95
+
96
+ ```
97
+ src/
98
+ ├── _config.scss # All configuration & variables
99
+
100
+ ├── _properties.scss # All property maps & utility configs
101
+ ├── _base.scss # Base styles, typography, root
102
+ ├── _components.scss # All UI components
103
+ └── _utilities.scss # Generated utility classes
104
+ ```
105
+
106
+ ### _config.scss
107
+ Central configuration file containing all variables, settings, and global constants that
108
+ control the system behavior.
109
+
110
+
111
+
112
+ ### _properties.scss
113
+ All property maps and utility configurations. Contains the data structures that define how
114
+ utility classes are generated.
115
+
116
+ ### _base.scss
117
+ Foundation styles including CSS resets, base typography, root variables, and fundamental
118
+ styling that applies globally.
119
+
120
+ ### _components.scss
121
+ All UI component styles consolidated into a single file. Contains complete styling
122
+ solutions for interface elements.
123
+
124
+ ### _utilities.scss
125
+ Generated utility classes. The output of the utility generation system, containing all the
126
+ actual CSS utility classes.
package/index.html CHANGED
@@ -13,6 +13,126 @@
13
13
 
14
14
 
15
15
  <body class="zebra c-py-5-3-2">
16
+
17
+
18
+ <nav aria-label="Page navigation example">
19
+ <ul class="flex items-center -space-x-px h-8 text-sm">
20
+ <li>
21
+ <a href="#" class="flex items-center justify-center px-3 h-8 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
22
+ <span class="sr-only">Previous</span>
23
+ <svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
24
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4" />
25
+ </svg>
26
+ </a>
27
+ </li>
28
+ <li>
29
+ <a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">1</a>
30
+ </li>
31
+ <li>
32
+ <a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">2</a>
33
+ </li>
34
+ <li>
35
+ <a href="#" aria-current="page" class="z-10 flex items-center justify-center px-3 h-8 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white">3</a>
36
+ </li>
37
+ <li>
38
+ <a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">4</a>
39
+ </li>
40
+ <li>
41
+ <a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">5</a>
42
+ </li>
43
+ <li>
44
+ <a href="#" class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
45
+ <span class="sr-only">Next</span>
46
+ <svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
47
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4" />
48
+ </svg>
49
+ </a>
50
+ </li>
51
+ </ul>
52
+ </nav>
53
+ <nav aria-label="Page navigation example">
54
+ <ul class="flex items-center -space-x-px h-10 text-base">
55
+ <li>
56
+ <a href="#" class="flex items-center justify-center px-4 h-10 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
57
+ <span class="sr-only">Previous</span>
58
+ <svg class="w-3 h-3 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
59
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4" />
60
+ </svg>
61
+ </a>
62
+ </li>
63
+ <li>
64
+ <a href="#" class="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">1</a>
65
+ </li>
66
+ <li>
67
+ <a href="#" class="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">2</a>
68
+ </li>
69
+ <li>
70
+ <a href="#" aria-current="page" class="z-10 flex items-center justify-center px-4 h-10 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white">3</a>
71
+ </li>
72
+ <li>
73
+ <a href="#" class="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">4</a>
74
+ </li>
75
+ <li>
76
+ <a href="#" class="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">5</a>
77
+ </li>
78
+ <li>
79
+ <a href="#" class="flex items-center justify-center px-4 h-10 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white">
80
+ <span class="sr-only">Next</span>
81
+ <svg class="w-3 h-3 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
82
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4" />
83
+ </svg>
84
+ </a>
85
+ </li>
86
+ </ul>
87
+ </nav>
88
+
89
+ <section class="py-3">
90
+ <div class="container">
91
+ <h2 class="title txt-blue">Responsive Testing</h2>
92
+
93
+ <h4>Hide 'ON' Screen Size</h4>
94
+ <p>The box should not be visible on the current screen size.</p>
95
+ <div class="grid cols-5 tac my">
96
+ <div>
97
+ <div class="py px-025 pink on-sm:hidden"><code class="txt-sm txt-white">on-sm:hidden</code></div>
98
+ </div>
99
+ <div>
100
+ <div class="py px-025 pink on-md:hidden"><code class="txt-sm txt-white">on-md:hidden</code></div>
101
+ </div>
102
+ <div>
103
+ <div class="py px-025 pink on-lg:hidden"><code class="txt-sm txt-white">on-lg:hidden</code></div>
104
+ </div>
105
+ <div>
106
+ <div class="py px-025 pink on-xl:hidden"><code class="txt-sm txt-white">on-xl:hidden</code></div>
107
+ </div>
108
+ <div>
109
+ <div class="py px-025 pink on-xxl:hidden"><code class="txt-sm txt-white">on-xxl:hidden</code></div>
110
+ </div>
111
+ </div>
112
+
113
+ <h4>Display 'ON' Screen Size</h4>
114
+
115
+ <p>Hidden by default, you should only see a single box on the current screen size.</p>
116
+
117
+ <div class="grid cols-5 tac my">
118
+ <div>
119
+ <div class="py px-025 blue hidden on-sm:block"><code class="txt-sm txt-white">on-sm:block</code></div>
120
+ </div>
121
+ <div>
122
+ <div class="py px-025 blue hidden on-md:block"><code class="txt-sm txt-white">on-md:block</code></div>
123
+ </div>
124
+ <div>
125
+ <div class="py px-025 blue hidden on-lg:block"><code class="txt-sm txt-white">on-lg:block</code></div>
126
+ </div>
127
+ <div>
128
+ <div class="py px-025 blue hidden on-xl:block"><code class="txt-sm txt-white">on-xl:block</code></div>
129
+ </div>
130
+ <div>
131
+ <div class="py px-025 blue hidden on-xxl:block"><code class="txt-sm txt-white">on-xxl:block</code></div>
132
+ </div>
133
+ </div>
134
+ </div>
135
+ </section>
16
136
  <section class="py-3">
17
137
  <div class="container">
18
138
  <h2 class="title txt-blue">Outline</h2>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nk_jtb",
3
3
  "description": "Yet another utility based framework.",
4
- "version": "0.18.0",
4
+ "version": "0.19.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/naykel76/nk_jtb.git"
package/resolvers.md CHANGED
@@ -1,16 +1,16 @@
1
- # Resolvers
1
+ # Resolvers and Getters
2
2
 
3
- Resolvers centralise the conditional logic and data normalisation needed to turn raw
4
- configuration maps into predictable structures. This avoids scattering edge cases,
5
- defaults, and transformations throughout mixins.
3
+ Resolvers and getters work together to centralise conditional logic and data
4
+ normalisation, turning raw configuration maps into predictable structures. This avoids
5
+ scattering edge cases, defaults, and transformations throughout mixins.
6
6
 
7
7
  ## Purpose
8
8
 
9
9
  Configuration maps often contain optional properties, conditional logic, and mixed
10
- formats. Resolvers process these once and return clean, standardised data that mixins can
11
- rely on.
10
+ formats. Resolvers and getters process these once and return clean, standardised data that
11
+ mixins can rely on.
12
12
 
13
- **Before resolvers:**
13
+ **Before resolvers and getters:**
14
14
 
15
15
  ```scss
16
16
  @mixin some-mixin($config) {
@@ -20,7 +20,7 @@ rely on.
20
20
  }
21
21
  ```
22
22
 
23
- **After resolvers:**
23
+ **After resolvers and getters:**
24
24
 
25
25
  ```scss
26
26
  @mixin some-mixin($config) {
@@ -29,22 +29,64 @@ rely on.
29
29
  }
30
30
  ```
31
31
 
32
+ ## Resolvers
32
33
 
33
- <!-- ```scss
34
- // _resolvers.scss
34
+ Resolvers handle conditional logic and data transformation:
35
+ - They make decisions based on multiple parameters
36
+ - They transform or normalise data based on context
37
+ - They contain the "business logic" of your system
35
38
 
36
- // Configuration resolvers
37
- @function resolve-prefix($prefix, $property) { ... }
38
- @function resolve-states($with-state, $map-states) { ... }
39
- @function resolve-breakpoints($responsive, $map-breakpoints) { ... }
40
- @function resolve-unit($value, $default-unit) { ... }
39
+ **Example:**
40
+ ```scss
41
+ @function resolve-breakpoints($responsive, $breakpoints) {
42
+ @return if($responsive, get-breakpoints($breakpoints), $breakpoints);
43
+ }
44
+ ```
45
+ This **decides** whether to process `$breakpoints` through `get-breakpoints()` or return
46
+ it as-is, based on the `$responsive` flag.
47
+
48
+ ## Getters
49
+
50
+ Getters provide simple data retrieval with defaults:
51
+ - They return data or fallback to defaults
52
+ - They don't make complex decisions
53
+ - They're purely about data access
54
+
55
+ **Example:**
56
+ ```scss
57
+ @function get-breakpoints($breakpoints) {
58
+ $default-breakpoints: ('sm', 'md', 'lg', 'xl');
59
+ @return if($breakpoints == null, $default-breakpoints, $breakpoints);
60
+ }
61
+ ```
62
+ This simply **retrieves** breakpoints or provides defaults - no complex logic.
63
+
64
+ ## Resolvers vs Getters
65
+
66
+ The key distinction lies in their scope and decision-making complexity:
67
+
68
+ | Aspect | Resolvers | Getters |
69
+ | ------------------ | ------------------------------ | ---------------------------- |
70
+ | **Input** | Multiple parameters | Single parameter |
71
+ | **Logic** | Complex conditional processing | Simple null/default checks |
72
+ | **Purpose** | Transform and normalise data | Retrieve data with fallbacks |
73
+ | **Decision scope** | Multi-parameter business logic | Single-parameter data access |
74
+
75
+ **Resolvers** handle the "what should we do?" questions based on context and multiple
76
+ inputs. **Getters** handle the "what do we have?" questions with simple data retrieval.
77
+
78
+ ## The Pattern
79
+
80
+ **Resolvers** follow this pattern:
81
+ 1. **Input**: Multiple parameters that affect the decision
82
+ 2. **Logic**: Conditional processing based on those parameters
83
+ 3. **Output**: Transformed/normalised data ready for use
41
84
 
42
- // Value resolvers
43
- @function resolve-variant-label($key, $value) { ... }
44
- @function resolve-css-value($value, $unit) { ... }
45
- @function resolve-class-suffix($label, $unit) { ... }
85
+ **Getters** follow this pattern:
86
+ 1. **Input**: Single data parameter
87
+ 2. **Logic**: Simple null check
88
+ 3. **Output**: Data or default fallback
46
89
 
47
- // Composite resolvers (use the above)
48
- @function resolve-property-config($name, $raw-config) { ... }
49
- @function resolve-value-config($key, $value, $unit) { ... }
50
- ``` -->
90
+ This separation keeps your conditional logic centralised in resolvers while keeping simple
91
+ data access in getters, creating a clean architectural pattern that makes your code more
92
+ maintainable.
@@ -0,0 +1,54 @@
1
+ // =========================================================================
2
+ // Getter Functions
3
+ // --------------------------------------------------------------------------
4
+ // These functions return default values when none are provided, ensuring
5
+ // consistent data access.
6
+ // =========================================================================
7
+
8
+ @function get-breakpoints($breakpoints) {
9
+ $default-breakpoints: ('sm', 'md', 'lg', 'xl');
10
+
11
+ @return if($breakpoints == null, $default-breakpoints, $breakpoints);
12
+ }
13
+
14
+ @function get-states($states) {
15
+ $default-states: ('hover', 'focus', 'active');
16
+
17
+ @return if($states == null, $default-states, $states);
18
+ }
19
+
20
+ // =========================================================================
21
+ // Resolver Functions
22
+ // --------------------------------------------------------------------------
23
+ // These functions conditionally resolve values based on configuration modes.
24
+ // They ensure valid lists or values are returned, preserving original values
25
+ // when the mode is disabled.
26
+ // =========================================================================
27
+
28
+ @function resolve-breakpoints($responsive, $breakpoints) {
29
+ @return if($responsive, get-breakpoints($breakpoints), $breakpoints);
30
+ }
31
+
32
+ @function resolve-states($with-state, $map-states) {
33
+ @return if($with-state, get-states($map-states), $map-states);
34
+ }
35
+
36
+ @function resolve-prefix($prefix, $property) {
37
+ @return if($prefix == false, '', if($prefix == null, $property + '-', $prefix));
38
+ }
39
+
40
+ // @function resolve-prefix($raw-prefix, $fallback-name) {
41
+ // @return if($raw-prefix, $raw-prefix, $fallback-name);
42
+ // }
43
+
44
+ // @function resolve-unit($value, $fallback-unit) {
45
+ // @return if(value-has-unit($value), null, $fallback-unit);
46
+ // }
47
+
48
+ // @function resolve-class-suffix($label, $unit) {
49
+ // @return #{$label}#{handle-class-unit($unit)};
50
+ // }
51
+
52
+ // @function resolve-class-name($prefix, $suffix) {
53
+ // @return strip-class-suffixes(#{$prefix}#{$suffix});
54
+ // }
@@ -1,8 +1,8 @@
1
1
  @use '../functions/classes' as *;
2
2
  @use '../functions/strings' as *;
3
+ @use '../functions/resolvers' as *;
3
4
  @use '../mixins/make-classes' as *;
4
5
  @use '../mixins/property-makers' as *;
5
- @use '../mixins/helpers' as *;
6
6
  @use 'sass:list';
7
7
  @use 'sass:map';
8
8
  @use 'sass:string';
@@ -30,62 +30,25 @@
30
30
  // Supports responsive variants, automatic value-unit handling, position-based
31
31
  // classes, and optional axis key omission for cleaner class names.
32
32
  // --------------------------------------------------------------------------
33
- // Key variables in the value processing logic:
34
- //
35
- // 1. $derived-unit: Prevents double-unit application by checking if the $value
36
- // already includes a unit (12px, 1em, 100vh, etc.). If it does,
37
- // $derived-unit is set to null to avoid adding the map's unit. If it doesn't,
38
- // $derived-unit is set to $map-unit to apply the default unit.
39
- //
40
- // 2. $derived-value: The final processed CSS value for the property, created by
41
- // combining the original $value with the appropriate unit (if needed). This
42
- // ensures values are properly formatted for CSS output.
43
- //
44
- // 3. $derived-suffix: The unique identifier portion of the class name, created
45
- // by combining the variant label with the processed unit string. This forms
46
- // the distinctive part of each utility class (e.g., "12px" in "margin-12px").
47
- //
48
- // New in this version:
49
- // 4. $omit-axis-keys: Optional configuration to omit specific axis keys from
50
- // class names. For example, omitting 'xy' creates '.padding' instead of
51
- // '.padding-xy' while preserving '.padding-x', '.padding-y', etc.
52
- //
53
- // @example scss - Using omit-axis-keys
54
- // $properties-map: (
55
- // padding: (
56
- // values: $spacing-values,
57
- // unit: 'rem',
58
- // positions: $logical-position-map,
59
- // omit-axis-keys: (xy) // Creates .padding instead of .padding-xy
60
- // )
61
- // );
33
+ //
62
34
  // ==========================================================================
63
35
 
64
- // should i consider Taking Arbitrary ArgumentsTaking Arbitrary Arguments permalink
65
- // Sometimes it’s useful for a function to b
66
-
67
-
68
- // SassPlayground
69
- // SCSS Syntax
70
- // @function sum($numbers...) {
71
- // $sum: 0;
72
- // @each $number in $numbers {
73
- // $sum: $sum + $number;
74
- // }
75
- // @return $sum;
76
- // }
77
36
  // prettier-ignore
78
37
  @mixin build-property-classes($properties-map, $responsive: true, $with-state: false, $debug: false) {
79
- @each $property, $map in $properties-map {
80
- $map-unit: map.get($map, 'unit');
81
- $map-positions: map.get($map, 'positions');
82
- $omit-axis-keys: map.get($map, 'omit-axis-keys'); // NEW: extract omit-axis-keys config
38
+ // NK?? add option to create different responsive builds. (on, from, to)
39
+ // - should this be done on a per-property basis?
40
+ // - should this be done on a global basis?
83
41
 
84
- $prefix: resolve-prefix(map.get($map, 'prefix'), $property);
85
- $breakpoints: resolve-breakpoints($responsive, map.get($map, 'breakpoints'));
86
- $states: resolve-states($with-state, map.get($map, 'states'));
42
+ @each $property, $config in $properties-map {
43
+ $config-unit: map.get($config, 'unit');
44
+ $config-positions: map.get($config, 'positions');
45
+ $omit-axis-keys: map.get($config, 'omit-axis-keys');
46
+
47
+ $prefix: resolve-prefix(map.get($config, 'prefix'), $property);
48
+ $breakpoints: resolve-breakpoints($responsive, map.get($config, 'breakpoints'));
49
+ $states: resolve-states($with-state, map.get($config, 'states'));
87
50
 
88
- @each $key, $value in map.get($map, 'values') {
51
+ @each $key, $value in map.get($config, 'values') {
89
52
  // Normalize each key-value pair to ensure consistent variant label and value
90
53
  // for reliable class generation across different input formats
91
54
  $item: normalise-variant-value($key, $value);
@@ -93,19 +56,15 @@
93
56
  $value: list.nth($item, 2);
94
57
 
95
58
  // Process the value and create class name components
96
- $derived-unit: if(value-has-unit($value), null, ($map-unit)); // 1.
97
- $derived-value: #{handle-class-value($value, $derived-unit)}; // 2.
98
- $derived-suffix: #{$label}#{handle-class-unit($derived-unit)}; // 3.
59
+ $derived-unit: if(value-has-unit($value), null, ($config-unit));
60
+ $derived-value: #{handle-class-value($value, $derived-unit)};
61
+ $derived-suffix: #{$label}#{handle-class-unit($derived-unit)};
99
62
 
100
- // Generate the final class name by combining prefix and suffix,
101
63
  // then clean up any unwanted suffixes
102
64
  $derived-class: strip-class-suffixes(#{$prefix}#{$derived-suffix});
103
65
 
104
- // always create individual directions and avoid shorthands like
105
- // margin-inline, margin-block, and margin. This ensures maximum
106
- // flexibility and avoids unintended overrides in complex layouts.
107
- @if $map-positions {
108
- @include make-position-based-class($property, $derived-value, $map-positions, $prefix, $derived-suffix, $breakpoints, $states, $omit-axis-keys);
66
+ @if $config-positions {
67
+ @include make-position-based-class($property, $derived-value, $config-positions, $prefix, $derived-suffix, $breakpoints, $states, $omit-axis-keys);
109
68
  } @else{
110
69
  @include make-single-property-class( $property, #{$derived-class}, #{$derived-value}, $breakpoints, $states );
111
70
  }
@@ -1,92 +1,104 @@
1
1
  @use '../maps_and_variables/layout' as *;
2
2
 
3
- // |-- on-device --|
4
3
  // ==========================================================================
4
+ // Media Query Mixins
5
+ // ==========================================================================
6
+ // Responsive breakpoint mixins for handling different screen sizes
7
+ //
8
+ // Available patterns:
9
+ // - on-{size}: Target specific breakpoint range only
10
+ // - from-{size}: Target breakpoint and larger (mobile-first)
11
+ // - to-{size}: Target up to but not including breakpoint
12
+ //
13
+ // Examples:
14
+ // @include on-md { ... } // Only on medium screens
15
+ // @include from-lg { ... } // Large screens and up
16
+ // @include to-sm { ... } // Smaller than small screens
17
+ // ==========================================================================
18
+
19
+ // Target specific breakpoint ranges only
5
20
  @mixin on-sm {
6
- @media (min-width: $sm) and (max-width: calc($md - 1px)) {
21
+ @media ($sm <= width < $md) {
7
22
  @content;
8
23
  }
9
24
  }
10
25
 
11
26
  @mixin on-md {
12
- @media (min-width: $md) and (max-width: calc($lg - 1px)) {
27
+ @media ($md <= width < $lg) {
13
28
  @content;
14
29
  }
15
30
  }
16
31
 
17
32
  @mixin on-lg {
18
- @media (min-width: $lg) and (max-width: calc($xl - 1px)) {
33
+ @media ($lg <= width < $xl) {
19
34
  @content;
20
35
  }
21
36
  }
22
37
 
23
38
  @mixin on-xl {
24
- @media (min-width: $xl) and (max-width: calc($xxl - 1px)) {
39
+ @media ($xl <= width < $xxl) {
25
40
  @content;
26
41
  }
27
42
  }
28
43
 
29
44
  @mixin on-xxl {
30
- @media (min-width: $xxl) {
45
+ @media (width >= $xxl) {
31
46
  @content;
32
47
  }
33
48
  }
34
49
 
35
- // |-- from-device (device and larger) --|
36
- // ==========================================================================
37
-
50
+ // Target breakpoint and larger (mobile-first approach)
38
51
  @mixin from-sm {
39
- @media (min-width: $sm) {
52
+ @media (width >= $sm) {
40
53
  @content;
41
54
  }
42
55
  }
43
56
 
44
57
  @mixin from-md {
45
- @media (min-width: $md) {
58
+ @media (width >= $md) {
46
59
  @content;
47
60
  }
48
61
  }
49
62
 
50
63
  @mixin from-lg {
51
- @media (min-width: $lg) {
64
+ @media (width >= $lg) {
52
65
  @content;
53
66
  }
54
67
  }
55
68
 
56
69
  @mixin from-xl {
57
- @media (min-width: $xl) {
70
+ @media (width >= $xl) {
58
71
  @content;
59
72
  }
60
73
  }
61
74
 
62
75
  @mixin from-xxl {
63
- @media (min-width: $xxl) {
76
+ @media (width >= $xxl) {
64
77
  @content;
65
78
  }
66
79
  }
67
80
 
68
- // |-- to-device (up-to but not including) --|
69
- // ==========================================================================
81
+ // Target up to but not including breakpoint
70
82
  @mixin to-sm {
71
- @media (max-width: calc($sm - 1px)) {
83
+ @media (width < $sm) {
72
84
  @content;
73
85
  }
74
86
  }
75
87
 
76
88
  @mixin to-md {
77
- @media (max-width: calc($md - 1px)) {
89
+ @media (width < $md) {
78
90
  @content;
79
91
  }
80
92
  }
81
93
 
82
94
  @mixin to-lg {
83
- @media (max-width: calc($lg - 1px)) {
95
+ @media (width < $lg) {
84
96
  @content;
85
97
  }
86
98
  }
87
99
 
88
100
  @mixin to-xl {
89
- @media (max-width: calc($xl - 1px)) {
101
+ @media (width < $xl) {
90
102
  @content;
91
103
  }
92
104
  }
package/src/play.scss CHANGED
@@ -1,6 +1,6 @@
1
1
  // @use './utilities/border' as *;
2
2
  @use './common-tools' as *;
3
- @use './functions/helpers' as *;
3
+ @use './functions/resolvers' as *;
4
4
  @use './mixins/build-magic-grid' as *;
5
5
  @use './mixins/make-classes' as *;
6
6
  @use 'sass:color';
@@ -8,6 +8,37 @@
8
8
  @use 'sass:map';
9
9
  @use 'sass:string';
10
10
 
11
+ $display: ( block, flex, ( hidden: none ));
12
+ $display: ( ( hidden: none ));
13
+
14
+ $display-visibility-properties-map: (
15
+ display: ( prefix: false, values: $display ),
16
+ // visibility: ( prefix: false, values: $visibility )
17
+ );
18
+
19
+ // ==========================================================================
20
+ // Builds
21
+ // ==========================================================================
22
+ @include build-property-classes($display-visibility-properties-map, $responsive: true);
23
+
24
+
25
+ // Additional responsive display utilities for convienence with display and visibility
26
+
27
+ // DISPLAY AND HIDE 'ON' THE SELECTED SCREEN SIZE
28
+ @include make-on-breakpoint((display: flex), "flex", $responsive-variants);
29
+ @include make-on-breakpoint((display: block), "block", $responsive-variants);
30
+ @include make-on-breakpoint((display: none), "hidden", $responsive-variants);
31
+
32
+ // DISPLAY AND HIDE 'TO' THE SELECTED SCREEN SIZE
33
+ @include make-to-breakpoint((display: block), "block", remove-from-list($responsive-variants, xxl));
34
+ @include make-to-breakpoint((display: none), "hidden", remove-from-list($responsive-variants, xxl));
35
+
36
+
37
+
38
+
39
+
40
+
41
+
11
42
  // ==========================================================================
12
43
  // COMMON MAPS AND VARIABLES FOR TESTING
13
44
  // ==========================================================================
@@ -11,14 +11,15 @@ $display-visibility-properties-map: (
11
11
  // ==========================================================================
12
12
  @include build-property-classes($display-visibility-properties-map, $responsive: true);
13
13
 
14
- // ==========================================================================
15
- // DISPLAY AND HIDE 'ON' THE SELECTED SCREEN SIZE
16
- // ==========================================================================
14
+ // --------------------------------------------------------------------------
15
+ // Additional responsive display utilities for specific breakpoints
16
+ // --------------------------------------------------------------------------
17
+
18
+ // Show/hide AT specific breakpoint (e.g., .flex-md shows flex only on medium screens)
19
+ @include make-on-breakpoint((display: flex), "flex", $responsive-variants);
17
20
  @include make-on-breakpoint((display: block), "block", $responsive-variants);
18
21
  @include make-on-breakpoint((display: none), "hidden", $responsive-variants);
19
22
 
20
- // ==========================================================================
21
- // DISPLAY AND HIDE 'TO' THE SELECTED SCREEN SIZE
22
- // ==========================================================================
23
+ // Show/hide UP TO specific breakpoint (e.g., .block-to-lg shows block up to large screens)
23
24
  @include make-to-breakpoint((display: block), "block", remove-from-list($responsive-variants, xxl));
24
- @include make-to-breakpoint((display: none), "hidden", remove-from-list($responsive-variants, xxl));
25
+ @include make-to-breakpoint((display: none), "hidden", remove-from-list($responsive-variants, xxl));
@@ -1,81 +0,0 @@
1
- @use 'sass:map';
2
-
3
- // ==========================================================================
4
- // get-breakpoints()
5
- // --------------------------------------------------------------------------
6
- // Ensures a valid list of breakpoints is returned. Allows properties to define
7
- // custom breakpoint sets, or fall back to a default set when none are provided.
8
- // --------------------------------------------------------------------------
9
- // Example:
10
- // - get-breakpoints(null) => ('sm', 'md', 'lg', 'xl')
11
- // - get-breakpoints(('xs', 'md')) => ('xs', 'md')
12
- // ==========================================================================
13
- @function get-breakpoints($breakpoints) {
14
- $default-breakpoints: ('sm', 'md', 'lg', 'xl');
15
-
16
- @return if($breakpoints == null, $default-breakpoints, $breakpoints);
17
- }
18
-
19
- // ==========================================================================
20
- // get-states()
21
- // --------------------------------------------------------------------------
22
- // Ensures a valid list of states is returned. Allows properties to define
23
- // custom state sets, or fall back to a default set when none are provided.
24
- // --------------------------------------------------------------------------
25
- // Example:
26
- // - get-states(null) => ('hover', 'focus', 'active')
27
- // - get-states(('hover', 'disabled')) => ('hover', 'disabled')
28
- // ==========================================================================
29
- @function get-states($states) {
30
- $default-states: ('hover', 'focus', 'active');
31
-
32
- @return if($states == null, $default-states, $states);
33
- }
34
-
35
- // ==========================================================================
36
- // resolve-breakpoints()
37
- // --------------------------------------------------------------------------
38
- // Conditionally resolves breakpoints based on responsive mode. When responsive
39
- // is enabled, ensures a valid breakpoint list. When disabled, preserves the
40
- // original map value (which may be null).
41
- // --------------------------------------------------------------------------
42
- // Example:
43
- // - resolve-breakpoints(true, null) => ('sm', 'md', 'lg', 'xl')
44
- // - resolve-breakpoints(false, ('lg')) => ('lg')
45
- // - resolve-breakpoints(false, null) => null
46
- // ==========================================================================
47
- @function resolve-breakpoints($responsive, $breakpoints) {
48
- @return if($responsive, get-breakpoints($breakpoints), $breakpoints);
49
- }
50
-
51
- // ==========================================================================
52
- // resolve-states()
53
- // --------------------------------------------------------------------------
54
- // Conditionally resolves state variants based on state mode. When states are
55
- // enabled, ensures a valid state list. When disabled, preserves the original
56
- // map value (which may be null).
57
- // --------------------------------------------------------------------------
58
- // Example:
59
- // - resolve-states(true, null) => ('hover', 'focus', 'active')
60
- // - resolve-states(false, ('hover')) => ('hover')
61
- // - resolve-states(false, null) => null
62
- // ==========================================================================
63
- @function resolve-states($with-state, $map-states) {
64
- @return if($with-state, get-states($map-states), $map-states);
65
- }
66
-
67
- // ==========================================================================
68
- // resolve-prefix()
69
- // --------------------------------------------------------------------------
70
- // Determines the appropriate CSS class prefix based on map configuration.
71
- // Handles three scenarios: no prefix, custom prefix, or default prefix
72
- // derived from the property name.
73
- // --------------------------------------------------------------------------
74
- // Example:
75
- // - resolve-prefix(false, 'margin') => ''
76
- // - resolve-prefix('custom-', 'margin') => 'custom-'
77
- // - resolve-prefix(null, 'margin') => 'margin-'
78
- // ==========================================================================
79
- @function resolve-prefix($prefix, $property) {
80
- @return if($prefix == false, '', if($prefix == null, $property + '-', $prefix));
81
- }
File without changes