@omnisass/library 0.2.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 (93) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/LICENSE +21 -0
  3. package/README.md +2 -0
  4. package/_configs.scss +68 -0
  5. package/index.scss +95 -0
  6. package/modules/utilities/converters/_convert-camel2kebab.scss +186 -0
  7. package/modules/utilities/converters/_convert-em2px.scss +239 -0
  8. package/modules/utilities/converters/_convert-hex2rgb.scss +97 -0
  9. package/modules/utilities/converters/_convert-hex2rgba.scss +124 -0
  10. package/modules/utilities/converters/_convert-kebab2camel.scss +232 -0
  11. package/modules/utilities/converters/_convert-kebab2snake.scss +118 -0
  12. package/modules/utilities/converters/_convert-px2em.scss +236 -0
  13. package/modules/utilities/converters/_convert-px2rem.scss +180 -0
  14. package/modules/utilities/converters/_convert-rem2px.scss +207 -0
  15. package/modules/utilities/converters/_convert-snake2kebab.scss +173 -0
  16. package/modules/utilities/getters/color/_get-color-brightness.scss +138 -0
  17. package/modules/utilities/getters/color/_get-color-darkest.scss +178 -0
  18. package/modules/utilities/getters/list/_get-list-item-end.scss +114 -0
  19. package/modules/utilities/getters/list/_get-list-item-start.scss +109 -0
  20. package/modules/utilities/getters/list/_get-list-item.scss +179 -0
  21. package/modules/utilities/getters/number/_get-number-from-percent.scss +139 -0
  22. package/modules/utilities/getters/number/_get-number-height-by-ratio.scss +199 -0
  23. package/modules/utilities/getters/number/_get-number-max.scss +168 -0
  24. package/modules/utilities/getters/number/_get-number-min.scss +162 -0
  25. package/modules/utilities/getters/number/_get-number-percentage-of.scss +149 -0
  26. package/modules/utilities/getters/number/_get-number-unit.scss +111 -0
  27. package/modules/utilities/getters/number/_get-number-width-by-ratio.scss +223 -0
  28. package/modules/utilities/helpers/color/_color-blend-steps.scss +210 -0
  29. package/modules/utilities/helpers/color/_color-blend.scss +183 -0
  30. package/modules/utilities/helpers/color/_color-hue-shift.scss +148 -0
  31. package/modules/utilities/helpers/color/_color-scale.scss +208 -0
  32. package/modules/utilities/helpers/color/_color-shade.scss +113 -0
  33. package/modules/utilities/helpers/color/_color-tint.scss +118 -0
  34. package/modules/utilities/helpers/color/_color-triad.scss +141 -0
  35. package/modules/utilities/helpers/list/_list-dedupe.scss +146 -0
  36. package/modules/utilities/helpers/list/_list-insert-at.scss +166 -0
  37. package/modules/utilities/helpers/list/_list-merge.scss +86 -0
  38. package/modules/utilities/helpers/list/_list-remove-at.scss +160 -0
  39. package/modules/utilities/helpers/list/_list-sum-numbers-safe.scss +175 -0
  40. package/modules/utilities/helpers/list/_list-sum-numbers.scss +128 -0
  41. package/modules/utilities/helpers/misc/_url-encode.configs.scss +64 -0
  42. package/modules/utilities/helpers/misc/_url-encode.scss +148 -0
  43. package/modules/utilities/helpers/number/_number-ceil-to.scss +111 -0
  44. package/modules/utilities/helpers/number/_number-clamp-max.scss +92 -0
  45. package/modules/utilities/helpers/number/_number-clamp-min.scss +100 -0
  46. package/modules/utilities/helpers/number/_number-clamp.scss +109 -0
  47. package/modules/utilities/helpers/number/_number-denormalize.scss +172 -0
  48. package/modules/utilities/helpers/number/_number-fibonacci.scss +235 -0
  49. package/modules/utilities/helpers/number/_number-floor-to.scss +114 -0
  50. package/modules/utilities/helpers/number/_number-format-with-separator.scss +122 -0
  51. package/modules/utilities/helpers/number/_number-normalize.scss +160 -0
  52. package/modules/utilities/helpers/number/_number-random-between-int.scss +84 -0
  53. package/modules/utilities/helpers/number/_number-random-between.scss +120 -0
  54. package/modules/utilities/helpers/number/_number-range.scss +268 -0
  55. package/modules/utilities/helpers/number/_number-round-to-nearest.scss +131 -0
  56. package/modules/utilities/helpers/number/_number-round-to.scss +118 -0
  57. package/modules/utilities/helpers/number/_number-strip-unit.scss +97 -0
  58. package/modules/utilities/helpers/string/_string-capitalize.scss +84 -0
  59. package/modules/utilities/helpers/string/_string-replace.scss +69 -0
  60. package/modules/utilities/helpers/string/_string-trim-end.scss +62 -0
  61. package/modules/utilities/helpers/string/_string-trim-start.scss +62 -0
  62. package/modules/utilities/helpers/string/_string-trim.scss +69 -0
  63. package/modules/utilities/loggers/_log-invalid-type.scss +151 -0
  64. package/modules/utilities/loggers/_log-invalid-value.scss +151 -0
  65. package/modules/utilities/setters/_index.scss +3 -0
  66. package/modules/utilities/validators/color/_is-color-light.scss +132 -0
  67. package/modules/utilities/validators/color/_is-color-list.scss +124 -0
  68. package/modules/utilities/validators/list/_is-list-contained.scss +65 -0
  69. package/modules/utilities/validators/misc/_is-time.scss +115 -0
  70. package/modules/utilities/validators/number/_is-int-even.scss +69 -0
  71. package/modules/utilities/validators/number/_is-int-odd.scss +70 -0
  72. package/modules/utilities/validators/number/_is-int.scss +124 -0
  73. package/modules/utilities/validators/number/_is-number-has-unit.scss +85 -0
  74. package/modules/utilities/validators/number/_is-number-negative.scss +76 -0
  75. package/modules/utilities/validators/number/_is-number-positive.scss +74 -0
  76. package/modules/utilities/validators/number/_is-number-unitless.scss +88 -0
  77. package/modules/utilities/validators/number/_is-number-zero.scss +75 -0
  78. package/modules/utilities/validators/string/_is-string-contained.scss +108 -0
  79. package/modules/utilities/validators/string/_is-string-empty.scss +56 -0
  80. package/modules/utilities/validators/string/_is-string-ending-with.scss +66 -0
  81. package/modules/utilities/validators/string/_is-string-starting-with.scss +66 -0
  82. package/modules/utilities/validators/type-of/_is-boolean.scss +92 -0
  83. package/modules/utilities/validators/type-of/_is-color.scss +96 -0
  84. package/modules/utilities/validators/type-of/_is-list.scss +105 -0
  85. package/modules/utilities/validators/type-of/_is-map.scss +105 -0
  86. package/modules/utilities/validators/type-of/_is-number.scss +103 -0
  87. package/modules/utilities/validators/type-of/_is-string.scss +110 -0
  88. package/modules/utilities/validators/type-of/_is-type.scss +77 -0
  89. package/package.json +54 -0
  90. package/package.scss +156 -0
  91. package/test.md +168 -0
  92. package/test.scss +405 -0
  93. package/test.sh +149 -0
