Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
33.33% |
9 / 27 |
|
11.11% |
1 / 9 |
CRAP | |
0.00% |
0 / 1 |
AccordionBuilder | |
33.33% |
9 / 27 |
|
11.11% |
1 / 9 |
46.85 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setId | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setTitle | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
setDescription | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setContentText | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setContentHtml | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setOpen | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
setAttributes | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
build | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * AccordionBuilder.php |
4 | * |
5 | * This file is part of the Codex design system, the official design system |
6 | * for Wikimedia projects. It provides the `Accordion` class, a builder for constructing |
7 | * accordion components using the Codex design system. |
8 | * |
9 | * An Accordion is an expandable and collapsible section of content, often featured in a |
10 | * vertically stacked list with other Accordions. Accordions are commonly used to organize |
11 | * content into collapsed sections, making the interface easier to navigate. |
12 | * |
13 | * @category Builder |
14 | * @package Codex\Builder |
15 | * @since 0.1.0 |
16 | * @author Doğu Abaris <abaris@null.net> |
17 | * @license https://www.gnu.org/copyleft/gpl.html GPL-2.0-or-later |
18 | * @link https://doc.wikimedia.org/codex/main/ Codex Documentation |
19 | */ |
20 | |
21 | namespace Wikimedia\Codex\Builder; |
22 | |
23 | use InvalidArgumentException; |
24 | use Wikimedia\Codex\Component\Accordion; |
25 | use Wikimedia\Codex\Component\HtmlSnippet; |
26 | use Wikimedia\Codex\Renderer\AccordionRenderer; |
27 | |
28 | /** |
29 | * AccordionBuilder |
30 | * |
31 | * This class implements the builder pattern to construct instances of Accordion. |
32 | * It provides a fluent interface for setting various properties and building the |
33 | * final immutable object with predefined configurations and immutability. |
34 | * |
35 | * @category Builder |
36 | * @package Codex\Builder |
37 | * @since 0.1.0 |
38 | * @author Doğu Abaris <abaris@null.net> |
39 | * @license https://www.gnu.org/copyleft/gpl.html GPL-2.0-or-later |
40 | * @link https://doc.wikimedia.org/codex/main/ Codex Documentation |
41 | */ |
42 | class AccordionBuilder { |
43 | |
44 | /** |
45 | * The ID for the accordion. |
46 | */ |
47 | protected string $id = ''; |
48 | |
49 | /** |
50 | * The accordion's header title. |
51 | */ |
52 | protected string $title = ''; |
53 | |
54 | /** |
55 | * Additional text under the title. |
56 | */ |
57 | protected string $description = ''; |
58 | |
59 | /** |
60 | * The content shown when the accordion is expanded. |
61 | */ |
62 | protected string $content = ''; |
63 | |
64 | /** |
65 | * Determines if the accordion is expanded by default. |
66 | */ |
67 | protected bool $isOpen = false; |
68 | |
69 | /** |
70 | * Additional HTML attributes for the <details> element. |
71 | */ |
72 | protected array $attributes = []; |
73 | |
74 | /** |
75 | * The renderer instance used to render the accordion. |
76 | */ |
77 | protected AccordionRenderer $renderer; |
78 | |
79 | /** |
80 | * Constructor for the Accordion class. |
81 | * |
82 | * @param AccordionRenderer $renderer The renderer to use for rendering the accordion. |
83 | */ |
84 | public function __construct( AccordionRenderer $renderer ) { |
85 | $this->renderer = $renderer; |
86 | } |
87 | |
88 | /** |
89 | * Set the accordion's HTML ID attribute. |
90 | * |
91 | * @since 0.1.0 |
92 | * @param string $id The ID for the accordion element. |
93 | * @return $this |
94 | */ |
95 | public function setId( string $id ): self { |
96 | $this->id = $id; |
97 | |
98 | return $this; |
99 | } |
100 | |
101 | /** |
102 | * Set the title for the accordion header. |
103 | * |
104 | * This method specifies the title text that appears in the accordion's header section. |
105 | * The title serves as the main clickable element that users interact with to expand or collapse |
106 | * the accordion content. The title is rendered inside a `<span>` element with the class |
107 | * `cdx-accordion__header__title`, which is nested within an `<h3>` header inside the `<summary>` element. |
108 | * |
109 | * The title should be concise yet descriptive enough to give users a clear understanding |
110 | * of the content they will see when the accordion is expanded. |
111 | * |
112 | * @since 0.1.0 |
113 | * @param string $title The title text to be displayed in the accordion header. |
114 | * @return $this Returns the Accordion instance for method chaining. |
115 | */ |
116 | public function setTitle( string $title ): self { |
117 | if ( trim( $title ) === '' ) { |
118 | throw new InvalidArgumentException( 'Title cannot be empty.' ); |
119 | } |
120 | $this->title = $title; |
121 | |
122 | return $this; |
123 | } |
124 | |
125 | /** |
126 | * Set the description for the accordion header. |
127 | * |
128 | * The description is an optional text that provides additional context or details about the accordion's content. |
129 | * This text is displayed beneath the title in the header section and is wrapped in a `<span>` element with |
130 | * the class `cdx-accordion__header__description`. This description is particularly useful when the title alone |
131 | * does not fully convey the nature of the accordion's content. |
132 | * |
133 | * This method is especially helpful for making the accordion more accessible and informative, |
134 | * allowing users to understand the content before deciding to expand it. |
135 | * |
136 | * @since 0.1.0 |
137 | * @param string $description The description text to be displayed in the accordion header. |
138 | * @return $this Returns the Accordion instance for method chaining. |
139 | */ |
140 | public function setDescription( string $description ): self { |
141 | $this->description = $description; |
142 | |
143 | return $this; |
144 | } |
145 | |
146 | /** |
147 | * Set the content for the accordion body as plain text. |
148 | * |
149 | * This method defines plain text content that will be safely escaped before rendering. |
150 | * It should be used when the content does not contain any HTML markup and needs to be treated strictly as text. |
151 | * |
152 | * @since 0.1.0 |
153 | * @param string $content The plain text content to be displayed inside the accordion. |
154 | * @param-taint $content escapes_html |
155 | * @return $this Returns the Accordion instance for method chaining. |
156 | */ |
157 | public function setContentText( string $content ): self { |
158 | $this->content = $content; |
159 | |
160 | return $this; |
161 | } |
162 | |
163 | /** |
164 | * Set the content for the accordion body as HTML. |
165 | * |
166 | * This method defines HTML content by passing an `HtmlSnippet` object. The content |
167 | * will be rendered as-is without escaping, ensuring the correct HTML output. |
168 | * |
169 | * @since 0.1.0 |
170 | * @param HtmlSnippet $content The HTML content to be displayed inside the accordion. |
171 | * @param-taint $content exec_html |
172 | * @return $this Returns the Accordion instance for method chaining. |
173 | */ |
174 | public function setContentHtml( HtmlSnippet $content ): self { |
175 | $this->content = (string)$content; |
176 | |
177 | return $this; |
178 | } |
179 | |
180 | /** |
181 | * Set whether the accordion should be open by default. |
182 | * |
183 | * By default, accordions are rendered in a collapsed state. However, setting this property to `true` |
184 | * will cause the accordion to be expanded when the page initially loads. This adds the `open` attribute |
185 | * to the `<details>` element, making the content visible without interaction. |
186 | * |
187 | * This feature is useful in scenarios where critical content needs to be immediately visible, without requiring |
188 | * any action to expand the accordion. |
189 | * |
190 | * @since 0.1.0 |
191 | * @param bool $isOpen Indicates whether the accordion should be open by default. |
192 | * @return $this Returns the Accordion instance for method chaining. |
193 | */ |
194 | public function setOpen( bool $isOpen ): self { |
195 | $this->isOpen = $isOpen; |
196 | |
197 | return $this; |
198 | } |
199 | |
200 | /** |
201 | * Set additional HTML attributes for the `<details>` element. |
202 | * |
203 | * This method allows custom attributes to be added to the `<details>` element, such as `id`, `class`, `data-*`, |
204 | * `role`, or any other valid HTML attributes. These attributes can be used to further customize the accordion |
205 | * behavior, integrate it with JavaScript, or enhance accessibility. |
206 | * |
207 | * The values of these attributes are automatically escaped to prevent XSS vulnerabilities. |
208 | * |
209 | * Example usage: |
210 | * |
211 | * $accordion->setAttributes([ |
212 | * 'id' => 'some-id', |
213 | * 'data-toggle' => 'collapse' |
214 | * ]); |
215 | * |
216 | * @since 0.1.0 |
217 | * @param array $attributes An associative array of HTML attributes. |
218 | * @return $this Returns the Accordion instance for method chaining. |
219 | */ |
220 | public function setAttributes( array $attributes ): self { |
221 | foreach ( $attributes as $key => $value ) { |
222 | $this->attributes[$key] = $value; |
223 | } |
224 | return $this; |
225 | } |
226 | |
227 | /** |
228 | * Build and return the Accordion component object. |
229 | * This method constructs the immutable Accordion object with all the properties set via the builder. |
230 | * |
231 | * @since 0.1.0 |
232 | * @return Accordion The constructed Accordion. |
233 | */ |
234 | public function build(): Accordion { |
235 | return new Accordion( |
236 | $this->id, |
237 | $this->title, |
238 | $this->description, |
239 | $this->content, |
240 | $this->isOpen, |
241 | $this->attributes, |
242 | $this->renderer |
243 | ); |
244 | } |
245 | } |