PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.3.17
UiCore Elements – Free widgets and templates for Elementor v1.3.17
1.3.17 1.3.16 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 All 41 releases
uicore-elements / includes / widgets / custom-table.php

custom-table.php in UiCore Elements – Free widgets and templates for Elementor 1.3.17, at includes/widgets/custom-table.php

465 lines 14.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace UiCoreElements;
4
5 use Elementor\Plugin;
6 use Elementor\Controls_Manager;
7 use Elementor\Repeater;
8 use Elementor\Modules\NestedElements\Controls\Control_Nested_Repeater;
9 use UiCoreElements\Utils\Animation_Trait;
10
11 defined('ABSPATH') || exit();
12
13 class CustomTable extends UiCoreNestedWidget
14 {
15
16 use Animation_Trait;
17
18 public function get_name()
19 {
20 return 'uicore-custom-table';
21 }
22 public function get_title()
23 {
24 return esc_html__('Custom Table', 'uicore-elements');
25 }
26 public function get_icon()
27 {
28 return 'eicon-table ui-e-widget';
29 }
30 public function get_categories()
31 {
32 return ['uicore'];
33 }
34 public function get_keywords()
35 {
36 return ['slide', 'table', 'nested'];
37 }
38 public function get_styles()
39 {
40 return ['custom-table'];
41 }
42 public function get_scripts()
43 {
44 return [];
45 }
46 public function has_widget_inner_wrapper(): bool
47 {
48 // TODO: remove after Optmized Markup experiment is merged to the core
49 return ! \Elementor\Plugin::$instance->experiments->is_feature_active('e_optimized_markup');
50 }
51
52 protected function carousel_content_container(int $index)
53 {
54 return [
55 'elType' => 'container',
56 'settings' => [
57 /* translators: %s: Item index */
58 '_title' => sprintf(__('Cel #%s', 'uicore-elements'), $index),
59 'content_width' => 'full',
60 ],
61 ];
62 }
63
64 protected function get_default_children_elements()
65 {
66 return [
67 $this->carousel_content_container(1),
68 $this->carousel_content_container(2),
69 $this->carousel_content_container(3),
70 ];
71 }
72
73 protected function get_default_repeater_title_setting_key()
74 {
75 return 'item';
76 }
77
78 protected function get_default_children_title()
79 {
80 /* translators: %d: Item index */
81 return esc_html__('Cel #%d', 'uicore-elements');
82 }
83 protected function get_default_children_placeholder_selector()
84 {
85 return '.ui-e-table';
86 }
87
88 protected function get_default_children_container_placeholder_selector()
89 {
90 return '.ui-e-table-editor-placeholder';
91 }
92
93 protected function register_controls()
94 {
95 if (!Plugin::$instance->experiments->is_feature_active('nested-elements')) {
96 $this->nesting_fallback('controls');
97 return;
98 }
99
100 $this->start_controls_section(
101 'section_content',
102 [
103 'label' => __('Items', 'uicore-elements'),
104 'tab' => Controls_Manager::TAB_CONTENT,
105 ]
106 );
107
108 $this->add_control(
109 'rerender_table',
110 [
111 'label' => esc_html__('Preview', 'uicore-elements'),
112 'type' => Controls_Manager::BUTTON,
113 'text' => esc_html__('Refresh Table', 'uicore-elements'),
114 'separator' => 'before',
115 'event' => 'ui-e-custom-table-rerender',
116 ]
117 );
118
119 //Columns
120 $columns = new Repeater();
121 $columns->add_responsive_control(
122 'col_size',
123 [
124 'label' => __('Column Size', 'uicore-elements'),
125 'type' => Controls_Manager::SLIDER,
126 'size_units' => ['px', 'fr', 'custom'],
127 'default' => [
128 'size' => 300,
129 'unit' => 'px',
130 ],
131 'range' => [
132 'px' => [
133 'min' => 1,
134 'max' => 1200,
135 ],
136 'fr' => [
137 'min' => 1,
138 'max' => 12,
139 ],
140 ],
141 'render_type' => 'ui',
142 'selectors' => [
143 '{{WRAPPER}}' => '--ui-e-last:{{SIZE}}{{UNIT}};',
144 ],
145 ]
146 );
147
148 $this->add_control(
149 'columns',
150 [
151 'type' => Controls_Manager::REPEATER,
152 'fields' => $columns->get_controls(),
153 'title_field' => 'Column',
154 'render_type' => 'ui',
155 'default' => [
156 ['col_size' => ['size' => 1, 'unit' => 'fr']],
157 ['col_size' => ['size' => 1, 'unit' => 'fr']],
158 ['col_size' => ['size' => 1, 'unit' => 'fr']],
159 ],
160 ]
161 );
162
163
164
165 //Cells
166 $repeater = new Repeater();
167 $repeater->add_control(
168 'item',
169 [
170 'label' => __('Title', 'uicore-elements'),
171 'type' => Controls_Manager::TEXT,
172 'render_type' => 'ui'
173 ]
174 );
175
176 $this->add_control(
177 'cells',
178 [
179 'type' => Control_Nested_Repeater::CONTROL_TYPE,
180 'fields' => $repeater->get_controls(),
181 'title_field' => '{{{ item }}}',
182 'allow_empty' => false,
183 'default' => [
184 ['item' => __('Cel #1', 'uicore-elements')],
185 ['item' => __('Cel #2', 'uicore-elements')],
186 ['item' => __('Cel #3', 'uicore-elements')],
187 ],
188 ]
189 );
190
191 $this->end_controls_section();
192
193
194 //style
195 $this->start_controls_section(
196 'section_table_style',
197 [
198 'label' => __('Table Style', 'uicore-elements'),
199 'tab' => Controls_Manager::TAB_STYLE,
200 ]
201 );
202
203 $this->start_controls_tabs(
204 'row_tabs'
205 );
206
207 $this->start_controls_tab(
208 'odd_row',
209 [
210 'label' => esc_html__('Odd row', 'textdomain'),
211 ]
212 );
213
214 $this->add_control(
215 'odd_row_bg_color',
216 [
217 'label' => __('Row background', 'uicore-elements'),
218 'type' => Controls_Manager::COLOR,
219 'selectors' => [
220 '{{WRAPPER}} .ui-e-table > .ui-e-odd' => 'background-color: {{VALUE}};',
221 ],
222 ]
223 );
224
225 $this->add_control(
226 'odd_row_padding',
227 [
228 'label' => esc_html__('Row Padding', 'uicore-elements'),
229 'type' => Controls_Manager::DIMENSIONS,
230 'size_units' => ['px', 'em', 'rem', 'custom'],
231 'selectors' => [
232 "{{WRAPPER}} .ui-e-table > .ui-e-odd" => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
233 ],
234 ]
235 );
236
237 $this->add_control(
238 'odd_row_radius',
239 [
240 'label' => esc_html__('Row Border Radius', 'uicore-elements'),
241 'type' => Controls_Manager::DIMENSIONS,
242 'size_units' => ['px', 'em', 'rem', 'custom'],
243 'selectors' => [
244 "{{WRAPPER}} .ui-e-table > .ui-e-odd.ui-e-first-row-cel" => 'border-radius: {{TOP}}{{UNIT}} 0 0 {{LEFT}}{{UNIT}};',
245 "{{WRAPPER}} .ui-e-table > .ui-e-odd.ui-e-last-row-cel" => 'border-radius: 0 {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} 0;'
246 ],
247 ]
248 );
249
250 $this->end_controls_tab();
251
252 $this->start_controls_tab(
253 'even_row',
254 [
255 'label' => esc_html__('Even row', 'textdomain'),
256 ]
257 );
258
259 $this->add_control(
260 'even_row_bg_color',
261 [
262 'label' => __('Row background', 'uicore-elements'),
263 'type' => Controls_Manager::COLOR,
264 'selectors' => [
265 '{{WRAPPER}} .ui-e-table > .ui-e-even' => 'background-color: {{VALUE}};',
266 ],
267 ]
268 );
269
270 $this->add_control(
271 'even_row_padding',
272 [
273 'label' => esc_html__('Row Padding', 'uicore-elements'),
274 'type' => Controls_Manager::DIMENSIONS,
275 'size_units' => ['px', 'em', 'rem', 'custom'],
276 'selectors' => [
277 "{{WRAPPER}} .ui-e-table > .ui-e-even" => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
278 ],
279 ]
280 );
281
282 $this->add_control(
283 'even_row_radius',
284 [
285 'label' => esc_html__('Row Border Radius', 'uicore-elements'),
286 'type' => Controls_Manager::DIMENSIONS,
287 'size_units' => ['px', 'em', 'rem', 'custom'],
288 'selectors' => [
289 "{{WRAPPER}} .ui-e-table > .ui-e-even.ui-e-first-row-cel" => 'border-radius: {{TOP}}{{UNIT}} 0 0 {{LEFT}}{{UNIT}};',
290 "{{WRAPPER}} .ui-e-table > .ui-e-even.ui-e-last-row-cel" => 'border-radius: 0 {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} 0;'
291 ],
292 ]
293 );
294
295 $this->end_controls_tab();
296
297 $this->end_controls_tabs();
298
299
300 $this->end_controls_section();
301 }
302
303 protected function build_grid_css($cols)
304 {
305 // Build the grid columns css
306 if ($cols) {
307 $grid_css = '';
308 $grid_columns = [];
309 $breakpoints = Plugin::$instance->breakpoints->get_active_breakpoints();
310
311 foreach ($cols as $index => $item) {
312
313 // Set desktop column size
314 $grid_columns['desktop'][] = isset($item['col_size']['size']) && isset($item['col_size']['unit'])
315 ? $item['col_size']['size'] . $item['col_size']['unit']
316 : '1fr'; // fallback
317
318 foreach ($breakpoints as $breakpoint => $object) {
319 $size_slug = 'col_size_' . $breakpoint;
320
321 // Register the current column responsive size if exists and the
322 // value is not empty, because empty values breaks the table design
323 $grid_columns[$breakpoint][] = isset($item[$size_slug]['size']) && isset($item[$size_slug]['unit'])
324 ? $item[$size_slug]['size'] . $item[$size_slug]['unit']
325 : $grid_columns['desktop'][$index];
326 }
327 }
328
329 // Generate the css variables
330 foreach ($grid_columns as $device => $values) {
331 $breakpoint = $device === 'desktop' ? '' : '-' . $device;
332 $grid_css .= '--ui-e-table-cols' . $breakpoint . ':' . implode(' ', $values) . ';';
333 }
334
335 return $grid_css;
336 }
337 }
338
339 public function render()
340 {
341 if (!Plugin::$instance->experiments->is_feature_active('nested-elements')) {
342 $this->nesting_fallback();
343 return;
344 }
345
346 $cells = $this->get_settings_for_display('cells');
347 $cols = $this->get_settings_for_display('columns');
348 $grid_css = $this->build_grid_css($cols);
349
350 // Add it to the widget wrapper
351 $this->add_render_attribute('_wrapper', ['style' => $grid_css]);
352
353 ?>
354 <div class="ui-e-table">
355 <?php
356
357 $columns = count($cols);
358
359 foreach ($cells as $index => $item) {
360 $row_class = floor($index / $columns) % 2 !== 0
361 ? 'ui-e-even'
362 : 'ui-e-odd';
363
364 // TODO: in the future experiment a nth-child approach so we don't need this first/last classes
365 // Add classes to the first and last items of each row
366 if ($index % $columns === 0) {
367 $row_class .= ' ui-e-first-row-cel';
368 } else if (($index + 1) % $columns === 0) {
369 $row_class .= ' ui-e-last-row-cel';
370 }
371
372 $this->print_child($index, ['class' => $row_class]);
373 }
374 ?>
375 </div>
376 <?php
377 }
378
379 public function print_child($index, array $atts = [])
380 {
381 $children = $this->get_children();
382
383 if (! empty($children[$index])) {
384
385 // Add custom attributes to each child container.
386 if (!empty($atts)) {
387 //$child_settings = $children[ $index ]->get_settings_for_display();
388 foreach ($atts as $key => $value) {
389 $children[$index]->add_render_attribute('_wrapper', $key, $value);
390 }
391 }
392
393 $children[$index]->print_element();
394 }
395 }
396
397 protected function get_initial_config(): array
398 {
399 if (Plugin::$instance->experiments->is_feature_active('e_nested_atomic_repeaters')) {
400 return array_merge(parent::get_initial_config(), [
401 'support_improved_repeaters' => true,
402 'node' => '.ui-e-table'
403 ]);
404 }
405
406 return parent::get_initial_config();
407 }
408
409
410 protected function content_template()
411 {
412 ?>
413 <#
414 const cols=settings.columns || [];
415 const cells=settings.cells || [];
416 const cols_qty='--ui-e-cols-qty:' + cols.length;
417
418 if ( cols ) {
419 let gridCss='' ;
420 const gridColumns={};
421 const breakpoints=elementorFrontend.config.responsive.activeBreakpoints;
422
423 _.each( cols, function( item, index ) {
424
425 if ( ! gridColumns.desktop ) {
426 gridColumns.desktop=[];
427 }
428
429 gridColumns.desktop.push( item.col_size.size + item.col_size.unit );
430
431 _.each( breakpoints, function( object, breakpoint ) {
432 const sizeSlug='col_size_' + breakpoint;
433
434 if ( item[sizeSlug] && item[sizeSlug].size ) {
435 if ( ! gridColumns[breakpoint] ) {
436 gridColumns[breakpoint]=[];
437 }
438 gridColumns[breakpoint].push( item[sizeSlug].size + item[sizeSlug].unit );
439 } else {
440 if ( ! gridColumns[breakpoint] ) {
441 gridColumns[breakpoint]=[];
442 }
443 gridColumns[breakpoint].push( item.col_size.size + item.col_size.unit );
444 }
445 });
446 });
447
448 _.each( gridColumns, function( values, device ) {
449 const breakpoint=device==='desktop' ? '' : '-' + device;
450 gridCss +='--ui-e-table-cols' + breakpoint + ':' + values.join(' ') + ' ;';
451 });
452
453 view.addRenderAttribute('table', 'data-cell-count' , cells.length);
454 view.addRenderAttribute('table', 'style' , [gridCss, cols_qty].join(' '));
455 }
456 #>
457 <div class="ui-e-table" {{{ view.getRenderAttributeString('table') }}}>
458
459 </div>
460 <div class="ui-e-table-editor-placeholder"></div>
461 <?php
462 }
463 }
464 \Elementor\Plugin::instance()->widgets_manager->register(new CustomTable());
465