@omnisass/library 0.2.0 → 2026.1.0-alpha.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 (101) hide show
  1. package/.editorconfig +13 -0
  2. package/.omnisass/scripts/bump-version.sh +288 -0
  3. package/.sassdoc.yaml +21 -0
  4. package/.vscode/settings.json +17 -0
  5. package/_configs.scss +10 -45
  6. package/index.scss +5 -91
  7. package/modules/utilities/converters/_convert-em2px.scss +3 -49
  8. package/modules/utilities/converters/_convert-hex2rgb.scss +2 -44
  9. package/modules/utilities/converters/_convert-hex2rgba.scss +2 -57
  10. package/modules/utilities/converters/_convert-px2em.scss +3 -62
  11. package/modules/utilities/converters/_convert-px2rem.scss +3 -62
  12. package/modules/utilities/converters/_convert-rem2px.scss +3 -62
  13. package/modules/utilities/converters/_index.scss +10 -0
  14. package/modules/utilities/getters/_index.scss +23 -0
  15. package/modules/utilities/getters/color/_get-color-brightness.scss +2 -48
  16. package/modules/utilities/getters/color/_get-color-darkest.scss +13 -68
  17. package/modules/utilities/getters/list/_get-list-item-end.scss +2 -29
  18. package/modules/utilities/getters/list/_get-list-item-start.scss +2 -29
  19. package/modules/utilities/getters/list/_get-list-item.scss +6 -82
  20. package/modules/utilities/getters/number/_get-number-from-percent.scss +2 -40
  21. package/modules/utilities/getters/number/_get-number-height-by-ratio.scss +3 -35
  22. package/modules/utilities/getters/number/_get-number-max-safe.scss +112 -0
  23. package/modules/utilities/getters/number/_get-number-max.scss +10 -88
  24. package/modules/utilities/getters/number/_get-number-min-safe.scss +114 -0
  25. package/modules/utilities/getters/number/_get-number-min.scss +9 -84
  26. package/modules/utilities/getters/number/_get-number-percentage-of.scss +2 -58
  27. package/modules/utilities/getters/number/_get-number-unit.scss +5 -46
  28. package/modules/utilities/getters/number/_get-number-width-by-ratio.scss +3 -56
  29. package/modules/utilities/helpers/_index.scss +44 -0
  30. package/modules/utilities/helpers/color/_color-blend-steps.scss +5 -89
  31. package/modules/utilities/helpers/color/_color-blend.scss +11 -85
  32. package/modules/utilities/helpers/color/_color-hue-shift.scss +7 -61
  33. package/modules/utilities/helpers/color/_color-scale.scss +7 -74
  34. package/modules/utilities/helpers/color/_color-shade.scss +2 -60
  35. package/modules/utilities/helpers/color/_color-tint.scss +2 -60
  36. package/modules/utilities/helpers/color/_color-triad.scss +9 -53
  37. package/modules/utilities/helpers/list/_list-dedupe.scss +9 -50
  38. package/modules/utilities/helpers/list/_list-insert-at.scss +16 -86
  39. package/modules/utilities/helpers/list/_list-merge.scss +1 -1
  40. package/modules/utilities/helpers/list/_list-remove-at.scss +9 -71
  41. package/modules/utilities/helpers/list/_list-sum-numbers-safe.scss +17 -81
  42. package/modules/utilities/helpers/list/_list-sum-numbers.scss +9 -57
  43. package/modules/utilities/helpers/number/_number-ceil-to.scss +1 -1
  44. package/modules/utilities/helpers/number/_number-clamp-max.scss +1 -1
  45. package/modules/utilities/helpers/number/_number-clamp-min.scss +1 -1
  46. package/modules/utilities/helpers/number/_number-clamp.scss +1 -1
  47. package/modules/utilities/helpers/number/_number-denormalize.scss +1 -1
  48. package/modules/utilities/helpers/number/_number-fibonacci.scss +2 -2
  49. package/modules/utilities/helpers/number/_number-floor-to.scss +1 -1
  50. package/modules/utilities/helpers/number/_number-format-with-separator.scss +4 -4
  51. package/modules/utilities/helpers/number/_number-normalize.scss +1 -1
  52. package/modules/utilities/helpers/number/_number-random-between-int.scss +1 -1
  53. package/modules/utilities/helpers/number/_number-random-between.scss +1 -1
  54. package/modules/utilities/helpers/number/_number-range.scss +7 -7
  55. package/modules/utilities/helpers/number/_number-round-to-nearest.scss +1 -1
  56. package/modules/utilities/helpers/number/_number-round-to.scss +1 -1
  57. package/modules/utilities/helpers/number/_number-strip-unit.scss +2 -14
  58. package/modules/utilities/helpers/string/_string-capitalize.scss +1 -1
  59. package/modules/utilities/helpers/string/_string-replace.scss +1 -1
  60. package/modules/utilities/helpers/string/_string-trim-end.scss +2 -2
  61. package/modules/utilities/helpers/string/_string-trim-start.scss +2 -2
  62. package/modules/utilities/helpers/string/_string-trim.scss +1 -1
  63. package/modules/utilities/loggers/_index.scss +6 -0
  64. package/modules/utilities/validators/_index.scss +38 -0
  65. package/modules/utilities/validators/{misc/_is-time.scss → _is-time.scss} +2 -2
  66. package/modules/utilities/validators/color/_is-color-light.scss +1 -1
  67. package/modules/utilities/validators/color/_is-color-list.scss +1 -1
  68. package/modules/utilities/validators/list/_is-list-contained.scss +1 -1
  69. package/modules/utilities/validators/number/_is-int-even.scss +1 -1
  70. package/modules/utilities/validators/number/_is-int-odd.scss +1 -1
  71. package/modules/utilities/validators/number/_is-int.scss +1 -1
  72. package/modules/utilities/validators/number/_is-number-has-unit.scss +1 -1
  73. package/modules/utilities/validators/number/_is-number-negative.scss +1 -1
  74. package/modules/utilities/validators/number/_is-number-positive.scss +1 -1
  75. package/modules/utilities/validators/number/_is-number-unitless.scss +1 -1
  76. package/modules/utilities/validators/number/_is-number-zero.scss +1 -1
  77. package/modules/utilities/validators/string/_is-string-contained.scss +25 -25
  78. package/modules/utilities/validators/string/_is-string-empty.scss +1 -1
  79. package/modules/utilities/validators/string/_is-string-ending-with.scss +1 -1
  80. package/modules/utilities/validators/string/_is-string-starting-with.scss +1 -1
  81. package/modules/utilities/validators/type-of/_is-boolean.scss +1 -1
  82. package/modules/utilities/validators/type-of/_is-color.scss +1 -1
  83. package/modules/utilities/validators/type-of/_is-list.scss +1 -1
  84. package/modules/utilities/validators/type-of/_is-map.scss +1 -1
  85. package/modules/utilities/validators/type-of/_is-number.scss +1 -1
  86. package/modules/utilities/validators/type-of/_is-string.scss +1 -1
  87. package/modules/utilities/validators/type-of/_is-type.scss +1 -1
  88. package/package.json +5 -6
  89. package/package.scss +3 -3
  90. package/playground/index.scss +8 -0
  91. package/modules/utilities/converters/_convert-camel2kebab.scss +0 -186
  92. package/modules/utilities/converters/_convert-kebab2camel.scss +0 -232
  93. package/modules/utilities/converters/_convert-kebab2snake.scss +0 -118
  94. package/modules/utilities/converters/_convert-snake2kebab.scss +0 -173
  95. package/modules/utilities/helpers/misc/_url-encode.configs.scss +0 -64
  96. package/modules/utilities/helpers/misc/_url-encode.scss +0 -148
  97. package/modules/utilities/loggers/_log-invalid-type.scss +0 -151
  98. package/modules/utilities/loggers/_log-invalid-value.scss +0 -151
  99. package/test.md +0 -168
  100. package/test.scss +0 -405
  101. package/test.sh +0 -149