@@ -0,0 +1,160 @@
1
+ @use 'sass:list';
2
+ @use '../../loggers/log-invalid-type' as *;
3
+ @use '../../validators/type-of/is-list' as *;
4
+ @use '../../validators/type-of/is-number' as *;
5
+
6
+ /// Удаляет элемент из списка по указанному индексу.
7
+ ///
8
+ /// Функция создает новый список, копируя все элементы
9
+ /// исходного списка, за исключением элемента с указанным
10
+ /// индексом. Исходный список не изменяется. Индексация в
11
+ /// Sass начинается с 1 (1-based indexing).
12
+ ///
13
+ /// Важные особенности функции:
14
+ /// - Использует 1-based индексацию (первый элемент имеет
15
+ /// индекс 1)
16
+ /// - Не изменяет исходный список, возвращает новый
17
+ /// - Не проверяет валидность индекса (выход за границы
18
+ /// игнорируется)
19
+ /// - Поддерживает любые типы элементов в списке
20
+ /// - Сохраняет порядок оставшихся элементов
21
+ /// - Использует локальные переменные с префиксом `$-` для
22
+ /// избежания конфликтов
23
+ /// ---
24
+ /// @name list-remove-at
25
+ /// @group utilities-helpers
26
+ /// @since 2025.12.27
27
+ /// @access public
28
+ /// @author Murad Rustamov (therteenten)
29
+ /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
30
+ /// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
31
+ /// @link https://sass-lang.com/documentation/modules/list#nth См. также: Официальная документация Sass - Функция list.nth()
32
+ /// @link https://sass-lang.com/documentation/modules/list#length См. также: Официальная документация Sass - Функция list.length()
33
+ /// @link https://sass-lang.com/documentation/values/lists См. также: Официальная документация Sass - Тип данных "Списки"
34
+ /// @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice MDN Web Docs - Array.splice()
35
+ /// @link https://css-tricks.com/snippets/sass/ См. также: CSS-Tricks - Коллекция сниппетов Sass
36
+ /// @link https://sass-guidelin.es/ru/#list-functions См. также: Sass Guidelines - Функции для работы со списками
37
+ /// @link https://frontender.info/sass-lists/ См. также: Frontender Magazine - Работа со списками в Sass
38
+ /// @link https://www.w3schools.com/sass/sass_functions_list.php См. также: W3Schools - Функции для работы со списками в Sass
39
+ /// @link https://habr.com/ru/post/156549/ См. также: Habr - Статья "Sass для верстальщика: списки и циклы"
40
+ /// @example scss - Удаление элемента по индексу
41
+ /// @debug list-remove-at((a, b, c, d, e), 3); // (a, b, d, e)
42
+ /// @debug list-remove-at((10, 20, 30, 40), 1); // (20, 30, 40)
43
+ /// @debug list-remove-at((red, blue, green), 2); // (red, green)
44
+ /// @example scss - Удаление первого и последнего элементов
45
+ /// @debug list-remove-at((a, b, c, d), 1); // (b, c, d)
46
+ /// @debug list-remove-at((a, b, c, d), 4); // (a, b, c)
47
+ /// $colors: (#ff0000, #00ff00, #0000ff);
48
+ /// @debug list-remove-at($colors, list.length($colors)); // (#ff0000, #00ff00)
49
+ /// @example scss - Граничные случаи и невалидные индексы
50
+ /// @debug list-remove-at((a, b, c), 0); // (a, b, c) (индекс 0 игнорируется)
51
+ /// @debug list-remove-at((a, b, c), 5); // (a, b, c) (индекс > длины)
52
+ /// @debug list-remove-at((), 1); // Error: $n: List index may not be 0.
53
+ /// @debug list-remove-at((single), 1); // () (удаление единственного элемента)
54
+ /// @example scss - Сохранение оригинального списка
55
+ /// $original: (apple, banana, cherry);
56
+ /// $modified: list-remove-at($original, 2);
57
+ /// @debug $original; // (apple, banana, cherry)
58
+ /// @debug $modified; // (apple, cherry)
59
+ /// @example scss - Практическое использование для удаления классов
60
+ /// $button-classes: (btn, btn-primary, btn-lg, active, disabled);
61
+ /// $clean-classes: list-remove-at($button-classes, 5); // Удаляем 'disabled'
62
+ /// // .button { @each $class in $clean-classes { ... } }
63
+ /// @example scss - Удаление значения из списка медиа-запросов
64
+ /// $breakpoints: (320px, 768px, 1024px, 1280px);
65
+ /// $mobile-breakpoints: list-remove-at($breakpoints, 4); // Удаляем 1280px
66
+ /// // @include media($mobile-breakpoints) { ... }
67
+ /// @example scss - Создание подсписка с пропуском элемента
68
+ /// $days: (mon, tue, wed, thu, fri, sat, sun);
69
+ /// $weekdays: list-remove-at(list-remove-at($days, 7), 6); // Удаляем выходные
70
+ /// @debug $weekdays; // (mon, tue, wed, thu, fri)
71
+ /// @param {List} $list - Исходный список, из которого
72
+ /// нужно удалить элемент. Может содержать элементы
73
+ /// любых типов и может быть пустым.
74
+ /// @param {Number} $index - Индекс элемента для удаления.
75
+ /// Используется 1-based индексация (первый элемент = 1).
76
+ /// Если индекс выходит за границы списка (меньше 1 или
77
+ /// больше длины списка), функция вернет исходный список
78
+ /// без изменений.
79
+ /// @return {List} - Новый список, содержащий все элементы
80
+ /// исходного списка, кроме элемента с указанным индексом.
81
+ /// Если индекс невалиден, возвращается исходный список.
82
+ /// Если удаляется единственный элемент, возвращается
83
+ /// пустой список `()`.
84
+ /// @throws {Error} - Не выбрасывает ошибок при невалидных
85
+ /// индексах, но может выбросить ошибку если `$index` не
86
+ /// является числом.
87
+ @function list-remove-at($list, $index) {
88
+
89
+ // Проверка типа первого параметра: ожидается список или arglist.
90
+ // Функция is-list() проверяет, является ли $list валидным списком
91
+ // или arglist (специальный тип для переменного числа аргументов).
92
+ @if not is-list($list) {
93
+
94
+ // Если $list не является списком, возвращаем ошибку через
95
+ // стандартную функцию логирования. Это предотвращает
96
+ // некорректные вычисления с некорректными данными.
97
+ @return log-invalid-type(
98
+ 'list-remove-at',
99
+ $list,
100
+ '$list',
101
+ ('list', 'arglist')
102
+ );
103
+
104
+ }
105
+
106
+ // Проверка типа второго параметра: ожидается числовое значение индекса.
107
+ // $index определяет позицию элемента, который нужно удалить из списка.
108
+ @else if not is-number($index) {
109
+
110
+ // Если $index не является числом, возвращаем ошибку.
111
+ // Проверка выполняется только если $list прошел валидацию.
112
+ @return log-invalid-type(
113
+ 'list-remove-at',
114
+ $index,
115
+ '$index',
116
+ 'number'
117
+ );
118
+
119
+ }
120
+
121
+ // Все параметры прошли валидацию - выполняем удаление элемента.
122
+ @else {
123
+
124
+ // Инициализация переменной для хранения результата.
125
+ // $-result будет содержать новый список без удаленного элемента.
126
+ $-result: ();
127
+
128
+ // Определение длины исходного списка.
129
+ // Функция list.length() возвращает количество элементов в списке.
130
+ $-length: list.length($list);
131
+
132
+ // Цикл по всем элементам исходного списка.
133
+ // Переменная $i принимает значения от 1 до $-length включительно.
134
+ @for $i from 1 through $-length {
135
+
136
+ // Проверка: не является ли текущий индекс целевым индексом удаления.
137
+ @if $i != $index {
138
+
139
+ // Если текущий индекс НЕ равен индексу удаления,
140
+ // добавляем элемент в результат.
141
+ // - Функция list.nth() извлекает элемент списка по
142
+ // указанному индексу.
143
+ // - Функция list.append() добавляет элемент в конец
144
+ // списка результата.
145
+ $-result: list.append($-result, list.nth($list, $i));
146
+
147
+ }
148
+
149
+ }
150
+
151
+ // Возвращаем новый список без удаленного элемента.
152
+ // Если индекс был в пределах длины списка (1 ≤ $index ≤ $-length),
153
+ // соответствующий элемент будет пропущен. Если индекс вне диапазона,
154
+ // исходный список вернется без изменений. Порядок оставшихся
155
+ // элементов сохраняется.
156
+ @return $-result;
157
+
158
+ }
159
+
160
+ }
@@ -0,0 +1,175 @@
1
+ @use 'sass:math';
2
+ @use 'sass:meta';
3
+ @use '../../loggers/log-invalid-type' as *;
4
+ @use '../../validators/type-of/is-list' as *;
5
+ @use '../../validators/type-of/is-number' as *;
6
+
7
+ /// Безопасно суммирует числовые значения в списке с
8
+ /// проверкой единиц измерения.
9
+ ///
10
+ /// Функция проходит по всем элементам списка и суммирует
11
+ /// только числовые элементы, при этом проверяя совместимость
12
+ /// единиц измерения. Все числовые элементы должны иметь
13
+ /// одинаковые единицы измерения или быть безразмерными.
14
+ ///
15
+ /// Элементы с несовместимыми единицами пропускаются с
16
+ /// выводом предупреждения.
17
+ ///
18
+ /// Ключевые особенности функции:
19
+ /// - Проверяет совместимость единиц измерения всех чисел
20
+ /// - Принимает только числа с одинаковыми единицами или
21
+ /// безразмерные
22
+ /// - Безразмерные числа (без единиц) совместимы с любыми
23
+ /// единицами
24
+ /// - Использует единицы измерения первого найденного числа
25
+ /// как эталон
26
+ /// - Игнорирует нечисловые элементы без предупреждений
27
+ /// - Выводит предупреждение для чисел с несовместимыми
28
+ /// единицами
29
+ /// - Использует локальные переменные с префиксом `$-` для
30
+ /// избежания конфликтов
31
+ /// ---
32
+ /// @name list-sum-numbers-safe
33
+ /// @group utilities-helpers
34
+ /// @since 2025.12.27
35
+ /// @access public
36
+ /// @author Murad Rustamov (therteenten)
37
+ /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
38
+ /// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
39
+ /// @link https://sass-lang.com/documentation/values/numbers#units См. также: Официальная документация Sass - Числа и единицы измерения
40
+ /// @link https://sass-lang.com/documentation/modules/math#unit См. также: Официальная документация Sass - Функция math.unit()
41
+ /// @link https://sass-lang.com/documentation/modules/math#compatible См. также: Официальная документация Sass - Функция math.compatible()
42
+ /// @link https://developer.mozilla.org/en-US/docs/Web/CSS/calc MDN Web Docs - CSS функция calc()
43
+ /// @link https://stackoverflow.com/questions/16455752/sass-sum-up-a-list-of-numbers Stack Overflow - Суммирование списка чисел в Sass
44
+ /// @link https://css-tricks.com/snippets/sass/ См. также: CSS-Tricks - Коллекция сниппетов Sass
45
+ /// @link https://sass-guidelin.es/ru/#list-functions См. также: Sass Guidelines - Функции для работы со списками
46
+ /// @link https://frontender.info/sass-lists/ См. также: Frontender Magazine - Работа со списками в Sass
47
+ /// @link https://www.w3schools.com/sass/sass_functions_numeric.php См. также: W3Schools - Числовые функции в Sass
48
+ /// @link https://habr.com/ru/post/247887/ См. также: Habr - Статья "Sass для верстальщика: числа и математика"
49
+ /// @example scss - Суммирование чисел с одинаковыми единицами
50
+ /// @debug list-sum-numbers-safe((10px, 20px, 30px)); // 60px
51
+ /// @debug list-sum-numbers-safe((1rem, 2rem, 0.5rem)); // 3.5rem
52
+ /// @debug list-sum-numbers-safe((50%, 30%, 20%)); // 100%
53
+ /// @example scss - Суммирование безразмерных чисел
54
+ /// @debug list-sum-numbers-safe((10, 20, 30)); // 60
55
+ /// @debug list-sum-numbers-safe((0.1, 0.2, 0.3)); // 0.6
56
+ /// @debug list-sum-numbers-safe((1, 2px, 3)); // 4 (пропускает 2px)
57
+ /// @example scss - Обработка смешанных единиц измерения
58
+ /// @debug list-sum-numbers-safe((10px, 2em, 30px));
59
+ /// // Предупреждение: "Пропускаю элемент 2em: несовместимые единицы (em vs px)"
60
+ /// // Возвращает: 40px (только 10px + 30px)
61
+ /// @example scss - Смешанные типы данных
62
+ /// @debug list-sum-numbers-safe((10px, "текст", 20px, #fff, 5px)); // 35px
63
+ /// @debug list-sum-numbers-safe((1, true, 2, null, 3)); // 6
64
+ /// @debug list-sum-numbers-safe(("only", "strings")); // 0
65
+ /// @example scss - Пустые списки и крайние случаи
66
+ /// @debug list-sum-numbers-safe(()); // 0
67
+ /// @debug list-sum-numbers-safe(none); // 0
68
+ /// @debug list-sum-numbers-safe((10px)); // 10px
69
+ /// @debug list-sum-numbers-safe((10px, 20em, 30rem)); // 10px (только первый элемент)
70
+ /// @example scss - Практическое использование для margin/padding
71
+ /// $margins: 10px, 20px, 15px, 5px;
72
+ /// @debug list-sum-numbers-safe($margins); // 50px
73
+ /// @example scss - Суммирование процентных значений
74
+ /// $widths: 25%, 25%, 25%, 25%;
75
+ /// @debug list-sum-numbers-safe($widths); // 100%
76
+ /// @see list-sum-numbers
77
+ /// @param {List} $list - Список значений, который может
78
+ /// содержать элементы разных типов. Функция будет
79
+ /// обрабатывать только числовые элементы.
80
+ /// @return {Number} - Сумма всех числовых элементов с
81
+ /// совместимыми единицами измерения. Если в списке нет
82
+ /// числовых элементов или все они имеют несовместимые
83
+ /// единицы, возвращает `0`. Возвращает сумму в единицах
84
+ /// измерения первого найденного числа.
85
+ /// @throws {Warning} - Выводит предупреждение при обнаружении
86
+ /// чисел с несовместимыми единицами измерения.
87
+ @function list-sum-numbers-safe($list) {
88
+
89
+ // Проверка типа входного параметра: ожидается список или arglist.
90
+ // Функция is-list() проверяет, является ли $list валидным списком
91
+ // или arglist (специальный тип для переменного числа аргументов).
92
+ @if not is-list($list) {
93
+
94
+ // Если $list не является списком, возвращаем ошибку через
95
+ // стандартную функцию логирования. Это предотвращает
96
+ // некорректные вычисления с некорректными данными.
97
+ @return log-invalid-type(
98
+ 'list-sum-numbers-safe',
99
+ $list,
100
+ '$list',
101
+ ('list', 'arglist')
102
+ );
103
+
104
+ }
105
+
106
+ // Основная логика выполняется только если $list является
107
+ // корректным списком или arglist.
108
+ @else {
109
+
110
+ // Инициализация переменной для хранения суммы чисел.
111
+ // $-sum будет содержать итоговую сумму совместимых числовых элементов.
112
+ $-sum: 0;
113
+
114
+ // Переменная для хранения единицы измерения первого найденного числа.
115
+ // Используется для проверки совместимости единиц измерения
116
+ // всех последующих чисел.
117
+ $-first-unit: null;
118
+
119
+ // Итерация по всем элементам исходного списка.
120
+ // Переменная $-item содержит текущий обрабатываемый элемент.
121
+ @each $-item in $list {
122
+
123
+ // Проверка: является ли текущий элемент числом.
124
+ // Функция is-number() возвращает true для числовых значений.
125
+ @if is-number($-item) {
126
+
127
+ // Проверка: является ли это первым найденным числом в списке.
128
+ @if $-first-unit == null {
129
+
130
+ // Если это первое число:
131
+ // 1. Сохраняем его единицу измерения для последующей проверки
132
+ // Функция math.unit() возвращает единицу измерения числа как строку.
133
+ // 2. Инициализируем сумму значением этого числа
134
+ $-first-unit: math.unit($-item);
135
+ $-sum: $-item;
136
+
137
+ }
138
+
139
+ // Проверка: совместимы ли единицы измерения текущего числа
140
+ // с единицей измерения первого числа.
141
+ // Условие выполняется, если:
142
+ // 1. Единицы измерения совпадают (math.unit($-item) == $-first-unit)
143
+ // 2. Текущее число безразмерное (math.unit($-item) == '')
144
+ @else if math.unit($-item) == $-first-unit or math.unit($-item) == '' {
145
+
146
+ // Если единицы измерения совместимы, добавляем число к сумме.
147
+ // Оператор + в Sass автоматически проверяет совместимость единиц,
148
+ // но мы уже выполнили проверку выше для безопасности.
149
+ $-sum: $-sum + $-item;
150
+
151
+ } @else {
152
+
153
+ // Если единицы измерения не совместимы:
154
+ // Выводим предупреждение в консоль с информацией о пропущенном элементе.
155
+ // Функция meta.inspect() преобразует значение в читаемую строку.
156
+ // Функция math.unit() возвращает единицу измерения числа.
157
+ // Это предупреждение помогает выявить потенциальные ошибки в данных.
158
+ @warn "Пропускаю элемент «#{meta.inspect($-item)}»: единица «#{math.unit($-item)}» несовместима с «#{$-first-unit}»!";
159
+
160
+ }
161
+
162
+ }
163
+
164
+ }
165
+
166
+ // Возвращаем итоговую сумму совместимых числовых элементов.
167
+ // Если в списке не было чисел или все числа были пропущены из-за
168
+ // несовместимости единиц измерения, возвращается 0 (начальное значение).
169
+ // Единица измерения результата соответствует единице измерения
170
+ // первого добавленного числа.
171
+ @return $-sum;
172
+
173
+ }
174
+
175
+ }
@@ -0,0 +1,128 @@
1
+ @use '../../loggers/log-invalid-type' as *;
2
+ @use '../../validators/type-of/is-list' as *;
3
+ @use '../../validators/type-of/is-number' as *;
4
+
5
+ /// Суммирует все числовые значения в списке.
6
+ ///
7
+ /// Функция проходит по всем элементам переданного списка и
8
+ /// суммирует только те элементы, которые являются числами.
9
+ /// Нечисловые элементы (строки, цвета, списки, карты и т.д.)
10
+ /// игнорируются без вывода ошибок.
11
+ ///
12
+ /// Важные особенности функции:
13
+ /// - Игнорирует все нечисловые элементы без предупреждений
14
+ /// - Возвращает 0 для пустых списков или списков без чисел
15
+ /// - Использует локальные переменные с префиксом `$-` для
16
+ /// избежания конфликтов
17
+ /// - Сохраняет единицы измерения первого числового элемента
18
+ /// - Может вызвать ошибку при сложении несовместимых единиц
19
+ /// ---
20
+ /// @name list-sum-numbers
21
+ /// @group utilities-helpers
22
+ /// @since 2025.12.27
23
+ /// @access public
24
+ /// @author Murad Rustamov (therteenten)
25
+ /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
26
+ /// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
27
+ /// @link https://sass-lang.com/documentation/values/numbers#units См. также: Официальная документация Sass - Числа и единицы измерения
28
+ /// @link https://sass-lang.com/documentation/modules/math См. также: Официальная документация Sass - Модуль math
29
+ /// @link https://developer.mozilla.org/en-US/docs/Web/CSS/calc MDN Web Docs - CSS функция calc()
30
+ /// @link https://stackoverflow.com/questions/16455752/sass-sum-up-a-list-of-numbers Stack Overflow - Суммирование списка чисел в Sass
31
+ /// @link https://css-tricks.com/snippets/sass/ См. также: CSS-Tricks - Коллекция сниппетов Sass
32
+ /// @link https://sass-guidelin.es/ru/#list-functions См. также: Sass Guidelines - Функции для работы со списками
33
+ /// @link https://frontender.info/sass-lists/ См. также: Frontender Magazine - Работа со списками в Sass
34
+ /// @link https://www.w3schools.com/sass/sass_functions_numeric.php См. также: W3Schools - Числовые функции в Sass
35
+ /// @link https://habr.com/ru/post/247887/ См. также: Habr - Статья "Sass для верстальщика: числа и математика"
36
+ /// @example scss - Суммирование простых чисел
37
+ /// @debug list-sum-numbers((10, 20, 30, 40)); // 100
38
+ /// @debug list-sum-numbers((1, 2, 3, 4, 5)); // 15
39
+ /// @debug list-sum-numbers((0.1, 0.2, 0.3)); // 0.6
40
+ /// @example scss - Суммирование чисел с единицами измерения
41
+ /// @debug list-sum-numbers((10px, 20px, 30px)); // 60px
42
+ /// @debug list-sum-numbers((1rem, 2rem, 0.5rem)); // 3.5rem
43
+ /// @debug list-sum-numbers((50%, 30%)); // 80%
44
+ /// @example scss - Обработка смешанных типов данных
45
+ /// @debug list-sum-numbers((10, "text", 20, #fff, 30)); // 10text20#fff30
46
+ /// @debug list-sum-numbers((true, false, null, 5)); // 0truefalse5
47
+ /// @debug list-sum-numbers((1px, 2em, 3rem)); // Ошибка: несовместимые единицы
48
+ /// @example scss - Пустые списки и отсутствие чисел
49
+ /// @debug list-sum-numbers(()); // 0
50
+ /// @debug list-sum-numbers(("a", "b", "c")); // 0abc
51
+ /// @debug list-sum-numbers(none); // 0none
52
+ /// @example scss - Практическое использование
53
+ /// $margins: 10px, 20px, 15px, 5px;
54
+ /// @debug list-sum-numbers($margins); // $total-margin: 50px
55
+ /// @example scss - Суммирование с разными единицами (осторожно!)
56
+ /// // Будет работать только если единицы совместимы
57
+ /// @debug list-sum-numbers((10px, 2cm, 3mm)); // 96.9291338582677px, но может вызвать ошибку
58
+ /// @see list-sum-numbers-safe
59
+ /// @param {List} $list - Список значений, который может
60
+ /// содержать элементы разных типов. Функция будет
61
+ /// обрабатывать только числовые элементы.
62
+ /// @return {Number} - Сумма всех числовых элементов списка.
63
+ /// Если в списке нет числовых элементов, возвращает `0`.
64
+ /// Единицы измерения сохраняются, но могут быть
65
+ /// несовместимыми (например, 10px + 2em вызовет ошибку).
66
+ /// @throws {Error} - Может выбросить ошибку при попытке
67
+ /// сложить числа с несовместимыми единицами измерения
68
+ /// (например, px + em).
69
+ @function list-sum-numbers($list) {
70
+
71
+ // Проверка типа входного параметра: ожидается список или arglist.
72
+ // Функция is-list() проверяет, является ли $list валидным списком
73
+ // или arglist (специальный тип для переменного числа аргументов).
74
+ @if not is-list($list) {
75
+
76
+ // Если $list не является списком, возвращаем ошибку через
77
+ // стандартную функцию логирования. Это предотвращает
78
+ // некорректные вычисления с некорректными данными.
79
+ @return log-invalid-type(
80
+ 'list-sum-numbers',
81
+ $list,
82
+ '$list',
83
+ ('list', 'arglist')
84
+ );
85
+
86
+ }
87
+
88
+ // Основная логика выполняется только если $list является
89
+ // корректным списком или arglist.
90
+ @else {
91
+
92
+ // Инициализация переменной для хранения суммы чисел.
93
+ // $-sum будет содержать итоговую сумму всех числовых элементов
94
+ // в списке. Начальное значение 0 гарантирует корректный результат
95
+ // даже для пустых списков или списков без числовых элементов.
96
+ $-sum: 0;
97
+
98
+ // Итерация по всем элементам исходного списка.
99
+ // Переменная $-item содержит текущий обрабатываемый элемент.
100
+ @each $-item in $list {
101
+
102
+ // Проверка: является ли текущий элемент числом.
103
+ // Функция is-number() возвращает true для числовых значений,
104
+ // включая числа с единицами измерения (px, rem, em и т.д.)
105
+ // и безразмерные числа.
106
+ @if is-number($-item) {
107
+
108
+ // Если элемент является числом, добавляем его к общей сумме.
109
+ // Оператор + в Sass автоматически складывает числа,
110
+ // учитывая их единицы измерения. Если единицы измерения
111
+ // несовместимы (например, px + em), Sass вызовет ошибку
112
+ // компиляции на этом этапе.
113
+ $-sum: $-sum + $-item;
114
+
115
+ }
116
+
117
+ }
118
+
119
+ // Возвращаем итоговую сумму всех числовых элементов.
120
+ // Если в списке не было чисел, возвращается 0 (начальное значение).
121
+ // Если были числа с единицами измерения, результат будет иметь
122
+ // те же единицы измерения, что и первое найденное число
123
+ // (при условии совместимости всех единиц).
124
+ @return $-sum;
125
+
126
+ }
127
+
128
+ }
@@ -0,0 +1,64 @@
1
+ /// Это карта соответствий между специальными символами URL и
2
+ /// их кодированием (например, '#' → '%23'). Используется для
3
+ /// автоматического корректного кодирования URL в SCSS.
4
+ ///
5
+ /// Использование этой карты помогает избежать ручного
6
+ /// кодирования, предотвращает ошибки и обеспечивает единообразие
7
+ /// при генерации URL-адресов в проекте. Флаг `!default` означает,
8
+ /// что переменная будет использована только если ранее не была
9
+ /// определена, что позволяет её переопределить при необходимости.
10
+ /// ---
11
+ /// @name set-url-reserved-chars
12
+ /// @group utilities-helpers
13
+ /// @since 2026.01.13
14
+ /// @access public
15
+ /// @author Sindre Sorhus
16
+ /// @author Murad Rustamov (therteenten) [адаптация]
17
+ /// @link https://github.com/sindresorhus GitHub - Sindre Sorhus
18
+ /// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
19
+ /// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
20
+ /// @prop {String} ' ' ['%20'] - Пробел
21
+ /// @prop {String} '!' ['%21'] - Восклицательный знак
22
+ /// @prop {String} '#' ['%23'] - Символ решетки
23
+ /// @prop {String} '$' ['%24'] - Знак доллара
24
+ /// @prop {String} '&' ['%26'] - Амперсанд
25
+ /// @prop {String} '\'' ['%27'] - Одинарная кавычка
26
+ /// @prop {String} '(' ['%28'] - Открывающая скобка
27
+ /// @prop {String} ')' ['%29'] - Закрывающая скобка
28
+ /// @prop {String} '*' ['%2A'] - Звездочка
29
+ /// @prop {String} '+' ['%2B'] - Знак плюса
30
+ /// @prop {String} ',' ['%2C'] - Запятая
31
+ /// @prop {String} '/' ['%2F'] - Слеш
32
+ /// @prop {String} ':' ['%3A'] - Двоеточие
33
+ /// @prop {String} ';' ['%3B'] - Точка с запятой
34
+ /// @prop {String} '=' ['%3D'] - Знак равенства
35
+ /// @prop {String} '?' ['%3F'] - Вопросительный знак
36
+ /// @prop {String} '@' ['%40'] - Символ "собака"
37
+ /// @prop {String} '[' ['%5B'] - Открывающая квадратная скобка
38
+ /// @prop {String} ']' ['%5D'] - Закрывающая квадратная скобка
39
+ /// @prop {String} '"' ['%22'] - Двойная кавычка
40
+ /// @see url-encode
41
+ /// @type Map
42
+ $set-url-reserved-chars: (
43
+ ' ': '%20',
44
+ '!': '%21',
45
+ '#': '%23',
46
+ '$': '%24',
47
+ '&': '%26',
48
+ '\'': '%27',
49
+ '(': '%28',
50
+ ')': '%29',
51
+ '*': '%2A',
52
+ '+': '%2B',
53
+ ',': '%2C',
54
+ '/': '%2F',
55
+ ':': '%3A',
56
+ ';': '%3B',
57
+ '=': '%3D',
58
+ '?': '%3F',
59
+ '@': '%40',
60
+ '[': '%5B',
61
+ ']': '%5D',
62
+ // Если результат заключен в двойные кавычки
63
+ '"': '%22'
64
+ ) !default;