PluginProbe
Elementor Website Builder – more than just a page builder / 3.27.0-dev2
Elementor Website Builder – more than just a page builder v3.27.0-dev2
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / modules / atomic-widgets / styles / styles-renderer.php

styles-renderer.php in Elementor Website Builder – more than just a page builder 3.27.0-dev2, at modules/atomic-widgets/styles/styles-renderer.php

143 lines 3.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Elementor\Modules\AtomicWidgets\Styles;
4
5 use Elementor\Core\Utils\Collection;
6 use Elementor\Modules\AtomicWidgets\PropsResolver\Props_Resolver;
7
8 class Styles_Renderer {
9 /**
10 * @var array<string, array{direction: 'min' | 'max', value: int, is_enabled: boolean}> $breakpoints
11 */
12 private array $breakpoints;
13
14 /**
15 * Styles_Renderer constructor.
16 *
17 * @param array{
18 * breakpoints: array<string, array{direction: 'min' | 'max', value: int, is_enabled: boolean}>
19 * } $config
20 */
21 public function __construct( array $config ) {
22 $this->breakpoints = $config['breakpoints'];
23 }
24
25 public static function make( array $config ): self {
26 return new self( $config );
27 }
28
29 /**
30 * Render the styles to a CSS string.
31 *
32 * @param array<int, array{
33 * id: string,
34 * type: string,
35 * variants: array<int, array{
36 * props: array<string, mixed>,
37 * meta: array<string, mixed>
38 * }>
39 * }> $styles Array of style definitions.
40 *
41 * @return string Rendered CSS string.
42 */
43 public function render( array $styles ): string {
44 $css_style = [];
45
46 foreach ( $styles as $style_def ) {
47 $style = $this->style_definition_to_css_string( $style_def );
48 $css_style[] = $style;
49 }
50
51 return implode( '', $css_style );
52 }
53
54 private function style_definition_to_css_string( array $style ): string {
55 $base_selector = $this->get_base_selector( $style );
56
57 if ( ! $base_selector ) {
58 return '';
59 }
60
61 $stylesheet = [];
62
63 foreach ( $style['variants'] as $variant ) {
64 $style_declaration = $this->variant_to_css_string( $base_selector, $variant );
65
66 if ( $style_declaration ) {
67 $stylesheet[] = $style_declaration;
68 }
69 }
70
71 return implode( '', $stylesheet );
72 }
73
74 private function get_base_selector( array $style_def ): ?string {
75 $map = [
76 'class' => '.',
77 ];
78
79 if (
80 isset( $style_def['type'] ) &&
81 isset( $style_def['id'] ) &&
82 isset( $map[ $style_def['type'] ] ) &&
83 $style_def['id']
84 ) {
85 return $map[ $style_def['type'] ] . $style_def['id'];
86 }
87
88 return null;
89 }
90
91 private function variant_to_css_string( string $base_selector, array $variant ): string {
92 $css = $this->props_to_css_string( $variant['props'] );
93
94 if ( ! $css ) {
95 return '';
96 }
97
98 $state = isset( $variant['meta']['state'] ) ? ':' . $variant['meta']['state'] : '';
99 $selector = $base_selector . $state;
100
101 $style_declaration = $selector . '{' . $css . '}';
102
103 if ( isset( $variant['meta']['breakpoint'] ) ) {
104 $style_declaration = $this->wrap_with_media_query( $variant['meta']['breakpoint'], $style_declaration );
105 }
106
107 return $style_declaration;
108 }
109
110 private function props_to_css_string( array $props ): string {
111 $schema = Style_Schema::get();
112
113 return Collection::make( Props_Resolver::for_styles()->resolve( $schema, $props ) )
114 ->filter()
115 ->map( function ( $value, $prop ) {
116 return $prop . ':' . $value . ';';
117 } )
118 ->implode( '' );
119 }
120
121 private function wrap_with_media_query( string $breakpoint_id, string $css ): string {
122 if ( ! isset( $this->breakpoints[ $breakpoint_id ] ) ) {
123 return $css;
124 }
125
126 $breakpoint = $this->breakpoints[ $breakpoint_id ];
127 if ( isset( $breakpoint['is_enabled'] ) && ! $breakpoint['is_enabled'] ) {
128 return '';
129 }
130
131 $size = $this->get_breakpoint_size( $this->breakpoints[ $breakpoint_id ] );
132
133 return $size ? '@media(' . $size . '){' . $css . '}' : $css;
134 }
135
136 private function get_breakpoint_size( array $breakpoint ): ?string {
137 $bound = 'min' === $breakpoint['direction'] ? 'min-width' : 'max-width';
138 $width = $breakpoint['value'] . 'px';
139
140 return "{$bound}:{$width}";
141 }
142 }
143