├── composer-require-checker.json ├── .phpunit-watcher.yml ├── infection.json.dist ├── src ├── ButtonSize.php ├── ProgressVariant.php ├── Utility │ ├── TogglerType.php │ ├── Responsive.php │ ├── Sizing.php │ ├── TextBackgroundColor.php │ ├── TextColor.php │ ├── BackgroundColor.php │ └── AlignItems.php ├── NavBarPlacement.php ├── ButtonType.php ├── OffcanvasPlacement.php ├── DropdownItemType.php ├── NavBarExpand.php ├── DropdownAutoClose.php ├── AlertVariant.php ├── NavStyle.php ├── ModalDialogFullScreenSize.php ├── DropdownDirection.php ├── NavLayout.php ├── Assets │ ├── BootstrapCdnAsset.php │ └── BootstrapAsset.php ├── DropdownAlignment.php ├── ButtonVariant.php ├── BreadcrumbLink.php ├── AccordionItem.php ├── ProgressStack.php ├── ButtonToolbar.php ├── Toggler.php ├── ButtonGroup.php ├── CarouselItem.php ├── NavLink.php ├── DropdownItem.php ├── Collapse.php ├── Progress.php ├── Breadcrumbs.php ├── Button.php └── Alert.php ├── CHANGELOG.md ├── psalm.xml ├── rector.php ├── LICENSE.md ├── .styleci.yml ├── composer.json └── README.md /composer-require-checker.json: -------------------------------------------------------------------------------- 1 | { 2 | "symbol-whitelist": [ 3 | "Yiisoft\\Assets\\AssetBundle", 4 | "Yiisoft\\Files\\PathMatcher\\PathMatcher" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.phpunit-watcher.yml: -------------------------------------------------------------------------------- 1 | watch: 2 | directories: 3 | - src 4 | - tests 5 | fileMask: '*.php' 6 | notifications: 7 | passingTests: false 8 | failingTests: false 9 | phpunit: 10 | binaryPath: vendor/bin/phpunit 11 | timeout: 180 12 | -------------------------------------------------------------------------------- /infection.json.dist: -------------------------------------------------------------------------------- 1 | { 2 | "source": { 3 | "directories": [ 4 | "src" 5 | ] 6 | }, 7 | "logs": { 8 | "text": "php:\/\/stderr", 9 | "stryker": { 10 | "report": "master" 11 | } 12 | }, 13 | "mutators": { 14 | "@default": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/ButtonSize.php: -------------------------------------------------------------------------------- 1 | ` element. 14 | */ 15 | case LINK = 'link'; 16 | /** 17 | * Reset button, renders as `
11 | 12 | [](https://packagist.org/packages/yiisoft/bootstrap5) 13 | [](https://packagist.org/packages/yiisoft/bootstrap5) 14 | [](https://github.com/yiisoft/bootstrap5/actions?query=workflow%3Abuild) 15 | [](https://codecov.io/gh/yiisoft/bootstrap5) 16 | [](https://dashboard.stryker-mutator.io/reports/github.com/yiisoft/bootstrap5/master) 17 | [](https://github.com/yiisoft/bootstrap5/actions?query=workflow%3A%22static+analysis%22) 18 | [](https://shepherd.dev/github/yiisoft/bootstrap5) 19 | 20 | This [Yii Framework] extension encapsulates [Twitter Bootstrap 5] components 21 | and plugins in terms of Yii widgets, and thus makes using Bootstrap components/plugins 22 | in Yii applications extremely easy. 23 | 24 | For example, to use the [Bootstrap 5 Carousel](https://getbootstrap.com/docs/5.3/components/carousel/) component, you 25 | can do the following: 26 | 27 | ```php 28 | 39 | 40 | = Carousel::widget() 41 | ->id('carouselExampleOnlyText') 42 | ->items( 43 | CarouselItem::to( 44 | Div::tag() 45 | ->addClass('bg-primary text-white p-5 text-center') 46 | ->addContent( 47 | H2::tag()->content('Title 1'), 48 | P::tag()->content('This is the first slide with text.'), 49 | ), 50 | ), 51 | CarouselItem::to( 52 | Div::tag() 53 | ->addClass('bg-success text-white p-5 text-center') 54 | ->addContent( 55 | H2::tag()->content('Title 2'), 56 | P::tag()->content('This is the second slide with text.'), 57 | ), 58 | ), 59 | CarouselItem::to( 60 | Div::tag() 61 | ->addClass('bg-danger text-white p-5 text-center') 62 | ->addContent( 63 | H2::tag()->content('Title 3'), 64 | P::tag()->content('This is the third slide with text.'), 65 | ), 66 | ), 67 | ); 68 | ``` 69 | 70 | ## Requirements 71 | 72 | - PHP 8.1 or higher. 73 | 74 | ## Installation 75 | 76 | The package could be installed with [Composer](https://getcomposer.org): 77 | 78 | ```shell 79 | composer require yiisoft/bootstrap5 80 | ``` 81 | 82 | ## Install assets 83 | 84 | There are several ways to install the assets, they are: 85 | 86 | 1. Using the [AssetPackagist](https://asset-packagist.org/) package manager. 87 | 88 | Add to composer.json the following: 89 | 90 | ```json 91 | { 92 | "require": { 93 | "npm-asset/bootstrap": "^5.3", 94 | "oomphinc/composer-installers-extender": "^2.0" 95 | }, 96 | "extra": { 97 | "installer-types": [ 98 | "npm-asset" 99 | ], 100 | "installer-paths": { 101 | "./node_modules/{$name}": [ 102 | "type:npm-asset" 103 | ] 104 | } 105 | }, 106 | "repositories": [ 107 | { 108 | "type": "composer", 109 | "url": "https://asset-packagist.org" 110 | } 111 | ] 112 | } 113 | ``` 114 | 115 | Once the changes are made, you can install the assets using the following command: 116 | 117 | ```shell 118 | composer update 119 | ``` 120 | 121 | 2. Using the [npm-asset](https://www.npmjs.com/) package manager. 122 | 123 | Run the following command at the root directory of your application. 124 | 125 | ```shell 126 | npm i bootstrap@5.3.1 127 | ``` 128 | 129 | ## Using the [yiisoft/assets](https://github.com/yiisoft/assets) package 130 | 131 | To use the asset classes in the `src/Assets` directory (such as `BootstrapAsset` and `BootstrapCdnAsset`), you need to 132 | install additional packages: 133 | 134 | ```shell 135 | composer require yiisoft/assets yiisoft/files 136 | ``` 137 | 138 | ## Documentation 139 | 140 | - [Twitter Bootstrap 5.3](https://getbootstrap.com/docs/5.3/getting-started/introduction/) 141 | - Guide: 142 | - [English](docs/guide/en/README.md) 143 | - [Internals](docs/internals.md) 144 | 145 | If you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/63) is a good place for that. 146 | You may also check out other [Yii Community Resources](https://www.yiiframework.com/community). 147 | 148 | ## License 149 | 150 | The Yii Framework Twitter Bootstrap 5 Extension is free software. It is released under the terms of the BSD License. 151 | Please see [`LICENSE`](./LICENSE.md) for more information. 152 | 153 | Maintained by [Yii Software](https://www.yiiframework.com/). 154 | 155 | ## Support the project 156 | 157 | [](https://opencollective.com/yiisoft) 158 | 159 | ## Follow updates 160 | 161 | [](https://www.yiiframework.com/) 162 | [](https://twitter.com/yiiframework) 163 | [](https://t.me/yii3en) 164 | [](https://www.facebook.com/groups/yiitalk) 165 | [](https://yiiframework.com/go/slack) 166 | 167 | [Yii Framework]: https://www.yiiframework.com/ 168 | [Twitter Bootstrap 5]: https://getbootstrap.com/docs/5.3/getting-started/introduction/ 169 | -------------------------------------------------------------------------------- /src/ProgressStack.php: -------------------------------------------------------------------------------- 1 | bars( 20 | * Progress::widget() 21 | * ->ariaLabel('Segment one') 22 | * ->id('segment-one') 23 | * ->percent(15), 24 | * Progress::widget() 25 | * ->ariaLabel('Segment two') 26 | * ->backGroundColor(BackgroundColor::SUCCESS) 27 | * ->id('segment-two') 28 | * ->percent(30), 29 | * Progress::widget() 30 | * ->ariaLabel('Segment three') 31 | * ->backGroundColor(BackgroundColor::INFO) 32 | * ->id('segment-three') 33 | * ->percent(20), 34 | * ) 35 | * ->render(); 36 | * 37 | * @see https://getbootstrap.com/docs/5.3/components/progress/#multiple-bars 38 | */ 39 | final class ProgressStack extends Widget 40 | { 41 | private const NAME = 'progress-stack'; 42 | 43 | private const PROGRESS_STACKED = 'progress-stacked'; 44 | 45 | private array $attributes = []; 46 | 47 | private array $cssClasses = []; 48 | 49 | private array $bars = []; 50 | 51 | private bool|string $id = true; 52 | 53 | /** 54 | * Adds a set of attributes. 55 | * 56 | * @param array $attributes Attribute values indexed by attribute names. for example, `['id' => 'my-id']`. 57 | * 58 | * @return self A new instance with the specified attributes added. 59 | * 60 | * Example usage: 61 | * ```php 62 | * $progressStack->addAttributes(['data-id' => '123']); 63 | * ``` 64 | */ 65 | public function addAttributes(array $attributes): self 66 | { 67 | $new = clone $this; 68 | $new->attributes = [...$this->attributes, ...$attributes]; 69 | 70 | return $new; 71 | } 72 | 73 | /** 74 | * Adds one or more CSS classes to the existing classes. 75 | * 76 | * @param BackedEnum|string|null ...$class One or more CSS class names to add. Pass `null` to skip adding a class. 77 | * 78 | * @return self A new instance with the specified CSS classes added to existing ones. 79 | * 80 | * @link https://html.spec.whatwg.org/#classes 81 | * 82 | * Example usage: 83 | * ```php 84 | * $progressStack->addClass('custom-class', null, 'another-class', BackGroundColor::PRIMARY); 85 | * ``` 86 | */ 87 | public function addClass(BackedEnum|string|null ...$class): self 88 | { 89 | $new = clone $this; 90 | $new->cssClasses = [...$this->cssClasses, ...$class]; 91 | 92 | return $new; 93 | } 94 | 95 | /** 96 | * Adds a CSS style. 97 | * 98 | * @param array|string $style The CSS style. If the value is an array, a space will separate the values. 99 | * For example, `['color' => 'red', 'font-weight' => 'bold']` will be rendered as `color: red; font-weight: bold;`. 100 | * If it is a string, it will be added as is, for example, `color: red`. 101 | * @param bool $overwrite Whether to overwrite existing styles with the same name. If `false`, the new value will be 102 | * appended to the existing one. 103 | * 104 | * @return self A new instance with the specified CSS style value added. 105 | * 106 | * Example usage: 107 | * ```php 108 | * $progressStack->addCssStyle('color: red'); 109 | * 110 | * // or 111 | * $progressStack->addCssStyle(['color' => 'red', 'font-weight' => 'bold']); 112 | * ``` 113 | */ 114 | public function addCssStyle(array|string $style, bool $overwrite = true): self 115 | { 116 | $new = clone $this; 117 | Html::addCssStyle($new->attributes, $style, $overwrite); 118 | 119 | return $new; 120 | } 121 | 122 | /** 123 | * Sets attribute value. 124 | * 125 | * @param string $name The attribute name. 126 | * @param mixed $value The attribute value. 127 | * 128 | * @return self A new instance with the specified attribute set. 129 | * 130 | * Example usage: 131 | * ```php 132 | * $progressStack->attribute('data-id', '123'); 133 | * ``` 134 | */ 135 | public function attribute(string $name, mixed $value): self 136 | { 137 | $new = clone $this; 138 | $new->attributes[$name] = $value; 139 | 140 | return $new; 141 | } 142 | 143 | /** 144 | * Sets the HTML attributes. 145 | * 146 | * @param array $attributes Attribute values indexed by attribute names. 147 | * 148 | * @return self A new instance with the specified attributes. 149 | * 150 | * @see {\Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered. 151 | * 152 | * Example usage: 153 | * ```php 154 | * $progressStack->attributes(['data-id' => '123']); 155 | * ``` 156 | */ 157 | public function attributes(array $attributes): self 158 | { 159 | $new = clone $this; 160 | $new->attributes = $attributes; 161 | 162 | return $new; 163 | } 164 | 165 | /** 166 | * Sets the progress bars to be displayed. 167 | * 168 | * @param Progress ...$bars One or more Progress instances to include in the stack. 169 | * 170 | * @return self A new instance with the specified bars. 171 | * 172 | * Example usage: 173 | * ```php 174 | * $progressStack->bars( 175 | * Progress::widget()->percent(15)->backgroundColor(BackgroundColor::SUCCESS), 176 | * Progress::widget()->percent(30)->backgroundColor(BackgroundColor::INFO) 177 | * ); 178 | * ``` 179 | */ 180 | public function bars(Progress ...$bars): self 181 | { 182 | $new = clone $this; 183 | $new->bars = $bars; 184 | 185 | return $new; 186 | } 187 | 188 | /** 189 | * Replaces all existing CSS classes with the specified one(s). 190 | * 191 | * @param BackedEnum|string|null ...$class One or more CSS class names to set. Pass `null` to skip setting a class. 192 | * 193 | * @return self A new instance with the specified CSS classes set. 194 | * 195 | * Example usage: 196 | * ```php 197 | * $progressStack->class('custom-class', null, 'another-class', BackGroundColor::PRIMARY); 198 | * ``` 199 | */ 200 | public function class(BackedEnum|string|null ...$class): self 201 | { 202 | $new = clone $this; 203 | $new->cssClasses = $class; 204 | 205 | return $new; 206 | } 207 | 208 | /** 209 | * Sets the ID. 210 | * 211 | * @param bool|string $id The ID of the component. If `true`, an ID will be generated automatically. 212 | * 213 | * @return self A new instance with the specified ID. 214 | * 215 | * Example usage: 216 | * ```php 217 | * $progressStack->id('my-id'); 218 | * ``` 219 | */ 220 | public function id(bool|string $id): self 221 | { 222 | $new = clone $this; 223 | $new->id = $id; 224 | 225 | return $new; 226 | } 227 | 228 | /** 229 | * Run the widget. 230 | * 231 | * @return string The HTML representation of the element. 232 | */ 233 | public function render(): string 234 | { 235 | if ($this->bars === []) { 236 | return ''; 237 | } 238 | 239 | $attributes = $this->attributes; 240 | $content = ''; 241 | $classes = $attributes['class'] ?? null; 242 | 243 | unset($attributes['class']); 244 | 245 | foreach ($this->bars as $bar) { 246 | $content .= $bar->stacked()->render() . "\n"; 247 | } 248 | 249 | return Div::tag() 250 | ->attributes($attributes) 251 | ->addClass( 252 | self::PROGRESS_STACKED, 253 | ...$this->cssClasses, 254 | ) 255 | ->addClass($classes) 256 | ->content( 257 | "\n", 258 | $content, 259 | ) 260 | ->encode(false) 261 | ->id($this->getId()) 262 | ->render(); 263 | } 264 | 265 | /** 266 | * Generates the ID. 267 | * 268 | * @return string|null The generated ID. 269 | * 270 | * @psalm-return non-empty-string|null The generated ID. 271 | */ 272 | private function getId(): string|null 273 | { 274 | return match ($this->id) { 275 | true => $this->attributes['id'] ?? Html::generateId(self::NAME . '-'), 276 | '', false => null, 277 | default => $this->id, 278 | }; 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /src/ButtonToolbar.php: -------------------------------------------------------------------------------- 1 | ariaLabel('Toolbar with button groups') 24 | * ->buttonGroups( 25 | * ButtonGroup::widget() 26 | * ->addClass('me-2') 27 | * ->ariaLabel('First group') 28 | * ->buttons( 29 | * Button::widget()->label('1')->variant(ButtonVariant::PRIMARY), 30 | * Button::widget()->label('2')->variant(ButtonVariant::PRIMARY), 31 | * Button::widget()->label('3')->variant(ButtonVariant::PRIMARY), 32 | * Button::widget()->label('4')->variant(ButtonVariant::PRIMARY), 33 | * ), 34 | * ButtonGroup::widget() 35 | * ->addClass('me-2') 36 | * ->ariaLabel('Second group') 37 | * ->buttons( 38 | * Button::widget()->label('5'), 39 | * Button::widget()->label('6'), 40 | * Button::widget()->label('7'), 41 | * ), 42 | * ButtonGroup::widget() 43 | * ->ariaLabel('Third group') 44 | * ->buttons( 45 | * Button::widget()->label('8')->variant(ButtonVariant::INFO), 46 | * ) 47 | * ) 48 | * ->render(); 49 | * ``` 50 | * 51 | * @link https://getbootstrap.com/docs/5.3/components/button-group/#button-toolbar 52 | */ 53 | final class ButtonToolbar extends Widget 54 | { 55 | private const NAME = 'btn-toolbar'; 56 | 57 | private array $attributes = []; 58 | 59 | /** @psalm-var ButtonGroup[]|Tag[] $buttonGroups */ 60 | private array $buttonGroups = []; 61 | 62 | private array $cssClasses = []; 63 | 64 | private bool|string $id = true; 65 | 66 | /** 67 | * Adds a sets of attributes. 68 | * 69 | * @param array $attributes Attribute values indexed by attribute names. for example, `['id' => 'my-id']`. 70 | * 71 | * @return self A new instance with the specified attributes added. 72 | * 73 | * Example usage: 74 | * ```php 75 | * $buttonToolbar->addAttributes(['data-id' => '123']); 76 | * ``` 77 | */ 78 | public function addAttributes(array $attributes): self 79 | { 80 | $new = clone $this; 81 | $new->attributes = [...$new->attributes, ...$attributes]; 82 | 83 | return $new; 84 | } 85 | 86 | /** 87 | * Adds one or more CSS classes to the existing classes. 88 | * 89 | * Multiple classes can be added by passing them as separate arguments. `null` values are filtered out 90 | * automatically. 91 | * 92 | * @param BackedEnum|string|null ...$class One or more CSS class names to add. Pass `null` to skip adding a class. 93 | * 94 | * @return self A new instance with the specified CSS classes added to existing ones. 95 | * 96 | * @link https://html.spec.whatwg.org/#classes 97 | * 98 | * Example usage: 99 | * ```php 100 | * $buttonToolbar->addClass('custom-class', null, 'another-class', BackGroundColor::PRIMARY); 101 | * ``` 102 | */ 103 | public function addClass(BackedEnum|string|null ...$class): self 104 | { 105 | $new = clone $this; 106 | $new->cssClasses = [...$this->cssClasses, ...$class]; 107 | 108 | return $new; 109 | } 110 | 111 | /** 112 | * Adds a CSS style. 113 | * 114 | * @param array|string $style The CSS style. If the value is an array, a space will separate the values. 115 | * For example, `['color' => 'red', 'font-weight' => 'bold']` will be rendered as `color: red; font-weight: bold;`. 116 | * If it is a string, it will be added as is, for example, `color: red`. 117 | * @param bool $overwrite Whether to overwrite existing styles with the same name. If `false`, the new value will be 118 | * appended to the existing one. 119 | * 120 | * @return self A new instance with the specified CSS style value added. 121 | * 122 | * Example usage: 123 | * ```php 124 | * $buttonToolbar->addCssStyle('color: red'); 125 | * 126 | * // or 127 | * $buttonToolbar->addCssStyle(['color' => 'red', 'font-weight' => 'bold']); 128 | * ``` 129 | */ 130 | public function addCssStyle(array|string $style, bool $overwrite = true): self 131 | { 132 | $new = clone $this; 133 | Html::addCssStyle($new->attributes, $style, $overwrite); 134 | 135 | return $new; 136 | } 137 | 138 | /** 139 | * Sets the ARIA label. 140 | * 141 | * @param string $label The ARIA label. 142 | * 143 | * @return self A new instance with the specified ARIA label. 144 | * 145 | * @link https://www.w3.org/TR/wai-aria-1.1/#aria-label 146 | * 147 | * Example usage: 148 | * ```php 149 | * $buttonToolbar->ariaLabel('Toolbar with button groups'); 150 | * ``` 151 | */ 152 | public function ariaLabel(string $label): self 153 | { 154 | return $this->attribute('aria-label', $label); 155 | } 156 | 157 | /** 158 | * Adds a sets attribute value. 159 | * 160 | * @param string $name The attribute name. 161 | * @param mixed $value The attribute value. 162 | * 163 | * @return self A new instance with the specified attribute added. 164 | * 165 | * Example usage: 166 | * ```php 167 | * $buttonToolbar->attribute('data-id', '123'); 168 | * ``` 169 | */ 170 | public function attribute(string $name, mixed $value): self 171 | { 172 | $new = clone $this; 173 | $new->attributes[$name] = $value; 174 | 175 | return $new; 176 | } 177 | 178 | /** 179 | * Sets the HTML attributes. 180 | * 181 | * @param array $attributes Attribute values indexed by attribute names. 182 | * 183 | * @return self A new instance with the specified attributes. 184 | * 185 | * @see {\Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered. 186 | * 187 | * Example usage: 188 | * ```php 189 | * $buttonToolbar->attributes(['data-id' => '123']); 190 | * ``` 191 | */ 192 | public function attributes(array $attributes): self 193 | { 194 | $new = clone $this; 195 | $new->attributes = $attributes; 196 | 197 | return $new; 198 | } 199 | 200 | /** 201 | * List of buttons groups. 202 | * 203 | * @param ButtonGroup|Tag ...$groups The button group. 204 | * 205 | * @return self A new instance with the specified buttons groups. 206 | */ 207 | public function buttonGroups(ButtonGroup|Tag ...$groups): self 208 | { 209 | $new = clone $this; 210 | $new->buttonGroups = $groups; 211 | 212 | return $new; 213 | } 214 | 215 | /** 216 | * Replaces all existing CSS classes with the specified one(s). 217 | * 218 | * Multiple classes can be added by passing them as separate arguments. `null` values are filtered out 219 | * automatically. 220 | * 221 | * @param BackedEnum|string|null ...$class One or more CSS class names to set. Pass `null` to skip setting a class. 222 | * 223 | * @return self A new instance with the specified CSS classes set. 224 | * 225 | * Example usage: 226 | * ```php 227 | * $buttonToolbar->class('custom-class', null, 'another-class', BackGroundColor::PRIMARY); 228 | * ``` 229 | */ 230 | public function class(BackedEnum|string|null ...$class): self 231 | { 232 | $new = clone $this; 233 | $new->cssClasses = $class; 234 | 235 | return $new; 236 | } 237 | 238 | /** 239 | * Sets the ID. 240 | * 241 | * @param bool|string $id The ID of the component. If `true`, an ID will be generated automatically. 242 | * 243 | * @return self A new instance with the specified ID. 244 | * 245 | * Example usage: 246 | * ```php 247 | * $buttonToolbar->id('my-id'); 248 | * ``` 249 | */ 250 | public function id(bool|string $id): self 251 | { 252 | $new = clone $this; 253 | $new->id = $id; 254 | 255 | return $new; 256 | } 257 | 258 | /** 259 | * Run the widget. 260 | * 261 | * @return string The HTML representation of the element. 262 | */ 263 | public function render(): string 264 | { 265 | $attributes = $this->attributes; 266 | $classes = $attributes['class'] ?? null; 267 | 268 | unset($attributes['class'], $attributes['id']); 269 | 270 | $buttonGroup = implode("\n", $this->buttonGroups); 271 | $buttonsGroups = $buttonGroup === '' ? '' : "\n" . $buttonGroup . "\n"; 272 | 273 | if ($buttonsGroups === '') { 274 | return ''; 275 | } 276 | 277 | return Div::tag() 278 | ->attributes($attributes) 279 | ->attribute('role', 'toolbar') 280 | ->addClass( 281 | self::NAME, 282 | $classes, 283 | ...$this->cssClasses, 284 | ) 285 | ->content($buttonsGroups) 286 | ->encode(false) 287 | ->id($this->getId()) 288 | ->render(); 289 | } 290 | 291 | /** 292 | * Generates the ID. 293 | * 294 | * @return string|null The generated ID. 295 | * 296 | * @psalm-return non-empty-string|null The generated ID. 297 | */ 298 | private function getId(): string|null 299 | { 300 | return match ($this->id) { 301 | true => $this->attributes['id'] ?? Html::generateId(self::NAME . '-'), 302 | '', false => null, 303 | default => $this->id, 304 | }; 305 | } 306 | } 307 | -------------------------------------------------------------------------------- /src/Toggler.php: -------------------------------------------------------------------------------- 1 | togglerMultiple(true) 36 | * ->ariaControls('collapse1 collapse2') 37 | * ->togglerContent('Toggle multiple collapses'); 38 | * ``` 39 | */ 40 | final class Toggler 41 | { 42 | /** 43 | * Use {@see Toggler::for()} to create an instance. 44 | */ 45 | private function __construct( 46 | private string $content, 47 | private string|bool $id, 48 | private string $togglerTag, 49 | private string $togglerContent, 50 | private bool $togglerAsLink, 51 | private array $togglerAttributes, 52 | private bool $encode, 53 | private bool $togglerMultiple, 54 | private string $ariaControls, 55 | ) { 56 | } 57 | 58 | public static function for( 59 | string $content = '', 60 | string|bool $id = true, 61 | string $togglerTag = 'button', 62 | string $togglerContent = '', 63 | bool $togglerAsLink = false, 64 | array $togglerAttributes = [], 65 | bool $encode = true, 66 | bool $togglerMultiple = false, 67 | string $ariaControls = '', 68 | ): self { 69 | $new = new self( 70 | $content, 71 | $id, 72 | $togglerTag, 73 | $togglerContent, 74 | $togglerAsLink, 75 | $togglerAttributes, 76 | $encode, 77 | $togglerMultiple, 78 | $ariaControls, 79 | ); 80 | 81 | return $new->id($new->getId()); 82 | } 83 | 84 | /** 85 | * Sets the `aria-controls` attribute value for the toggler. 86 | * 87 | * @param string $ariaControls The `aria-controls` attribute value for the toggler. 88 | * 89 | * @return self A new instance with the specified `aria-controls` attribute value for the toggler. 90 | */ 91 | public function ariaControls(string $ariaControls): self 92 | { 93 | $new = clone $this; 94 | $new->ariaControls = $ariaControls; 95 | 96 | return $new; 97 | } 98 | 99 | /** 100 | * Sets the content to be displayed in the collapsible item. 101 | * 102 | * @param string|Stringable $content The content to be displayed in the collapsible item. 103 | * 104 | * @return self A new instance with the specified content to be displayed in the collapsible item. 105 | */ 106 | public function content(string|Stringable $content): self 107 | { 108 | $new = clone $this; 109 | $new->content = (string)$content; 110 | 111 | return $new; 112 | } 113 | 114 | /** 115 | * Sets whether to HTML encode the content. 116 | * 117 | * @param bool $enabled Whether to HTML encode the content. 118 | * 119 | * @return self A new instance with the specified encoding behavior. 120 | */ 121 | public function encode(bool $enabled): self 122 | { 123 | $new = clone $this; 124 | $new->encode = $enabled; 125 | 126 | return $new; 127 | } 128 | 129 | /** 130 | * Generates the ID. 131 | * 132 | * @throws InvalidArgumentException if the ID is an empty string or `false`. 133 | * 134 | * @return string The generated ID. 135 | * 136 | * @psalm-return non-empty-string The generated ID. 137 | */ 138 | public function getId(): string 139 | { 140 | return match ($this->id) { 141 | true => Html::generateId('collapse-'), 142 | '', false => throw new InvalidArgumentException('The "id" must be specified.'), 143 | default => $this->id, 144 | }; 145 | } 146 | 147 | /** 148 | * Sets the ID. 149 | * 150 | * @param bool|string $id The ID of the component. If `true`, an ID will be generated automatically. 151 | * 152 | * @throws InvalidArgumentException if the ID is an empty string or `false`. 153 | * 154 | * @return self A new instance with the specified ID. 155 | */ 156 | public function id(bool|string $id): self 157 | { 158 | $new = clone $this; 159 | $new->id = $id; 160 | 161 | return $new; 162 | } 163 | 164 | /** 165 | * @return string The content to be displayed in the collapsible item. 166 | */ 167 | public function getContent(): string 168 | { 169 | return $this->encode ? Html::encode($this->content) : $this->content; 170 | } 171 | 172 | public function getTogglerMultiple(): bool 173 | { 174 | return $this->togglerMultiple; 175 | } 176 | 177 | /** 178 | * Render the toggler to be displayed in the collapsible item. 179 | * 180 | * @throws InvalidArgumentException if the toggler tag is an empty string. 181 | * 182 | * @return string The HTML representation of the element. 183 | */ 184 | public function renderToggler(): string 185 | { 186 | if ($this->togglerTag === '') { 187 | throw new InvalidArgumentException('Toggler tag cannot be empty string.'); 188 | } 189 | 190 | $tagName = $this->togglerAsLink ? 'a' : $this->togglerTag; 191 | 192 | $togglerAttributes = $this->togglerAttributes; 193 | $togglerClasses = $this->togglerAttributes['class'] ?? 'btn btn-primary'; 194 | 195 | unset($togglerAttributes['class']); 196 | 197 | return Html::tag($tagName, $this->togglerContent) 198 | ->attribute('type', $tagName === 'button' ? 'button' : null) 199 | ->attribute('data-bs-toggle', 'collapse') 200 | ->attribute('data-bs-target', $this->togglerMultiple ? '.multi-collapse' : '#' . $this->id) 201 | ->attribute('role', $this->togglerAsLink ? 'button' : null) 202 | ->attribute('aria-expanded', 'false') 203 | ->attribute('aria-controls', $this->togglerMultiple ? $this->ariaControls : $this->id) 204 | ->addClass($togglerClasses) 205 | ->addAttributes($togglerAttributes) 206 | ->render(); 207 | } 208 | 209 | /** 210 | * Sets whether the toggler should be rendered as a link. 211 | * 212 | * @param bool $enabled Whether to render the toggler as a link. 213 | * When true, render as an `` tag with `role="button"`. 214 | * When false, renders as the specified `togglerTag` (defaults to `button`). 215 | * 216 | * @return self A new instance with the specified toggler as link setting. 217 | */ 218 | public function togglerAsLink(bool $enabled): self 219 | { 220 | $new = clone $this; 221 | $new->togglerAsLink = $enabled; 222 | 223 | return $new; 224 | } 225 | 226 | /** 227 | * Sets the HTML attributes for the toggler. 228 | * 229 | * @param array $attributes Attribute values indexed by attribute names. 230 | * 231 | * @return self A new instance with the specified attributes for the toggler. 232 | * 233 | * @see {\Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered. 234 | */ 235 | public function togglerAttributes(array $attributes): self 236 | { 237 | $new = clone $this; 238 | $new->togglerAttributes = $attributes; 239 | 240 | return $new; 241 | } 242 | 243 | /** 244 | * Sets the content to be displayed in the toggler. 245 | * 246 | * @param string|Stringable $content The content to be displayed in the toggler. 247 | * 248 | * @return self A new instance with the specified content to be displayed in the toggler. 249 | * 250 | * Example usage: 251 | * ```php 252 | * Toggler::to()->togglerContent('Toggle collapse'); 253 | * ``` 254 | */ 255 | public function togglerContent(string|Stringable $content): self 256 | { 257 | $new = clone $this; 258 | $new->togglerContent = (string) $content; 259 | 260 | return $new; 261 | } 262 | 263 | /** 264 | * Sets whether the toggler should control multiple collapse items. 265 | * 266 | * @param bool $enabled Whether the toggler should control multiple collapse items. 267 | * When true, the toggler will target all collapse items with class `.multi-collapse`. 268 | * When false, the toggler will only target the collapse item with the specified ID. 269 | * 270 | * @return self A new instance with the specified toggler multiple setting. 271 | * 272 | * Example usage: 273 | * ```php 274 | * Toggler::to()->togglerMultiple(true)->ariaControls('collapseOne collapseTwo'); 275 | * ``` 276 | */ 277 | public function togglerMultiple(bool $enabled): self 278 | { 279 | $new = clone $this; 280 | $new->togglerMultiple = $enabled; 281 | 282 | return $new; 283 | } 284 | 285 | /** 286 | * Sets the tag name to be used to render the toggler. 287 | * 288 | * @param string $tag The tag name to be used to render the toggler. 289 | * 290 | * @throws InvalidArgumentException if the tag name is an empty string. 291 | * 292 | * @return self A new instance with the specified tag name to be used to render the toggler. 293 | * 294 | * Example usage: 295 | * ```php 296 | * Toggler::to()->togglerTag('a'); 297 | * ``` 298 | */ 299 | public function togglerTag(string $tag): self 300 | { 301 | $new = clone $this; 302 | $new->togglerTag = $tag; 303 | 304 | return $new; 305 | } 306 | } 307 | -------------------------------------------------------------------------------- /src/ButtonGroup.php: -------------------------------------------------------------------------------- 1 | addClass('btn-lg') 24 | * ->ariaLabel('Basic example') 25 | * ->buttons( 26 | * Button::widget()->label('Left')->variant(ButtonVariant::PRIMARY), 27 | * Button::widget()->label('Middle')->variant(ButtonVariant::PRIMARY), 28 | * Button::widget()->label('Right')->variant(ButtonVariant::PRIMARY), 29 | * ) 30 | * ?> 31 | * ``` 32 | * 33 | * Pressing on the button should be handled via JavaScript. See the following for details: 34 | * 35 | * @link https://getbootstrap.com/docs/5.3/components/button-group/ 36 | */ 37 | final class ButtonGroup extends Widget 38 | { 39 | private const NAME = 'btn-group'; 40 | 41 | private array $attributes = []; 42 | 43 | /** psalm-var Button[]|Checkbox[]|Radio[] $buttons */ 44 | private array $buttons = []; 45 | 46 | private array $cssClasses = []; 47 | 48 | private bool|string $id = true; 49 | 50 | /** 51 | * Adds a sets of attributes. 52 | * 53 | * @param array $attributes Attribute values indexed by attribute names. for example, `['id' => 'my-id']`. 54 | * 55 | * @return self A new instance with the specified attributes added. 56 | * 57 | * Example usage: 58 | * ```php 59 | * $buttonGroup->addAttributes(['data-id' => '123']); 60 | * ``` 61 | */ 62 | public function addAttributes(array $attributes): self 63 | { 64 | $new = clone $this; 65 | $new->attributes = [...$this->attributes, ...$attributes]; 66 | 67 | return $new; 68 | } 69 | 70 | /** 71 | * Adds one or more CSS classes to the existing classes. 72 | * 73 | * Multiple classes can be added by passing them as separate arguments. `null` values are filtered out 74 | * automatically. 75 | * 76 | * @param BackedEnum|string|null ...$class One or more CSS class names to add. Pass `null` to skip adding a class. 77 | * 78 | * @return self A new instance with the specified CSS classes added to existing ones. 79 | * 80 | * @link https://html.spec.whatwg.org/#classes 81 | * 82 | * Example usage: 83 | * ```php 84 | * $buttonGroup->addClass('custom-class', null, 'another-class', BackGroundColor::PRIMARY); 85 | * ``` 86 | */ 87 | public function addClass(BackedEnum|string|null ...$class): self 88 | { 89 | $new = clone $this; 90 | $new->cssClasses = [...$this->cssClasses, ...$class]; 91 | 92 | return $new; 93 | } 94 | 95 | /** 96 | * Adds a CSS style. 97 | * 98 | * @param array|string $style The CSS style. If the value is an array, a space will separate the values. 99 | * For example, `['color' => 'red', 'font-weight' => 'bold']` will be rendered as `color: red; font-weight: bold;`. 100 | * If it is a string, it will be added as is, for example, `color: red`. 101 | * @param bool $overwrite Whether to overwrite existing styles with the same name. If `false`, the new value will be 102 | * appended to the existing one. 103 | * 104 | * @return self A new instance with the specified CSS style value added. 105 | * 106 | * Example usage: 107 | * ```php 108 | * $buttonGroup->addCssStyle('color: red'); 109 | * 110 | * // or 111 | * $buttonGroup->addCssStyle(['color' => 'red', 'font-weight' => 'bold']); 112 | * ``` 113 | */ 114 | public function addCssStyle(array|string $style, bool $overwrite = true): self 115 | { 116 | $new = clone $this; 117 | Html::addCssStyle($new->attributes, $style, $overwrite); 118 | 119 | return $new; 120 | } 121 | 122 | /** 123 | * Sets the ARIA label. 124 | * 125 | * @param string $label The ARIA label. 126 | * 127 | * @return self A new instance with the specified ARIA label. 128 | * 129 | * @link https://www.w3.org/TR/wai-aria-1.1/#aria-label 130 | * 131 | * Example usage: 132 | * ```php 133 | * $buttonGroup->ariaLabel('Basic example'); 134 | * ``` 135 | */ 136 | public function ariaLabel(string $label): self 137 | { 138 | return $this->attribute('aria-label', $label); 139 | } 140 | 141 | /** 142 | * Adds a sets attribute value. 143 | * 144 | * @param string $name The attribute name. 145 | * @param mixed $value The attribute value. 146 | * 147 | * @return self A new instance with the specified attribute added. 148 | * 149 | * Example usage: 150 | * ```php 151 | * $buttonGroup->attribute('data-id', '123'); 152 | * ``` 153 | */ 154 | public function attribute(string $name, mixed $value): self 155 | { 156 | $new = clone $this; 157 | $new->attributes[$name] = $value; 158 | 159 | return $new; 160 | } 161 | 162 | /** 163 | * Sets the HTML attributes. 164 | * 165 | * @param array $attributes Attribute values indexed by attribute names. 166 | * 167 | * @return self A new instance with the specified attributes. 168 | * 169 | * @see {\Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered. 170 | * 171 | * Example usage: 172 | * ```php 173 | * $buttonGroup->attributes(['data-id' => '123']); 174 | * ``` 175 | */ 176 | public function attributes(array $attributes): self 177 | { 178 | $new = clone $this; 179 | $new->attributes = $attributes; 180 | 181 | return $new; 182 | } 183 | 184 | /** 185 | * List of buttons. 186 | * 187 | * @param Button|Checkbox|Radio ...$buttons The button. 188 | * 189 | * @return self A new instance with the specified buttons. 190 | * 191 | * Example usage: 192 | * ```php 193 | * $buttonGroup->buttons( 194 | * Button::widget()->label('Left')->variant(ButtonVariant::PRIMARY), 195 | * Button::widget()->label('Middle')->variant(ButtonVariant::PRIMARY), 196 | * Button::widget()->label('Right')->variant(ButtonVariant::PRIMARY), 197 | * ); 198 | * ``` 199 | */ 200 | public function buttons(Button|Checkbox|Radio ...$buttons): self 201 | { 202 | $new = clone $this; 203 | $new->buttons = $buttons; 204 | 205 | return $new; 206 | } 207 | 208 | /** 209 | * Replaces all existing CSS classes with the specified one(s). 210 | * 211 | * Multiple classes can be added by passing them as separate arguments. `null` values are filtered out 212 | * automatically. 213 | * 214 | * @param BackedEnum|string|null ...$class One or more CSS class names to set. Pass `null` to skip setting a class. 215 | * 216 | * @return self A new instance with the specified CSS classes set. 217 | * 218 | * Example usage: 219 | * ```php 220 | * $buttonGroup->class('custom-class', null, 'another-class', BackGroundColor::PRIMARY); 221 | * ``` 222 | */ 223 | public function class(BackedEnum|string|null ...$class): self 224 | { 225 | $new = clone $this; 226 | $new->cssClasses = $class; 227 | 228 | return $new; 229 | } 230 | 231 | /** 232 | * Sets the ID. 233 | * 234 | * @param bool|string $id The ID of the component. If `true`, an ID will be generated automatically. 235 | * 236 | * @return self A new instance with the specified ID. 237 | * 238 | * Example usage: 239 | * ```php 240 | * $buttonGroup->id('my-id'); 241 | * ``` 242 | */ 243 | public function id(bool|string $id): self 244 | { 245 | $new = clone $this; 246 | $new->id = $id; 247 | 248 | return $new; 249 | } 250 | 251 | /** 252 | * Sets the size. 253 | * 254 | * @param ButtonSize|null $size The size. If `null`, the size will not be set. 255 | * 256 | * @return self A new instance with the specified size. 257 | * 258 | * Example usage: 259 | * ```php 260 | * $buttonGroup->size(ButtonSize::LARGE); 261 | * ``` 262 | */ 263 | public function size(ButtonSize|null $size): self 264 | { 265 | return $this->addClass($size?->value); 266 | } 267 | 268 | /** 269 | * Sets the button group to be vertical. 270 | * 271 | * @return self A new instance of the current class with the button group as vertical. 272 | * 273 | * Example usage: 274 | * ```php 275 | * $buttonGroup->vertical(); 276 | * ``` 277 | */ 278 | public function vertical(): self 279 | { 280 | return $this->addClass('btn-group-vertical'); 281 | } 282 | 283 | /** 284 | * Run the button group widget. 285 | * 286 | * @return string The HTML representation of the element. 287 | */ 288 | public function render(): string 289 | { 290 | $attributes = $this->attributes; 291 | $classes = $attributes['class'] ?? null; 292 | 293 | unset($attributes['class'], $attributes['id']); 294 | 295 | $button = implode("\n", $this->buttons); 296 | $buttons = $button === '' ? '' : "\n" . $button . "\n"; 297 | 298 | if ($buttons === '') { 299 | return ''; 300 | } 301 | 302 | return Div::tag() 303 | ->attributes($attributes) 304 | ->attribute('role', 'group') 305 | ->addClass( 306 | self::NAME, 307 | $classes, 308 | ...$this->cssClasses, 309 | ) 310 | ->content($buttons) 311 | ->encode(false) 312 | ->id($this->getId()) 313 | ->render(); 314 | } 315 | 316 | /** 317 | * Generates the ID. 318 | * 319 | * @return string|null The generated ID. 320 | * 321 | * @psalm-return non-empty-string|null The generated ID. 322 | */ 323 | private function getId(): string|null 324 | { 325 | return match ($this->id) { 326 | true => $this->attributes['id'] ?? Html::generateId(self::NAME . '-'), 327 | '', false => null, 328 | default => $this->id, 329 | }; 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /src/CarouselItem.php: -------------------------------------------------------------------------------- 1 | ', 25 | * 'Image Caption', 26 | * 'Caption Placeholder' 27 | * ); 28 | * ?> 29 | * 30 | * // Create an active carousel item with autoplay. 31 | * = CarouselItem::to( 32 | * content: '
',
33 | * caption: 'Slide 1',
34 | * active: true,
35 | * autoPlayingInterval: 5000
36 | * );
37 | * ?>
38 | * ```
39 | */
40 | final class CarouselItem
41 | {
42 | /**
43 | * Use {@see CarouselItem::to()} to create a new instance.
44 | */
45 | private function __construct(
46 | private bool $active,
47 | private array $attributes,
48 | private int|null $autoPlayingInterval,
49 | private string|null $caption,
50 | private array $captionAttributes,
51 | private string|null $captionPlaceholder,
52 | private array $captionPlaceholderAttributes,
53 | private string|Stringable $content,
54 | private bool $encodeCaption,
55 | private bool $encodeCaptionPlaceholder,
56 | ) {
57 | }
58 |
59 | /**
60 | * Creates a new {@see CarouselItem} instance.
61 | *
62 | * @param string|Stringable $content The content of the carousel item.
63 | * @param string|null $caption The caption content for the carousel item.
64 | * @param string|null $captionPlaceholder The caption placeholder content for the carousel item.
65 | * @param int|null $autoPlayingInterval The autoplaying interval for the carousel item.
66 | * @param bool $active Whether the item is active.
67 | * @param bool $encodeCaption Whether to encode the caption content.
68 | * @param bool $encodeCaptionPlaceholder Whether to encode the caption placeholder content.
69 | * @param array $attributes The HTML attributes for the carousel item.
70 | * @param array $captionAttributes The HTML attributes for the caption.
71 | * @param array $captionPlaceholderAttributes The HTML attributes for the caption placeholder.
72 | *
73 | * @return self A new instance with the specified configuration.
74 | */
75 | public static function to(
76 | string|Stringable $content = '',
77 | string|null $caption = null,
78 | string|null $captionPlaceholder = null,
79 | int|null $autoPlayingInterval = null,
80 | bool $active = false,
81 | bool $encodeCaption = true,
82 | bool $encodeCaptionPlaceholder = true,
83 | array $attributes = [],
84 | array $captionAttributes = [],
85 | array $captionPlaceholderAttributes = [],
86 | ): self {
87 | return new self(
88 | $active,
89 | $attributes,
90 | $autoPlayingInterval,
91 | $caption,
92 | $captionAttributes,
93 | $captionPlaceholder,
94 | $captionPlaceholderAttributes,
95 | $content,
96 | $encodeCaption,
97 | $encodeCaptionPlaceholder,
98 | );
99 | }
100 |
101 | /**
102 | * Sets the active state.
103 | *
104 | * @param bool $enabled Whether the breadcrumb link is active.
105 | *
106 | * @return self A new instance with the specified active state.
107 | */
108 | public function active(bool $enabled): self
109 | {
110 | $new = clone $this;
111 | $new->active = $enabled;
112 |
113 | return $new;
114 | }
115 |
116 | /**
117 | * Sets the HTML attributes for the link.
118 | *
119 | * @param array $attributes Attribute values indexed by attribute names.
120 | *
121 | * @return self A new instance with the specified attributes.
122 | *
123 | * @see {\Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
124 | */
125 | public function attributes(array $attributes): self
126 | {
127 | $new = clone $this;
128 | $new->attributes = $attributes;
129 |
130 | return $new;
131 | }
132 |
133 | /**
134 | * Sets the autoplaying interval.
135 | *
136 | * @param int $interval The autoplaying interval in milliseconds.
137 | *
138 | * @return self A new instance with the specified autoplaying interval.
139 | */
140 | public function autoPlayingInterval(int $interval): self
141 | {
142 | $new = clone $this;
143 | $new->autoPlayingInterval = $interval;
144 |
145 | return $new;
146 | }
147 |
148 | /**
149 | * Sets the caption content.
150 | *
151 | * @param string $caption The caption content.
152 | *
153 | * @return self A new instance with the specified caption content.
154 | */
155 | public function caption(string $caption): self
156 | {
157 | $new = clone $this;
158 | $new->caption = $caption;
159 |
160 | return $new;
161 | }
162 |
163 | /**
164 | * Sets the HTML attributes for the caption.
165 | *
166 | * @param array $captionAttributes Attribute values indexed by attribute names.
167 | *
168 | * @return self A new instance with the specified attributes for the caption.
169 | *
170 | * @see {\Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
171 | */
172 | public function captionAttributes(array $captionAttributes): self
173 | {
174 | $new = clone $this;
175 | $new->captionAttributes = $captionAttributes;
176 |
177 | return $new;
178 | }
179 |
180 | /**
181 | * Sets the caption placeholder content.
182 | *
183 | * @param string $captionPlaceholder The caption placeholder content.
184 | *
185 | * @return self A new instance with the specified caption placeholder content.
186 | */
187 | public function captionPlaceholder(string $captionPlaceholder): self
188 | {
189 | $new = clone $this;
190 | $new->captionPlaceholder = $captionPlaceholder;
191 |
192 | return $new;
193 | }
194 |
195 | /**
196 | * Sets the HTML attributes for the caption placeholder.
197 | *
198 | * @param array $captionPlaceholderAttributes Attribute values indexed by attribute names.
199 | *
200 | * @return self A new instance with the specified attributes for the caption placeholder.
201 | *
202 | * @see {\Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
203 | */
204 | public function captionPlaceholderAttributes(array $captionPlaceholderAttributes): self
205 | {
206 | $new = clone $this;
207 | $new->captionPlaceholderAttributes = $captionPlaceholderAttributes;
208 |
209 | return $new;
210 | }
211 |
212 | /**
213 | * Sets the content.
214 | *
215 | * @param string|Stringable $content The content.
216 | *
217 | * @return self A new instance with the specified content.
218 | */
219 | public function content(string|Stringable $content): self
220 | {
221 | $new = clone $this;
222 | $new->content = $content;
223 |
224 | return $new;
225 | }
226 |
227 | /**
228 | * Sets whether to encode the caption content.
229 | *
230 | * @param bool $encode Whether to encode the caption content.
231 | *
232 | * @return self A new instance with the specified encoding setting.
233 | */
234 | public function encodeCaption(bool $encode): self
235 | {
236 | $new = clone $this;
237 | $new->encodeCaption = $encode;
238 |
239 | return $new;
240 | }
241 |
242 | /**
243 | * Sets whether to encode the caption placeholder content.
244 | *
245 | * @param bool $encode Whether to encode the caption placeholder content.
246 | *
247 | * @return self A new instance with the specified encoding setting.
248 | */
249 | public function encodeCaptionPlaceholder(bool $encode): self
250 | {
251 | $new = clone $this;
252 | $new->encodeCaptionPlaceholder = $encode;
253 |
254 | return $new;
255 | }
256 |
257 | /**
258 | * @return array Returns the HTML attributes for the carousel item.
259 | */
260 | public function getAttributes(): array
261 | {
262 | return $this->attributes;
263 | }
264 |
265 | /**
266 | * @return int|null Returns the autoplaying interval for the carousel item.
267 | */
268 | public function getAutoPlayingInterval(): int|null
269 | {
270 | return $this->autoPlayingInterval;
271 | }
272 |
273 | /**
274 | * @return string|null Returns the caption content for the carousel item.
275 | */
276 | public function getCaption(): string|null
277 | {
278 | return $this->encodeCaption ? Html::encode($this->caption) : $this->caption;
279 | }
280 |
281 | /**
282 | * @return array Returns the HTML attributes for the caption.
283 | */
284 | public function getCaptionAttributes(): array
285 | {
286 | return $this->captionAttributes;
287 | }
288 |
289 | /**
290 | * @return string|null Returns the caption placeholder content for the carousel item.
291 | */
292 | public function getCaptionPlaceholder(): string|null
293 | {
294 | return $this->encodeCaptionPlaceholder ? Html::encode($this->captionPlaceholder) : $this->captionPlaceholder;
295 | }
296 |
297 | /**
298 | * @return array Returns the HTML attributes for the caption placeholder.
299 | */
300 | public function getCaptionPlaceholderAttributes(): array
301 | {
302 | return $this->captionPlaceholderAttributes;
303 | }
304 |
305 | /**
306 | * @return string|Stringable Returns the content for the carousel item.
307 | */
308 | public function getContent(): string|Stringable
309 | {
310 | return $this->content;
311 | }
312 |
313 | /**
314 | * @return bool Whether the item is active.
315 | */
316 | public function isActive(): bool
317 | {
318 | return $this->active;
319 | }
320 | }
321 |
--------------------------------------------------------------------------------
/src/NavLink.php:
--------------------------------------------------------------------------------
1 | active = $enabled;
153 |
154 | return $new;
155 | }
156 |
157 | /**
158 | * Sets the HTML attributes for the nav item.
159 | *
160 | * @param array $attributes Attribute values indexed by attribute names.
161 | *
162 | * @return self A new instance with the specified attributes.
163 | *
164 | * @see {\Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
165 | */
166 | public function attributes(array $attributes): self
167 | {
168 | $new = clone $this;
169 | $new->attributes = $attributes;
170 |
171 | return $new;
172 | }
173 |
174 | /**
175 | * Sets the content of the tab pane.
176 | *
177 | * @param string|Stringable $content The content of the tab pane.
178 | *
179 | * @return self A new instance with the specified content.
180 | */
181 | public function content(string|Stringable $content): self
182 | {
183 | $new = clone $this;
184 | $new->content = $content;
185 |
186 | return $new;
187 | }
188 |
189 | /**
190 | * Sets the disabled state of the nav item.
191 | *
192 | * @param bool $disabled Whether the nav item is disabled.
193 | *
194 | * @return self A new instance with the specified disabled state.
195 | */
196 | public function disabled(bool $disabled): self
197 | {
198 | $new = clone $this;
199 | $new->disabled = $disabled;
200 |
201 | return $new;
202 | }
203 |
204 | /**
205 | * Sets weather to HTML-encode the content.
206 | *
207 | * @param bool $enabled Whether to encode the content.
208 | *
209 | * @return self New instance with the specified encoded setting.
210 | */
211 | public function encodeContent(bool $enabled): self
212 | {
213 | $new = clone $this;
214 | $new->encodeContent = $enabled;
215 |
216 | return $new;
217 | }
218 |
219 | /**
220 | * Sets weather to HTML-encode the label.
221 | *
222 | * @param bool $enabled Whether to encode the label.
223 | *
224 | * @return self New instance with the specified encoded setting.
225 | */
226 | public function encodeLabel(bool $enabled): self
227 | {
228 | $new = clone $this;
229 | $new->encodeLabel = $enabled;
230 |
231 | return $new;
232 | }
233 |
234 | /**
235 | * @return string|Stringable The content of the tab pane.
236 | */
237 | public function getContent(): string|Stringable
238 | {
239 | return $this->content;
240 | }
241 |
242 | public function getId(): string
243 | {
244 | /** @psalm-var non-empty-string|null $id */
245 | return match ($this->paneId) {
246 | true => $this->paneAttributes['id'] ?? Html::generateId('pane'),
247 | '', false => throw new InvalidArgumentException('The tab pane ID must be specified.'),
248 | default => $this->paneId,
249 | };
250 | }
251 |
252 | /**
253 | * @return string|Stringable The label of Stringable object.
254 | */
255 | public function getLabel(): string|Stringable
256 | {
257 | return $this->label;
258 | }
259 |
260 | /**
261 | * @return array The HTML attributes for the tab pane.
262 | */
263 | public function getPaneAttributes(): array
264 | {
265 | return $this->paneAttributes;
266 | }
267 |
268 | /**
269 | * @return string|null The URL of the nav item.
270 | */
271 | public function getUrl(): string|null
272 | {
273 | return $this->url;
274 | }
275 |
276 | /**
277 | * @return array The HTML attributes for the nav item link.
278 | */
279 | public function getUrlAttributes(): array
280 | {
281 | return $this->urlAttributes;
282 | }
283 |
284 | /**
285 | * @return bool Whether the nav item has content.
286 | */
287 | public function hasContent(): bool
288 | {
289 | return $this->content !== '';
290 | }
291 |
292 | /**
293 | * Sets the ID of the nav component.
294 | *
295 | * @param bool|string $id The ID of the alert component. If `true`, an ID will be generated automatically.
296 | *
297 | * @return self A new instance with the specified ID.
298 | */
299 | public function paneId(bool|string $id): self
300 | {
301 | $new = clone $this;
302 | $new->paneId = $id;
303 |
304 | return $new;
305 | }
306 |
307 | /**
308 | * Sets the label text for the nav item.
309 | *
310 | * @param string|Stringable $label The label text or Stringable object
311 | *
312 | * @return self New instance with the specified label text.
313 | */
314 | public function label(string|Stringable $label): self
315 | {
316 | $new = clone $this;
317 | $new->label = $label;
318 |
319 | return $new;
320 | }
321 |
322 | /**
323 | * Sets the HTML attributes for the tab pane.
324 | *
325 | * @param array $attributes Attribute values indexed by attribute names.
326 | *
327 | * @return self New instance with the specified pane attributes.
328 | *
329 | * @see Html::renderTagAttributes() for details on how attributes are rendered.
330 | */
331 | public function paneAttributes(array $attributes): self
332 | {
333 | $new = clone $this;
334 | $new->paneAttributes = $attributes;
335 |
336 | return $new;
337 | }
338 |
339 | /**
340 | * Sets the URL for the nav item.
341 | *
342 | * @param string|null $url The URL or `null` for no URL.
343 | *
344 | * @return self New instance with the specified URL.
345 | */
346 | public function url(string|null $url): self
347 | {
348 | $new = clone $this;
349 | $new->url = $url;
350 |
351 | return $new;
352 | }
353 |
354 | /**
355 | * Sets HTML attributes for the nav item link.
356 | *
357 | * @param array $attributes Attribute values indexed by attribute names.
358 | *
359 | * @return self New instance with the specified link attributes.
360 | *
361 | * @see Html::renderTagAttributes() for details on how attributes are rendered.
362 | */
363 | public function urlAttributes(array $attributes): self
364 | {
365 | $new = clone $this;
366 | $new->urlAttributes = $attributes;
367 |
368 | return $new;
369 | }
370 |
371 | /**
372 | * Sets the visibility of the nav item.
373 | *
374 | * @param bool $enabled Whether the nav item is visible.
375 | *
376 | * @return self A new instance with the specified visibility.
377 | */
378 | public function visible(bool $enabled): self
379 | {
380 | $new = clone $this;
381 | $new->visible = $enabled;
382 |
383 | return $new;
384 | }
385 |
386 | /**
387 | * @return array The HTML attributes for the nav item.
388 | */
389 | public function getAttributes(): array
390 | {
391 | return $this->attributes;
392 | }
393 |
394 | /**
395 | * @return bool Whether the nav item is active.
396 | */
397 | public function isActive(): bool
398 | {
399 | return $this->active;
400 | }
401 |
402 | /**
403 | * @return bool Whether the nav item is disabled.
404 | */
405 | public function isDisabled(): bool
406 | {
407 | return $this->disabled;
408 | }
409 |
410 | /**
411 | * @return bool Whether the nav item is visible.
412 | */
413 | public function isVisible(): bool
414 | {
415 | return $this->visible;
416 | }
417 |
418 | /**
419 | * @return bool Whether the content should be encoded.
420 | */
421 | public function shouldEncodeContent(): bool
422 | {
423 | return $this->encodeContent;
424 | }
425 |
426 | /**
427 | * @return bool Whether the label should be encoded.
428 | */
429 | public function shouldEncodeLabel(): bool
430 | {
431 | return $this->encodeLabel;
432 | }
433 | }
434 |
--------------------------------------------------------------------------------
/src/DropdownItem.php:
--------------------------------------------------------------------------------
1 | ` tag.
63 | * @param array $itemAttributes The HTML attributes for the `