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

436 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'][] = $this->get_option_size(
291 'col_size',
292 ['size' => 2, 'unit' => 'fr'],
293 true
294 );
295
296 foreach ($breakpoints as $breakpoint => $object) {
297 $size_slug = 'col_size_' . $breakpoint;
298
299 // Register the current column responsive size if exists and the
300 // value is not empty, because empty values breaks the table design
301 $grid_columns[$breakpoint][] = isset($item[$size_slug]['size']) && isset($item[$size_slug]['unit'])
302 ? $item[$size_slug]['size'] . $item[$size_slug]['unit']
303 : $grid_columns['desktop'][$index];
304 }
305 }
306
307 // Generate the css variables
308 foreach ($grid_columns as $device => $values) {
309 $breakpoint = $device === 'desktop' ? '' : '-' . $device;
310 $grid_css .= '--ui-e-table-cols' . $breakpoint . ':' . implode(' ', $values) . ';';
311 }
312
313 return $grid_css;
314 }
315 }
316
317 public function render()
318 {
319 if(!Plugin::$instance->experiments->is_feature_active('nested-elements')) {
320 $this->nesting_fallback();
321 return;
322 }
323
324 $cells = $this->get_settings_for_display('cells');
325 $cols = $this->get_settings_for_display('columns');
326 $grid_css = $this->build_grid_css($cols);
327
328 // Add it to the widget wrapper
329 $this->add_render_attribute('_wrapper', ['style' => $grid_css]);
330
331 ?>
332 <div class="ui-e-table">
333 <?php
334
335 $columns = count($cols);
336
337 foreach ($cells as $index => $item) {
338 $row_class = floor($index / $columns) % 2 !== 0
339 ? 'ui-e-even'
340 : 'ui-e-odd';
341
342 // TODO: in the future experiment a nth-child approach so we don't need this first/last classes
343 // Add classes to the first and last items of each row
344 if ($index % $columns === 0) {
345 $row_class .= ' ui-e-first-row-cel';
346 } else if (($index + 1) % $columns === 0) {
347 $row_class .= ' ui-e-last-row-cel';
348 }
349
350 $this->print_child($index, ['class' => $row_class]);
351 }
352 ?>
353 </div>
354 <?php
355 }
356
357 public function print_child( $index , array $atts = []) {
358 $children = $this->get_children();
359
360 if ( ! empty( $children[ $index ] ) ) {
361
362 // Add custom attributes to each child container.
363 if( !empty($atts) ){
364 //$child_settings = $children[ $index ]->get_settings_for_display();
365 foreach($atts as $key => $value){
366 $children[ $index ]->add_render_attribute( '_wrapper', $key, $value );
367 }
368 }
369
370 $children[ $index ]->print_element();
371 }
372 }
373
374 protected function get_initial_config(): array {
375 if (Plugin::$instance->experiments->is_feature_active('e_nested_atomic_repeaters')) {
376 return array_merge(parent::get_initial_config(), [
377 'support_improved_repeaters' => true,
378 'node' => '.ui-e-table'
379 ]);
380 }
381
382 return parent::get_initial_config();
383 }
384
385
386 protected function content_template() {
387 ?>
388 <#
389 const cols = settings.columns;
390 const cols_qty = '--ui-e-cols-qty:' + settings.columns.length;
391
392 if ( cols ) {
393 let gridCss = '';
394 const gridColumns = {};
395 const breakpoints = elementorFrontend.config.responsive.activeBreakpoints;
396
397 _.each( cols, function( item, index ) {
398
399 if ( ! gridColumns.desktop ) {
400 gridColumns.desktop = [];
401 }
402
403 gridColumns.desktop.push( item.col_size.size + item.col_size.unit );
404
405 _.each( breakpoints, function( object, breakpoint ) {
406 const sizeSlug = 'col_size_' + breakpoint;
407
408 if ( item[sizeSlug] && item[sizeSlug].size ) {
409 if ( ! gridColumns[breakpoint] ) {
410 gridColumns[breakpoint] = [];
411 }
412 gridColumns[breakpoint].push( item[sizeSlug].size + item[sizeSlug].unit );
413 } else {
414 if ( ! gridColumns[breakpoint] ) {
415 gridColumns[breakpoint] = [];
416 }
417 gridColumns[breakpoint].push( item.col_size.size + item.col_size.unit );
418 }
419 });
420 });
421
422 _.each( gridColumns, function( values, device ) {
423 const breakpoint = device === 'desktop' ? '' : '-' + device;
424 gridCss += '--ui-e-table-cols' + breakpoint + ':' + values.join(' ') + ';';
425 });
426
427 view.addRenderAttribute('table', 'style', [gridCss, cols_qty].join(' '));
428 }
429 #>
430 <div class="ui-e-table" {{{ view.getRenderAttributeString('table') }}}>
431
432 </div>
433 <?php
434 }
435 }
436 \Elementor\Plugin::instance()->widgets_manager->register(new CustomTable());