@nuvoui/core 1.3.4 → 1.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 (64) hide show
  1. package/LICENSE +21 -0
  2. package/dist/nuvoui.css +424 -342
  3. package/dist/nuvoui.css.map +1 -1
  4. package/dist/nuvoui.min.css +23 -1
  5. package/dist/nuvoui.min.css.map +1 -1
  6. package/package.json +1 -1
  7. package/src/styles/base/_base.scss +148 -147
  8. package/src/styles/base/_reset.scss +41 -49
  9. package/src/styles/build.scss +25 -1
  10. package/src/styles/components/_tooltips.scss +271 -0
  11. package/src/styles/config/_borders.scss +15 -0
  12. package/src/styles/config/_breakpoints.scss +11 -0
  13. package/src/styles/config/_colors.scss +192 -0
  14. package/src/styles/config/_constants.scss +1 -0
  15. package/src/styles/config/_container-queries.scss +1 -0
  16. package/src/styles/config/_feature-flags.scss +33 -0
  17. package/src/styles/config/_layouts.scss +13 -0
  18. package/src/styles/config/_shadows.scss +9 -0
  19. package/src/styles/config/_spacing.scss +41 -0
  20. package/src/styles/config/_theme-validation.scss +59 -0
  21. package/src/styles/config/_typography.scss +45 -0
  22. package/src/styles/functions/_breakpoints.scss +15 -0
  23. package/src/styles/functions/_colors.scss +280 -0
  24. package/src/styles/functions/_css-vars.scss +33 -0
  25. package/src/styles/functions/_feature-flags.scss +20 -0
  26. package/src/styles/functions/_math.scss +72 -0
  27. package/src/styles/functions/_strings.scss +68 -0
  28. package/src/styles/functions/_types.scss +104 -0
  29. package/src/styles/functions/_units.scss +83 -0
  30. package/src/styles/index.scss +26 -5
  31. package/src/styles/layouts/_container.scss +28 -27
  32. package/src/styles/layouts/_flex.scss +340 -341
  33. package/src/styles/layouts/_grid.scss +131 -128
  34. package/src/styles/mixins-map.json +484 -479
  35. package/src/styles/mixins-map.scss +1 -1
  36. package/src/styles/themes/_theme.scss +230 -211
  37. package/src/styles/tools/_accessibility.scss +50 -0
  38. package/src/styles/tools/_container-queries.scss +98 -0
  39. package/src/styles/tools/_feature-support.scss +46 -0
  40. package/src/styles/tools/_media-queries.scss +70 -0
  41. package/src/styles/tools/_modern-layout.scss +49 -0
  42. package/src/styles/utilities/_alignment.scss +35 -34
  43. package/src/styles/utilities/_animations.scss +312 -311
  44. package/src/styles/utilities/_backdrop-filters.scss +194 -193
  45. package/src/styles/utilities/_borders.scss +243 -237
  46. package/src/styles/utilities/_colors.scss +16 -136
  47. package/src/styles/utilities/_cursor.scss +10 -10
  48. package/src/styles/utilities/_display.scss +192 -191
  49. package/src/styles/utilities/_helpers.scss +106 -106
  50. package/src/styles/utilities/_opacity.scss +27 -25
  51. package/src/styles/utilities/_position.scss +124 -121
  52. package/src/styles/utilities/_shadows.scss +171 -169
  53. package/src/styles/utilities/_sizing.scss +197 -194
  54. package/src/styles/utilities/_spacing.scss +231 -224
  55. package/src/styles/utilities/_transforms.scss +235 -234
  56. package/src/styles/utilities/_transitions.scss +136 -135
  57. package/src/styles/utilities/_typography.scss +242 -239
  58. package/src/styles/utilities/_z-index.scss +69 -68
  59. package/src/styles/abstracts/_config.scss +0 -253
  60. package/src/styles/abstracts/_functions.scss +0 -626
  61. package/src/styles/themes/refactored_borders.ipynb +0 -37
  62. package/src/styles/utilities/_container-queries.scss +0 -95
  63. package/src/styles/utilities/_media-queries.scss +0 -189
  64. 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
+ }