@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.
- package/CHANGELOG.md +5 -0
- package/LICENSE +21 -0
- package/README.md +2 -0
- package/_configs.scss +68 -0
- package/index.scss +95 -0
- package/modules/utilities/converters/_convert-camel2kebab.scss +186 -0
- package/modules/utilities/converters/_convert-em2px.scss +239 -0
- package/modules/utilities/converters/_convert-hex2rgb.scss +97 -0
- package/modules/utilities/converters/_convert-hex2rgba.scss +124 -0
- package/modules/utilities/converters/_convert-kebab2camel.scss +232 -0
- package/modules/utilities/converters/_convert-kebab2snake.scss +118 -0
- package/modules/utilities/converters/_convert-px2em.scss +236 -0
- package/modules/utilities/converters/_convert-px2rem.scss +180 -0
- package/modules/utilities/converters/_convert-rem2px.scss +207 -0
- package/modules/utilities/converters/_convert-snake2kebab.scss +173 -0
- package/modules/utilities/getters/color/_get-color-brightness.scss +138 -0
- package/modules/utilities/getters/color/_get-color-darkest.scss +178 -0
- package/modules/utilities/getters/list/_get-list-item-end.scss +114 -0
- package/modules/utilities/getters/list/_get-list-item-start.scss +109 -0
- package/modules/utilities/getters/list/_get-list-item.scss +179 -0
- package/modules/utilities/getters/number/_get-number-from-percent.scss +139 -0
- package/modules/utilities/getters/number/_get-number-height-by-ratio.scss +199 -0
- package/modules/utilities/getters/number/_get-number-max.scss +168 -0
- package/modules/utilities/getters/number/_get-number-min.scss +162 -0
- package/modules/utilities/getters/number/_get-number-percentage-of.scss +149 -0
- package/modules/utilities/getters/number/_get-number-unit.scss +111 -0
- package/modules/utilities/getters/number/_get-number-width-by-ratio.scss +223 -0
- package/modules/utilities/helpers/color/_color-blend-steps.scss +210 -0
- package/modules/utilities/helpers/color/_color-blend.scss +183 -0
- package/modules/utilities/helpers/color/_color-hue-shift.scss +148 -0
- package/modules/utilities/helpers/color/_color-scale.scss +208 -0
- package/modules/utilities/helpers/color/_color-shade.scss +113 -0
- package/modules/utilities/helpers/color/_color-tint.scss +118 -0
- package/modules/utilities/helpers/color/_color-triad.scss +141 -0
- package/modules/utilities/helpers/list/_list-dedupe.scss +146 -0
- package/modules/utilities/helpers/list/_list-insert-at.scss +166 -0
- package/modules/utilities/helpers/list/_list-merge.scss +86 -0
- package/modules/utilities/helpers/list/_list-remove-at.scss +160 -0
- package/modules/utilities/helpers/list/_list-sum-numbers-safe.scss +175 -0
- package/modules/utilities/helpers/list/_list-sum-numbers.scss +128 -0
- package/modules/utilities/helpers/misc/_url-encode.configs.scss +64 -0
- package/modules/utilities/helpers/misc/_url-encode.scss +148 -0
- package/modules/utilities/helpers/number/_number-ceil-to.scss +111 -0
- package/modules/utilities/helpers/number/_number-clamp-max.scss +92 -0
- package/modules/utilities/helpers/number/_number-clamp-min.scss +100 -0
- package/modules/utilities/helpers/number/_number-clamp.scss +109 -0
- package/modules/utilities/helpers/number/_number-denormalize.scss +172 -0
- package/modules/utilities/helpers/number/_number-fibonacci.scss +235 -0
- package/modules/utilities/helpers/number/_number-floor-to.scss +114 -0
- package/modules/utilities/helpers/number/_number-format-with-separator.scss +122 -0
- package/modules/utilities/helpers/number/_number-normalize.scss +160 -0
- package/modules/utilities/helpers/number/_number-random-between-int.scss +84 -0
- package/modules/utilities/helpers/number/_number-random-between.scss +120 -0
- package/modules/utilities/helpers/number/_number-range.scss +268 -0
- package/modules/utilities/helpers/number/_number-round-to-nearest.scss +131 -0
- package/modules/utilities/helpers/number/_number-round-to.scss +118 -0
- package/modules/utilities/helpers/number/_number-strip-unit.scss +97 -0
- package/modules/utilities/helpers/string/_string-capitalize.scss +84 -0
- package/modules/utilities/helpers/string/_string-replace.scss +69 -0
- package/modules/utilities/helpers/string/_string-trim-end.scss +62 -0
- package/modules/utilities/helpers/string/_string-trim-start.scss +62 -0
- package/modules/utilities/helpers/string/_string-trim.scss +69 -0
- package/modules/utilities/loggers/_log-invalid-type.scss +151 -0
- package/modules/utilities/loggers/_log-invalid-value.scss +151 -0
- package/modules/utilities/setters/_index.scss +3 -0
- package/modules/utilities/validators/color/_is-color-light.scss +132 -0
- package/modules/utilities/validators/color/_is-color-list.scss +124 -0
- package/modules/utilities/validators/list/_is-list-contained.scss +65 -0
- package/modules/utilities/validators/misc/_is-time.scss +115 -0
- package/modules/utilities/validators/number/_is-int-even.scss +69 -0
- package/modules/utilities/validators/number/_is-int-odd.scss +70 -0
- package/modules/utilities/validators/number/_is-int.scss +124 -0
- package/modules/utilities/validators/number/_is-number-has-unit.scss +85 -0
- package/modules/utilities/validators/number/_is-number-negative.scss +76 -0
- package/modules/utilities/validators/number/_is-number-positive.scss +74 -0
- package/modules/utilities/validators/number/_is-number-unitless.scss +88 -0
- package/modules/utilities/validators/number/_is-number-zero.scss +75 -0
- package/modules/utilities/validators/string/_is-string-contained.scss +108 -0
- package/modules/utilities/validators/string/_is-string-empty.scss +56 -0
- package/modules/utilities/validators/string/_is-string-ending-with.scss +66 -0
- package/modules/utilities/validators/string/_is-string-starting-with.scss +66 -0
- package/modules/utilities/validators/type-of/_is-boolean.scss +92 -0
- package/modules/utilities/validators/type-of/_is-color.scss +96 -0
- package/modules/utilities/validators/type-of/_is-list.scss +105 -0
- package/modules/utilities/validators/type-of/_is-map.scss +105 -0
- package/modules/utilities/validators/type-of/_is-number.scss +103 -0
- package/modules/utilities/validators/type-of/_is-string.scss +110 -0
- package/modules/utilities/validators/type-of/_is-type.scss +77 -0
- package/package.json +54 -0
- package/package.scss +156 -0
- package/test.md +168 -0
- package/test.scss +405 -0
- package/test.sh +149 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
@use 'sass:color';
|
|
2
|
+
@use 'sass:meta';
|
|
3
|
+
@use '../../loggers/log-invalid-type' as *;
|
|
4
|
+
@use '../../validators/type-of/is-color' as *;
|
|
5
|
+
|
|
6
|
+
/// Генерирует триадную цветовую схему из трех
|
|
7
|
+
/// равноудаленных цветов.
|
|
8
|
+
///
|
|
9
|
+
/// Функция `color-triad()` создает триадную цветовую
|
|
10
|
+
/// схему, состоящую из трех цветов, которые равномерно
|
|
11
|
+
/// распределены по цветовому кругу (разделены на 120 градусов).
|
|
12
|
+
///
|
|
13
|
+
/// Триадные схемы обладают высокой контрастностью при
|
|
14
|
+
/// сохранении гармонии и часто используются в дизайне для
|
|
15
|
+
/// создания ярких, сбалансированных цветовых сочетаний.
|
|
16
|
+
///
|
|
17
|
+
/// > Функция возвращает строковые представления цветов
|
|
18
|
+
/// > (используя `meta.inspect()`), что позволяет сохранять
|
|
19
|
+
/// > разные форматы. Для использования в CSS свойствах может
|
|
20
|
+
/// > потребоваться `unquote()` для удаления кавычек.
|
|
21
|
+
///
|
|
22
|
+
/// > Все цвета в триаде имеют одинаковые значения
|
|
23
|
+
/// > насыщенности и светлоты, что обеспечивает визуальную
|
|
24
|
+
/// > согласованность цветовой схемы.
|
|
25
|
+
///
|
|
26
|
+
/// Также в основном функция возвращает цвета в формате HSL.
|
|
27
|
+
/// ---
|
|
28
|
+
/// @name color-triad
|
|
29
|
+
/// @group utilities-helpers
|
|
30
|
+
/// @since 2025.12.27
|
|
31
|
+
/// @access public
|
|
32
|
+
/// @author Murad Rustamov (therteenten)
|
|
33
|
+
/// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
|
|
34
|
+
/// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
|
|
35
|
+
/// @link https://en.wikipedia.org/wiki/Color_scheme#Triadic См. также: Wikipedia - Triadic color schemes
|
|
36
|
+
/// @link https://color.adobe.com/create/color-wheel См. также: Adobe Color - Инструмент цветового круга
|
|
37
|
+
/// @link https://www.canva.com/colors/color-wheel/ См. также: Canva - Теория цвета и цветовой круг
|
|
38
|
+
/// @link https://www.smashingmagazine.com/2016/04/web-developer-guide-color/ См. также: Smashing Magazine - Гид по цвету для веб-разработчиков
|
|
39
|
+
/// @example scss - Создание триадной схемы из красного цвета
|
|
40
|
+
/// @use 'sass:list';
|
|
41
|
+
/// @use 'sass:string';
|
|
42
|
+
///
|
|
43
|
+
/// $triad: color-triad(#ff0000);
|
|
44
|
+
///
|
|
45
|
+
/// .element {
|
|
46
|
+
/// color: string.unquote(list.nth($triad, 1)); // #ff0000
|
|
47
|
+
/// border-color: string.unquote(list.nth($triad, 2)); // hsl(120, 100%, 50%) → зеленый
|
|
48
|
+
/// background-color: string.unquote(list.nth($triad, 3)); // hsl(240, 100%, 50%) → синий
|
|
49
|
+
/// }
|
|
50
|
+
/// @example css - Результат
|
|
51
|
+
/// .element {
|
|
52
|
+
/// color: #ff0000;
|
|
53
|
+
/// border-color: hsl(120, 100%, 50%);
|
|
54
|
+
/// background-color: hsl(240, 100%, 50%);
|
|
55
|
+
/// }
|
|
56
|
+
/// @example scss - Использование в дизайн-системе
|
|
57
|
+
/// @use 'sass:list';
|
|
58
|
+
/// @use 'sass:string';
|
|
59
|
+
/// :root {
|
|
60
|
+
/// $primary-triad: color-triad(#2c3e50);
|
|
61
|
+
/// --color-primary: #{string.unquote(list.nth($primary-triad, 1))};
|
|
62
|
+
/// --color-secondary: #{string.unquote(list.nth($primary-triad, 2))};
|
|
63
|
+
/// --color-accent: #{string.unquote(list.nth($primary-triad, 3))};
|
|
64
|
+
/// }
|
|
65
|
+
/// @example css - Результат
|
|
66
|
+
/// :root {
|
|
67
|
+
/// --color-primary: #2c3e50;
|
|
68
|
+
/// --color-secondary: hsl(330, 29.032258064516128%, 24.313725490196074%);
|
|
69
|
+
/// --color-accent: hsl(90, 29.032258064516128%, 24.313725490196074%);
|
|
70
|
+
/// }
|
|
71
|
+
/// @see color-blend
|
|
72
|
+
/// @param {Color} $color - Базовый цвет для построения
|
|
73
|
+
/// триады. Может быть в любом формате, поддерживаемом Sass
|
|
74
|
+
/// (HEX, RGB, HSL, имя цвета).
|
|
75
|
+
/// Цветовой тон (hue) этого цвета используется как отправная
|
|
76
|
+
/// точка для расчета двух дополнительных цветов.
|
|
77
|
+
///
|
|
78
|
+
/// @return {List} - Список (list) из трех строковых
|
|
79
|
+
/// представлений цветов в формате, который Sass использует
|
|
80
|
+
/// для внутреннего хранения (обычно HEX для цветов в
|
|
81
|
+
/// пространстве `srgb`). Все цвета сохраняют одинаковые
|
|
82
|
+
/// значения насыщенности и светлоты исходного цвета,
|
|
83
|
+
/// изменяется только цветовой тон.
|
|
84
|
+
/// - Первый элемент: строковое представление исходного цвета
|
|
85
|
+
/// - Второй элемент: цвет со смещением +120° по цветовому кругу
|
|
86
|
+
/// - Третий элемент: цвет со смещением +240° по цветовому кругу
|
|
87
|
+
@function color-triad($color) {
|
|
88
|
+
|
|
89
|
+
// Проверка типа входного параметра: ожидается цветовое значение.
|
|
90
|
+
// Функция is-color() проверяет, является ли $color валидным цветом CSS.
|
|
91
|
+
@if not is-color($color) {
|
|
92
|
+
|
|
93
|
+
// Если $color не является цветом, возвращаем ошибку через
|
|
94
|
+
// стандартную функцию логирования. Это предотвращает
|
|
95
|
+
// некорректные вычисления с нецветовыми данными.
|
|
96
|
+
@return log-invalid-type(
|
|
97
|
+
'color-triad',
|
|
98
|
+
$color,
|
|
99
|
+
'$color',
|
|
100
|
+
'color'
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Основная логика выполняется только если $color является
|
|
106
|
+
// корректным цветом.
|
|
107
|
+
@else {
|
|
108
|
+
|
|
109
|
+
// Извлечение компонентов цвета из входного параметра
|
|
110
|
+
// в пространстве HSL (Hue, Saturation, Lightness).
|
|
111
|
+
// Функция color.channel() возвращает конкретный канал цвета:
|
|
112
|
+
$-hue: color.channel($color, "hue", $space: hsl); // Оттенок: 0-360 градусов
|
|
113
|
+
$-saturation: color.channel($color, "saturation", $space: hsl); // Насыщенность: 0-100%
|
|
114
|
+
$-lightness: color.channel($color, "lightness", $space: hsl); // Яркость: 0-100%
|
|
115
|
+
|
|
116
|
+
// Создание триадной цветовой схемы.
|
|
117
|
+
// Триада - это три цвета, равномерно распределенных
|
|
118
|
+
// по цветовому кругу (разделенных 120 градусами).
|
|
119
|
+
//
|
|
120
|
+
// Формула триады:
|
|
121
|
+
// 1. Исходный цвет: $color (оттенок = $-hue)
|
|
122
|
+
// 2. Второй цвет: оттенок = ($-hue + 120) % 360
|
|
123
|
+
// (120 градусов по часовой стрелке от исходного)
|
|
124
|
+
// 3. Третий цвет: оттенок = ($-hue + 240) % 360
|
|
125
|
+
// (240 градусов по часовой стрелке от исходного)
|
|
126
|
+
//
|
|
127
|
+
// Оператор % 360 гарантирует, что значение оттенка всегда
|
|
128
|
+
// остается в диапазоне 0-359 градусов (полный круг).
|
|
129
|
+
//
|
|
130
|
+
// Функция meta.inspect() преобразует цветовые значения
|
|
131
|
+
// в строки, чтобы они могли быть корректно представлены
|
|
132
|
+
// в возвращаемом списке.
|
|
133
|
+
@return (
|
|
134
|
+
meta.inspect($color), // Исходный цвет
|
|
135
|
+
meta.inspect(hsl(($-hue + 120) % 360, $-saturation, $-lightness)), // Второй цвет триады
|
|
136
|
+
meta.inspect(hsl(($-hue + 240) % 360, $-saturation, $-lightness)) // Третий цвет триады
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
@use 'sass:list';
|
|
2
|
+
@use '../../loggers/log-invalid-type' as *;
|
|
3
|
+
@use '../../validators/list/is-list-contained' as *;
|
|
4
|
+
@use '../../validators/type-of/is-list' as *;
|
|
5
|
+
|
|
6
|
+
/// Удаляет дублирующиеся значения из списка.
|
|
7
|
+
///
|
|
8
|
+
/// Функция `list-dedupe()` принимает список и возвращает
|
|
9
|
+
/// новый список, в котором удалены все повторяющиеся
|
|
10
|
+
/// значения, сохраняя только первое вхождение каждого
|
|
11
|
+
/// уникального элемента. Порядок элементов сохраняется.
|
|
12
|
+
///
|
|
13
|
+
/// Полезно для очистки данных, обработки пользовательского
|
|
14
|
+
/// ввода или подготовки списков для дальнейших операций, где
|
|
15
|
+
/// дубликаты нежелательны.
|
|
16
|
+
///
|
|
17
|
+
/// - Функция использует строгое сравнение (оператор ==)
|
|
18
|
+
/// для определения дубликатов.
|
|
19
|
+
/// - Для сложных структур (maps, вложенные списки) сравнение
|
|
20
|
+
/// может быть неточным.
|
|
21
|
+
/// - Производительность - для больших списков рассмотрите
|
|
22
|
+
/// другие подходы.
|
|
23
|
+
/// - Порядок элементов сохраняется, удаляются только
|
|
24
|
+
/// последующие дубликаты.
|
|
25
|
+
/// ---
|
|
26
|
+
/// @name list-dedupe
|
|
27
|
+
/// @group utilities-helpers
|
|
28
|
+
/// @since 2025.12.27
|
|
29
|
+
/// @access public
|
|
30
|
+
/// @author Murad Rustamov (therteenten)
|
|
31
|
+
/// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
|
|
32
|
+
/// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
|
|
33
|
+
/// @link https://sass-lang.com/documentation/values/lists См. также: Sass - Работа со списками
|
|
34
|
+
/// @link https://sass-lang.com/documentation/modules/list См. также: Sass - Модуль для работы со списками
|
|
35
|
+
/// @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set См. также: MDN - Set объект в JavaScript
|
|
36
|
+
/// @link https://www.w3schools.com/python/ref_set_difference.asp См. также: W3Schools - Множества в Python
|
|
37
|
+
/// @link https://css-tricks.com/snippets/sass/remove-duplicates-from-list/ См. также: CSS-Tricks - Удаление дубликатов из списка
|
|
38
|
+
/// @link https://stackoverflow.com/questions/30865280 См. также: StackOverflow - Удаление дубликатов в Sass
|
|
39
|
+
/// @example scss - Удаление дубликатов цветов
|
|
40
|
+
/// $colors: (#ff0000, #00ff00, #0000ff, #ff0000, #00ff00);
|
|
41
|
+
/// $unique-colors: list-dedupe($colors); // Результат: #ff0000, #00ff00, #0000ff
|
|
42
|
+
/// @example scss - Обработка пользовательского ввода
|
|
43
|
+
/// $user-tags: ("css", "sass", "design", "css", "ui", "sass");
|
|
44
|
+
/// $clean-tags: list-dedupe($user-tags);
|
|
45
|
+
///
|
|
46
|
+
/// .tags {
|
|
47
|
+
/// @each $tag in $clean-tags {
|
|
48
|
+
/// &--#{$tag} { display: inline-block; }
|
|
49
|
+
/// }
|
|
50
|
+
/// }
|
|
51
|
+
/// @example css - Результат
|
|
52
|
+
/// .tags--css {
|
|
53
|
+
/// display: inline-block;
|
|
54
|
+
/// }
|
|
55
|
+
/// .tags--sass {
|
|
56
|
+
/// display: inline-block;
|
|
57
|
+
/// }
|
|
58
|
+
/// .tags--design {
|
|
59
|
+
/// display: inline-block;
|
|
60
|
+
/// }
|
|
61
|
+
/// .tags--ui {
|
|
62
|
+
/// display: inline-block;
|
|
63
|
+
/// }
|
|
64
|
+
/// @example scss - Подготовка списка для CSS-переменных
|
|
65
|
+
/// @use 'sass:list';
|
|
66
|
+
///
|
|
67
|
+
/// $font-sizes: (16px, 18px, 20px, 16px, 24px, 18px);
|
|
68
|
+
/// $unique-sizes: list-dedupe($font-sizes);
|
|
69
|
+
///
|
|
70
|
+
/// :root {
|
|
71
|
+
/// @for $i from 1 through list.length($unique-sizes) {
|
|
72
|
+
/// --font-size-#{$i}: #{list.nth($unique-sizes, $i)};
|
|
73
|
+
/// }
|
|
74
|
+
/// }
|
|
75
|
+
/// @example css - Результат
|
|
76
|
+
/// :root {
|
|
77
|
+
/// --font-size-1: 16px;
|
|
78
|
+
/// --font-size-2: 18px;
|
|
79
|
+
/// --font-size-3: 20px;
|
|
80
|
+
/// --font-size-4: 24px;
|
|
81
|
+
/// }
|
|
82
|
+
/// @example scss - Обработка вложенных списков
|
|
83
|
+
/// $nested: ((1, 2), (3, 4), (1, 2), (5, 6));
|
|
84
|
+
/// $deduped: list-dedupe($nested); //=> Результат: (1, 2) (3, 4) (5, 6)
|
|
85
|
+
/// @param {List} $list - Исходный список, который может
|
|
86
|
+
/// содержать дубликаты. Может быть любым списком: цвета,
|
|
87
|
+
/// строки, числа, вложенные списки и т.д. Для корректного
|
|
88
|
+
/// сравнения элементы должны быть строго равны (==).
|
|
89
|
+
/// @return {List} - Новый список без дублирующихся значений.
|
|
90
|
+
/// Сохраняет порядок элементов, оставляя только первое
|
|
91
|
+
/// вхождение каждого значения. Если исходный список
|
|
92
|
+
/// пустой, возвращает пустой список.
|
|
93
|
+
@function list-dedupe($list) {
|
|
94
|
+
|
|
95
|
+
// Проверка типа входного параметра: ожидается список или arglist.
|
|
96
|
+
// Функция is-list() проверяет, является ли $list валидным списком
|
|
97
|
+
// или arglist (специальный тип для переменного числа аргументов).
|
|
98
|
+
@if not is-list($list) {
|
|
99
|
+
|
|
100
|
+
// Если $list не является списком, возвращаем ошибку через
|
|
101
|
+
// стандартную функцию логирования. Это предотвращает
|
|
102
|
+
// некорректные вычисления с некорректными данными.
|
|
103
|
+
@return log-invalid-type(
|
|
104
|
+
'list-dedupe',
|
|
105
|
+
$list,
|
|
106
|
+
'$list',
|
|
107
|
+
('list', 'arglist')
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Основная логика выполняется только если $list является
|
|
113
|
+
// корректным списком или arglist.
|
|
114
|
+
@else {
|
|
115
|
+
|
|
116
|
+
// Инициализация переменной для хранения результата.
|
|
117
|
+
// $-result будет содержать список без дубликатов.
|
|
118
|
+
$-result: ();
|
|
119
|
+
|
|
120
|
+
// Итерация по всем элементам исходного списка.
|
|
121
|
+
// Переменная $-item содержит текущий обрабатываемый элемент.
|
|
122
|
+
@each $-item in $list {
|
|
123
|
+
|
|
124
|
+
// Проверка: содержится ли текущий элемент уже в результате.
|
|
125
|
+
// Используется вспомогательная функция is-list-contained(),
|
|
126
|
+
// которая должна возвращать true, если элемент уже присутствует
|
|
127
|
+
// в списке $-result.
|
|
128
|
+
@if not is-list-contained($-result, $-item) {
|
|
129
|
+
|
|
130
|
+
// Если элемент еще не содержится в результате,
|
|
131
|
+
// добавляем его в конец списка $-result.
|
|
132
|
+
// Функция list.append() добавляет новый элемент в список.
|
|
133
|
+
$-result: list.append($-result, $-item);
|
|
134
|
+
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Возвращаем список без дубликатов.
|
|
140
|
+
// Порядок элементов сохраняется (первое вхождение каждого элемента
|
|
141
|
+
// сохраняет свою позицию, последующие дубликаты игнорируются).
|
|
142
|
+
@return $-result;
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
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
|
+
/// элементом с этим индексом. Если индекс больше длины списка,
|
|
12
|
+
/// значение добавляется в конец списка.
|
|
13
|
+
///
|
|
14
|
+
/// Важные особенности функции:
|
|
15
|
+
/// - Использует 1-based индексацию (первый элемент имеет
|
|
16
|
+
/// индекс 1)
|
|
17
|
+
/// - Не изменяет исходный список, возвращает новый
|
|
18
|
+
/// - Если индекс > длины списка, добавляет значение в конец
|
|
19
|
+
/// - Если индекс = 1, вставляет значение в начало списка
|
|
20
|
+
/// - Поддерживает любые типы значений для вставки
|
|
21
|
+
/// - Сохраняет порядок остальных элементов
|
|
22
|
+
/// - Использует локальные переменные с префиксом `$-` для
|
|
23
|
+
/// избежания конфликтов
|
|
24
|
+
/// ---
|
|
25
|
+
/// @name list-insert-at
|
|
26
|
+
/// @group utilities-helpers
|
|
27
|
+
/// @since 2025.12.27
|
|
28
|
+
/// @access public
|
|
29
|
+
/// @author Murad Rustamov (therteenten)
|
|
30
|
+
/// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
|
|
31
|
+
/// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
|
|
32
|
+
/// @link https://sass-lang.com/documentation/modules/list#nth См. также: Официальная документация Sass - Функция list.nth()
|
|
33
|
+
/// @link https://sass-lang.com/documentation/modules/list#length См. также: Официальная документация Sass - Функция list.length()
|
|
34
|
+
/// @link https://sass-lang.com/documentation/values/lists См. также: Официальная документация Sass - Тип данных "Списки"
|
|
35
|
+
/// @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice MDN Web Docs - Array.splice()
|
|
36
|
+
/// @link https://css-tricks.com/snippets/sass/ См. также: CSS-Tricks - Коллекция сниппетов Sass
|
|
37
|
+
/// @link https://sass-guidelin.es/ru/#list-functions См. также: Sass Guidelines - Функции для работы со списками
|
|
38
|
+
/// @link https://frontender.info/sass-lists/ См. также: Frontender Magazine - Работа со списками в Sass
|
|
39
|
+
/// @link https://www.w3schools.com/sass/sass_functions_list.php См. также: W3Schools - Функции для работы со списками в Sass
|
|
40
|
+
/// @link https://habr.com/ru/post/156549/ См. также: Habr - Статья "Sass для верстальщика: списки и циклы"
|
|
41
|
+
/// @example scss - Вставка в середину списка
|
|
42
|
+
/// @debug list-insert-at((a, b, c, d), "X", 3); // (a, b, X, c, d)
|
|
43
|
+
/// @debug list-insert-at((10, 20, 30, 40), 25, 3); // (10, 20, 25, 30, 40)
|
|
44
|
+
/// @debug list-insert-at((red, blue, green), yellow, 2); // (red, yellow, blue, green)
|
|
45
|
+
/// @example scss - Вставка в начало и конец списка
|
|
46
|
+
/// @debug list-insert-at((b, c, d), a, 1); // (a, b, c, d)
|
|
47
|
+
/// @debug list-insert-at((a, b, c), d, 4); // (a, b, c, d)
|
|
48
|
+
/// @debug list-insert-at((a, b, c), d, 10); // (a, b, c, d) (индекс > длины)
|
|
49
|
+
/// @example scss - Вставка в пустой список
|
|
50
|
+
/// // @debug list-insert-at((), "first", 1); // Error: $n: Invalid index 1 for a list with 0 elements.
|
|
51
|
+
/// // @debug list-insert-at((), "element", 5); // Error: $n: Invalid index 1 for a list with 0 elements.
|
|
52
|
+
/// @debug list-insert-at(none, "value", 1); // (value)
|
|
53
|
+
/// @example scss - Вставка разных типов данных
|
|
54
|
+
/// @debug list-insert-at((a, b, c), 123, 2); // (a, 123, b, c)
|
|
55
|
+
/// @debug list-insert-at((1, 2, 3), #ff0000, 2); // (1, #ff0000, 2, 3)
|
|
56
|
+
/// @debug list-insert-at((true, false), null, 1); // (null, true, false)
|
|
57
|
+
/// @example scss - Практическое использование: расширение палитры
|
|
58
|
+
/// $base-colors: (#ff0000, #00ff00, #0000ff);
|
|
59
|
+
/// $extended-palette: list-insert-at($base-colors, #ffff00, 3);
|
|
60
|
+
/// @debug $extended-palette; // (#ff0000, #00ff00, #ffff00, #0000ff)
|
|
61
|
+
/// @param {List} $list - Исходный список, в который
|
|
62
|
+
/// нужно вставить значение. Может содержать элементы
|
|
63
|
+
/// любых типов и может быть пустым.
|
|
64
|
+
/// @param {*} $value - Значение для вставки в список.
|
|
65
|
+
/// Может быть любого типа (строка, число, цвет, список и т.д.).
|
|
66
|
+
/// @param {Number} $index - Позиция для вставки значения.
|
|
67
|
+
/// Используется 1-based индексация. Если индекс находится
|
|
68
|
+
/// в пределах списка (1 ≤ индекс ≤ длина), значение
|
|
69
|
+
/// вставляется перед элементом с этим индексом. Если
|
|
70
|
+
/// индекс > длины списка, значение добавляется в конец.
|
|
71
|
+
/// @return {List} - Новый список, содержащий все элементы
|
|
72
|
+
/// исходного списка с добавленным значением в указанной
|
|
73
|
+
/// позиции. Если список был пустым, возвращается список
|
|
74
|
+
/// из одного элемента (вставленного значения).
|
|
75
|
+
/// @throws {Error | Warning} - Может выбросить ошибку если
|
|
76
|
+
/// `$index` не является числом или если индекс меньше 1,
|
|
77
|
+
/// а также предупреждение, если индекс превышает длину
|
|
78
|
+
/// списка.
|
|
79
|
+
@function list-insert-at($list, $value, $index) {
|
|
80
|
+
|
|
81
|
+
// Проверка типа первого параметра: ожидается список или arglist.
|
|
82
|
+
// Функция is-list() проверяет, является ли $list валидным списком
|
|
83
|
+
// или arglist (специальный тип для переменного числа аргументов).
|
|
84
|
+
@if not is-list($list) {
|
|
85
|
+
|
|
86
|
+
// Если $list не является списком, возвращаем ошибку через
|
|
87
|
+
// стандартную функцию логирования. Это предотвращает
|
|
88
|
+
// некорректные вычисления с некорректными данными.
|
|
89
|
+
@return log-invalid-type(
|
|
90
|
+
'list-insert-at',
|
|
91
|
+
$list,
|
|
92
|
+
'$list',
|
|
93
|
+
('list', 'arglist')
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Проверка типа третьего параметра: ожидается числовое значение индекса.
|
|
99
|
+
// $index определяет позицию, на которую нужно вставить значение в список.
|
|
100
|
+
// Индексация в Sass начинается с 1, а не с 0.
|
|
101
|
+
@else if not is-number($index) {
|
|
102
|
+
|
|
103
|
+
// Если $index не является числом, возвращаем ошибку.
|
|
104
|
+
// Проверка выполняется только если $list прошел валидацию.
|
|
105
|
+
@return log-invalid-type(
|
|
106
|
+
'list-insert-at',
|
|
107
|
+
$index,
|
|
108
|
+
'$index',
|
|
109
|
+
'number'
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Все параметры прошли валидацию - выполняем вставку значения.
|
|
115
|
+
@else {
|
|
116
|
+
|
|
117
|
+
// Инициализация переменной для хранения результата.
|
|
118
|
+
// $-result будет содержать новый список с вставленным значением.
|
|
119
|
+
$-result: ();
|
|
120
|
+
|
|
121
|
+
// Определение длины исходного списка.
|
|
122
|
+
// Функция list.length() возвращает количество элементов в списке.
|
|
123
|
+
$-length: list.length($list);
|
|
124
|
+
|
|
125
|
+
// Цикл по всем элементам исходного списка.
|
|
126
|
+
// Переменная $i принимает значения от 1 до $-length включительно.
|
|
127
|
+
@for $i from 1 through $-length {
|
|
128
|
+
|
|
129
|
+
// Проверка: достигли ли мы позиции для вставки.
|
|
130
|
+
@if $i == $index {
|
|
131
|
+
|
|
132
|
+
// Если текущий индекс равен целевому индексу вставки,
|
|
133
|
+
// добавляем новое значение в результат перед текущим элементом.
|
|
134
|
+
$-result: list.append($-result, $value);
|
|
135
|
+
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Добавляем текущий элемент исходного списка в результат.
|
|
139
|
+
// Функция list.nth() извлекает элемент списка по указанному индексу.
|
|
140
|
+
$-result: list.append($-result, list.nth($list, $i));
|
|
141
|
+
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Обработка случая, когда индекс вставки больше длины списка.
|
|
145
|
+
// В этом случае значение добавляется в конец списка.
|
|
146
|
+
@if $index > $-length {
|
|
147
|
+
|
|
148
|
+
// Выводим предупреждение о том, что индекс превышает длину списка.
|
|
149
|
+
// Это помогает обнаружить потенциальные ошибки в логике программы.
|
|
150
|
+
@warn '$index (#{$index}) > $-length (#{$-length}): Индекс больше длины списка. Значение будет добавлено в конец!';
|
|
151
|
+
|
|
152
|
+
// Добавляем значение в конец списка результата.
|
|
153
|
+
$-result: list.append($-result, $value);
|
|
154
|
+
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Возвращаем новый список с вставленным значением.
|
|
158
|
+
// Если индекс был в пределах длины списка, значение вставлено
|
|
159
|
+
// на указанную позицию. Если индекс превышал длину, значение
|
|
160
|
+
// добавлено в конец. Если индекс меньше 1, поведение не определено
|
|
161
|
+
// (в текущей реализации значение не будет добавлено).
|
|
162
|
+
@return $-result;
|
|
163
|
+
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
@use 'sass:list';
|
|
2
|
+
|
|
3
|
+
/// Объединяет несколько списков в один плоский список.
|
|
4
|
+
///
|
|
5
|
+
/// Функция принимает произвольное количество списков и
|
|
6
|
+
/// объединяет их элементы в единый результирующий список.
|
|
7
|
+
/// Порядок элементов сохраняется: сначала идут все элементы
|
|
8
|
+
/// первого списка, затем второго, и так далее.
|
|
9
|
+
///
|
|
10
|
+
/// Важные особенности:
|
|
11
|
+
/// - Функция не выполняет рекурсивное разворачивание вложенных
|
|
12
|
+
/// списков
|
|
13
|
+
/// - Не удаляет дубликаты (используйте list-dedupe() при
|
|
14
|
+
/// необходимости)
|
|
15
|
+
/// - Сохраняет порядок элементов
|
|
16
|
+
/// - Использует локальные переменные с префиксом `$-` для
|
|
17
|
+
/// избежания конфликтов
|
|
18
|
+
/// - Аналогична `list.join()`, но поддерживает произвольное
|
|
19
|
+
/// количество аргументов
|
|
20
|
+
/// ---
|
|
21
|
+
/// @name list-merge
|
|
22
|
+
/// @group utilities-helpers
|
|
23
|
+
/// @since 2025.12.27
|
|
24
|
+
/// @access public
|
|
25
|
+
/// @author Murad Rustamov (therteenten)
|
|
26
|
+
/// @link https://sourcecraft.dev/users/therteenten/overview SourceCraft - therteenten
|
|
27
|
+
/// @link https://sourcecraft.dev/omnisass/library SourceCraft - OmniSass
|
|
28
|
+
/// @link https://sass-lang.com/documentation/modules/list#join См. также: Официальная документация Sass - Функция list.join()
|
|
29
|
+
/// @link https://sass-lang.com/documentation/values/lists См. также: Официальная документация Sass - Тип данных "Списки"
|
|
30
|
+
/// @link https://sass-lang.com/documentation/at-rules/function#taking-arbitrary-arguments См. также: Документация Sass - Функции с произвольными аргументами
|
|
31
|
+
/// @link https://stackoverflow.com/questions/21832031/how-can-i-merge-multiple-lists-together-in-sass См. также: Stack Overflow - Как объединить несколько списков в Sass
|
|
32
|
+
/// @link https://css-tricks.com/snippets/sass/ См. также: CSS-Tricks - Коллекция сниппетов Sass
|
|
33
|
+
/// @link https://sass-guidelin.es/ru/#list-functions См. также: Sass Guidelines - Функции для работы со списками
|
|
34
|
+
/// @link https://frontender.info/sass-lists/ См. также: Frontender Magazine - Работа со списками в Sass
|
|
35
|
+
/// @link https://www.w3schools.com/sass/sass_functions_list.php См. также: W3Schools - Функции для работы со списками в Sass
|
|
36
|
+
/// @link https://habr.com/ru/post/156549/ См. также: Habr - Статья "Sass для верстальщика: списки и циклы"
|
|
37
|
+
/// @example scss - Объединение двух списков
|
|
38
|
+
/// $list1: a, b, c;
|
|
39
|
+
/// $list2: d, e, f;
|
|
40
|
+
/// @debug list-merge($list1, $list2); // (a, b, c, d, e, f);
|
|
41
|
+
/// @example scss - Объединение трех списков
|
|
42
|
+
/// $colors: red, blue;
|
|
43
|
+
/// $sizes: small, medium, large;
|
|
44
|
+
/// $shapes: circle, square;
|
|
45
|
+
/// @debug list-merge($colors, $sizes, $shapes); // (red, blue, small, medium, large, circle, square)
|
|
46
|
+
/// @example scss - Объединение списков разных типов
|
|
47
|
+
/// @debug list-merge((1, 2, 3), (a, b, c), (true, false)); // (1, 2, 3, a, b, c, true, false)
|
|
48
|
+
/// @example scss - Объединение вложенных списков (без рекурсии)
|
|
49
|
+
/// $nested: ((1, 2), (3, 4));
|
|
50
|
+
/// @debug list-merge($nested); // ((1, 2), (3, 4));
|
|
51
|
+
/// @example scss - Объединение пустых списков
|
|
52
|
+
/// @debug list-merge((), (a, b), ()); // (a, b)
|
|
53
|
+
/// @debug list-merge(); // ()
|
|
54
|
+
/// @example scss - Использование в CSS функциях
|
|
55
|
+
/// $transition-props: opacity, transform;
|
|
56
|
+
/// $transition-durations: 0.3s, 0.5s;
|
|
57
|
+
///
|
|
58
|
+
/// .test {
|
|
59
|
+
/// transition: list-merge($transition-props, $transition-durations); // transition: opacity, transform, 0.3s, 0.5s;
|
|
60
|
+
/// }
|
|
61
|
+
/// @example css - Результат
|
|
62
|
+
/// .test {
|
|
63
|
+
/// transition: opacity transform 0.3s 0.5s;
|
|
64
|
+
/// }
|
|
65
|
+
/// @param {ArgList} $lists... - Произвольное количество
|
|
66
|
+
/// списков для объединения. Каждый аргумент должен быть
|
|
67
|
+
/// списком. Функция использует `arglist` для поддержки
|
|
68
|
+
/// переменного числа аргументов.
|
|
69
|
+
/// @return {List} - Новый список, содержащий все элементы из
|
|
70
|
+
/// входных списков в порядке их следования. Если ни одного
|
|
71
|
+
/// списка не передано, возвращается пустой список `()`.
|
|
72
|
+
/// @throws Не выбрасывает ошибок, но если передать не список,
|
|
73
|
+
/// элемент будет добавлен как есть (не рекомендуется).
|
|
74
|
+
@function list-merge($lists...) {
|
|
75
|
+
|
|
76
|
+
$-result: ();
|
|
77
|
+
|
|
78
|
+
@each $-list in $lists {
|
|
79
|
+
@each $-item in $-list {
|
|
80
|
+
$-result: list.append($-result, $-item);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@return $-result;
|
|
85
|
+
|
|
86
|
+
}
|