diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..c2913c2
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,20 @@
+# Changelog
+
+Starting with version 2.4.0, all notable changes will be documented in this file following
+the [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format. This project adheres
+to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+## [2.4.0] - 2021-01-22
+
+### Added
+
+- Added support for [Laravel Blade Components](https://laravel.com/docs/8.x/blade#components)
+
+## 2.3.4 and before
+
+For all releases from 2.3.4 and below, see the [Github Releases](https://github.com/glhd/aire/releases).
+
+[Unreleased]: https://github.com/olivierlacan/keep-a-changelog/compare/2.4.0...HEAD
+[2.4.0]: https://github.com/olivierlacan/keep-a-changelog/compare/2.3.4...2.4.0
diff --git a/README.md b/README.md
index 027bb8c..732d428 100755
--- a/README.md
+++ b/README.md
@@ -73,6 +73,36 @@ are fluent, allowing for easy configuration of your form components:
{{ Aire::close() }}
```
+### Blade Components
+
+As of Aire 2.4.0, you can also use all Aire elements as [Blade Components](https://laravel.com/docs/8.x/blade#components).
+The above form is identical to:
+
+```html
+
+
+
+
+
+
+
+
+
+```
+
## Installation
Install via composer with:
diff --git a/bin/build-blade-components.php b/bin/build-blade-components.php
new file mode 100755
index 0000000..6c07d8a
--- /dev/null
+++ b/bin/build-blade-components.php
@@ -0,0 +1,129 @@
+#!/usr/bin/env php
+files()
+ ->in(__DIR__.'/../src/Elements')
+ ->depth(0)
+ ->name('*.php');
+
+$ignored_concerns = ['CreatesElements', 'CreatesInputTypes'];
+
+$ignored_methods = collect($ignored_concerns)
+ ->flatMap(function($name) {
+ return (new ReflectionClass("Galahad\\Aire\\Elements\\Concerns\\{$name}"))->getMethods();
+ })
+ ->map(function(ReflectionMethod $method) {
+ return $method->getName();
+ })
+ ->values()
+ ->all();
+
+collect($finder)
+ ->map(function(\Symfony\Component\Finder\SplFileInfo $file) {
+ return 'Galahad\\Aire\\Elements\\'.$file->getBasename('.php');
+ })
+ ->values()
+ ->filter(function($class_name) {
+ return class_exists($class_name);
+ })
+ ->map(function($class_name) {
+ return new ReflectionClass($class_name);
+ })
+ ->reject(function(ReflectionClass $class) {
+ return $class->isAbstract();
+ })
+ ->each(function(ReflectionClass $class) use ($ignored_methods) {
+ $methods = collect($class->getMethods(ReflectionMethod::IS_PUBLIC))
+ ->keyBy(function(ReflectionMethod $method) {
+ return $method->getName();
+ })
+ ->reject(function(ReflectionMethod $method) {
+ return $method->isStatic()
+ || $method->isAbstract()
+ || $method->getDeclaringClass()->getName() === 'Galahad\\Aire\\Elements\\Concerns\\CreatesElements'
+ || preg_match('/^(__|(get|set|has|is)[A-Z])/', $method->getName());
+ })
+ ->except([
+ 'render',
+ 'toHtml',
+ 'hasViewData',
+ 'callMacro',
+ 'registerElement',
+ ])
+ ->except($ignored_methods);
+
+ $properties = $methods->map(function(ReflectionMethod $method) {
+ if (0 === $method->getNumberOfParameters()) {
+ $type = '?bool ';
+ } elseif ($method->getNumberOfParameters() > 1) {
+ $type = '?array ';
+ } else {
+ $parameter = $method->getParameters()[0];
+ if ($parameter->hasType()) {
+ $type = '?'.$parameter->getType()->getName().' ';
+ } else {
+ $type = '';
+ }
+ }
+
+ return (object) [
+ 'name' => $method->getName(),
+ 'type' => $type,
+ ];
+ });
+
+ // $props = $properties
+ // ->map(function($property) {
+ // return "public {$property->type}\${$property->name} = null;";
+ // })
+ // ->implode("\n\t\n\t");
+
+ $params = $properties
+ ->map(function($property) {
+ return "{$property->type}\${$property->name} = null";
+ })
+ ->implode(",\n\t\t");
+
+ $compact = $properties
+ ->map(function($property) {
+ return "'{$property->name}'";
+ })
+ ->implode(",\n\t\t\t");
+
+ $name = class_basename($class->getName());
+
+ $code = <<createElement({$name}Element::class, compact(
+ {$compact}
+ ));
+ }
+}
+
+PHP;
+
+ $filename = __DIR__.'/../src/Components/'.$name.'.php';
+
+ if (!file_exists($filename)) {
+ file_put_contents($filename, $code);
+ echo "Wrote $filename\n";
+ } else {
+ echo "FILE ALREADY EXISTS: $filename\n\n";
+ echo $code;
+ echo "\n\n";
+ }
+
+ });
diff --git a/bin/codegen.php b/bin/codegen.php
index 115634b..adfcf5d 100755
--- a/bin/codegen.php
+++ b/bin/codegen.php
@@ -1,6 +1,8 @@
#!/usr/bin/env php
$camel,
- 'snake' => snake_case($camel),
- 'hyphen' => snake_case($camel, '-'),
- 'studly' => studly_case($camel),
+ 'snake' => Str::snake($camel),
+ 'hyphen' => Str::snake($camel, '-'),
+ 'studly' => Str::studly($camel),
];
}
@@ -175,12 +177,13 @@ function print_setter($attribute, $attribute_config, $parent = 'Element') {
}
}
-function print_setter_test($attribute, $attribute_config, $tag = 'form') {
- $class_name = studly_case($tag);
+function print_setter_test($attribute, $attribute_config, $tag = 'form', $component = false) {
+ $class_name = Str::studly($tag);
$is_flag = isset($attribute_config['type']) && 'flag' === $attribute_config['type'];
$is_bool = isset($attribute_config['type']) && 'boolean' === $attribute_config['type'];
$test_name = $attribute_config['spellings']->snake;
$method = $attribute_config['spellings']->camel;
+ $xml_attribute = $attribute_config['spellings']->hyphen;
if ($is_flag) {
@@ -199,37 +202,59 @@ function print_setter_test($attribute, $attribute_config, $tag = 'form') {
}
- $target = '$form';
+ $target = '$'.strtolower($class_name);
- if ('Form' !== $class_name) {
- $target = '$'.strtolower($class_name);
-
- echo "\t\t$target = new $class_name(\$this->aire(), \$this->aire()->form());\n";
- } else {
- echo "\t\t\$form = \$this->aire()->form();\n";
+ if (!$component) {
+ if ('Form' !== $class_name) {
+ echo "\t\t$target = new $class_name(\$this->aire(), \$this->aire()->form());\n";
+ } else {
+ echo "\t\t$target = \$this->aire()->form();\n";
+ }
+ echo "\t\t\n";
}
- echo "\t\t\n";
-
if ($is_flag) {
- echo "\t\t$target->$method();\n";
+ if ($component) {
+ echo "\t\t$target = \$this->renderBlade('');\n";
+ } else {
+ echo "\t\t$target->$method();\n";
+ }
echo "\t\t\$this->assertSelectorAttribute($target, '$tag', '$attribute');\n";
echo "\t\t\n";
- echo "\t\t$target->$method(false);\n";
+
+ if ($component) {
+ echo "\t\t$target = \$this->renderBlade('');\n";
+ } else {
+ echo "\t\t$target->$method(false);\n";
+ }
echo "\t\t\$this->assertSelectorAttributeMissing($target, '$tag', '$attribute');\n";
echo "\t}\n";
echo "\t\n";
} else if ($is_bool) {
- echo "\t\t$target->$method();\n";
+ if ($component) {
+ echo "\t\t$target = \$this->renderBlade('');\n";
+ } else {
+ echo "\t\t$target->$method();\n";
+ }
echo "\t\t\$this->assertSelectorAttribute($target, '$tag', '$attribute', 'true');\n";
echo "\t\t\n";
- echo "\t\t$target->$method(false);\n";
+
+ if ($component) {
+ echo "\t\t$target = \$this->renderBlade('');\n";
+ } else {
+ echo "\t\t$target->$method(false);\n";
+ }
echo "\t\t\$this->assertSelectorAttribute($target, '$tag', '$attribute', 'false');\n";
echo "\t\t\n";
- echo "\t\t$target->$method(null);\n";
+
+ if ($component) {
+ echo "\t\t$target = \$this->renderBlade('');\n";
+ } else {
+ echo "\t\t$target->$method(null);\n";
+ }
echo "\t\t\$this->assertSelectorAttributeMissing($target, '$tag', '$attribute');\n";
echo "\t}\n";
echo "\t\n";
@@ -239,19 +264,33 @@ function print_setter_test($attribute, $attribute_config, $tag = 'form') {
if (isset($attribute_config['attribOption'])) {
foreach ($attribute_config['attribOption'] as $value) {
$value = addslashes($value);
- echo "\t\t$target->$method('$value');\n";
+
+ if ($component) {
+ echo "\t\t$target = \$this->renderBlade('');\n";
+ } else {
+ echo "\t\t$target->$method('$value');\n";
+ }
echo "\t\t\$this->assertSelectorAttribute($target, '$tag', '$attribute', '$value');\n";
echo "\t\t\n";
}
} else {
echo "\t\t\$value = Str::random();\n";
echo "\t\t\n";
- echo "\t\t$target->$method(\$value);\n";
+
+ if ($component) {
+ echo "\t\t$target = \$this->renderBlade('', compact('value'));\n";
+ } else {
+ echo "\t\t$target->$method(\$value);\n";
+ }
echo "\t\t\$this->assertSelectorAttribute($target, '$tag', '$attribute', \$value);\n";
echo "\t\t\n";
}
- echo "\t\t$target->$method(null);\n";
+ if ($component) {
+ echo "\t\t$target = \$this->renderBlade('');\n";
+ } else {
+ echo "\t\t$target->$method(null);\n";
+ }
echo "\t\t\$this->assertSelectorAttributeMissing($target, '$tag', '$attribute');\n";
echo "\t}\n";
echo "\t\n";
diff --git a/bin/codegen/component_global_attribute_tests.php b/bin/codegen/component_global_attribute_tests.php
new file mode 100644
index 0000000..f1b3ce2
--- /dev/null
+++ b/bin/codegen/component_global_attribute_tests.php
@@ -0,0 +1,37 @@
+ $attribute_config) {
+ print_setter_test($attribute, $attribute_config, 'form', true);
+}
+
+echo "}\n";
+
+if ($write) {
+ $php = ob_get_clean();
+
+ $file_path = __DIR__.'/../../tests/Components/GlobalAttributesTest.php';
+ file_put_contents($file_path, $php);
+ echo "Wrote $file_path\n";
+}
diff --git a/bin/codegen/component_tests.php b/bin/codegen/component_tests.php
new file mode 100644
index 0000000..0db1173
--- /dev/null
+++ b/bin/codegen/component_tests.php
@@ -0,0 +1,47 @@
+ $config) {
+
+ if (!isset($config['attributes'])) {
+ continue;
+ }
+
+ if ($write) {
+ ob_start();
+ }
+
+ echo " $attribute_config) {
+ print_setter_test($attribute, $attribute_config, $tag, true);
+ }
+
+ echo "}\n";
+
+ if ($write) {
+ $file_path = __DIR__.'/../../tests/Components/'.$class_name.'Test.php';
+ file_put_contents($file_path, ob_get_clean());
+ echo "Wrote $file_path\n";
+ }
+}
diff --git a/composer.json b/composer.json
index 809c8a5..96b07ab 100755
--- a/composer.json
+++ b/composer.json
@@ -22,12 +22,12 @@
"mockery/mockery": "^1.3"
},
"require-dev": {
- "orchestra/testbench": "^4.0",
+ "orchestra/testbench": "^6.0",
"phpunit/phpunit": "^8.0",
"php-coveralls/php-coveralls": "^2.1",
"guzzlehttp/guzzle": "~6.0",
- "symfony/css-selector": "^4.1",
- "symfony/dom-crawler": "^4.1",
+ "symfony/css-selector": "^5.0",
+ "symfony/dom-crawler": "^5.0",
"barryvdh/reflection-docblock": "^2.0"
},
"suggest": {
diff --git a/src/Components/Button.php b/src/Components/Button.php
new file mode 100644
index 0000000..96ce5d7
--- /dev/null
+++ b/src/Components/Button.php
@@ -0,0 +1,120 @@
+createElement(ButtonElement::class, compact(
+ 'open',
+ 'close',
+ 'labelHtml',
+ 'autoFocus',
+ 'disabled',
+ 'form',
+ 'formAction',
+ 'formEncType',
+ 'formMethod',
+ 'formNoValidate',
+ 'formTarget',
+ 'name',
+ 'type',
+ 'value',
+ 'data',
+ 'addClass',
+ 'removeClass',
+ 'accessKey',
+ 'class',
+ 'contentEditable',
+ 'contextMenu',
+ 'dir',
+ 'draggable',
+ 'dropZone',
+ 'hide',
+ 'id',
+ 'lang',
+ 'role',
+ 'spellCheck',
+ 'style',
+ 'tabIndex',
+ 'title',
+ 'ariaActiveDescendant',
+ 'ariaAtomic',
+ 'ariaBusy',
+ 'ariaControls',
+ 'ariaDescribedBy',
+ 'ariaDisabled',
+ 'ariaDropEffect',
+ 'ariaFlowTo',
+ 'ariaGrabbed',
+ 'ariaHasPopup',
+ 'ariaHidden',
+ 'ariaInvalid',
+ 'ariaLabel',
+ 'ariaLabelledBy',
+ 'ariaLive',
+ 'ariaOwns',
+ 'ariaRelevant',
+ 'grouped',
+ 'withoutGroup',
+ 'variant',
+ 'variants'
+ ));
+ }
+}
diff --git a/src/Components/Checkbox.php b/src/Components/Checkbox.php
new file mode 100644
index 0000000..94461c9
--- /dev/null
+++ b/src/Components/Checkbox.php
@@ -0,0 +1,244 @@
+createElement(CheckboxElement::class, compact(
+ 'labelHtml',
+ 'name',
+ 'defaultChecked',
+ 'type',
+ 'accept',
+ 'alt',
+ 'autoComplete',
+ 'autoFocus',
+ 'checked',
+ 'dirName',
+ 'disabled',
+ 'form',
+ 'formAction',
+ 'formEncType',
+ 'formMethod',
+ 'formNoValidate',
+ 'formTarget',
+ 'height',
+ 'list',
+ 'max',
+ 'maxLength',
+ 'min',
+ 'multiple',
+ 'pattern',
+ 'placeholder',
+ 'readOnly',
+ 'required',
+ 'size',
+ 'src',
+ 'step',
+ 'value',
+ 'width',
+ 'data',
+ 'addClass',
+ 'removeClass',
+ 'accessKey',
+ 'class',
+ 'contentEditable',
+ 'contextMenu',
+ 'dir',
+ 'draggable',
+ 'dropZone',
+ 'hide',
+ 'id',
+ 'lang',
+ 'role',
+ 'spellCheck',
+ 'style',
+ 'tabIndex',
+ 'title',
+ 'ariaActiveDescendant',
+ 'ariaAtomic',
+ 'ariaBusy',
+ 'ariaControls',
+ 'ariaDescribedBy',
+ 'ariaDisabled',
+ 'ariaDropEffect',
+ 'ariaFlowTo',
+ 'ariaGrabbed',
+ 'ariaHasPopup',
+ 'ariaHidden',
+ 'ariaInvalid',
+ 'ariaLabel',
+ 'ariaLabelledBy',
+ 'ariaLive',
+ 'ariaOwns',
+ 'ariaRelevant',
+ 'grouped',
+ 'withoutGroup',
+ 'variant',
+ 'variants',
+ 'defaultValue',
+ 'label',
+ 'helpText',
+ 'validated',
+ 'valid',
+ 'invalid',
+ 'errors',
+ 'prepend',
+ 'append',
+ 'groupData',
+ 'groupAccessKey',
+ 'groupClass',
+ 'groupContentEditable',
+ 'groupContextMenu',
+ 'groupDir',
+ 'groupDraggable',
+ 'groupDropZone',
+ 'groupHide',
+ 'groupId',
+ 'groupLang',
+ 'groupRole',
+ 'groupSpellCheck',
+ 'groupStyle',
+ 'groupTabIndex',
+ 'groupTitle',
+ 'groupAriaActiveDescendant',
+ 'groupAriaAtomic',
+ 'groupAriaBusy',
+ 'groupAriaControls',
+ 'groupAriaDescribedBy',
+ 'groupAriaDisabled',
+ 'groupAriaDropEffect',
+ 'groupAriaFlowTo',
+ 'groupAriaGrabbed',
+ 'groupAriaHasPopup',
+ 'groupAriaHidden',
+ 'groupAriaInvalid',
+ 'groupAriaLabel',
+ 'groupAriaLabelledBy',
+ 'groupAriaLive',
+ 'groupAriaOwns',
+ 'groupAriaRelevant',
+ 'groupAddClass',
+ 'groupRemoveClass'
+ ));
+ }
+}
diff --git a/src/Components/CheckboxGroup.php b/src/Components/CheckboxGroup.php
new file mode 100644
index 0000000..2aaf305
--- /dev/null
+++ b/src/Components/CheckboxGroup.php
@@ -0,0 +1,247 @@
+options = $options;
+
+ $this->createElement(CheckboxGroupElement::class, compact(
+ 'accept',
+ 'alt',
+ 'autoComplete',
+ 'autoFocus',
+ 'checked',
+ 'dirName',
+ 'disabled',
+ 'form',
+ 'formAction',
+ 'formEncType',
+ 'formMethod',
+ 'formNoValidate',
+ 'formTarget',
+ 'height',
+ 'list',
+ 'max',
+ 'maxLength',
+ 'min',
+ 'multiple',
+ 'name',
+ 'pattern',
+ 'placeholder',
+ 'readOnly',
+ 'required',
+ 'size',
+ 'src',
+ 'step',
+ 'type',
+ 'value',
+ 'width',
+ 'data',
+ 'addClass',
+ 'removeClass',
+ 'accessKey',
+ 'class',
+ 'contentEditable',
+ 'contextMenu',
+ 'dir',
+ 'draggable',
+ 'dropZone',
+ 'hide',
+ 'id',
+ 'lang',
+ 'role',
+ 'spellCheck',
+ 'style',
+ 'tabIndex',
+ 'title',
+ 'ariaActiveDescendant',
+ 'ariaAtomic',
+ 'ariaBusy',
+ 'ariaControls',
+ 'ariaDescribedBy',
+ 'ariaDisabled',
+ 'ariaDropEffect',
+ 'ariaFlowTo',
+ 'ariaGrabbed',
+ 'ariaHasPopup',
+ 'ariaHidden',
+ 'ariaInvalid',
+ 'ariaLabel',
+ 'ariaLabelledBy',
+ 'ariaLive',
+ 'ariaOwns',
+ 'ariaRelevant',
+ 'grouped',
+ 'withoutGroup',
+ 'variant',
+ 'variants',
+ 'defaultValue',
+ 'prependEmptyOption',
+ 'label',
+ 'helpText',
+ 'validated',
+ 'valid',
+ 'invalid',
+ 'errors',
+ 'prepend',
+ 'append',
+ 'groupData',
+ 'groupAccessKey',
+ 'groupClass',
+ 'groupContentEditable',
+ 'groupContextMenu',
+ 'groupDir',
+ 'groupDraggable',
+ 'groupDropZone',
+ 'groupHide',
+ 'groupId',
+ 'groupLang',
+ 'groupRole',
+ 'groupSpellCheck',
+ 'groupStyle',
+ 'groupTabIndex',
+ 'groupTitle',
+ 'groupAriaActiveDescendant',
+ 'groupAriaAtomic',
+ 'groupAriaBusy',
+ 'groupAriaControls',
+ 'groupAriaDescribedBy',
+ 'groupAriaDisabled',
+ 'groupAriaDropEffect',
+ 'groupAriaFlowTo',
+ 'groupAriaGrabbed',
+ 'groupAriaHasPopup',
+ 'groupAriaHidden',
+ 'groupAriaInvalid',
+ 'groupAriaLabel',
+ 'groupAriaLabelledBy',
+ 'groupAriaLive',
+ 'groupAriaOwns',
+ 'groupAriaRelevant',
+ 'groupAddClass',
+ 'groupRemoveClass'
+ ));
+ }
+}
diff --git a/src/Components/Color.php b/src/Components/Color.php
new file mode 100644
index 0000000..3330c43
--- /dev/null
+++ b/src/Components/Color.php
@@ -0,0 +1,13 @@
+element;
+ }
+
+ public function withAttributes(array $attributes)
+ {
+ parent::withAttributes($attributes);
+
+ collect($this->attributes->getAttributes())
+ ->reject(function($arguments) {
+ return null === $arguments;
+ })
+ ->each(function($arguments, $name) {
+ if (method_exists($this->element, $name)) {
+ $arguments = Arr::wrap($arguments);
+ $this->element->{$name}(...$arguments);
+ } else {
+ $this->element->setAttribute($name, $arguments);
+ }
+ });
+
+ return $this;
+ }
+
+ protected function createElement(string $element_class, array $parameters)
+ {
+ $this->element = $this->getElementInstance($element_class);
+
+ collect($parameters)
+ ->reject(function($arguments) {
+ return null === $arguments;
+ })
+ ->each(function($arguments, $name) {
+ $arguments = Arr::wrap($arguments);
+ $this->element->{$name}(...$arguments);
+ });
+ }
+
+ protected function getElementInstance(string $element_class): Element
+ {
+ $aire = Aire::getFacadeRoot();
+
+ return new $element_class($aire, $aire->form());
+ }
+}
diff --git a/src/Components/Email.php b/src/Components/Email.php
new file mode 100644
index 0000000..c396e73
--- /dev/null
+++ b/src/Components/Email.php
@@ -0,0 +1,13 @@
+createElement(FormElement::class, compact(
+ 'dev',
+ 'bind',
+ 'resourceful',
+ 'asAlpineComponent',
+ 'open',
+ 'close',
+ 'openButton',
+ 'closeButton',
+ 'route',
+ 'get',
+ 'post',
+ 'put',
+ 'patch',
+ 'delete',
+ 'method',
+ 'urlEncoded',
+ 'multipart',
+ 'validate',
+ 'withoutValidation',
+ 'rules',
+ 'messages',
+ 'formRequest',
+ 'acceptCharset',
+ 'action',
+ 'autoComplete',
+ 'encType',
+ 'name',
+ 'noValidate',
+ 'target',
+ 'data',
+ 'addClass',
+ 'removeClass',
+ 'accessKey',
+ 'class',
+ 'contentEditable',
+ 'contextMenu',
+ 'dir',
+ 'draggable',
+ 'dropZone',
+ 'hide',
+ 'id',
+ 'lang',
+ 'role',
+ 'spellCheck',
+ 'style',
+ 'tabIndex',
+ 'title',
+ 'ariaActiveDescendant',
+ 'ariaAtomic',
+ 'ariaBusy',
+ 'ariaControls',
+ 'ariaDescribedBy',
+ 'ariaDisabled',
+ 'ariaDropEffect',
+ 'ariaFlowTo',
+ 'ariaGrabbed',
+ 'ariaHasPopup',
+ 'ariaHidden',
+ 'ariaInvalid',
+ 'ariaLabel',
+ 'ariaLabelledBy',
+ 'ariaLive',
+ 'ariaOwns',
+ 'ariaRelevant',
+ 'grouped',
+ 'withoutGroup',
+ 'variant',
+ 'variants'
+ ));
+ }
+
+ public function resolveView()
+ {
+ return function($data) {
+ $this->element->open();
+ echo $data['slot'];
+ return $this->element->close();
+ };
+ }
+
+ protected function getElementInstance(string $element_class) : Element
+ {
+ return Aire::getFacadeRoot()->form();
+ }
+}
diff --git a/src/Components/Hidden.php b/src/Components/Hidden.php
new file mode 100644
index 0000000..6b130c1
--- /dev/null
+++ b/src/Components/Hidden.php
@@ -0,0 +1,13 @@
+createElement(InputElement::class, compact(
+ 'type',
+ 'accept',
+ 'alt',
+ 'autoComplete',
+ 'autoFocus',
+ 'checked',
+ 'dirName',
+ 'disabled',
+ 'form',
+ 'formAction',
+ 'formEncType',
+ 'formMethod',
+ 'formNoValidate',
+ 'formTarget',
+ 'height',
+ 'list',
+ 'max',
+ 'maxLength',
+ 'min',
+ 'multiple',
+ 'name',
+ 'pattern',
+ 'placeholder',
+ 'readOnly',
+ 'required',
+ 'size',
+ 'src',
+ 'step',
+ 'value',
+ 'width',
+ 'data',
+ 'addClass',
+ 'removeClass',
+ 'accessKey',
+ 'class',
+ 'contentEditable',
+ 'contextMenu',
+ 'dir',
+ 'draggable',
+ 'dropZone',
+ 'hide',
+ 'id',
+ 'lang',
+ 'role',
+ 'spellCheck',
+ 'style',
+ 'tabIndex',
+ 'title',
+ 'ariaActiveDescendant',
+ 'ariaAtomic',
+ 'ariaBusy',
+ 'ariaControls',
+ 'ariaDescribedBy',
+ 'ariaDisabled',
+ 'ariaDropEffect',
+ 'ariaFlowTo',
+ 'ariaGrabbed',
+ 'ariaHasPopup',
+ 'ariaHidden',
+ 'ariaInvalid',
+ 'ariaLabel',
+ 'ariaLabelledBy',
+ 'ariaLive',
+ 'ariaOwns',
+ 'ariaRelevant',
+ 'grouped',
+ 'withoutGroup',
+ 'variant',
+ 'variants',
+ 'defaultValue',
+ 'label',
+ 'helpText',
+ 'validated',
+ 'valid',
+ 'invalid',
+ 'errors',
+ 'prepend',
+ 'append',
+ 'groupData',
+ 'groupAccessKey',
+ 'groupClass',
+ 'groupContentEditable',
+ 'groupContextMenu',
+ 'groupDir',
+ 'groupDraggable',
+ 'groupDropZone',
+ 'groupHide',
+ 'groupId',
+ 'groupLang',
+ 'groupRole',
+ 'groupSpellCheck',
+ 'groupStyle',
+ 'groupTabIndex',
+ 'groupTitle',
+ 'groupAriaActiveDescendant',
+ 'groupAriaAtomic',
+ 'groupAriaBusy',
+ 'groupAriaControls',
+ 'groupAriaDescribedBy',
+ 'groupAriaDisabled',
+ 'groupAriaDropEffect',
+ 'groupAriaFlowTo',
+ 'groupAriaGrabbed',
+ 'groupAriaHasPopup',
+ 'groupAriaHidden',
+ 'groupAriaInvalid',
+ 'groupAriaLabel',
+ 'groupAriaLabelledBy',
+ 'groupAriaLive',
+ 'groupAriaOwns',
+ 'groupAriaRelevant',
+ 'groupAddClass',
+ 'groupRemoveClass'
+ ));
+ }
+}
diff --git a/src/Components/Month.php b/src/Components/Month.php
new file mode 100644
index 0000000..bef036a
--- /dev/null
+++ b/src/Components/Month.php
@@ -0,0 +1,13 @@
+options = $options;
+
+ $this->createElement(RadioGroupElement::class, compact(
+ 'accept',
+ 'alt',
+ 'autoComplete',
+ 'autoFocus',
+ 'checked',
+ 'dirName',
+ 'disabled',
+ 'form',
+ 'formAction',
+ 'formEncType',
+ 'formMethod',
+ 'formNoValidate',
+ 'formTarget',
+ 'height',
+ 'list',
+ 'max',
+ 'maxLength',
+ 'min',
+ 'multiple',
+ 'name',
+ 'pattern',
+ 'placeholder',
+ 'readOnly',
+ 'required',
+ 'size',
+ 'src',
+ 'step',
+ 'type',
+ 'value',
+ 'width',
+ 'data',
+ 'addClass',
+ 'removeClass',
+ 'accessKey',
+ 'class',
+ 'contentEditable',
+ 'contextMenu',
+ 'dir',
+ 'draggable',
+ 'dropZone',
+ 'hide',
+ 'id',
+ 'lang',
+ 'role',
+ 'spellCheck',
+ 'style',
+ 'tabIndex',
+ 'title',
+ 'ariaActiveDescendant',
+ 'ariaAtomic',
+ 'ariaBusy',
+ 'ariaControls',
+ 'ariaDescribedBy',
+ 'ariaDisabled',
+ 'ariaDropEffect',
+ 'ariaFlowTo',
+ 'ariaGrabbed',
+ 'ariaHasPopup',
+ 'ariaHidden',
+ 'ariaInvalid',
+ 'ariaLabel',
+ 'ariaLabelledBy',
+ 'ariaLive',
+ 'ariaOwns',
+ 'ariaRelevant',
+ 'grouped',
+ 'withoutGroup',
+ 'variant',
+ 'variants',
+ 'defaultValue',
+ 'prependEmptyOption',
+ 'label',
+ 'helpText',
+ 'validated',
+ 'valid',
+ 'invalid',
+ 'errors',
+ 'prepend',
+ 'append',
+ 'groupData',
+ 'groupAccessKey',
+ 'groupClass',
+ 'groupContentEditable',
+ 'groupContextMenu',
+ 'groupDir',
+ 'groupDraggable',
+ 'groupDropZone',
+ 'groupHide',
+ 'groupId',
+ 'groupLang',
+ 'groupRole',
+ 'groupSpellCheck',
+ 'groupStyle',
+ 'groupTabIndex',
+ 'groupTitle',
+ 'groupAriaActiveDescendant',
+ 'groupAriaAtomic',
+ 'groupAriaBusy',
+ 'groupAriaControls',
+ 'groupAriaDescribedBy',
+ 'groupAriaDisabled',
+ 'groupAriaDropEffect',
+ 'groupAriaFlowTo',
+ 'groupAriaGrabbed',
+ 'groupAriaHasPopup',
+ 'groupAriaHidden',
+ 'groupAriaInvalid',
+ 'groupAriaLabel',
+ 'groupAriaLabelledBy',
+ 'groupAriaLive',
+ 'groupAriaOwns',
+ 'groupAriaRelevant',
+ 'groupAddClass',
+ 'groupRemoveClass'
+ ));
+ }
+}
diff --git a/src/Components/Range.php b/src/Components/Range.php
new file mode 100644
index 0000000..0e547de
--- /dev/null
+++ b/src/Components/Range.php
@@ -0,0 +1,13 @@
+options, $aire->form());
+ }
+}
diff --git a/src/Components/Search.php b/src/Components/Search.php
new file mode 100644
index 0000000..8f22516
--- /dev/null
+++ b/src/Components/Search.php
@@ -0,0 +1,13 @@
+options = $options;
+
+ $this->createElement(SelectElement::class, compact(
+ 'autoFocus',
+ 'disabled',
+ 'form',
+ 'multiple',
+ 'name',
+ 'required',
+ 'size',
+ 'data',
+ 'addClass',
+ 'removeClass',
+ 'accessKey',
+ 'class',
+ 'contentEditable',
+ 'contextMenu',
+ 'dir',
+ 'draggable',
+ 'dropZone',
+ 'hide',
+ 'id',
+ 'lang',
+ 'role',
+ 'spellCheck',
+ 'style',
+ 'tabIndex',
+ 'title',
+ 'ariaActiveDescendant',
+ 'ariaAtomic',
+ 'ariaBusy',
+ 'ariaControls',
+ 'ariaDescribedBy',
+ 'ariaDisabled',
+ 'ariaDropEffect',
+ 'ariaFlowTo',
+ 'ariaGrabbed',
+ 'ariaHasPopup',
+ 'ariaHidden',
+ 'ariaInvalid',
+ 'ariaLabel',
+ 'ariaLabelledBy',
+ 'ariaLive',
+ 'ariaOwns',
+ 'ariaRelevant',
+ 'grouped',
+ 'withoutGroup',
+ 'variant',
+ 'variants',
+ 'defaultValue',
+ 'value',
+ 'prependEmptyOption',
+ 'label',
+ 'helpText',
+ 'validated',
+ 'valid',
+ 'invalid',
+ 'errors',
+ 'prepend',
+ 'append',
+ 'groupData',
+ 'groupAccessKey',
+ 'groupClass',
+ 'groupContentEditable',
+ 'groupContextMenu',
+ 'groupDir',
+ 'groupDraggable',
+ 'groupDropZone',
+ 'groupHide',
+ 'groupId',
+ 'groupLang',
+ 'groupRole',
+ 'groupSpellCheck',
+ 'groupStyle',
+ 'groupTabIndex',
+ 'groupTitle',
+ 'groupAriaActiveDescendant',
+ 'groupAriaAtomic',
+ 'groupAriaBusy',
+ 'groupAriaControls',
+ 'groupAriaDescribedBy',
+ 'groupAriaDisabled',
+ 'groupAriaDropEffect',
+ 'groupAriaFlowTo',
+ 'groupAriaGrabbed',
+ 'groupAriaHasPopup',
+ 'groupAriaHidden',
+ 'groupAriaInvalid',
+ 'groupAriaLabel',
+ 'groupAriaLabelledBy',
+ 'groupAriaLive',
+ 'groupAriaOwns',
+ 'groupAriaRelevant',
+ 'groupAddClass',
+ 'groupRemoveClass'
+ ));
+ }
+}
diff --git a/src/Components/Submit.php b/src/Components/Submit.php
new file mode 100644
index 0000000..54b85e7
--- /dev/null
+++ b/src/Components/Submit.php
@@ -0,0 +1,13 @@
+createElement(SummaryElement::class, compact(
+ 'verbose',
+ 'simple',
+ 'data',
+ 'addClass',
+ 'removeClass',
+ 'accessKey',
+ 'class',
+ 'contentEditable',
+ 'contextMenu',
+ 'dir',
+ 'draggable',
+ 'dropZone',
+ 'hide',
+ 'id',
+ 'lang',
+ 'role',
+ 'spellCheck',
+ 'style',
+ 'tabIndex',
+ 'title',
+ 'ariaActiveDescendant',
+ 'ariaAtomic',
+ 'ariaBusy',
+ 'ariaControls',
+ 'ariaDescribedBy',
+ 'ariaDisabled',
+ 'ariaDropEffect',
+ 'ariaFlowTo',
+ 'ariaGrabbed',
+ 'ariaHasPopup',
+ 'ariaHidden',
+ 'ariaInvalid',
+ 'ariaLabel',
+ 'ariaLabelledBy',
+ 'ariaLive',
+ 'ariaOwns',
+ 'ariaRelevant',
+ 'grouped',
+ 'withoutGroup',
+ 'variant',
+ 'variants'
+ ));
+ }
+}
diff --git a/src/Components/Tel.php b/src/Components/Tel.php
new file mode 100644
index 0000000..21cf088
--- /dev/null
+++ b/src/Components/Tel.php
@@ -0,0 +1,13 @@
+createElement(TextareaElement::class, compact(
+ 'autoSize',
+ 'autoFocus',
+ 'cols',
+ 'dirName',
+ 'disabled',
+ 'form',
+ 'maxLength',
+ 'name',
+ 'placeholder',
+ 'readOnly',
+ 'required',
+ 'rows',
+ 'wrap',
+ 'data',
+ 'addClass',
+ 'removeClass',
+ 'accessKey',
+ 'class',
+ 'contentEditable',
+ 'contextMenu',
+ 'dir',
+ 'draggable',
+ 'dropZone',
+ 'hide',
+ 'id',
+ 'lang',
+ 'role',
+ 'spellCheck',
+ 'style',
+ 'tabIndex',
+ 'title',
+ 'ariaActiveDescendant',
+ 'ariaAtomic',
+ 'ariaBusy',
+ 'ariaControls',
+ 'ariaDescribedBy',
+ 'ariaDisabled',
+ 'ariaDropEffect',
+ 'ariaFlowTo',
+ 'ariaGrabbed',
+ 'ariaHasPopup',
+ 'ariaHidden',
+ 'ariaInvalid',
+ 'ariaLabel',
+ 'ariaLabelledBy',
+ 'ariaLive',
+ 'ariaOwns',
+ 'ariaRelevant',
+ 'grouped',
+ 'withoutGroup',
+ 'variant',
+ 'variants',
+ 'defaultValue',
+ 'value',
+ 'label',
+ 'helpText',
+ 'validated',
+ 'valid',
+ 'invalid',
+ 'errors',
+ 'prepend',
+ 'append',
+ 'groupData',
+ 'groupAccessKey',
+ 'groupClass',
+ 'groupContentEditable',
+ 'groupContextMenu',
+ 'groupDir',
+ 'groupDraggable',
+ 'groupDropZone',
+ 'groupHide',
+ 'groupId',
+ 'groupLang',
+ 'groupRole',
+ 'groupSpellCheck',
+ 'groupStyle',
+ 'groupTabIndex',
+ 'groupTitle',
+ 'groupAriaActiveDescendant',
+ 'groupAriaAtomic',
+ 'groupAriaBusy',
+ 'groupAriaControls',
+ 'groupAriaDescribedBy',
+ 'groupAriaDisabled',
+ 'groupAriaDropEffect',
+ 'groupAriaFlowTo',
+ 'groupAriaGrabbed',
+ 'groupAriaHasPopup',
+ 'groupAriaHidden',
+ 'groupAriaInvalid',
+ 'groupAriaLabel',
+ 'groupAriaLabelledBy',
+ 'groupAriaLive',
+ 'groupAriaOwns',
+ 'groupAriaRelevant',
+ 'groupAddClass',
+ 'groupRemoveClass'
+ ));
+ }
+}
diff --git a/src/Components/Time.php b/src/Components/Time.php
new file mode 100644
index 0000000..d3c10cb
--- /dev/null
+++ b/src/Components/Time.php
@@ -0,0 +1,13 @@
+bootConfig();
$this->bootViews();
+ $this->bootBladeComponents();
$this->bootTranslations();
$this->bootPublicAssets();
}
@@ -119,6 +122,15 @@ protected function bootViews() : self
return $this;
}
+ protected function bootBladeComponents() : self
+ {
+ if (version_compare($this->app->version(), '8.0.0', '>=')) {
+ $this->app['blade.compiler']->componentNamespace('Galahad\\Aire\\Components', 'aire');
+ }
+
+ return $this;
+ }
+
/**
* Boot the configuration
*
diff --git a/tests/Components/ButtonTest.php b/tests/Components/ButtonTest.php
new file mode 100644
index 0000000..130ccca
--- /dev/null
+++ b/tests/Components/ButtonTest.php
@@ -0,0 +1,177 @@
+app->version(), '8.0.0', '<')) {
+ $this->markTestSkipped('Only applies to Laravel 8 and higher.');
+ }
+ }
+
+ public function test_auto_focus_flag_can_be_set_on_and_off() : void
+ {
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'autofocus');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($button, 'button', 'autofocus');
+ }
+
+ public function test_disabled_flag_can_be_set_on_and_off() : void
+ {
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'disabled');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($button, 'button', 'disabled');
+ }
+
+ public function test_form_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $button = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($button, 'button', 'form', $value);
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($button, 'button', 'form');
+ }
+
+ public function test_form_action_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $button = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($button, 'button', 'formaction', $value);
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($button, 'button', 'formaction');
+ }
+
+ public function test_form_enc_type_attribute_can_be_set_and_unset() : void
+ {
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'formenctype', 'application/x-www-form-urlencoded');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'formenctype', 'multipart/form-data');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'formenctype', 'text/plain');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($button, 'button', 'formenctype');
+ }
+
+ public function test_form_method_attribute_can_be_set_and_unset() : void
+ {
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'formmethod', 'get');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'formmethod', 'post');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($button, 'button', 'formmethod');
+ }
+
+ public function test_form_no_validate_flag_can_be_set_on_and_off() : void
+ {
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'formnovalidate');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($button, 'button', 'formnovalidate');
+ }
+
+ public function test_form_target_attribute_can_be_set_and_unset() : void
+ {
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'formtarget', '_blank');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'formtarget', '_parent');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'formtarget', '_self');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'formtarget', '_top');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($button, 'button', 'formtarget');
+ }
+
+ public function test_name_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $button = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($button, 'button', 'name', $value);
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($button, 'button', 'name');
+ }
+
+ public function test_type_attribute_can_be_set_and_unset() : void
+ {
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'type', 'button');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'type', 'reset');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttribute($button, 'button', 'type', 'submit');
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($button, 'button', 'type');
+ }
+
+ public function test_value_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $button = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($button, 'button', 'value', $value);
+
+ $button = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($button, 'button', 'value');
+ }
+
+}
diff --git a/tests/Components/ColorTest.php b/tests/Components/ColorTest.php
new file mode 100644
index 0000000..5e9c13b
--- /dev/null
+++ b/tests/Components/ColorTest.php
@@ -0,0 +1,8 @@
+app->version(), '8.0.0', '<')) {
+ $this->markTestSkipped('Only applies to Laravel 8 and higher.');
+ }
+ }
+}
diff --git a/tests/Components/DateTest.php b/tests/Components/DateTest.php
new file mode 100644
index 0000000..27bfb5d
--- /dev/null
+++ b/tests/Components/DateTest.php
@@ -0,0 +1,8 @@
+renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'accept-charset', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'accept-charset');
+ }
+
+ public function test_action_attribute_can_be_set() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'action', $value);
+
+ // Action is special so it cannot be unset
+ }
+
+ public function test_auto_complete_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'additional-name');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'address-level1');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'address-level2');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'address-level3');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'address-level4');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'address-line1');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'address-line2');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'address-line3');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'bday');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'bday-year');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'bday-day');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'bday-month');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'billing');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'cc-additional-name');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'cc-csc');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'cc-exp');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'cc-exp-month');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'cc-exp-year');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'cc-family-name');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'cc-given-name');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'cc-name');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'cc-number');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'cc-type');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'country');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'country-name');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'current-password');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'email');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'family-name');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'fax');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'given-name');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'home');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'honorific-prefix');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'honorific-suffix');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'impp');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'language');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'mobile');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'name');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'new-password');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'nickname');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'off');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'on');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'organization');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'organization-title');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'pager');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'photo');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'postal-code');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'sex');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'shipping');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'street-address');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'tel-area-code');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'tel');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'tel-country-code');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'tel-extension');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'tel-local');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'tel-local-prefix');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'tel-local-suffix');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'tel-national');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'transaction-amount');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'transaction-currency');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'url');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'username');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'autocomplete', 'work');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'autocomplete');
+ }
+
+ public function test_enc_type_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'enctype', 'application/x-www-form-urlencoded');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'enctype', 'multipart/form-data');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'enctype', 'text/plain');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'enctype');
+ }
+
+ public function test_method_attribute_can_be_set() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'method', 'GET');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'method', 'POST');
+
+ // Method cannot be unset
+ }
+
+ public function test_name_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'name', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'name');
+ }
+
+ public function test_no_validate_flag_can_be_set_on_and_off() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'novalidate');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'novalidate');
+ }
+
+ public function test_target_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'target', '_blank');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'target', '_parent');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'target', '_self');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'target', '_top');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'target');
+ }
+
+}
diff --git a/tests/Components/GlobalAttributesTest.php b/tests/Components/GlobalAttributesTest.php
new file mode 100644
index 0000000..d8dde6a
--- /dev/null
+++ b/tests/Components/GlobalAttributesTest.php
@@ -0,0 +1,1046 @@
+renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'accesskey', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'accesskey');
+ }
+
+ public function test_class_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'class', $value);
+ }
+
+ public function test_content_editable_boolean_can_be_set_to_true_and_false_and_be_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'contenteditable', 'true');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'contenteditable', 'false');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'contenteditable');
+ }
+
+ public function test_context_menu_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'contextmenu', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'contextmenu');
+ }
+
+ public function test_dir_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'dir', 'ltr');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'dir', 'rtl');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'dir');
+ }
+
+ public function test_draggable_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'draggable', 'auto');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'draggable', 'false');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'draggable', 'true');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'draggable');
+ }
+
+ public function test_drop_zone_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'dropzone', 'copy');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'dropzone', 'move');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'dropzone', 'link');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'dropzone');
+ }
+
+ public function test_hidden_flag_can_be_set_on_and_off() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'hidden');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'hidden');
+ }
+
+ public function test_id_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'id', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'id');
+ }
+
+ public function test_lang_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ab');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'aa');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'af');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sq');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'am');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ar');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'an');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'hy');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'as');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ay');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'az');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ba');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'eu');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'bn');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'dz');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'bh');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'bi');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'br');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'bg');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'my');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'be');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'km');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ca');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'zh');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'co');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'hr');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'cs');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'da');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'nl');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'en');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'eo');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'et');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'fo');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'fa');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'fi');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'fr');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'fy');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'gl');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'gd');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'gv');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ka');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'de');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'el');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'kl');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'gn');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'gu');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ht');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ha');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'he');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'hi');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'hu');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'is');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'io');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'id');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ia');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ie');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'iu');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ik');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ga');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'it');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ja');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'jv');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'kn');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ks');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'kk');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'rw');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ky');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'rn');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ko');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ku');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'lo');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'la');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'lv');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'li');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ln');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'lt');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'mk');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'mg');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ms');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ml');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'mt');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'mi');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'mr');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'mo');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'mn');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'na');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ne');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'no');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'oc');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'or');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'om');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ps');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'pl');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'pt');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'pa');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'qu');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'rm');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ro');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ru');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sz');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sm');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sg');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sa');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sr');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sh');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'st');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'tn');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sn');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ii');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sd');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'si');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ss');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sk');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sl');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'so');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'es');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'su');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sw');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'sv');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'tl');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'tg');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ta');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'tt');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'te');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'th');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'bo');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ti');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'to');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ts');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'tr');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'tk');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'tw');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ug');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'uk');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'ur');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'uz');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'vi');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'vo');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'wa');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'cy');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'wo');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'xh');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'yi');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'yo');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'lang', 'zu');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'lang');
+ }
+
+ public function test_role_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'alert');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'alertdialog');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'article');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'application');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'banner');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'button');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'checkbox');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'columnheader');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'combobox');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'complementary');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'contentinfo');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'definition');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'directory');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'dialog');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'document');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'form');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'grid');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'gridcell');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'group');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'heading');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'img');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'link');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'list');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'listbox');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'listitem');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'log');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'main');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'marquee');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'math');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'menu');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'menubar');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'menuitem');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'menuitemcheckbox');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'menuitemradio');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'navigation');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'note');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'option');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'presentation');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'progressbar');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'radio');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'radiogroup');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'region');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'row');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'rowgroup');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'rowheader');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'scrollbar');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'search');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'separator');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'slider');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'spinbutton');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'status');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'tab');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'tablist');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'tabpanel');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'textbox');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'timer');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'toolbar');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'tooltip');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'tree');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'treegrid');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'role', 'treeitem');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'role');
+ }
+
+ public function test_spell_check_boolean_can_be_set_to_true_and_false_and_be_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'spellcheck', 'true');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'spellcheck', 'false');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'spellcheck');
+ }
+
+ public function test_style_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'style', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'style');
+ }
+
+ public function test_tab_index_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'tabindex', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'tabindex');
+ }
+
+ public function test_title_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'title', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'title');
+ }
+
+ public function test_aria_active_descendant_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'aria-activedescendant', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-activedescendant');
+ }
+
+ public function test_aria_atomic_boolean_can_be_set_to_true_and_false_and_be_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-atomic', 'true');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-atomic', 'false');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-atomic');
+ }
+
+ public function test_aria_busy_boolean_can_be_set_to_true_and_false_and_be_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-busy', 'true');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-busy', 'false');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-busy');
+ }
+
+ public function test_aria_controls_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'aria-controls', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-controls');
+ }
+
+ public function test_aria_described_by_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'aria-describedby', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-describedby');
+ }
+
+ public function test_aria_disabled_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-disabled', 'true');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-disabled', 'false');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-disabled');
+ }
+
+ public function test_aria_drop_effect_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-dropeffect', 'copy');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-dropeffect', 'move');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-dropeffect', 'link');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-dropeffect', 'execute');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-dropeffect', 'popup');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-dropeffect', 'none');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-dropeffect');
+ }
+
+ public function test_aria_flow_to_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'aria-flowto', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-flowto');
+ }
+
+ public function test_aria_grabbed_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-grabbed', 'true');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-grabbed', 'false');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-grabbed', 'undefined');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-grabbed');
+ }
+
+ public function test_aria_has_popup_boolean_can_be_set_to_true_and_false_and_be_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-haspopup', 'true');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-haspopup', 'false');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-haspopup');
+ }
+
+ public function test_aria_hidden_boolean_can_be_set_to_true_and_false_and_be_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-hidden', 'true');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-hidden', 'false');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-hidden');
+ }
+
+ public function test_aria_invalid_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-invalid', 'grammar');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-invalid', 'false');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-invalid', 'spelling');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-invalid', 'true');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-invalid');
+ }
+
+ public function test_aria_label_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'aria-label', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-label');
+ }
+
+ public function test_aria_labelled_by_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'aria-labelledby', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-labelledby');
+ }
+
+ public function test_aria_live_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-live', 'off');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-live', 'polite');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-live', 'assertive');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-live');
+ }
+
+ public function test_aria_owns_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $form = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($form, 'form', 'aria-owns', $value);
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-owns');
+ }
+
+ public function test_aria_relevant_attribute_can_be_set_and_unset() : void
+ {
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-relevant', 'additions');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-relevant', 'removals');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-relevant', 'text');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-relevant', 'all');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttribute($form, 'form', 'aria-relevant', 'additions text');
+
+ $form = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($form, 'form', 'aria-relevant');
+ }
+
+}
diff --git a/tests/Components/HiddenTest.php b/tests/Components/HiddenTest.php
new file mode 100644
index 0000000..7990ab6
--- /dev/null
+++ b/tests/Components/HiddenTest.php
@@ -0,0 +1,8 @@
+renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'text/html');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'text/plain');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'application/msword');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'application/msexcel');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'application/postscript');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'application/x-zip-compressed');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'application/pdf');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'application/rtf');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'video/x-msvideo');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'video/quicktime');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'video/x-mpeg2');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'audio/x-pn/realaudio');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'audio/x-mpeg');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'audio/x-waw');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'audio/x-aiff');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'audio/basic');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'image/tiff');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'image/jpeg');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'image/gif');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'image/x-png');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'image/x-photo-cd');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'image/x-MS-bmp');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'image/x-rgb');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'image/x-portable-pixmap');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'image/x-portable-greymap');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'accept', 'image/x-portablebitmap');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'accept');
+ }
+
+ public function test_alt_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'alt', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'alt');
+ }
+
+ public function test_auto_complete_attribute_can_be_set_and_unset() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'additional-name');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'address-level1');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'address-level2');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'address-level3');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'address-level4');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'address-line1');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'address-line2');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'address-line3');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'bday');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'bday-year');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'bday-day');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'bday-month');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'billing');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'cc-additional-name');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'cc-csc');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'cc-exp');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'cc-exp-month');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'cc-exp-year');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'cc-family-name');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'cc-given-name');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'cc-name');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'cc-number');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'cc-type');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'country');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'country-name');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'current-password');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'email');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'family-name');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'fax');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'given-name');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'home');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'honorific-prefix');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'honorific-suffix');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'impp');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'language');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'mobile');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'name');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'new-password');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'nickname');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'off');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'on');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'organization');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'organization-title');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'pager');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'photo');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'postal-code');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'sex');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'shipping');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'street-address');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'tel-area-code');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'tel');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'tel-country-code');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'tel-extension');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'tel-local');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'tel-local-prefix');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'tel-local-suffix');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'tel-national');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'transaction-amount');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'transaction-currency');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'url');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'username');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autocomplete', 'work');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'autocomplete');
+ }
+
+ public function test_auto_focus_flag_can_be_set_on_and_off() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'autofocus');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'autofocus');
+ }
+
+ public function test_checked_flag_can_be_set_on_and_off() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'checked');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'checked');
+ }
+
+ public function test_dir_name_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'dirname', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'dirname');
+ }
+
+ public function test_disabled_flag_can_be_set_on_and_off() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'disabled');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'disabled');
+ }
+
+ public function test_form_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'form', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'form');
+ }
+
+ public function test_form_action_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'formaction', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'formaction');
+ }
+
+ public function test_form_enc_type_attribute_can_be_set_and_unset() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'formenctype', 'application/x-www-form-urlencoded');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'formenctype', 'multipart/form-data');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'formenctype', 'text/plain');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'formenctype');
+ }
+
+ public function test_form_method_attribute_can_be_set_and_unset() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'formmethod', 'get');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'formmethod', 'post');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'formmethod');
+ }
+
+ public function test_form_no_validate_flag_can_be_set_on_and_off() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'formnovalidate');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'formnovalidate');
+ }
+
+ public function test_form_target_attribute_can_be_set_and_unset() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'formtarget', '_blank');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'formtarget', '_parent');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'formtarget', '_self');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'formtarget', '_top');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'formtarget');
+ }
+
+ public function test_height_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'height', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'height');
+ }
+
+ public function test_list_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'list', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'list');
+ }
+
+ public function test_max_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'max', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'max');
+ }
+
+ public function test_max_length_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'maxlength', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'maxlength');
+ }
+
+ public function test_min_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'min', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'min');
+ }
+
+ public function test_multiple_flag_can_be_set_on_and_off() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'multiple');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'multiple');
+ }
+
+ public function test_name_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'name', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'name');
+ }
+
+ public function test_pattern_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'pattern', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'pattern');
+ }
+
+ public function test_placeholder_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'placeholder', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'placeholder');
+ }
+
+ public function test_read_only_flag_can_be_set_on_and_off() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'readonly');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'readonly');
+ }
+
+ public function test_required_flag_can_be_set_on_and_off() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'required');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'required');
+ }
+
+ public function test_size_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'size', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'size');
+ }
+
+ public function test_src_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'src', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'src');
+ }
+
+ public function test_step_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'step', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'step');
+ }
+
+ public function test_type_attribute_can_be_set_and_unset() : void
+ {
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'button');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'checkbox');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'color');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'date');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'datetime');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'datetime-local');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'email');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'file');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'hidden');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'image');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'month');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'number');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'password');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'radio');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'range');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'reset');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'search');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'submit');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'tel');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'text');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'time');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'url');
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', 'week');
+ }
+
+ public function test_value_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'value', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'value');
+ }
+
+ public function test_width_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $input = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($input, 'input', 'width', $value);
+
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($input, 'input', 'width');
+ }
+
+}
diff --git a/tests/Components/InputTypeTestCase.php b/tests/Components/InputTypeTestCase.php
new file mode 100644
index 0000000..e241700
--- /dev/null
+++ b/tests/Components/InputTypeTestCase.php
@@ -0,0 +1,23 @@
+inputType();
+ $input = $this->renderBlade('');
+ $this->assertSelectorAttribute($input, 'input', 'type', $type);
+ }
+
+ protected function inputType()
+ {
+ return Str::of(static::class)
+ ->afterLast('\\')
+ ->before('Test')
+ ->lower();
+ }
+}
diff --git a/tests/Components/MonthTest.php b/tests/Components/MonthTest.php
new file mode 100644
index 0000000..54253a3
--- /dev/null
+++ b/tests/Components/MonthTest.php
@@ -0,0 +1,8 @@
+
+ ';
+
+ $form = $this->renderBlade($blade, ['keyup' => 'doKeyUp()', 'click' => 'doClick()']);
+
+ $this->assertSelectorAttribute($form, 'form', 'x-data', '{ open: true }');
+ $this->assertSelectorAttribute($form, 'form', 'x-init', 'baz');
+ $this->assertSelectorAttribute($form, 'form', 'x-show.transition.in.duration.200ms.out.duration.50ms', '!open');
+ $this->assertSelectorAttribute($form, 'form', 'x-bind:type', 'input_type');
+ $this->assertSelectorAttribute($form, 'form', 'x-bind:view-box.camel', 'viewBox');
+ $this->assertSelectorAttribute($form, 'form', 'x-on:click', 'open = true');
+ $this->assertSelectorAttribute($form, 'form', 'x-on:keydown.escape', 'open = false');
+ $this->assertSelectorAttribute($form, 'form', 'x-on:keyup', 'doKeyUp()');
+ $this->assertSelectorAttribute($form, 'form', 'x-transition:enter', 'transition ease-out duration-300');
+ $this->assertSelectorAttribute($form, 'form', 'x-cloak');
+
+ // DOM Crawler doesn't like @-prefixed attributes, so we'll just check those strings
+ $this->assertStringContainsString('@click="doClick()"', $form);
+ $this->assertStringContainsString('@click.away="open = false"', $form);
+ }
+
+ public function test_livewire_style_attributes() : void
+ {
+ $blade = '
+
+ ';
+
+ $form = $this->renderBlade($blade, ['poll' => 'poll_500ms']);
+
+ $this->assertSelectorAttribute($form, 'form', 'wire:key', 'form_key');
+ $this->assertSelectorAttribute($form, 'form', 'wire:click.prefetch', 'prefetch_click');
+ $this->assertSelectorAttribute($form, 'form', 'wire:model.debounce.100ms', 'debounced_model');
+ $this->assertSelectorAttribute($form, 'form', 'wire:poll.500ms', 'poll_500ms');
+ }
+}
diff --git a/tests/Components/NumberTest.php b/tests/Components/NumberTest.php
new file mode 100644
index 0000000..7ff83cd
--- /dev/null
+++ b/tests/Components/NumberTest.php
@@ -0,0 +1,8 @@
+renderBlade('');
+ $this->assertSelectorAttribute($select, 'select', 'autofocus');
+
+ $select = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($select, 'select', 'autofocus');
+ }
+
+ public function test_disabled_flag_can_be_set_on_and_off() : void
+ {
+ $select = $this->renderBlade('');
+ $this->assertSelectorAttribute($select, 'select', 'disabled');
+
+ $select = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($select, 'select', 'disabled');
+ }
+
+ public function test_form_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $select = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($select, 'select', 'form', $value);
+
+ $select = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($select, 'select', 'form');
+ }
+
+ public function test_multiple_flag_can_be_set_on_and_off() : void
+ {
+ $select = $this->renderBlade('');
+ $this->assertSelectorAttribute($select, 'select', 'multiple');
+
+ $select = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($select, 'select', 'multiple');
+ }
+
+ public function test_name_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $select = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($select, 'select', 'name', $value);
+
+ $select = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($select, 'select', 'name');
+ }
+
+ public function test_required_flag_can_be_set_on_and_off() : void
+ {
+ $select = $this->renderBlade('');
+ $this->assertSelectorAttribute($select, 'select', 'required');
+
+ $select = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($select, 'select', 'required');
+ }
+
+ public function test_size_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $select = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($select, 'select', 'size', $value);
+
+ $select = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($select, 'select', 'size');
+ }
+
+}
diff --git a/tests/Components/TelTest.php b/tests/Components/TelTest.php
new file mode 100644
index 0000000..23215a3
--- /dev/null
+++ b/tests/Components/TelTest.php
@@ -0,0 +1,8 @@
+renderBlade('');
+ $this->assertSelectorAttribute($textarea, 'textarea', 'autofocus');
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'autofocus');
+ }
+
+ public function test_cols_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $textarea = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($textarea, 'textarea', 'cols', $value);
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'cols');
+ }
+
+ public function test_dir_name_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $textarea = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($textarea, 'textarea', 'dirname', $value);
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'dirname');
+ }
+
+ public function test_disabled_flag_can_be_set_on_and_off() : void
+ {
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttribute($textarea, 'textarea', 'disabled');
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'disabled');
+ }
+
+ public function test_form_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $textarea = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($textarea, 'textarea', 'form', $value);
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'form');
+ }
+
+ public function test_max_length_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $textarea = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($textarea, 'textarea', 'maxlength', $value);
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'maxlength');
+ }
+
+ public function test_name_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $textarea = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($textarea, 'textarea', 'name', $value);
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'name');
+ }
+
+ public function test_placeholder_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $textarea = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($textarea, 'textarea', 'placeholder', $value);
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'placeholder');
+ }
+
+ public function test_read_only_flag_can_be_set_on_and_off() : void
+ {
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttribute($textarea, 'textarea', 'readonly');
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'readonly');
+ }
+
+ public function test_required_flag_can_be_set_on_and_off() : void
+ {
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttribute($textarea, 'textarea', 'required');
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'required');
+ }
+
+ public function test_rows_attribute_can_be_set_and_unset() : void
+ {
+ $value = Str::random();
+
+ $textarea = $this->renderBlade('', compact('value'));
+ $this->assertSelectorAttribute($textarea, 'textarea', 'rows', $value);
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'rows');
+ }
+
+ public function test_wrap_attribute_can_be_set_and_unset() : void
+ {
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttribute($textarea, 'textarea', 'wrap', 'hard');
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttribute($textarea, 'textarea', 'wrap', 'soft');
+
+ $textarea = $this->renderBlade('');
+ $this->assertSelectorAttributeMissing($textarea, 'textarea', 'wrap');
+ }
+
+}
diff --git a/tests/Components/TimeTest.php b/tests/Components/TimeTest.php
new file mode 100644
index 0000000..89060b3
--- /dev/null
+++ b/tests/Components/TimeTest.php
@@ -0,0 +1,8 @@
+render();
+ $this->performBasicFormAssertions($html);
+ }
+
+ public function test_a_basic_form_using_blade_components_renders_as_expected()
+ {
+ if (version_compare($this->app->version(), '8.0.0', '<')) {
+ $this->markTestSkipped('Only applies to Laravel 8 and higher.');
+ }
+
+ // Needed occasionally to clear the view cache for tests:
+ // $this->artisan('view:clear');
+
+ $html = View::make('basic-component-form')->render();
+ $this->performBasicFormAssertions($html);
+ }
+
+ public function test_a_button_with_html_content_renders()
+ {
+ $html = View::make('button-open-close')->render();
+ $this->assertSelectorExists($html, 'form > button');
+ $this->assertSelectorAttribute($html, 'form > button', 'type', 'submit');
+ $this->assertSelectorExists($html, 'form > button > strong');
+ $this->assertSelectorTextEquals($html, 'form > button > strong', 'Hello world');
+ }
+
+ protected function performBasicFormAssertions($html)
+ {
// Form
$this->assertSelectorExists($html, 'form#test_form');
@@ -65,24 +92,18 @@ public function test_a_basic_form_renders_as_expected()
$this->assertSelectorAttribute($html, '#checkbox', 'type', 'checkbox');
$this->assertSelectorExists($html, 'label[for="checkbox"]');
- // Radio Button
- // $this->assertSelectorExists($html, 'input#radio');
- // $this->assertSelectorAttribute($html, '#radio', 'name', 'radio');
- // $this->assertSelectorAttribute($html, '#radio', 'type', 'radio');
- // $this->assertSelectorExists($html, 'label[for="radio"]');
+ // Radio Group
+ $this->assertSelectorExists($html, 'input[name=radio_group]');
+ $this->assertSelectorAttribute($html, 'input[name=radio_group]', 'type', 'radio');
+ $this->assertSelectorExists($html, 'label input[name=radio_group]');
+
+ // Checkbox Group
+ $this->assertSelectorExists($html, 'input[name^=checkbox_group]');
+ $this->assertSelectorAttribute($html, 'input[name^=checkbox_group]', 'type', 'checkbox');
+ $this->assertSelectorExists($html, 'label input[name^=checkbox_group]');
// Submit Button
$this->assertSelectorExists($html, 'button#submit');
$this->assertSelectorAttribute($html, '#submit', 'type', 'submit');
}
-
- public function test_a_button_with_html_content_renders()
- {
- $html = View::make('button-open-close')->render();
-
- $this->assertSelectorExists($html, 'form > button');
- $this->assertSelectorAttribute($html, 'form > button', 'type', 'submit');
- $this->assertSelectorExists($html, 'form > button > strong');
- $this->assertSelectorTextEquals($html, 'form > button > strong', 'Hello world');
- }
}
diff --git a/tests/Feature/stubs/basic-component-form.blade.php b/tests/Feature/stubs/basic-component-form.blade.php
new file mode 100644
index 0000000..4f52483
--- /dev/null
+++ b/tests/Feature/stubs/basic-component-form.blade.php
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/Feature/stubs/basic-form.blade.php b/tests/Feature/stubs/basic-form.blade.php
index 00f3ffc..143b90f 100644
--- a/tests/Feature/stubs/basic-form.blade.php
+++ b/tests/Feature/stubs/basic-form.blade.php
@@ -28,10 +28,11 @@
{{ Aire::checkbox('checkbox', 'Checkbox')
->id('checkbox') }}
-{{-- TODO: Radio buttons don't make any sense singularly, so implement as a group
-{{ Aire::radio('radio', 'Radio')
- ->id('radio') }}
---}}
+{{ Aire::radioGroup(['a' => 'eh', 'b' => 'bee'], 'radio_group', 'Radio Group')
+ ->id('radio_group') }}
+
+{{ Aire::checkboxGroup(['a' => 'eh', 'b' => 'bee'], 'checkbox_group', 'Checkbox Group')
+ ->id('checkbox_group') }}
{{ Aire::submit('Submit Button')->id('submit') }}
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 3b1e57d..8023b13 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -14,6 +14,7 @@
use Galahad\Aire\Tests\Constraints\SelectorHasClassNames;
use Galahad\Aire\Tests\Constraints\SelectorMissingClassNames;
use Galahad\Aire\Tests\Constraints\SelectorTextEquals;
+use Illuminate\Container\Container;
use Orchestra\Testbench\TestCase as Orchestra;
use PHPUnit\Framework\Constraint\LogicalNot;
use Symfony\Component\DomCrawler\Crawler;
@@ -73,6 +74,31 @@ protected function crawl($html) : Crawler
: new Crawler((string) $html);
}
+ protected function renderBlade($contents, array $data = [])
+ {
+ $factory = $this->app['view'];
+
+ $factory->addNamespace(
+ '__aire_test_components',
+ $directory = $this->app['config']->get('view.compiled')
+ );
+
+ $basename = sha1($contents);
+ $filename = "{$directory}/{$basename}.blade.php";
+
+ if (!is_file($filename)) {
+ if (!is_dir($directory)) {
+ mkdir($directory, 0755, true);
+ }
+
+ file_put_contents($filename, $contents);
+ }
+
+ $component_name = "__aire_test_components::{$basename}";
+
+ return $factory->make($component_name, $data)->render();
+ }
+
protected function assertSelectorExists($html, $selector)
{
static::assertThat($html, new SelectorExists($selector));