@nuvoui/core 1.3.5 → 1.4.1

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 (65) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -1
  3. package/dist/nuvoui.css +878 -646
  4. package/dist/nuvoui.css.map +1 -1
  5. package/dist/nuvoui.min.css +23 -1
  6. package/dist/nuvoui.min.css.map +1 -1
  7. package/package.json +1 -1
  8. package/src/styles/base/_base.scss +148 -147
  9. package/src/styles/base/_reset.scss +41 -49
  10. package/src/styles/build.scss +25 -1
  11. package/src/styles/components/_tooltips.scss +271 -0
  12. package/src/styles/config/_borders.scss +15 -0
  13. package/src/styles/config/_breakpoints.scss +11 -0
  14. package/src/styles/config/_colors.scss +192 -0
  15. package/src/styles/config/_constants.scss +1 -0
  16. package/src/styles/config/_container-queries.scss +1 -0
  17. package/src/styles/config/_feature-flags.scss +33 -0
  18. package/src/styles/config/_layouts.scss +13 -0
  19. package/src/styles/config/_shadows.scss +9 -0
  20. package/src/styles/config/_spacing.scss +41 -0
  21. package/src/styles/config/_theme-validation.scss +59 -0
  22. package/src/styles/config/_typography.scss +45 -0
  23. package/src/styles/functions/_breakpoints.scss +15 -0
  24. package/src/styles/functions/_colors.scss +280 -0
  25. package/src/styles/functions/_css-vars.scss +33 -0
  26. package/src/styles/functions/_feature-flags.scss +20 -0
  27. package/src/styles/functions/_math.scss +72 -0
  28. package/src/styles/functions/_strings.scss +68 -0
  29. package/src/styles/functions/_types.scss +104 -0
  30. package/src/styles/functions/_units.scss +83 -0
  31. package/src/styles/index.scss +26 -5
  32. package/src/styles/layouts/_container.scss +28 -27
  33. package/src/styles/layouts/_flex.scss +343 -337
  34. package/src/styles/layouts/_grid.scss +131 -128
  35. package/src/styles/mixins-map.json +486 -479
  36. package/src/styles/mixins-map.scss +1 -1
  37. package/src/styles/themes/_theme.scss +230 -211
  38. package/src/styles/tools/_accessibility.scss +50 -0
  39. package/src/styles/tools/_container-queries.scss +98 -0
  40. package/src/styles/tools/_feature-support.scss +46 -0
  41. package/src/styles/tools/_media-queries.scss +70 -0
  42. package/src/styles/tools/_modern-layout.scss +49 -0
  43. package/src/styles/utilities/_alignment.scss +35 -34
  44. package/src/styles/utilities/_animations.scss +312 -311
  45. package/src/styles/utilities/_backdrop-filters.scss +194 -193
  46. package/src/styles/utilities/_borders.scss +243 -237
  47. package/src/styles/utilities/_colors.scss +16 -136
  48. package/src/styles/utilities/_cursor.scss +10 -10
  49. package/src/styles/utilities/_display.scss +192 -191
  50. package/src/styles/utilities/_helpers.scss +106 -106
  51. package/src/styles/utilities/_opacity.scss +27 -25
  52. package/src/styles/utilities/_position.scss +124 -121
  53. package/src/styles/utilities/_shadows.scss +171 -169
  54. package/src/styles/utilities/_sizing.scss +197 -194
  55. package/src/styles/utilities/_spacing.scss +230 -227
  56. package/src/styles/utilities/_transforms.scss +235 -234
  57. package/src/styles/utilities/_transitions.scss +136 -135
  58. package/src/styles/utilities/_typography.scss +254 -239
  59. package/src/styles/utilities/_z-index.scss +69 -68
  60. package/src/styles/abstracts/_config.scss +0 -254
  61. package/src/styles/abstracts/_functions.scss +0 -626
  62. package/src/styles/themes/refactored_borders.ipynb +0 -37
  63. package/src/styles/utilities/_container-queries.scss +0 -95
  64. package/src/styles/utilities/_media-queries.scss +0 -189
  65. package/src/styles/utilities/_tooltips.scss +0 -258
