PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.2.4
UiCore Elements – Free widgets and templates for Elementor v1.2.4
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.2.4, at includes/widgets/custom-table.php

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