iwgt 2.4.11 → 2.4.13

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.
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Генератор меню категорий
3
+ */
4
+ import type { CollectionsMenuResult } from './types.js';
5
+ /**
6
+ * Генерирует код меню категорий на основе выбранного паттерна
7
+ */
8
+ export declare function generateCollectionsMenu(args: {
9
+ patternId: string;
10
+ customSettings?: any;
11
+ cssPrefix?: string;
12
+ }): CollectionsMenuResult;
13
+ //# sourceMappingURL=collections-menu.d.ts.map
@@ -0,0 +1,268 @@
1
+ /**
2
+ * Генератор меню категорий
3
+ */
4
+ /**
5
+ * Генерирует код меню категорий на основе выбранного паттерна
6
+ */
7
+ export function generateCollectionsMenu(args) {
8
+ // Импортируем паттерны
9
+ const collectionsMenuPatterns = {
10
+ patterns: [
11
+ {
12
+ id: 'two_level_hierarchical',
13
+ cacheKeyPattern: 'cache_menu_key_{{ widget_drop.list_item_id }}_{{ collections.last_updated_at }}_{{ language.locale }}_{{ custom_params }}',
14
+ requiredSettings: [
15
+ {
16
+ handle: 'subcollections-items-limit',
17
+ type: 'to_integer',
18
+ default: 10,
19
+ description: 'Ограничение количества подкатегорий для отображения'
20
+ },
21
+ {
22
+ handle: 'hide-menu-photo',
23
+ type: 'checkbox',
24
+ default: false,
25
+ description: 'Скрыть фотографии категорий'
26
+ },
27
+ {
28
+ handle: 'hide-counts',
29
+ type: 'checkbox',
30
+ default: false,
31
+ description: 'Скрыть счетчики товаров'
32
+ }
33
+ ],
34
+ liquidCode: `{% assign subcollections_items_limit = widget_settings.subcollections-items-limit | to_integer %}
35
+ {% capture cache_menu_key %}cache_menu_key_{{ collections.last_updated_at }}_{{ language.locale }}_{{ widget_settings.hide-menu-photo }}_{{ widget_settings.subcollections-items-limit }}{% endcapture %}
36
+
37
+ <ul class="menu" data-navigation data-subcollections-items-limit={{subcollections_items_limit}}>
38
+ {% cache cache_menu_key %}
39
+ {% assign level_1 = collections.root_category.subcollections %}
40
+ {% for level_1_item in level_1 %}
41
+ {% assign level_2 = level_1_item.subcollections %}
42
+
43
+ <li class="menu__item is-level-1" data-navigation-item>
44
+ <div class="menu__controls">
45
+ <a href="{{ level_1_item.url }}" class="menu__link" data-navigation-link="{{ level_1_item.url }}">
46
+ {{ level_1_item.title }}
47
+ </a>
48
+
49
+ {% if level_2.size > 0 %}
50
+ <button class="menu__show-submenu-btn" type="button">
51
+ <i class="icon icon-angle-down"></i>
52
+ </button>
53
+ {% endif %}
54
+ </div>
55
+
56
+ {% if level_2.size > 0 %}
57
+ <ul class="menu__submenu" data-navigation-submenu>
58
+ {% for level_2_item in level_2 %}
59
+ <li class="menu__item {%if forloop.index > subcollections_items_limit %}is-hide{% endif%}" data-navigation-item>
60
+ <div class="menu__controls">
61
+ <a href="{{ level_2_item.url }}" class="menu__link" data-navigation-link="{{ level_2_item.url }}">
62
+ {{ level_2_item.title }}
63
+ {% if editor_mode? or widget_settings.hide-counts != true %}
64
+ {% if level_2_item.products_count > 0 %}
65
+ <span class="menu__item-count">{{ level_2_item.products_count }}</span>
66
+ {% endif %}
67
+ {% endif %}
68
+ </a>
69
+ </div>
70
+ </li>
71
+ {% endfor %}
72
+ </ul>
73
+ {% endif %}
74
+ </li>
75
+ {% endfor %}
76
+ {% endcache %}
77
+ </ul>`
78
+ },
79
+ {
80
+ id: 'multi_level_flatten',
81
+ cacheKeyPattern: 'cache_menu_key_{{ widget_drop.list_item_id }}_{{ collections.last_updated_at }}_{{ language.locale }}_{{ level_limit }}',
82
+ requiredSettings: [
83
+ {
84
+ handle: 'level-limit',
85
+ type: 'to_integer',
86
+ default: 3,
87
+ description: 'Максимальная глубина вложенности меню'
88
+ }
89
+ ],
90
+ liquidCode: `{% assign level_limit = widget_settings.level-limit | default: 3 | to_integer %}
91
+ {% capture cache_menu_key %}cache_menu_key_{{ collections.last_updated_at }}_{{ language.locale }}_{{ level_limit }}{% endcapture %}
92
+ {% assign prev_link_level = 1 %}
93
+
94
+ <ul class="menu" data-navigation>
95
+ {% cache cache_menu_key %}
96
+ {% assign root_level = collections.root_category.level %}
97
+ {% for link in collections.root_category.flatten_branch %}
98
+ {% assign node_level = link.level | minus: root_level %}
99
+ {% assign _in_limit = level_limit | minus: node_level %}
100
+ {% assign _next_level_in_limit = _in_limit | minus: 1 %}
101
+
102
+ {% assign show_level = false %}
103
+ {% if _in_limit >= 0 %}
104
+ {% assign show_level = true %}
105
+ {% endif %}
106
+
107
+ {% assign show_next_level = false %}
108
+ {% if link.subcollections.size > 0 and _next_level_in_limit >= 0 %}
109
+ {% assign show_next_level = true %}
110
+ {% endif %}
111
+
112
+ {% if show_level %}
113
+ {% assign level_difference = prev_link_level | minus: link.level | plus: root_level %}
114
+
115
+ {% if level_difference > 0 %}
116
+ {% for i in (1..level_difference) %}
117
+ {% unless forloop.first %}</li>{% endunless %}
118
+ </ul>
119
+ {% endfor %}
120
+ </li>
121
+ {% endif %}
122
+
123
+ <li class="menu__item" data-navigation-item>
124
+ <div class="menu__controls {% if show_next_level %}with-submenu{% endif %}">
125
+ <a href="{{ link.url }}" class="menu__link" data-navigation-link="{{ link.url }}">
126
+ {{ link.title }}
127
+ </a>
128
+
129
+ {% if show_next_level %}
130
+ <button class="menu__show-submenu-btn" type="button">
131
+ <i class="icon icon-angle-down"></i>
132
+ </button>
133
+ {% endif %}
134
+ </div>
135
+
136
+ {% if show_next_level %}
137
+ <ul class="menu__submenu" data-navigation-submenu>
138
+ {% endif %}
139
+
140
+ {% assign prev_link_level = node_level %}
141
+
142
+ {% unless show_next_level %}
143
+ </li>
144
+ {% endunless %}
145
+
146
+ {% if forloop.last %}
147
+ {% assign prev_link_level = node_level | minus: 1 %}
148
+ {% for i in (1..prev_link_level) %}
149
+ </ul>
150
+ {% endfor %}
151
+ {% endif %}
152
+ {% endif %}
153
+ {% endfor %}
154
+ {% endcache %}
155
+ </ul>`
156
+ },
157
+ {
158
+ id: 'simple_subcollections',
159
+ cacheKeyPattern: 'cache_menu_key_{{ widget_drop.list_item_id }}_{{ collections.last_updated_at }}_{{ language.locale }}_{{ collection_handle }}',
160
+ requiredSettings: [
161
+ {
162
+ handle: 'collection-handle',
163
+ type: 'string',
164
+ default: '',
165
+ description: 'Handle категории (по умолчанию root_category)'
166
+ }
167
+ ],
168
+ liquidCode: `{% capture cache_menu_key %}cache_menu_key_{{ collections.last_updated_at }}_{{ language.locale }}_{{ widget_settings.collection-handle }}{% endcapture %}
169
+ {% cache cache_menu_key %}
170
+ {% assign source_handle = widget_settings.collection-handle | default: collections.root_category.handle %}
171
+ {% assign collection_list = collections[source_handle].subcollections %}
172
+ {% if collection_list.size > 0 %}
173
+ <div class="menu-wrapper">
174
+ <ul class="menu" data-navigation>
175
+ {% for collection_item in collection_list %}
176
+ <li class="menu__item" data-navigation-item>
177
+ <div class="menu__controls">
178
+ <a href="{{ collection_item.url }}" class="menu__link" data-navigation-link="{{ collection_item.url }}">
179
+ {{ collection_item.title }}
180
+ </a>
181
+ </div>
182
+ </li>
183
+ {% endfor %}
184
+ </ul>
185
+ </div>
186
+ {% endif %}
187
+ {% endcache %}`
188
+ },
189
+ {
190
+ id: 'flat_collections_list',
191
+ cacheKeyPattern: 'cache_menu_key_{{ widget_drop.list_item_id }}_{{ collections.last_updated_at }}_{{ language.locale }}',
192
+ requiredSettings: [],
193
+ liquidCode: `{% capture cache_menu_key %}cache_menu_key_{{ collections.last_updated_at }}_{{ language.locale }}{% endcapture %}
194
+ {% cache cache_menu_key %}
195
+ {% if collections.root_category.subcollections.size > 0 %}
196
+ <div class="menu-wrapper" data-navigation>
197
+ {% for collection in collections %}
198
+ {% if collection.products_count > 0 %}
199
+ <div class="menu__item" data-navigation-item>
200
+ <a class="menu__link" href="{{ collection.url }}" data-navigation-link="{{ collection.url }}">
201
+ <span class="menu__title">{{ collection.title }}</span>
202
+ </a>
203
+ </div>
204
+ {% endif %}
205
+ {% endfor %}
206
+ </div>
207
+ {% endif %}
208
+ {% endcache %}`
209
+ },
210
+ {
211
+ id: 'tree_structure_flatten',
212
+ cacheKeyPattern: 'cache_menu_key_{{ widget_drop.list_item_id }}_{{ collections.last_updated_at }}_{{ language.locale }}',
213
+ requiredSettings: [],
214
+ liquidCode: `{% capture cache_menu_key %}cache_menu_key_{{ collections.last_updated_at }}_{{ language.locale }}{% endcapture %}
215
+ {% cache cache_menu_key %}
216
+ {% for collection in collections.flatten %}
217
+ {% if collection.first? %}<ul class="menu" data-navigation>{% endif %}
218
+ {% if collection.show? %}
219
+ <li class="menu__item" data-navigation-item>
220
+ <a href="{{ collection.url }}" class="menu__link" data-navigation-link="{{ collection.url }}">
221
+ {{ collection.title }}
222
+ </a>
223
+ </li>
224
+ {% endif %}
225
+ {% if collection.last? %}
226
+ {% for i in (1..collection.level_difference) %}</ul>{% endfor %}
227
+ {% endif %}
228
+ {% endfor %}
229
+ {% endcache %}`
230
+ }
231
+ ]
232
+ };
233
+ const { patternId, customSettings = {}, cssPrefix = 'menu' } = args;
234
+ // Находим паттерн
235
+ const pattern = collectionsMenuPatterns.patterns.find(p => p.id === patternId);
236
+ if (!pattern) {
237
+ throw new Error(`Паттерн меню "${patternId}" не найден. Доступные: ${collectionsMenuPatterns.patterns.map(p => p.id).join(', ')}`);
238
+ }
239
+ // Применяем кастомный CSS префикс если задан
240
+ let liquidCode = pattern.liquidCode;
241
+ if (cssPrefix !== 'menu') {
242
+ liquidCode = liquidCode.replace(/class="menu/g, `class="${cssPrefix}`);
243
+ }
244
+ // Объединяем настройки
245
+ const requiredSettings = [...pattern.requiredSettings];
246
+ if (customSettings && Object.keys(customSettings).length > 0) {
247
+ Object.entries(customSettings).forEach(([key, value]) => {
248
+ requiredSettings.push({
249
+ handle: key,
250
+ type: 'string',
251
+ default: value,
252
+ description: `Custom setting: ${key}`
253
+ });
254
+ });
255
+ }
256
+ return {
257
+ liquidCode,
258
+ requiredSettings,
259
+ cssPrefix,
260
+ dataAttributes: [
261
+ { name: 'data-navigation', description: 'Основной контейнер навигации' },
262
+ { name: 'data-navigation-item', description: 'Элемент навигации' },
263
+ { name: 'data-navigation-link', description: 'Ссылка навигации' },
264
+ { name: 'data-navigation-submenu', description: 'Подменю' }
265
+ ]
266
+ };
267
+ }
268
+ //# sourceMappingURL=collections-menu.js.map
@@ -1,110 +1,21 @@
1
1
  /**
2
2
  * Генераторы файлов виджетов
3
- * Модуль содержит функции для генерации содержимого файлов виджета
4
- */
5
- import type { BlockTemplate } from '../types/index.js';
6
- export interface WidgetConfig {
7
- handle: string;
8
- category: string;
9
- type: string;
10
- description: string;
11
- blockTemplate?: BlockTemplate;
12
- libraries: string[];
13
- commonSettings: any[];
14
- }
15
- /**
16
- * Генерирует имя виджета из описания
17
- */
18
- export declare function generateWidgetName(description: string): string;
19
- /**
20
- * Генерирует info.json
21
- */
22
- export declare function generateInfoJson(config: WidgetConfig): Record<string, any>;
23
- /**
24
- * Генерирует messages.json
25
- * Использует только те ключи, которых нет в глобальных messages
26
- * Глобальные ключи: background, indentation, content, adaptive, widget_background_color,
27
- * wide_background, wide_content, padding_top, padding_bottom, content_max_width,
28
- * remove_padding_at_edges, hide_desktop, hide_mobile и другие
29
- */
30
- export declare function generateMessages(description: string): Record<string, any>;
31
- /**
32
- * Генерирует settings_data.json
33
- */
34
- export declare function generateSettingsData(commonSettings: any[]): Record<string, any>;
35
- /**
36
- * Генерирует settings_form.json
37
- * Структура согласно документации:
38
- * - content: специфичные настройки виджета
39
- * - design: типовые настройки (фон, отступы, адаптивность)
40
- */
41
- export declare function generateSettingsForm(commonSettings: any[]): {
42
- form: Record<string, any[]>;
43
- count: number;
44
- };
45
- /**
46
- * Генерирует snippet.liquid
47
- * ВАЖНО: Код автоматически оборачивается системой в div.layout с CSS-переменными
48
- * НЕ добавляйте обёртку layout вручную!
49
- */
50
- export declare function generateSnippetLiquid(config: WidgetConfig): string;
51
- /**
52
- * Генерирует snippet.scss
53
- * ВАЖНО: Весь код оборачивается в класс виджета
54
- * Используйте & для обращения к родительскому элементу (layout + класс виджета)
55
- */
56
- export declare function generateSnippetScss(config: WidgetConfig): string;
57
- /**
58
- * Генерирует snippet.js
59
- * ВАЖНО:
60
- * - Код автоматически оборачивается в try/catch
61
- * - Доступны переменные: widget (селектор) и $widget (jQuery объект)
62
- * - НЕ используйте Vue.js или другие фреймворки!
63
- * - На странице может быть несколько экземпляров виджета - используйте $widget.each()
64
- */
65
- export declare function generateSnippetJs(config: WidgetConfig): string;
66
- /**
67
- * Генерирует setup.json для block_list_widget_type
68
- */
69
- export declare function generateSetupJson(blockTemplate: BlockTemplate): Record<string, any>;
70
- /**
71
- * Генерирует код меню категорий на основе выбранного паттерна
72
- */
73
- export declare function generateCollectionsMenu(args: {
74
- patternId: string;
75
- customSettings?: any;
76
- cssPrefix?: string;
77
- }): {
78
- liquidCode: string;
79
- requiredSettings: any[];
80
- cssPrefix: string;
81
- dataAttributes: any[];
82
- };
3
+ * Главный модуль для экспорта всех функций генерации
4
+ */
5
+ import type { WidgetConfig, ValidationError, ValidationResult, FixResult, CollectionsMenuResult, SettingsFormResult } from './types.js';
6
+ import { generateWidgetName, generateInfoJson, generateMessages } from './info-generator.js';
7
+ import { generateSettingsData, generateSettingsForm } from './settings-generator.js';
8
+ import { generateSnippetLiquid, generateSnippetScss, generateSnippetJs, generateSetupJson } from './snippet-generator.js';
9
+ import { validateLiquidFilters, fixInvalidFilters } from './validation.js';
10
+ import { generateCollectionsMenu } from './collections-menu.js';
11
+ export type { WidgetConfig, ValidationError, ValidationResult, FixResult, CollectionsMenuResult, SettingsFormResult };
12
+ export { generateWidgetName, generateInfoJson, generateMessages };
13
+ export { generateSettingsData, generateSettingsForm };
14
+ export { generateSnippetLiquid, generateSnippetScss, generateSnippetJs, generateSetupJson };
15
+ export { validateLiquidFilters, fixInvalidFilters };
16
+ export { generateCollectionsMenu };
83
17
  /**
84
18
  * Генерирует все файлы виджета
85
19
  */
86
- export declare function generateWidgetFiles(config: WidgetConfig): Record<string, any>;
87
- /**
88
- * Валидирует Liquid код на наличие несуществующих фильтров
89
- */
90
- export declare function validateLiquidFilters(liquidCode: string): {
91
- isValid: boolean;
92
- errors: Array<{
93
- filter: string;
94
- line: number;
95
- column: number;
96
- suggestion: string;
97
- }>;
98
- };
99
- /**
100
- * Проверяет и исправляет несуществующие фильтры в Liquid коде
101
- */
102
- export declare function fixInvalidFilters(liquidCode: string): {
103
- fixedCode: string;
104
- fixes: Array<{
105
- filter: string;
106
- line: number;
107
- suggestion: string;
108
- }>;
109
- };
20
+ export declare function generateWidgetFiles(config: WidgetConfig, cleanMode?: boolean): Record<string, any>;
110
21
  //# sourceMappingURL=index.d.ts.map