@@ -1,10 +1,5 @@
1
- @use 'sass:list';
2
- @use 'sass:map';
3
1
  @use './get-list-item-start' as *;
4
2
  @use './get-list-item-end' as *;
5
- @use '../../loggers/log-invalid-value' as *;
6
- @use '../../loggers/log-invalid-type' as *;
7
- @use '../../validators/type-of/is-string' as *;
8
3
 
9
4
  /// Возвращает первый или последний элемент списка.
10
5
  ///
@@ -28,7 +23,7 @@
28
23
  /// ---
29
24
  /// @name get-list-item
30
25
  /// @group utilities-getters
31
- /// @since 2025.12.27
26
+ /// @since 0.0.1
32
27
  /// @access public
33
28
  /// @author Murad Rustamov (therteenten)
34
29
  /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
@@ -95,85 +90,14 @@
95
90
  /// некорректных значений `$direction` возвращает `null`.
96
91
  @function get-list-item($list, $direction: 'start') {
97
92
 
98
- // Переменная для хранения результата функции
99
- // Инициализируем пустой строкой, но тип может
100
- // измениться в зависимости от функций get-list-item-start/end
101
- $-result: '';
102
-
103
- // ВАЛИДАЦИЯ ПАРАМЕТРА $direction
104
-
105
- // 1. Проверка типа: параметр `$direction` должен быть строкой.
106
- // Используем вспомогательную функцию is-string. Если тип не
107
- // `string`, выводим отладочное сообщение через
108
- // `log-invalid-type`:
109
- @if not is-string($direction) {
110
- @debug log-invalid-type(
111
- 'get-list-item',
112
- $direction,
113
- '$direction',
114
- 'string'
115
- );
116
- }
117
-
118
- // 2. Проверка значения: `$direction` должен быть `'start'`
119
- // или `'end'`.
120
- // Используем функцию `list.index` для поиска значения в списке.
121
- // Если `direction` не найден в списке `('start' 'end')`, выводим
122
- // сообщение об ошибке значения. Важно: эта проверка выполняется
123
- // только если первая проверка прошла (или пропущена).
124
- @if not list.index('start' 'end', $direction) {
125
- @debug log-invalid-value(
126
- 'get-list-item',
127
- $direction,
128
- '$direction',
129
- ('start', 'end')
130
- );
131
- } @else {
132
-
133
- // Если обе проверки пройдены (или не выполнялись из-за
134
- // логики условия), переходим к основной логике функции.
135
-
136
- // СОЗДАНИЕ КАРТЫ (MAP) ДЛЯ ВЫБОРА НУЖНОЙ ФУНКЦИИ
137
- // Карта связывает строковые ключи с результатами
138
- // соответствующих функций. Это элегантная альтернатива
139
- // конструкции if-else.
140
- $-directions: (
141
- 'start': get-list-item-start($list), // Вызываем функцию для получения первого элемента
142
- 'end': get-list-item-end($list) // Вызываем функцию для получения последнего элемента
143
- );
144
-
145
- // ПОЛУЧЕНИЕ РЕЗУЛЬТАТА ИЗ КАРТЫ
146
- // Используем функцию `map.get` для получения значения по
147
- // ключу `$direction`:
148
- // - Если `$direction = 'start'`, получим результат `get-list-item-start($list)`
149
- // - Если `$direction = 'end'`, получим результат `get-list-item-end($list)`
150
-
151
- // Альтернативный подход: использовать прямое условие:
152
- // `if(sass($direction == "start"): get-list-item-start($list); else: get-list-item-end($list))`
153
- // Но карта более масштабируема для добавления новых
154
- // направлений.
155
- $-result: map.get($-directions, $direction);
156
-
157
- // Примечание: если бы у нас было больше вариантов, можно
158
- // было бы добавить их в карту:
159
- // - `'middle': get-list-item-middle($list),`
160
- // - `'second': get-list-item-second($list),`
161
- // и т.д.
93
+ $-result: null;
162
94
 
95
+ @if $direction == 'start' {
96
+ $-result: get-list-item-start($list);
97
+ } @else if $direction == 'end' {
98
+ $-result: get-list-item-end($list);
163
99
  }
164
100
 
165
- // (!) Важно: мы не проводим проверку на тип `arglist` и/или
166
- // `list`, поскольку эти операции уже реализованы в функциях
167
- // `get-list-item-start` и `get-list-item-end`.
168
-
169
- // ВОЗВРАТ РЕЗУЛЬТАТА
170
- // - Если были ошибки валидации, вернется пустая строка
171
- // (инициализированное значение)
172
- // - Если валидация прошла, вернется результат соответствующей
173
- // функции
174
- // (!) Важно: функция `log-invalid-type` и `log-invalid-value`
175
- // возвращают `null`, но здесь мы его не используем, поэтому
176
- // ошибки только логируются, но не влияют на поток выполнения.
177
101
  @return $-result;
178
102
 
179
103
  }
@@ -1,6 +1,4 @@
1
1
  @use 'sass:math';
2
- @use '../../loggers/log-invalid-type' as *;
3
- @use '../../validators/type-of/is-number' as *;
4
2
 
5
3
  /// Вычисляет абсолютное значение по проценту от целого.
6
4
  ///
@@ -19,7 +17,7 @@
19
17
  /// ---
20
18
  /// @name get-number-from-percent
21
19
  /// @group utilities-getters
22
- /// @since 2025.12.27
20
+ /// @since 0.0.1
23
21
  /// @access public
24
22
  /// @author Murad Rustamov (therteenten)
25
23
  /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
@@ -99,41 +97,5 @@
99
97
  /// не содержит единицы измерения '%' или если параметры
100
98
  /// не являются числами.
101
99
  @function get-number-from-percent($percentage, $whole) {
102
-
103
- // ВАЛИДАЦИЯ ВХОДНЫХ ПАРАМЕТРОВ
104
- // Проверяем, что `$percentage` является числом. Используем
105
- // вспомогательную функцию `is-number` для проверки типа
106
- @if not is-number($percentage) {
107
-
108
- // Если `$percentage` не число, логируем ошибку типа.
109
- // `log-invalid-type` выводит информативное сообщение об ошибке
110
- @return log-invalid-type(
111
- 'get-number-from-percent',
112
- $percentage,
113
- '$percentage',
114
- 'number'
115
- );
116
-
117
- } @else if not is-number($whole) {
118
-
119
- // Проверяем, что `$whole` является числом.
120
- // Эта проверка выполняется только если первая проверка
121
- // пройдена. Если `$percentage` не число, мы сюда не
122
- // попадем из-за `@else if`
123
- @return log-invalid-type(
124
- 'get-number-from-percent',
125
- $whole,
126
- '$whole',
127
- 'number'
128
- );
129
-
130
- } @else {
131
-
132
- // ОСНОВНАЯ ЛОГИКА ФУНКЦИИ
133
- // Оба параметра прошли валидацию
134
- // Вычисляем результат: (процент / 100%) * целое
135
- @return math.div($percentage, 100%) * $whole;
136
-
137
- }
138
-
100
+ @return math.div($percentage, 100%) * $whole;
139
101
  }
@@ -1,6 +1,4 @@
1
1
  @use 'sass:math';
2
- @use '../../loggers/log-invalid-type' as *;
3
- @use '../../validators/type-of/is-number' as *;
4
2
 
5
3
  /// Вычисляет высоту на основе ширины и соотношения сторон.
6
4
  ///
@@ -44,7 +42,7 @@
44
42
  /// ---
45
43
  /// @name get-number-height-by-ratio
46
44
  /// @group utilities-getters
47
- /// @since 2025.12.27
45
+ /// @since 0.0.1
48
46
  /// @access public
49
47
  /// @author Murad Rustamov (therteenten)
50
48
  /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
@@ -153,43 +151,13 @@
153
151
  /// `$ratio = 0`. Это соответствует математически невозможной
154
152
  /// ситуации, когда высота была бы бесконечной.
155
153
  @function get-number-height-by-ratio($width, $ratio) {
156
-
157
- @if not is-number($width) {
158
-
159
- // Логируем ошибку: неверный тип параметра $width
160
- @return log-invalid-type(
161
- 'get-number-height-by-ratio',
162
- $width,
163
- '$width',
164
- 'number'
165
- );
166
-
167
- } @else if not is-number($ratio) {
168
-
169
- // Логируем ошибку: неверный тип параметра $ratio
170
- @return log-invalid-type(
171
- 'get-number-height-by-ratio',
172
- $ratio,
173
- '$ratio',
174
- 'number'
175
- );
176
-
177
- } @else {
178
-
179
- // Оба параметра корректны, вычисляем высоту
180
- // Используется функция math.div для деления ширины
181
- // на соотношение (более безопасная альтернатива
182
- // обычному оператору / в Sass)
183
- @return math.div($width, $ratio);
184
-
185
- }
186
-
154
+ @return math.div($width, $ratio);
187
155
  }
188
156
 
189
157
  /// @name get-height-by-ratio
190
158
  /// @alias get-number-height-by-ratio
191
159
  /// @group utilities-aliases
192
- /// @since 2025.12.27
160
+ /// @since 0.0.1
193
161
  /// @access public
194
162
  /// @author Murad Rustamov (therteenten)
195
163
  /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
@@ -0,0 +1,112 @@
1
+ @use 'sass:math';
2
+ @use 'sass:meta';
3
+ @use '../../validators' as validators; // need type-of/is-number
4
+
5
+ /// Безопасно находит максимальное числовое значение в
6
+ /// списке с проверкой совместимости единиц.
7
+ ///
8
+ /// Функция проходит по всем элементам списка и находит
9
+ /// наибольшее числовое значение, при этом проверяя
10
+ /// совместимость единиц измерения всех чисел с использованием
11
+ /// функции `math.compatible()`. Числа с несовместимыми
12
+ /// единицами измерения пропускаются с выводом предупреждения
13
+ /// в консоль.
14
+ ///
15
+ /// Ключевые особенности функции:
16
+ /// - Использует `math.compatible()` для строгой проверки
17
+ /// совместимости единиц
18
+ /// - Принимает только числа с совместимыми единицами измерения
19
+ /// - Использует первое найденное число как эталон для проверки
20
+ /// совместимости
21
+ /// - Пропускает числа с несовместимыми единицами с выводом
22
+ /// предупреждения
23
+ /// - Игнорирует нечисловые элементы без предупреждений
24
+ /// - Возвращает `null` если нет совместимых числовых элементов
25
+ /// - Использует локальные переменные с префиксом `$-` для
26
+ /// избежания конфликтов
27
+ /// - Безразмерные числа не совместимы с размерными (10 и 10px =
28
+ /// несовместимы)
29
+ /// ---
30
+ /// @name get-number-max-safe
31
+ /// @group utilities-getters
32
+ /// @since 0.0.1
33
+ /// @access public
34
+ /// @author Murad Rustamov (therteenten)
35
+ /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
36
+ /// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
37
+ /// @link https://sass-lang.com/documentation/modules/math#compatible См. также: Официальная документация Sass - Функция math.compatible()
38
+ /// @link https://sass-lang.com/documentation/values/numbers#units См. также: Официальная документация Sass - Совместимость единиц измерения
39
+ /// @link https://sass-lang.com/documentation/modules/math#max См. также: Официальная документация Sass - Функция math.max()
40
+ /// @link https://developer.mozilla.org/en-US/docs/Web/CSS/max MDN Web Docs - CSS функция max()
41
+ /// @link https://stackoverflow.com/questions/19088270/find-the-highest-number-in-a-list-with-sass Stack Overflow - Поиск наибольшего числа в списке Sass
42
+ /// @link https://css-tricks.com/snippets/sass/ См. также: CSS-Tricks - Коллекция сниппетов Sass
43
+ /// @link https://sass-guidelin.es/ru/#list-functions См. также: Sass Guidelines - Функции для работы со списками
44
+ /// @link https://frontender.info/sass-lists/ См. также: Frontender Magazine - Работа со списками в Sass
45
+ /// @link https://www.w3schools.com/sass/sass_functions_numeric.php См. также: W3Schools - Числовые функции в Sass
46
+ /// @link https://habr.com/ru/post/247887/ См. также: Habr - Статья "Sass для верстальщика: числа и математика"
47
+ /// @example scss - Поиск максимального числа с совместимыми единицами
48
+ /// @debug get-number-max-safe((10px, 20px, 30px)); // 30px
49
+ /// @debug get-number-max-safe((1rem, 2.5rem, 0.5rem)); // 2.5rem
50
+ /// @debug get-number-max-safe((50%, 30%, 80%)); // 80%
51
+ /// @debug get-number-max-safe((10, 20, 30)); // 30
52
+ /// @example scss - Обработка чисел с несовместимыми единицами
53
+ /// @debug get-number-max-safe((10px, 2em, 30px));
54
+ /// // [WARNING] Пропускаю элемент 2em: несовместимые единицы
55
+ /// // Возвращает: 30px (максимум среди совместимых px значений)
56
+ /// @example scss - Смешанные типы данных
57
+ /// @debug get-number-max-safe((10, "текст", 30, #fff, 20)); // 30
58
+ /// @debug get-number-max-safe((true, false, null, 5)); // 5
59
+ /// @debug get-number-max-safe(("only", "strings")); // null
60
+ /// @example scss - Обработка разных систем единиц
61
+ /// @debug get-number-max-safe((10px, 20px, 2cm));
62
+ /// // [WARNING] Пропускаю элемент 2cm: несовместимые единицы
63
+ /// // Возвращает: 20px (только совместимые px значения)
64
+ ///
65
+ /// @debug get-number-max-safe((1in, 25.4mm, 2.54cm)); // 1in (все совместимы)
66
+ /// @example scss - Пустые списки и крайние случаи
67
+ /// @debug get-number-max-safe(()); // null
68
+ /// @debug get-number-max-safe(none); // null
69
+ /// @debug get-number-max-safe((10px)); // 10px
70
+ /// @debug get-number-max-safe((-10, -5, -20)); // -5
71
+ /// @debug get-number-max-safe((10px, 15)); // 15
72
+ /// @example scss - Практическое использование для адаптивных размеров
73
+ /// $breakpoints: 320px, 768px, 1024px, 1280px;
74
+ /// @debug get-number-max-safe($breakpoints); // 1280px
75
+ /// @example scss - Поиск максимального размера шрифта с разными единицами
76
+ /// $font-sizes: 12px, 14px, 1rem, 16px, 1.2rem;
77
+ /// @debug get-number-max-safe($font-sizes);
78
+ /// // [WARNING] Пропускаю элемент 1rem: несовместимые единицы
79
+ /// // [WARNING] Пропускаю элемент 1.2rem: несовместимые единицы
80
+ /// // Возвращает: 16px (максимум среди px значений)
81
+ /// @see get-number-max
82
+ /// @param {List} $list - Список значений, который может
83
+ /// содержать элементы разных типов. Функция будет
84
+ /// обрабатывать только числовые элементы, нечисловые
85
+ /// элементы игнорируются без предупреждений.
86
+ /// @return {Number | Null} - Максимальное числовое значение
87
+ /// из совместимых чисел в списке или `null`, если в списке
88
+ /// нет совместимых числовых элементов. Сохраняет единицы
89
+ /// измерения найденного максимального значения.
90
+ /// @throws {Warning} - Выводит предупреждение в консоль при о
91
+ /// бнаружении чисел с несовместимыми единицами измерения
92
+ /// относительно первого найденного числа.
93
+ /// Формат: `[WARNING] Пропускаю элемент {значение}:
94
+ /// несовместимые единицы`
95
+ @function get-number-max-safe($list) {
96
+
97
+ $-max: null;
98
+
99
+ @each $-item in $list {
100
+ @if validators.is-number($-item) {
101
+ @if $-max == null or math.compatible($-max, $-item) {
102
+ @if $-max == null or $-item > $-max {
103
+ $-max: $-item;
104
+ }
105
+ } @else {
106
+ @warn "⚠️ Пропускаю элемент «#{meta.inspect($-item)}»: несовместимые единицы";
107
+ }
108
+ }
109
+ }
110
+
111
+ @return $-max;
112
+ }
@@ -1,6 +1,4 @@
1
- @use '../../loggers/log-invalid-type' as *;
2
- @use '../../validators/type-of/is-number' as *;
3
- @use '../../validators/type-of/is-list' as *;
1
+ @use '../../validators' as validators; // need type-of/is-number
4
2
 
5
3
  /// Находит максимальное числовое значение в списке.
6
4
  ///
@@ -23,7 +21,7 @@
23
21
  /// ---
24
22
  /// @name get-number-max
25
23
  /// @group utilities-getters
26
- /// @since 2025.12.27
24
+ /// @since 0.0.1
27
25
  /// @access public
28
26
  /// @author Murad Rustamov (therteenten)
29
27
  /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
@@ -64,6 +62,7 @@
64
62
  /// @example scss - Поиск максимальной ширины контейнера
65
63
  /// $container-widths: 320px, 768px, 1024px, 1280px;
66
64
  /// @debug get-number-max($container-widths); // $max-width: 1280px
65
+ /// @see get-number-max-safe
67
66
  /// @param {List} $list - Список значений, который может
68
67
  /// содержать элементы разных типов. Функция будет
69
68
  /// обрабатывать только числовые элементы.
@@ -75,94 +74,17 @@
75
74
  /// сравнить числа с несовместимыми единицами измерения.
76
75
  @function get-number-max($list) {
77
76
 
78
- // Переменная для хранения текущего максимального значения.
79
- // Инициализируется как null, чтобы отслеживать:
80
- // 1. Пустые списки (результат останется null)
81
- // 2. Первое найденное число (будет присвоено $-result)
82
- $-result: null;
83
-
84
- // Первичная валидация входных данных.
85
- // Убеждаемся, что переданный аргумент является
86
- // списком или arglist.
87
- @if not is-list($list) {
88
-
89
- // Если $list не является списком, логируем
90
- // ошибку и прерываем выполнение.
91
- @return log-invalid-type(
92
- 'get-number-max',
93
- $list,
94
- '$list',
95
- ('list', 'arglist')
96
- );
97
-
98
- }
99
-
100
- // Основная логика выполняется только если валидация прошла
101
- // успешно.
102
- // Блок @else гарантирует, что код ниже выполняется только
103
- // для корректных списков.
104
- @else {
105
-
106
- // Итерация по всем элементам списка.
107
- @each $-item in $list {
108
-
109
- // Проверка типа текущего элемента.
110
- // Функция is-number возвращает true только для:
111
- // - Целых чисел (42)
112
- // - Дробных чисел (3.14)
113
- // - Чисел с единицами измерения (10px, 2rem, 1.5em)
114
- @if is-number($-item) {
115
-
116
- // Обновление значения максимума.
117
- // Условие проверяет два случая:
118
- // 1. $-result == null: это первое найденное число
119
- // 2. $-item > $-result: текущее число больше текущего
120
- // максимума
121
- // Оператор > в Sass работает с учетом единиц измерения,
122
- // но требует их совместимости (например, нельзя
123
- // сравнить 10px и 2em).
124
- @if $-result == null or $-item > $-result {
125
- $-result: $-item;
126
- }
77
+ $-max: null;
127
78
 
79
+ @each $-item in $list {
80
+ @if validators.is-number($-item) {
81
+ @if $-max == null or $-item > $-max {
82
+ $-max: $-item;
128
83
  }
129
-
130
- // Обработка нечисловых элементов.
131
- // Если is-number($-item) вернул false, элемент имеет
132
- // неподдерживаемый тип (строка, булево значение, null,
133
- // карта и т.д.).
134
- @else {
135
-
136
- // Ветка обработки ошибок: элемент не является числом.
137
- // Прерываем выполнение функции при первом же нечисловом
138
- // элементе. Это "безопасный" подход - лучше явная
139
- // ошибка, чем неявное некорректное поведение.
140
- //
141
- // (!) Важно: функция не пытается пропустить нечисловые
142
- // элементы или преобразовать их - она строго требует
143
- // числового ввода.
144
- @return log-invalid-type(
145
- 'get-number-max',
146
- $-item,
147
- '$-item',
148
- 'number'
149
- );
150
-
151
- }
152
-
153
84
  }
154
-
155
85
  }
156
86
 
157
- // Возвращаем результат.
158
- // Возможные значения:
159
- // - null: если список был пустой (не содержал элементов)
160
- // - число: максимальное значение из списка
161
- //
162
- // Если функция дошла до этой точки, значит:
163
- // 1. $list был корректным списком
164
- // 2. Все элементы списка были числами
165
- // 3. Не было вызвано ни одной ошибки через log-invalid-type
166
- @return $-result;
87
+ @return $-max;
167
88
 
168
89
  }
90
+
@@ -0,0 +1,114 @@
1
+ @use 'sass:meta';
2
+ @use 'sass:math';
3
+ @use '../../validators' as validators; // need type-of/is-number
4
+
5
+ /// Безопасно находит минимальное числовое значение в списке
6
+ /// с проверкой совместимости единиц измерения.
7
+ ///
8
+ /// Функция проходит по всем элементам списка и находит
9
+ /// наименьшее числовое значение, при этом проверяя
10
+ /// совместимость единиц измерения всех чисел с использованием
11
+ /// функции `math.compatible()`. Числа с несовместимыми
12
+ /// единицами измерения пропускаются с выводом предупреждения в
13
+ /// консоль.
14
+ ///
15
+ /// Важные особенности функции:
16
+ /// - Использует `math.compatible()` для строгой проверки
17
+ /// совместимости единиц
18
+ /// - Принимает только числа с совместимыми единицами измерения
19
+ /// - Использует первое найденное число как эталон для проверки
20
+ /// совместимости
21
+ /// - Пропускает числа с несовместимыми единицами с выводом
22
+ /// предупреждения
23
+ /// - Игнорирует нечисловые элементы без предупреждений
24
+ /// - Возвращает `null` если нет совместимых числовых элементов
25
+ /// - Использует локальные переменные с префиксом `$-` для
26
+ /// избежания конфликтов
27
+ /// - Безразмерные числа не совместимы с размерными (10 и 10px =
28
+ /// несовместимы)
29
+ /// ---
30
+ /// @name get-number-min-safe
31
+ /// @group utilities-getters
32
+ /// @since 0.0.1
33
+ /// @access public
34
+ /// @author Murad Rustamov (therteenten)
35
+ /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
36
+ /// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
37
+ /// @link https://sass-lang.com/documentation/modules/math#compatible См. также: Официальная документация Sass - Функция math.compatible()
38
+ /// @link https://sass-lang.com/documentation/values/numbers#units См. также: Официальная документация Sass - Совместимость единиц измерения
39
+ /// @link https://sass-lang.com/documentation/modules/math#min См. также: Официальная документация Sass - Функция math.min()
40
+ /// @link https://developer.mozilla.org/en-US/docs/Web/CSS/min MDN Web Docs - CSS функция min()
41
+ /// @link https://css-tricks.com/snippets/sass/ См. также: CSS-Tricks - Коллекция сниппетов Sass
42
+ /// @link https://sass-guidelin.es/ru/#list-functions См. также: Sass Guidelines - Функции для работы со списками
43
+ /// @link https://frontender.info/sass-lists/ См. также: Frontender Magazine - Работа со списками в Sass
44
+ /// @link https://www.w3schools.com/sass/sass_functions_numeric.php См. также: W3Schools - Числовые функции в Sass
45
+ /// @link https://habr.com/ru/post/247887/ См. также: Habr - Статья "Sass для верстальщика: числа и математика"
46
+ /// @example scss - Базовые примеры с совместимыми единицами
47
+ /// @debug get-number-min-safe((10px, 20px, 5px)); // 5px
48
+ /// @debug get-number-min-safe((2.5rem, 0.8rem, 1rem)); // 0.8rem
49
+ /// @debug get-number-min-safe((75%, 50%, 25%)); // 25%
50
+ /// @debug get-number-min-safe((15, 8, 23)); // 8
51
+ /// @example scss - Обработка несовместимых единиц с предупреждениями
52
+ /// @debug get-number-min-safe((30px, 2em, 15px));
53
+ /// // [WARNING] Пропускаю элемент «2em»: несовместимые единицы
54
+ /// // Возвращает: 15px (только совместимые px)
55
+ ///
56
+ /// @debug get-number-min-safe((100px, 5, 50px)); // 5
57
+ /// @example scss - Разные единицы длины (совместимые)
58
+ /// @debug get-number-min-safe((1in, 25.4mm, 2.54cm)); // 1in
59
+ /// @debug get-number-min-safe((16px, 1pc, 12pt)); // 16px
60
+ /// @example scss - Разные единицы длины (несовместимые)
61
+ /// @debug get-number-min-safe((10vw, 20px, 5vh));
62
+ /// // [WARNING] Пропускаю элемент «20px»: несовместимые единицы
63
+ /// // [WARNING] Пропускаю элемент «5vh»: несовместимые единицы
64
+ /// // Возвращает: 10vw (только viewport единицы между собой)
65
+ /// @example scss - Смешанные типы данных
66
+ /// @debug get-number-min-safe((45, "игнорируется", 15, #ff0000, 30)); // 15
67
+ /// @debug get-number-min-safe((true, false, (1, 2), 8)); // 8
68
+ /// @debug get-number-min-safe(("только", "строки", null)); // null
69
+ /// @example scss - Отрицательные значения и ноль
70
+ /// @debug get-number-min-safe((-10px, -25px, -5px)); // -25px
71
+ /// @debug get-number-min-safe((0, -15, 10)); // -15
72
+ /// @debug get-number-min-safe((0px, 10px, -5px)); // -5px
73
+ /// @example scss - Практическое использование: минимальные отступы
74
+ /// $margins: 20px, 15px, "auto", 10px, 25px;
75
+ /// @debug get-number-min-safe($margins); // 10px ("auto" игнорируется)
76
+ /// @example scss - Практическое использование: минимальный размер шрифта
77
+ /// $font-sizes: 16px, 1.2rem, 14px, 1rem, 18px;
78
+ /// @debug get-number-min-safe($font-sizes);
79
+ /// // [WARNING] Пропускаю элемент «1.2rem»: несовместимые единицы
80
+ /// // [WARNING] Пропускаю элемент «1rem»: несовместимые единицы
81
+ /// // $min-font: 14px
82
+ /// @example scss - Практическое использование: медиа-запросы
83
+ /// $breakpoints: 320px, 480px, 768px, 1024px;
84
+ /// @debug get-number-min-safe($breakpoints); // 320px
85
+ /// @see get-number-min
86
+ /// @param {List} $list - Список значений, который может
87
+ /// содержать элементы разных типов. Функция будет
88
+ /// обрабатывать только числовые элементы.
89
+ /// @return {Number | Null} - Минимальное числовое значение из
90
+ /// совместимых чисел в списке или `null`, если в списке
91
+ /// нет совместимых числовых элементов. Сохраняет единицы
92
+ /// измерения найденного минимального значения.
93
+ /// @throws {Warning} - Выводит предупреждение в консоль при
94
+ /// обнаружении чисел с несовместимыми единицами измерения
95
+ /// относительно первого найденного числа. Формат:
96
+ /// `[WARNING] Пропускаю элемент «{значение}»: несовместимые
97
+ /// единицы`
98
+ @function get-number-min-safe($list) {
99
+ $-min: null;
100
+
101
+ @each $-item in $list {
102
+ @if validators.is-number($-item) {
103
+ @if $-min == null or math.compatible($-min, $-item) {
104
+ @if $-min == null or $-item < $-min {
105
+ $-min: $-item;
106
+ }
107
+ } @else {
108
+ @warn "⚠️ Пропускаю элемент «#{meta.inspect($-item)}»: несовместимые единицы";
109
+ }
110
+ }
111
+ }
112
+
113
+ @return $-min;
114
+ }