@@ -0,0 +1,15 @@
1
+ @use "sass:map";
2
+ @use "sass:meta";
3
+
4
+ @use "../config/breakpoints" as config-breakpoint;
5
+
6
+ @function get-breakpoint-value($bp, $debug: false) {
7
+ @if map.has-key(config-breakpoint.$breakpoints, #{$bp}) {
8
+ @return map.get(config-breakpoint.$breakpoints, #{$bp});
9
+ } @else if meta.type-of($bp) == "number" {
10
+ @return $bp;
11
+ } @else {
12
+ @error 'Invalid breakpoint: #{$bp}';
13
+ @return null;
14
+ }
15
+ }
@@ -0,0 +1,280 @@
1
+ // _colors.scss - Color functions and scale generation
2
+ @use "sass:math";
3
+ @use "sass:color";
4
+ @use "sass:map";
5
+ @use "sass:meta";
6
+ @use "sass:list";
7
+ @use "sass:string";
8
+
9
+ @use "../config/feature-flags" as config-flags;
10
+ @use "../config/breakpoints" as config-breakpoint;
11
+ @use "../config/colors" as config-color;
12
+ @use "../config/theme-validation" as config-theme;
13
+ @use "./css-vars" as fn-css-vars;
14
+ @use "./types" as fn-types;
15
+ @use "./math" as fn-math;
16
+ @use "./strings" as fn-strings;
17
+
18
+ @function to-color($color-name) {
19
+ // Return if already a color
20
+ @if meta.type-of($color-name) == "color" {
21
+ @return $color-name;
22
+ }
23
+
24
+ // Convert to string if needed
25
+ $color-string: string.unquote($color-name);
26
+ $color-lower: string.to-lower-case($color-string);
27
+
28
+ // Handle named colors (red, blue, etc.)
29
+ @if map.has-key(config-color.$colors-constants, $color-string) {
30
+ @return map.get(config-color.$colors-constants, $color-string);
31
+ }
32
+
33
+ // Handle hex colors - use from-hex function which returns a proper RGB color
34
+ @if string.slice($color-string, 1, 1) == "#" {
35
+ @return from-hex($color-string);
36
+ }
37
+
38
+ // Handle rgb/rgba strings
39
+ @if string.index($color-lower, "rgb(") == 1 {
40
+ $trimmed: string.slice($color-string, string.length("rgb(") + 1, -1);
41
+ $values: fn-strings.split($trimmed, ",");
42
+
43
+ @if list.length($values) == 3 {
44
+ @return rgb(fn-math.to-number(list.nth($values, 1)), fn-math.to-number(list.nth($values, 2)), fn-math.to-number(list.nth($values, 3)));
45
+ }
46
+ }
47
+
48
+ @if string.index($color-lower, "rgba(") == 1 {
49
+ $trimmed: string.slice($color-string, string.length("rgba(") + 1, -1);
50
+ $values: fn-strings.split($trimmed, ",");
51
+
52
+ @if list.length($values) == 4 {
53
+ @return rgba(fn-math.to-number(list.nth($values, 1)), fn-math.to-number(list.nth($values, 2)), fn-math.to-number(list.nth($values, 3)), fn-math.to-number(list.nth($values, 4)));
54
+ }
55
+ }
56
+
57
+ @warn "#{$color-string} is not a valid color format. Use hex colors like #FF0 or #FF0000";
58
+ @return null;
59
+ }
60
+
61
+ @function from-hex($hex-string) {
62
+ // Normalize input
63
+
64
+ $hex: string.to-lower-case(string.unquote($hex-string));
65
+ $valid-chars: "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "a" "b" "c" "d" "e" "f";
66
+ $length: string.length($hex);
67
+
68
+ // Validate format and length
69
+ @if string.slice($hex, 1, 1) != "#" {
70
+ @warn "Invalid hex color format: #{$hex-string}. Must start with #";
71
+ @return $hex-string;
72
+ }
73
+
74
+ // Check for valid lengths: #RGB, #RGBA, #RRGGBB, #RRGGBBAA
75
+ @if not($length == 4 or $length == 5 or $length == 7 or $length == 9) {
76
+ @warn "Invalid hex color length: #{$hex-string}. Must be 4, 5, 7 or 9 characters";
77
+ @return $hex-string;
78
+ }
79
+
80
+ // Extract components
81
+ $r: "";
82
+ $g: "";
83
+ $b: "";
84
+ $a: "";
85
+ $has-alpha: $length == 5 or $length == 9;
86
+ $component-size: if($length < 6, 1, 2);
87
+
88
+ // Validate and extract color components
89
+ @for $i from 2 through $length {
90
+ $char: string.slice($hex, $i, $i);
91
+
92
+ @if not list.index($valid-chars, $char) {
93
+ @warn "Invalid hex character: #{$char} in #{$hex-string}";
94
+ @return $hex-string;
95
+ }
96
+
97
+ // Determine which component we're building
98
+ $position: $i - 1;
99
+
100
+ @if $position <= $component-size {
101
+ $r: $r + $char;
102
+ } @else if $position <= $component-size * 2 {
103
+ $g: $g + $char;
104
+ } @else if $position <= $component-size * 3 {
105
+ $b: $b + $char;
106
+ } @else {
107
+ $a: $a + $char;
108
+ }
109
+ }
110
+
111
+ // Double characters for short hex notation
112
+ @if $component-size == 1 {
113
+ $r: $r + $r;
114
+ $g: $g + $g;
115
+ $b: $b + $b;
116
+ @if $has-alpha {
117
+ $a: $a + $a;
118
+ }
119
+ }
120
+
121
+ // Convert to RGB/RGBA
122
+ @if $has-alpha {
123
+ $alpha-value: math.div(hex-to-dec($a), 255);
124
+ @return rgba(hex-to-dec($r), hex-to-dec($g), hex-to-dec($b), $alpha-value);
125
+ } @else {
126
+ @return rgb(hex-to-dec($r), hex-to-dec($g), hex-to-dec($b));
127
+ }
128
+ }
129
+
130
+ @function hex-to-dec($string) {
131
+ $hex-digits: "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "a" "b" "c" "d" "e" "f";
132
+ $string: string.to-lower-case($string);
133
+ $length: string.length($string);
134
+
135
+ $dec: 0;
136
+ @for $i from 1 through $length {
137
+ $character: string.slice($string, $i, $i);
138
+ $digit-value: list.index($hex-digits, $character) - 1;
139
+
140
+ @if $digit-value >= 0 {
141
+ $position: $length - $i;
142
+ $dec: $dec + ($digit-value * math.pow(16, $position));
143
+ } @else {
144
+ @warn "Invalid hex character: #{$character}";
145
+ }
146
+ }
147
+
148
+ @return $dec;
149
+ }
150
+
151
+ // Color Validation
152
+ @function is-valid-color($color) {
153
+ @return meta.type-of($color) == "color";
154
+ }
155
+
156
+ // Scale Generation Function
157
+ @function create-color-scale($color) {
158
+ $scale: ();
159
+ $stops: (50, 100, 200, 300, 400, 500, 600, 700, 800, 900);
160
+
161
+ @each $shade in $stops {
162
+ $adjusted-color: get-color($color, $shade);
163
+ $scale: map.set($scale, $shade, $adjusted-color);
164
+ }
165
+
166
+ @return $scale;
167
+ }
168
+
169
+ $color-cache: (); // to store the generated colors
170
+ // todo : add documentation for Cache
171
+ @function get-color($color, $shade: 500, $default-color: config-color.$default-color) {
172
+ @if not $color {
173
+ @warn "No color provided to get-color()";
174
+ @return $default-color;
175
+ }
176
+
177
+ @if not is-valid-shade($shade) {
178
+ @warn "Invalid shade value: #{$shade}. Valid range is 50 to 900.";
179
+ @return $default-color;
180
+ }
181
+
182
+ $cache-key: "#{$color}-#{$shade}";
183
+ @if map.has-key($color-cache, $cache-key) {
184
+ @return map.get($color-cache, $cache-key);
185
+ }
186
+
187
+ @if fn-css-vars.is-css-var($color) {
188
+ @if $shade != 500 {
189
+ @warn "CSS variables do not support shade values. ";
190
+ }
191
+ @return fn-css-vars.get-css-var($color);
192
+ }
193
+
194
+ $colors-list: (
195
+ "primary": config-color.$primary,
196
+ "secondary": config-color.$secondary,
197
+ "success": config-color.$success,
198
+ "danger": config-color.$danger,
199
+ "warning": config-color.$warning,
200
+ "info": config-color.$info,
201
+ );
202
+
203
+ @if meta.type-of($shade) == "string" {
204
+ $shade: fn-math.to-number($shade);
205
+ }
206
+
207
+ @if fn-types.get-type($color) == "color" {
208
+ $color: to-color($color);
209
+ } @else if map.has-key($colors-list, $color) {
210
+ $color: map.get($colors-list, $color);
211
+ } @else if map.has-key(config-color.$color-primitives, $color) {
212
+ $color: map.get(config-color.$color-primitives, $color);
213
+ } @else {
214
+ @warn "Unexpected color value: #{$color}";
215
+ @return $default-color;
216
+ }
217
+
218
+ $x1: 50; // First input value
219
+ $y1: 95; // First output percentage
220
+ $x2: 900; // Second input value
221
+ $y2: 15; // Second output percentage
222
+ // Calculate slope (m) of the line
223
+ $slope: math.div($y2 - $y1, $x2 - $x1);
224
+
225
+ // Calculate y-intercept (b) of the line: y = mx + b
226
+ $y-intercept: $y1 - ($slope * $x1);
227
+
228
+ // Calculate the output percentage using the linear equation: y = mx + b
229
+ $result: ($slope * $shade) + $y-intercept;
230
+ $lightness: math.percentage(math.div($result, 100));
231
+ $adjusted-color: $color;
232
+
233
+ @if $shade < 500 {
234
+ // Lighter shades: mix with white
235
+ $mix-percentage: math.div($lightness - 50%, 50%) * 100%;
236
+ $adjusted-color: color.mix(white, $color, $mix-percentage);
237
+ } @else if $shade > 500 {
238
+ // Darker shades: mix with black
239
+ $mix-percentage: math.div(50% - $lightness, 50%) * 100%;
240
+ $adjusted-color: color.mix(black, $color, $mix-percentage);
241
+ }
242
+
243
+ $color-cache: map.set($color-cache, $cache-key, $adjusted-color) !global;
244
+ @return $adjusted-color;
245
+ }
246
+
247
+ // Luminance calculation for contrast
248
+ @function luminance($color) {
249
+ $red: math.div(color.channel($color, "red"), 255);
250
+ $green: math.div(color.channel($color, "green"), 255);
251
+ $blue: math.div(color.channel($color, "blue"), 255);
252
+
253
+ $red: if($red <= 0.0393, math.div($red, 12.92), math.pow((math.div($red + 0.055, 1.055)), 2.4));
254
+ $green: if($green <= 0.0393, math.div($green, 12.92), math.pow((math.div($green + 0.055, 1.055)), 2.4));
255
+ $blue: if($blue <= 0.0393, math.div($blue, 12.92), math.pow((math.div($blue + 0.055, 1.055)), 2.4));
256
+
257
+ @return 0.2126 * $red + 0.7152 * $green + 0.0722 * $blue;
258
+ }
259
+
260
+ // Find appropriate text color for a background
261
+ @function find-text-color($background) {
262
+ $luminance: luminance($background);
263
+ $dark-color: #000;
264
+ @if map.has-key(config-theme.$light-theme, "text-color") {
265
+ $dark-color: map.get(config-theme.$light-theme, "text-color");
266
+ }
267
+
268
+ $light-color: #fff;
269
+ @if map.has-key(config-theme.$light-theme, "text-inverted") {
270
+ $light-color: map.get(config-theme.$light-theme, "text-inverted");
271
+ }
272
+ @return if($luminance > 0.55, $dark-color, $light-color);
273
+ }
274
+
275
+ @function is-valid-shade($shade) {
276
+ @if meta.type-of($shade) == "number" {
277
+ @return $shade >= 50 and $shade <= 900;
278
+ }
279
+ @return false;
280
+ }
@@ -0,0 +1,33 @@
1
+ @use "sass:string";
2
+ @use "sass:math";
3
+ @use "sass:map";
4
+ @use "sass:list";
5
+ @use "sass:meta";
6
+
7
+ @use "./strings" as fn-strings;
8
+
9
+ @function is-css-var($value) {
10
+ @if meta.type-of($value) != "string" {
11
+ @return false;
12
+ }
13
+ $val: string.unquote(fn-strings.strip-quotes($value));
14
+ @return string.index($val, "var(") == 1;
15
+ }
16
+
17
+ @function get-css-var($value) {
18
+ @if is-css-var($value) {
19
+ $val: string.unquote(fn-strings.strip-quotes($value));
20
+ $var-name: string.slice($val, 5, -2);
21
+ @return var(#{$var-name});
22
+ } @else {
23
+ @error "Value is not a CSS variable";
24
+ @return null;
25
+ }
26
+ }
27
+
28
+ @function to-css-var($name, $fallback: null) {
29
+ @if $fallback {
30
+ @return var(--#{$name}, #{$fallback});
31
+ }
32
+ @return var(--#{$name});
33
+ }
@@ -0,0 +1,20 @@
1
+ @use "sass:string";
2
+ @use "sass:math";
3
+ @use "sass:map";
4
+ @use "sass:list";
5
+ @use "sass:meta";
6
+ @use "../config/feature-flags" as config-flags;
7
+ @use "../config/breakpoints" as config-breakpoint;
8
+
9
+ // Helper function to check if a feature is enabled
10
+ @function feature-enabled($feature) {
11
+ @if not config-flags.$generate-utility-classes {
12
+ @return false;
13
+ }
14
+
15
+ @if not map.has-key(config-flags.$feature-flags, $feature) {
16
+ @return true; // Default to enabled if not specified
17
+ }
18
+
19
+ @return map.get(config-flags.$feature-flags, $feature);
20
+ }
@@ -0,0 +1,72 @@
1
+ @use "sass:string";
2
+ @use "sass:math";
3
+ @use "sass:map";
4
+ @use "sass:list";
5
+ @use "sass:meta";
6
+ @use "../config/constants" as config-constants;
7
+ @use "./strings" as fn-strings;
8
+
9
+ @function to-number($value) {
10
+ @if meta.type-of($value) == "number" {
11
+ @return $value;
12
+ } @else if meta.type-of($value) != "string" {
13
+ @error "Value for `number` should be a number or a string.";
14
+ @return $value;
15
+ }
16
+
17
+ $val: string.unquote(fn-strings.strip-quotes($value));
18
+
19
+ $result: 0;
20
+ $digits: 0;
21
+ $minus: string.slice($value, 1, 1) == "-";
22
+ $numbers: (
23
+ "0": 0,
24
+ "1": 1,
25
+ "2": 2,
26
+ "3": 3,
27
+ "4": 4,
28
+ "5": 5,
29
+ "6": 6,
30
+ "7": 7,
31
+ "8": 8,
32
+ "9": 9,
33
+ );
34
+ $number-chars-end: 0;
35
+
36
+ @for $i from if($minus, 2, 1) through string.length($val) {
37
+ $character: string.slice($val, $i, $i);
38
+
39
+ @if list.index(map.keys($numbers), $character) or $character == "." {
40
+ $number-chars-end: $i;
41
+
42
+ @if $character == "." {
43
+ $digits: 1;
44
+ } @else if $digits == 0 {
45
+ $result: $result * 10 + map.get($numbers, $character);
46
+ } @else {
47
+ $digits: $digits * 10;
48
+ $result: $result + map.get($numbers, $character) / $digits;
49
+ }
50
+ } @else {
51
+ // Non-numeric character found - check for unit
52
+ $rest: string.slice($val, $i);
53
+
54
+ // Look for valid unit
55
+ @each $unit in config-constants.$units {
56
+ @if $rest == $unit {
57
+ @return if($minus, -$result, $result) + string.unquote($unit);
58
+ }
59
+ }
60
+
61
+ // No valid unit - return null for non-numeric strings
62
+ @if $i == if($minus, 2, 1) {
63
+ @return null; // First char is non-numeric
64
+ }
65
+
66
+ // Otherwise return just the parsed number
67
+ @return if($minus, -$result, $result);
68
+ }
69
+ }
70
+
71
+ @return if($minus, -$result, $result);
72
+ }
@@ -0,0 +1,68 @@
1
+ @use "sass:string";
2
+ @use "sass:math";
3
+ @use "sass:map";
4
+ @use "sass:list";
5
+ @use "sass:meta";
6
+
7
+ @function str-replace($string, $search, $replace: " ") {
8
+ $index: string.index($string, $search);
9
+ @if $index {
10
+ @return string.slice($string, 1, $index - 1) + $replace + str-replace(string.slice($string, $index + string.length($search)), $search, $replace);
11
+ }
12
+ @return $string;
13
+ }
14
+
15
+ @function strip-quotes($string) {
16
+ @if meta.type-of($string) == "string" {
17
+ @if string.slice($string, 1, 1) == '"' and string.slice($string, -1) == '"' {
18
+ @return string.slice($string, 2, -2);
19
+ } @else if string.slice($string, 1, 1) == "'" and string.slice($string, -1) == "'" {
20
+ @return string.slice($string, 2, -2);
21
+ }
22
+ }
23
+
24
+ @return $string;
25
+ }
26
+
27
+ @function str-trim($string) {
28
+ @while string.length($string) > 0 and string.slice($string, 1, 1) == " " {
29
+ $string: string.slice($string, 2);
30
+ }
31
+
32
+ @while string.length($string) > 0 and string.slice($string, -1) == " " {
33
+ $string: string.slice($string, 1, string.length($string) - 1);
34
+ }
35
+
36
+ @return $string;
37
+ }
38
+
39
+ @function split($string, $delimiter) {
40
+ $result: ();
41
+ $current: "";
42
+ $paren-depth: 0;
43
+
44
+ @for $i from 1 through string.length($string) {
45
+ $char: string.slice($string, $i, $i);
46
+
47
+ @if $char == "(" {
48
+ $paren-depth: $paren-depth + 1;
49
+ $current: $current + $char;
50
+ } @else if $char == ")" {
51
+ $paren-depth: $paren-depth - 1;
52
+ $current: $current + $char;
53
+ } @else if $char == $delimiter and $paren-depth == 0 {
54
+ // Only split on delimiter when not inside parentheses
55
+ $result: list.append($result, str-trim(string.unquote(strip-quotes($current))), "comma");
56
+ $current: "";
57
+ } @else {
58
+ $current: $current + $char;
59
+ }
60
+ }
61
+
62
+ // Add the last parameter
63
+ @if $current != "" {
64
+ $result: list.append($result, string.unquote(str-trim($current)));
65
+ }
66
+
67
+ @return $result;
68
+ }
@@ -0,0 +1,104 @@
1
+ @use "sass:string";
2
+ @use "sass:math";
3
+ @use "sass:map";
4
+ @use "sass:list";
5
+ @use "sass:meta";
6
+
7
+ @use "../config/colors" as config-colors;
8
+ @use "../config/constants" as config-constants;
9
+ @use "../config/borders" as config-borders;
10
+ @use "../config/breakpoints" as config-breakpoints;
11
+ @use "../config/typography" as config-type;
12
+ @use "./units" as fn-units;
13
+ @use "./strings" as fn-strings;
14
+ @use "./math" as fn-math;
15
+ @use "./css-vars" as fn-css-vars;
16
+
17
+ @function get-type($value) {
18
+ // Handle null and empty values
19
+ @if not $value {
20
+ @return "null";
21
+ }
22
+
23
+ // Handle already typed values
24
+ @if meta.type-of($value) == "color" {
25
+ @return "color";
26
+ } @else if meta.type-of($value) == "number" {
27
+ @return "number";
28
+ } @else if meta.type-of($value) == "bool" {
29
+ @return "boolean";
30
+ } @else if meta.type-of($value) == "list" or meta.type-of($value) == "map" {
31
+ @return meta.type-of($value);
32
+ }
33
+
34
+ // Convert to string if needed
35
+ $val: string.unquote(fn-strings.strip-quotes($value));
36
+ $val-lower: string.to-lower-case($val);
37
+
38
+ // Check for colors
39
+ @if string.slice($val, 1, 1) == "#" and (string.length($val) == 4 or string.length($val) == 7 or string.length($val) == 5 or string.length($val) == 9) {
40
+ @return "color";
41
+ }
42
+ @if string.index($val-lower, "rgb(") == 1 or string.index($val-lower, "rgba(") == 1 {
43
+ @return "color";
44
+ }
45
+ @if map.has-key(config-colors.$colors-constants, $val-lower) {
46
+ @return "color";
47
+ }
48
+
49
+ // Check for CSS variables first
50
+ @if fn-css-vars.is-css-var($val) {
51
+ @return "css-var";
52
+ }
53
+
54
+ // Check for known CSS states
55
+ $states: ("hover", "active", "focus", "visited", "disabled", "checked", "first-child", "last-child");
56
+ @if list.index($states, $val-lower) {
57
+ @return "state";
58
+ }
59
+
60
+ // Check for numbers with units
61
+ @each $unit in config-constants.$units {
62
+ @if string.slice($val, -1 * string.length($unit)) == $unit {
63
+ // Check if the part before the unit is numeric
64
+ $num-part: string.slice($val, 1, string.length($val) - string.length($unit));
65
+ @if fn-math.to-number($num-part) {
66
+ @return "number";
67
+ }
68
+ }
69
+ }
70
+
71
+ // Check for pure numbers
72
+ @if fn-math.to-number($val) {
73
+ @return "number";
74
+ }
75
+
76
+ // Check for breakpoints
77
+ @if map.has-key(config-breakpoints.$breakpoints, $val) {
78
+ @return "breakpoint";
79
+ }
80
+
81
+ // Check for font weights
82
+ @if map.has-key(config-type.$font-weights, $val-lower) {
83
+ @return "font-weight";
84
+ }
85
+
86
+ // Check for border radius values
87
+ @if map.has-key(config-borders.$border-radii, $val-lower) {
88
+ @return "border-radius";
89
+ }
90
+
91
+ // Check for special CSS keywords
92
+ $keywords: ("auto", "inherit", "initial", "unset", "none", "flex", "grid", "block", "inline");
93
+ @if list.index($keywords, $val-lower) {
94
+ @return "css-keyword";
95
+ }
96
+
97
+ // Check for CSS functions
98
+ @if string.index($val-lower, "calc(") == 1 or string.index($val-lower, "var(") == 1 or string.index($val-lower, "min(") == 1 or string.index($val-lower, "max(") == 1 {
99
+ @return "css-function";
100
+ }
101
+
102
+ // Default to string
103
+ @return "string";
104
+ }
@@ -0,0 +1,83 @@
1
+ @use "sass:string";
2
+ @use "sass:math";
3
+ @use "sass:map";
4
+ @use "sass:list";
5
+ @use "sass:meta";
6
+ @use "../config/feature-flags" as config-flags;
7
+ @use "../config/constants" as config-constants;
8
+ @use "../functions/strings" as fn-string;
9
+ @use "../functions/math" as fn-math;
10
+
11
+ @function strip-unit($value) {
12
+ @if meta.type-of($value) != "number" {
13
+ @error "strip-unit() requires a number";
14
+ }
15
+ @return math.div($value, ($value * 0 + 1));
16
+ }
17
+
18
+ // used in animation unique name creation
19
+ @function safe-unit-name($unit) {
20
+ @if $unit == "%" {
21
+ @return "per";
22
+ } @else if $unit == "." {
23
+ @return "dot";
24
+ } @else {
25
+ @return $unit;
26
+ }
27
+ }
28
+
29
+ // Ensures a value has a unit, adding $default-unit if none exists
30
+ // @param {Number|String} $val - The value to check
31
+ // @return {String} - The value with units
32
+ // todo improve this when we can
33
+ @function fix-units($val, $unit: config-flags.$default-unit, $debug: null) {
34
+ // Handle null values
35
+ @if not $val {
36
+ @return null;
37
+ }
38
+
39
+ // Check type
40
+ @if meta.type-of($val) != "number" and meta.type-of($val) != "string" {
41
+ @error "fix-units() requires a number or string value";
42
+ @return null;
43
+ }
44
+
45
+ // Handle number type
46
+ @if meta.type-of($val) == "number" {
47
+ @if math.is-unitless($val) {
48
+ @return $val + $unit;
49
+ }
50
+ @return $val;
51
+ }
52
+
53
+ // String handling - strip quotes first
54
+ $val: fn-string.strip-quotes($val);
55
+
56
+ // CSS keywords - return as is
57
+ @if $val == auto or $val == inherit or $val == initial or $val == "min-content" or $val == "max-content" or $val == "fit-content" {
58
+ @return #{$val};
59
+ }
60
+
61
+ // Check if string already has units
62
+ @each $u in config-constants.$units {
63
+ @if string.slice($val, -1 * string.length($u)) == $u {
64
+ // Try to convert numeric strings with units (like "20px") to actual numbers
65
+ $number-part: string.slice($val, 1, string.length($val) - string.length($u));
66
+
67
+ @if string.index($number-part, ".") or fn-math.to-number($number-part) {
68
+ @return fn-math.to-number($number-part) + string.unquote($u);
69
+ }
70
+
71
+ @return $val;
72
+ }
73
+ }
74
+
75
+ // Try to convert to number if possible
76
+ @if string.index($val, ".") or fn-math.to-number($val) {
77
+ $number-val: fn-math.to-number($val);
78
+ @return $number-val + $unit;
79
+ }
80
+
81
+ // Default: just add the unit
82
+ @return string.unquote($val + $unit);
83
+ }