diff --git a/.gitattributes b/.gitattributes index 2abcda003..3890062d6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -19,6 +19,17 @@ /phpunit.result.cache export-ignore /phpstan.neon export-ignore /phpunit.xml.dist export-ignore -/psalm.xml export-ignore -/psalm.xml.dist export-ignore -/testbench.yaml export-ignore +/psalm.xml export-ignore +/psalm.xml.dist export-ignore +/testbench.yaml export-ignore +/codecov.yml export-ignore +/coverage.xml export-ignore + +# Exclude unminified versions of files +/resources/js/laravel-livewire-tables-thirdparty.js export-ignore +/resources/js/laravel-livewire-tables.js export-ignore +/resources/css/laravel-livewire-tables-thirdparty.css export-ignore +/resources/css/laravel-livewire-tables.css export-ignore +/resources/css/numberRange.css export-ignore +/resources/css/numericSlider.css export-ignore +/resources/css/flatpickr.css export-ignore \ No newline at end of file diff --git a/.github/workflows/discord-releases.yml b/.github/workflows/discord-releases.yml new file mode 100644 index 000000000..c75bedd41 --- /dev/null +++ b/.github/workflows/discord-releases.yml @@ -0,0 +1,21 @@ +on: + release: + types: [published] + +jobs: + github-releases-to-discord: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Package Releases + uses: SethCohen/github-releases-to-discord@v1.13.1 + with: + webhook_url: ${{ secrets.WEBHOOK_DISCORD_RELEASE_URL }} + color: "2105893" + username: "GitHub Release-Bot" + avatar_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png" + content: "||@everyone||" + footer_title: "Release ChangeLog" + footer_icon_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png" + footer_timestamp: true \ No newline at end of file diff --git a/.github/workflows/run-phpstan.yml b/.github/workflows/run-phpstan.yml index b364f61a5..094841e2c 100644 --- a/.github/workflows/run-phpstan.yml +++ b/.github/workflows/run-phpstan.yml @@ -11,7 +11,7 @@ jobs: os: [ubuntu-latest] php: [8.2] laravel: [10] - stability: [prefer-stable] + stability: [prefer-dist] name: PHPStan - P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} env: diff --git a/.github/workflows/run-tests-pcov-pull.yml b/.github/workflows/run-tests-pcov-pull.yml new file mode 100644 index 000000000..fbfdb8af2 --- /dev/null +++ b/.github/workflows/run-tests-pcov-pull.yml @@ -0,0 +1,74 @@ +name: run-tests-pcov-pull + +on: [pull_request] + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + php: [8.2] + laravel: [10] + stability: [prefer-dist] + + name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, pcntl, pdo, sqlite, pdo_sqlite, bcmath, intl, iconv, fileinfo + tools: phpunit:latest + ini-values: memory_limit=512M + coverage: pcov + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup problem matchers for PHP + run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" + + - name: Get composer cache directory + id: composer-cache + run: | + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v3 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-PHP${{ matrix.php }}-Laravel${{ matrix.laravel }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-PHP${{ matrix.php }}-Laravel${{ matrix.laravel }}-composer- + + - name: Add token + run: | + composer config github-oauth.github.com ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies + if: steps.composer-cache.outputs.cache-hit != 'true' + run: composer require "laravel/framework:${{ matrix.laravel }}.*" --no-interaction --no-update + + - name: Update dependencies + if: steps.composer-cache.outputs.cache-hit != 'true' + run: composer update --${{ matrix.stability }} --no-interaction + + - name: Setup problem matchers for PHPUnit + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Run Unit Tests + run: php ./vendor/bin/paratest --cache-directory=".phpunit.cache/code-coverage" --strict-coverage --coverage-clover ./coverage.xml --processes=4 + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + token: ${{ secrets.CODE_COV_TOKEN }} + files: ./coverage.xml + verbose: true + + diff --git a/.github/workflows/run-tests-pcov.yml b/.github/workflows/run-tests-pcov.yml new file mode 100644 index 000000000..1456d1cf1 --- /dev/null +++ b/.github/workflows/run-tests-pcov.yml @@ -0,0 +1,74 @@ +name: run-tests-pcov + +on: [push] + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + php: [8.2] + laravel: [10] + stability: [prefer-dist] + + name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, pcntl, pdo, sqlite, pdo_sqlite, bcmath, intl, iconv, fileinfo + tools: phpunit:latest + ini-values: memory_limit=512M + coverage: pcov + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup problem matchers for PHP + run: echo "::add-matcher::${{ runner.tool_cache }}/php.json" + + - name: Get composer cache directory + id: composer-cache + run: | + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - uses: actions/cache@v3 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-PHP${{ matrix.php }}-Laravel${{ matrix.laravel }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-PHP${{ matrix.php }}-Laravel${{ matrix.laravel }}-composer- + + - name: Add token + run: | + composer config github-oauth.github.com ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies + if: steps.composer-cache.outputs.cache-hit != 'true' + run: composer require "laravel/framework:${{ matrix.laravel }}.*" --no-interaction --no-update + + - name: Update dependencies + if: steps.composer-cache.outputs.cache-hit != 'true' + run: composer update --${{ matrix.stability }} --no-interaction + + - name: Setup problem matchers for PHPUnit + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Run Unit Tests + run: php ./vendor/bin/paratest --cache-directory=".phpunit.cache/code-coverage" --strict-coverage --coverage-clover ./coverage.xml --processes=4 + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + token: ${{ secrets.CODE_COV_TOKEN }} + files: ./coverage.xml + verbose: true + + diff --git a/.github/workflows/run-tests-pull.yml b/.github/workflows/run-tests-pull.yml index cc9eeec5c..9c28ca24b 100644 --- a/.github/workflows/run-tests-pull.yml +++ b/.github/workflows/run-tests-pull.yml @@ -9,12 +9,9 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - php: [8.0, 8.1, 8.2] - laravel: [8, 9, 10] + php: [8.1, 8.2] + laravel: [10] stability: [prefer-dist] - exclude: - - laravel: 10 - php: 8.0 name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index f208aafc7..5fb8a4359 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -1,11 +1,6 @@ name: run-tests -on: - push: - branches-ignore: - - master - - main - - master2 +on: [push] jobs: test: @@ -13,17 +8,10 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04] - php: [7.4, 8.0, 8.1, 8.2] - laravel: [8, 9, 10] + os: [ubuntu-latest] + php: [8.1, 8.2] + laravel: [10] stability: [prefer-dist] - exclude: - - laravel: 10 - php: 8.0 - - laravel: 10 - php: 7.4 - - laravel: 9 - php: 7.4 name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} diff --git a/.gitignore b/.gitignore index 043be3f9a..d5834f1b7 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ phpunit.xml.dist.bak phpunit.xml.dist.dev .github/workflows/code-cov.yml .history/* +.env +phpunit.xml.bak +phpstan.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bebf46f0..9fc6176f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,147 @@ All notable changes to `laravel-livewire-tables` will be documented in this file -## [Unreleased] +## [v3.1.0] - 2023-10-31 +- Restore wire:confirm for Bulk Actions +- Stable Release of 3.1.0 Stable for Livewire v3 Support + +## [3.0.0-beta.11] - 2023-10-29 +- Update Date Range Icon Styling +- Migrate PHP from date-range blade into new DateRangeFilter method +- Add FilterHelper method for generating filter wire:keys +- Add Filter CustomPosition tests +- Add Placeholder config option for DateRangeFilter +- Add Placeholder config option for DateFilter, DateTimeFilter, NumberFilter +- Clean up classes on filters +- Minor tweaks to toolbar/column select styling +- Fix wire:confirm for BulkActions (removed in merge error) + +## [3.0.0-beta.10] - 2023-10-27 +- Changes to toolbar blade structure by @lrljoe in #[1454](https://github.com/rappasoft/laravel-livewire-tables/pull/1454) +- Fix queryStringEnabled by @lrljoe in #[1465](https://github.com/rappasoft/laravel-livewire-tables/pull/1465) +- Add missing x-cloak by @lrljoe in #[1463](https://github.com/rappasoft/laravel-livewire-tables/pull/1463) + +## [3.0.0-beta.9] - 2023-10-27 +- Fixes for missing default behaviour by @lrljoe in #[1455](https://github.com/rappasoft/laravel-livewire-tables/pull/1455) + +## [3.0.0-beta.8] - 2023-10-26 +- Fix for setFilter - allows setting values at mount/boot (#1451) by @lrljoe in #[1452](https://github.com/rappasoft/laravel-livewire-tables/pull/1452) + + +## [3.0.0-beta.7] - 2023-10-25 +- Add wire:navigate option for clickable rows + +## [3.0.0-beta.6] - 2023-10-25 +- Fix for collapsing column header shift + +## [3.0.0-beta.5] - 2023-10-25 +- Fix Return Type hinting for Column Rendering to allow Enum columns +- Add Bulk Action Confirmations, using wire:confirm + - setBulkActionConfirms + - setBulkActionConfirmMessage + - setBulkActionConfirmMessages + - setBulkActionDefaultConfirmationMessage + - Localisation for confirmation message + +## [3.0.0-beta.4] - 2023-10-17 +- Introduction of Loading Placeholder +- Docs livewire namespace fix [Here](https://github.com/rappasoft/laravel-livewire-tables/pull/1420) +- Add CollapseAlways capability for Columns +- Fix localisation bug + +## [3.0.0-beta.3] - 2023-10-13 +- Fix for Livewire ^3.0.6 where the table loading causes an additional lifecycle +- Add unminified files to .gitattributes export-ignore +- Increase cached time to 1 day from 1 hour if cache is enabled + +## [3.0.0-beta.2] - 2023-10-08 +- Removes superfluous @endphp from the DateRangeFilter blade +- Removes reference to remote/published 3rd party assets +- Add setFilterLabelAttributes Capability Per-Filter +- Fix for reorder sort not applying automatically + +## [3.0.0-beta.1] - 3.x Initial Release +- Amending Documentation for Reordering +- Adding capabilities & tests for setTrAttributes +- Force calculation of even/odd only once in reorder mode +- Call internal method for reordering, and pass to configured method to process +- Amend AutoInjection/FrontendAsset to ensure it returns the original content correctly +- Remove errant disabling of Blade Directives when disabling auto-injection +- Amended in-line config documentation +- Add setSearchFieldAttributes() and getSearchFieldAttributes() +- Add missing pagination tests +- Removal of setSearchLazy +- Fix for setSearchDebounce +- Fix publishing of views +- Fix for Bulk Actions dropdown not working in Bootstrap +- Fix for Column Select "Select All" not consistently updating +- Fix for lazy loading of table +- Fix for ColumnSelect falling out of sync, displaying unselectable colums, or persisting cols in query that are not selected +- Add setSearchBlur() +- Add setSearchThrottle() +- Add publish translations +- Add prependColumns() and appendColumns() functions +- Add documentation for setSearchPlaceholder() + +- Add setExcludeDeselectedColumnsFromQueryEnabled and setExcludeDeselectedColumnsFromQueryDisabled methods to configure() + +- Requirements Change + - Requires LiveWire 3.x + - Requires PHP 8.1+ + - Requires Laravel 10+ + + +- Core Changes + - Move sorts, search, selectedColumns out of the traditional __$this->{$this->getTableName()}['sorts']__ and instead place it directly within the component. This: + - Improves the query string behaviour + - Reduces the need to repeatedly set up that main array + [Commit 1 Here](https://github.com/LowerRockLabs/laravel-livewire-tables-v3/commit/d7ccabfc8adefeb4bddcbac64831ef1a688527a8) + [Commit 2 Here](https://github.com/LowerRockLabs/laravel-livewire-tables-v3/commit/0d8d98546b6a8051c4197804cc33b515faa02b07) + + - Tidying + - Removed Spatie Package Tools and replaced with a generic service provider + - Significant reduction in blade/view sizes, and repetition of code across Tailwind/Bootstrap 4/Bootstrap 5 themes + - Uses HeroIcons instead of hard-coded SVGs for icons + - Several variables are now inherited instead of being passed (e.g. Table Name) + - Change to how Filters are rendered (no longer receives $component) + - Wire keys and IDs now all conform to a format + + - Features + - General + - Added support for cursor pagination + - Cursor & Simple pagination both include a "Total Item Count" stored in $paginationTotalItemCount + - Added support for multiple relations on a single table (e.g. user has a "mother user" and a "father user") + - Replaced dependency on unsupported Sortable JS libraries. + - Option for a Search Placeholder to be set + - Bootstrap striping is now fully working + + - Filters + - Filter Construct calls config([]) by default to set configuration defaults, to avoid errors + - Added Numeric Range filter + - Added Date Range filter + - DateFilter & DateTimeFilter have customisable Pills Date Format + - DateFilter & DateTimeFilter fully support setFilterDefaultValue + - MultiSelectFilter & MultiSelectDropdownFilter both support setFirstOption() + - There are now two arrays relating to Filters: + - A wireable one ($filterComponents) + - An unwired one - only keeps track of those filters that have a value ($appliedFilters). This is what is bound to the query string, and populates the filters on mount if they are present in the query string. + + - Livewire 3 Specific + - Migrated any $component->id reference to $component->getId() + - Added SetSearchLive to allow for the search to be "live", with tests + - Added capability for external CSS file + - Custom CSS/JS and Alpine components are now stored in an external file, which has configurable injection options + - Added setSearchLive(), setSearchThrottle(int $milliseconds) and setSearchBlur() options for Search behaviour + +- Test Changes + - Temporarily removed the sort_events_apply_correctly and filter_events_apply_correctly due to LW3 not using Emit anymore. + + - Added extra column to the PetsTable -> last_visit and associated test changes to make the counts work. This column is deselected() by default to allow for testing on those methods. + +- Doc Changes + - Slowly begun updating the docs with the relevant new features, dependencies etc. + + ## [2.15.0] - 2023-07-15 diff --git a/README.md b/README.md index bce1fceab..fbde4b8da 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ [![Styling](https://github.com/rappasoft/laravel-livewire-tables/actions/workflows/php-cs-fixer.yml/badge.svg)](https://github.com/rappasoft/laravel-livewire-tables/actions/workflows/php-cs-fixer.yml) [![Tests](https://github.com/rappasoft/laravel-livewire-tables/actions/workflows/run-tests.yml/badge.svg)](https://github.com/rappasoft/laravel-livewire-tables/actions/workflows/run-tests.yml) [![Total Downloads](https://img.shields.io/packagist/dt/rappasoft/laravel-livewire-tables.svg?style=flat-square)](https://packagist.org/packages/rappasoft/laravel-livewire-tables) +[![codecov](https://codecov.io/gh/LowerRockLabs/laravel-livewire-tables-v3/branch/filterTidy/graph/badge.svg?token=FjDi2WIDyL)](https://codecov.io/gh/LowerRockLabs/laravel-livewire-tables-v3) +![PHP Stan Level 5](https://img.shields.io/badge/PHPStan-level%205-brightgreen.svg?style=flat) ### Enjoying this package? [Buy me a beer 🍺](https://www.buymeacoffee.com/rappasoft) diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..3491d5a70 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,10 @@ +coverage: + status: + project: + default: + target: 80% + threshold: 1% + patch: + default: + target: 80% + threshold: 1% diff --git a/composer.json b/composer.json index 8a67b9aaa..512a01e8e 100644 --- a/composer.json +++ b/composer.json @@ -18,17 +18,19 @@ } ], "require": { - "php": "^7.4|^8.0|^8.1|^8.2", - "illuminate/contracts": "^8.0|^9.0|^10.0", - "livewire/livewire": "^2.6", - "spatie/laravel-package-tools": "^1.4.3" + "php": "^8.1|^8.2", + "blade-ui-kit/blade-heroicons": "^2.1", + "illuminate/contracts": "^10.0|^11.0", + "livewire/livewire": "^3.0|dev-main" }, "require-dev": { "ext-sqlite3": "*", - "brianium/paratest": "^4.0|^5.0|^6.0|^7.0", - "nunomaduro/collision": "^4.0|^5.0|^6.0|^7.0", - "orchestra/testbench": "^6.0|^7.0|^8.0", - "phpunit/phpunit": "^9.0|^10.0" + "brianium/paratest": "^5.0|^6.0|^7.0|^8.0", + "laravel/pint": "^1.10", + "nunomaduro/collision": "^6.0|^7.0|^8.0", + "nunomaduro/larastan": "^2.6", + "orchestra/testbench": "^7.0|^8.0|^9.0", + "phpunit/phpunit": "^9.0|^10.0|^11.0" }, "autoload": { "psr-4": { diff --git a/config/livewire-tables.php b/config/livewire-tables.php index e90072ed5..3dbdf1757 100644 --- a/config/livewire-tables.php +++ b/config/livewire-tables.php @@ -5,4 +5,84 @@ * Options: tailwind | bootstrap-4 | bootstrap-5. */ 'theme' => 'tailwind', + + /** + * Filter Frontend Asset Options + */ + + /** + * Cache Rappasoft Frontend Assets + */ + 'cache_assets' => false, + + /** + * Enable or Disable automatic injection of core assets + */ + 'inject_core_assets_enabled' => true, + + /** + * Enable or Disable automatic injection of third-party assets + */ + 'inject_third_party_assets_enabled' => true, + + /** + * Enable Blade Directives (Not required if automatically injecting or using bundler approaches) + */ + 'enable_blade_directives ' => false, + + /** + * Filter Default Configuration Options + * + * */ + + /** + * Configuration options for DateFilter + */ + 'dateFilter' => [ + 'defaultConfig' => [ + 'format' => 'Y-m-d', + 'pillFormat' => 'd M Y', // Used to display in the Filter Pills + ], + ], + + /** + * Configuration options for DateTimeFilter + */ + 'dateTimeFilter' => [ + 'defaultConfig' => [ + 'format' => 'Y-m-d\TH:i', + 'pillFormat' => 'd M Y - H:i', // Used to display in the Filter Pills + ], + ], + + /** + * Configuration options for DateRangeFilter + */ + 'dateRange' => [ + 'defaultOptions' => [], + 'defaultConfig' => [ + 'allowInput' => true, // Allow manual input of dates + 'altFormat' => 'F j, Y', // Date format that will be displayed once selected + 'ariaDateFormat' => 'F j, Y', // An aria-friendly date format + 'dateFormat' => 'Y-m-d', // Date format that will be received by the filter + 'earliestDate' => null, // The earliest acceptable date + 'latestDate' => null, // The latest acceptable date + ], + ], + + /** + * Configuration options for NumberRangeFilter + */ + 'numberRange' => [ + 'defaultOptions' => [ + 'min' => 0, // The default start value + 'max' => 100, // The default end value + ], + 'defaultConfig' => [ + 'minRange' => 0, // The minimum possible value + 'maxRange' => 100, // The maximum possible value + 'suffix' => '', // A suffix to append to the values when displayed + ], + ], + ]; diff --git a/coverage.xml b/coverage.xml new file mode 100644 index 000000000..7428459d2 --- /dev/null +++ b/coverage.xml @@ -0,0 +1,2894 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_index.md b/docs/_index.md index cde0caa3b..854891848 100644 --- a/docs/_index.md +++ b/docs/_index.md @@ -1,5 +1,5 @@ --- -title: v2 +title: v3 slogan: A dynamic table component for Laravel Livewire. githubUrl: https://github.com/rappasoft/laravel-livewire-tables branch: master diff --git a/docs/bulk-actions/available-methods.md b/docs/bulk-actions/available-methods.md index 245e99a2b..41507dc24 100644 --- a/docs/bulk-actions/available-methods.md +++ b/docs/bulk-actions/available-methods.md @@ -133,3 +133,54 @@ public function configure(): void $this->setHideBulkActionsWhenEmptyDisabled(); } ``` + +## setBulkActionConfirms + +When a bulk action is included in the array passed to setBulkActionConfirms, the default wire:confirm pop-up will appear prior to executing the bulk action. The default message is: "Are you sure?". This should only be used if you wish to use the default message. + +```php +public function configure(): void +{ + $this->setBulkActionConfirms([ + 'delete', + 'reset' + ]); +} +``` +## setBulkActionDefaultConfirmationMessage + +You may use this method to over-ride the default message. To override the confirmation message for an individual Bulk Action, see the below setBulkActionConfirmMessage and setBulkActionConfirmMessages. You may also use the language files to do this. + +```php +public function configure(): void +{ + $this->setBulkActionDefaultConfirmationMessage('Are you certain?'); +} +``` + +## setBulkActionConfirmMessage + +You may use this method to specify a message other than the default message. + +```php +public function configure(): void +{ + $this->setBulkActionConfirmMessage('delete', 'Do you want to delete these items?'); +} +``` + +## setBulkActionConfirmMessages + +You may pass an array to this method, to more effectively update the confirmation message for a larger quantity of bulk actions. This expects an array keyed by the bulk action name, with the value being the message that will be displayed to the user. + +```php +public function configure(): void +{ + $this->setBulkActionConfirmMessages([ + 'delete' => 'Are you sure you want to delete these items?', + 'purge' => 'Are you sure you want to purge these items?', + 'reassign' => 'This will reassign selected items, are you sure?', + ]); +} +``` + diff --git a/docs/columns/available-methods.md b/docs/columns/available-methods.md index ebd7fa051..23797087d 100644 --- a/docs/columns/available-methods.md +++ b/docs/columns/available-methods.md @@ -153,7 +153,15 @@ The component has the ability to collapse certain columns at different screen si ![Collapsing](https://imgur.com/z1rWHzP.png) -You have 2 options when it comes to collapsing. +You have 3 options when it comes to collapsing. + +Collapse Always: + +```php +Column::make('Name') + ->collapseAlways(), +``` +The columns will always be collapsed Collapse on tablet: diff --git a/docs/columns/reusable-columns.md b/docs/columns/reusable-columns.md new file mode 100644 index 000000000..53b5865b2 --- /dev/null +++ b/docs/columns/reusable-columns.md @@ -0,0 +1,38 @@ +--- +title: Reusable Columns +weight: 8 +--- + +Often you will want to re-use the same column across multiple tables. For example a "Created At" and "Used At" column. + +To mitigate the pain of maintaining this, two new methods have been introduced. + +These methods both function in exactly the same way as your standard columns(), and expect an array of columns. + +Any columns defined in prependColumns() will be the first columns in your list of columns. +``` +public function prependColumns(): array +{ + return []; +} +``` + +Any columns defined in appendColumns() will be the last columns in your list of columns. +``` +public function appendColumns(): array +{ + return []; +} +``` + +You can call these in your trait, and they will be automatically appended/prepended to tables. + +For example, to append a Column for Updated At +``` +public function appendColumns(): array +{ + return [ + Column::make('Updated At', 'updated_at'), + ]; +} +``` diff --git a/docs/datatable/available-methods.md b/docs/datatable/available-methods.md index 949dda2ea..c5961359e 100644 --- a/docs/datatable/available-methods.md +++ b/docs/datatable/available-methods.md @@ -271,6 +271,31 @@ public function configure(): void return ['default' => true]; }); } + +``` +### setSearchFieldAttributes + +Set a list of attributes to override on the search field + +```php +public function configure(): void +{ + $this->setSearchFieldAttributes([ + 'class' => 'this that', + ]); +} +``` + +By default, this replaces the default classes on the search field, if you would like to keep them, set the default flag to true. + +```php +public function configure(): void +{ + $this->setSearchFieldAttributes([ + 'default' => true, + 'class' => 'added these classes', + ]); +} ``` ## Offline diff --git a/docs/datatable/configurable-areas.md b/docs/datatable/configurable-areas.md index e2ee45627..256d67dd4 100644 --- a/docs/datatable/configurable-areas.md +++ b/docs/datatable/configurable-areas.md @@ -91,11 +91,7 @@ Example dropdown for the toolbar: ```html @aware(['component']) -@php - $theme = $component->getTheme(); -@endphp - -@if ($theme === 'tailwind') +@if ($component->isTailwind())
-@elseif ($theme === 'bootstrap-4' || $theme === 'bootstrap-5') +@elseif ($component->isBootstrap())
@endif ``` diff --git a/docs/datatable/loaders.md b/docs/datatable/loaders.md new file mode 100644 index 000000000..a18c7b77e --- /dev/null +++ b/docs/datatable/loaders.md @@ -0,0 +1,80 @@ +--- +title: Loaders +weight: 4 +--- + +With the introduction of Livewire 3, there are several new methods available for use: + +## Loading Placeholder +```php +public function configure(): void +{ + $this->setLoadingPlaceholderBlade(''); +} +``` + +### setLoadingPlaceholderStatus +```php +public function configure(): void +{ + $this->setLoadingPlaceholderStatus(true); +} +``` + +### setLoadingPlaceholderEnabled +```php +public function configure(): void +{ + $this->setLoadingPlaceholderEnabled(); +} +``` + + +### setLoadingPlaceholderDisabled +```php +public function configure(): void +{ + $this->setLoadingPlaceholderDisabled(); +} +``` + +### setLoadingPlaceholderContent +```php +public function configure(): void +{ + $this->setLoadingPlaceholderContent(''); +} +``` + +### setLoadingPlaceHolderAttributes +```php +public function configure(): void +{ + $this->setLoadingPlaceHolderAttributes([]); +} +``` + +### setLoadingPlaceHolderIconAttributes +```php +public function configure(): void +{ + $this->setLoadingPlacehosetLoadingPlaceHolderIconAttributeslderBlade([]); +} +``` + +### setLoadingPlaceHolderWrapperAttributes +```php +public function configure(): void +{ + $this->setLoadingPlaceHolderWrapperAttributes([]); +} +``` + + +### setLoadingPlaceholderBlade +```php +public function configure(): void +{ + $this->setLoadingPlaceholderBlade(''); +} +``` diff --git a/docs/examples/advanced-example.md b/docs/examples/advanced-example.md index 86fc514b7..33166dc46 100644 --- a/docs/examples/advanced-example.md +++ b/docs/examples/advanced-example.md @@ -6,18 +6,14 @@ weight: 2 ```php update(['sort' => (int)$item['order']]); + User::find($item[$this->getPrimaryKey()])->update(['sort' => (int)$item[$this->getDefaultReorderColumn()]]); } } } @@ -298,4 +294,4 @@ class UsersTable extends DataTableComponent @endif @endif -``` \ No newline at end of file +``` diff --git a/docs/examples/basic-example.md b/docs/examples/basic-example.md index 60c2e07ca..d100933bd 100644 --- a/docs/examples/basic-example.md +++ b/docs/examples/basic-example.md @@ -6,7 +6,7 @@ weight: 1 ```php config([ + 'min' => '2020-01-01', // Earliest Acceptable Date + 'max' => '2021-12-31', // Latest Acceptable Date + 'pillFormat' => 'd M Y', // Format for use in Filter Pills + 'placeholder' => 'Enter Date', // A placeholder value + ]) + ]; +} +``` + +Date filters also support the setFilterDefaultValue() method, which must be a valid date in the "Y-m-d" format. This will apply as a default until removed. +```php +public function filters(): array +{ + return [ + DateFilter::make('Verified From') + ->config([ + 'min' => '2020-01-01', + 'max' => '2023-12-31', + 'pillFormat' => 'd M Y', + ])->setFilterDefaultValue('2023-08-01') + ]; +} +``` + + diff --git a/docs/filter-types/filters-daterange.md b/docs/filter-types/filters-daterange.md new file mode 100644 index 000000000..37d0ea552 --- /dev/null +++ b/docs/filter-types/filters-daterange.md @@ -0,0 +1,74 @@ +--- +title: DateRange Filters +weight: 3 +--- + +## DateRange Filters + +DateRange filters are Flatpickr based components, and simply filtering by a date range. If you would like to more smoothly filter your query by a start and end date, you can use the DateRangeFilter: + +```php +use Rappasoft\LaravelLivewireTables\Views\Filters\DateRangeFilter; + +public function filters(): array +{ + return [ + DateRangeFilter::make('Verified Period'), + ]; +} +``` + +DateRange filters have configs to set earliestDate and latestDate, to allow/disallow input, to set the input format, to set a placeholder value, display format, plus Filter Pills labels + +```php +public function filters(): array +{ + return [ + DateRangeFilter::make('EMail Verified Range') + ->config([ + 'allowInput' => true, // Allow manual input of dates + 'altFormat' => 'F j, Y', // Date format that will be displayed once selected + 'ariaDateFormat' => 'F j, Y', // An aria-friendly date format + 'dateFormat' => 'Y-m-d', // Date format that will be received by the filter + 'earliestDate' => '2020-01-01', // The earliest acceptable date + 'latestDate' => '2023-08-01', // The latest acceptable date + 'placeholder' => 'Enter Date Range', // A placeholder value + ]) + ->setFilterPillValues([0 => 'minDate', 1 => 'maxDate']) // The values that will be displayed for the Min/Max Date Values + ->filter(function (Builder $builder, array $dateRange) { // Expects an array. + $builder + ->whereDate('users.email_verified_at', '>=', $dateRange['minDate']) // minDate is the start date selected + ->whereDate('users.email_verified_at', '<=', $dateRange['maxDate']); // maxDate is the end date selected + }), + ]; +} +``` + + + +## Configuration +By default, this filter will use a CDN to include the Flatpickr JS Library and CSS. However, you can customise this behaviour using the configuration file. + +### Option 1 - The default CDN behaviour: +``` + 'published_third_party_assets' => false, + 'remote_third_party_assets' => true, +``` + +### Option 2 - Publish included version +You may publish the included version of Flatpickr. To do so, run: +``` +php artisan vendor:publish --tag=livewire-tables-public +``` +This will publish the tested version of Flatpickr to your public directory. You should then set +``` + 'published_third_party_assets' => true, + 'remote_third_party_assets' => false, +``` + +### Option 3 - Locally Installed +If you have a locally installed version of Flatpickr already, you can set both options to false, and your local version will be used instead. +``` + 'published_third_party_assets' => false, + 'remote_third_party_assets' => false, +``` diff --git a/docs/filter-types/filters-datetime.md b/docs/filter-types/filters-datetime.md new file mode 100644 index 000000000..288d90b4b --- /dev/null +++ b/docs/filter-types/filters-datetime.md @@ -0,0 +1,54 @@ +--- +title: DateTime Filters +weight: 4 +--- + +## DateTime Filters + +DateTime filters are HTML datetime-local elements and act the same as date filters. + +```php +use Rappasoft\LaravelLivewireTables\Views\Filters\DateTimeFilter; + +public function filters(): array +{ + return [ + DateTimeFilter::make('Verified From'), + ]; +} +``` + +DateTime filters have configs to set min and max, to set the format for the Filter Pills, and to set a placeholder value + +```php +public function filters(): array +{ + return [ + DateTimeFilter::make('Verified From') + ->config([ + 'min' => '2022-11-31 00:00:00', // Earliest Acceptable DateTime + 'max' => '2022-12-31 05:00:00', // Latest Acceptable Date + 'pillFormat' => 'd M Y - H:i', // Format for use in Filter Pills + 'placeholder' => 'Enter Date Time', // A placeholder value + ]) + ]; +} +``` + +DateTime filters also support the setFilterDefaultValue() method, which must be a valid datetime in the "Y-m-dTH:i" format. This will apply as a default until removed. +```php +public function filters(): array +{ + return [ + DateTimeFilter::make('Verified From') + ->config([ + 'min' => '2022-11-31 00:00:00', + 'max' => '2023-12-31 05:00:00', + 'pillFormat' => 'd M Y - H:i', + ]) + ->setFilterDefaultValue('2023-07-07T06:27') + ]; +} +``` + + diff --git a/docs/filter-types/filters-multiselect-dropdown.md b/docs/filter-types/filters-multiselect-dropdown.md new file mode 100644 index 000000000..d81c14570 --- /dev/null +++ b/docs/filter-types/filters-multiselect-dropdown.md @@ -0,0 +1,29 @@ +--- +title: Multi-Select Dropdown Filters +weight: 5 +--- + + +## Multi-select dropdown Filters + +Multi-select dropdown filters are a simple dropdown list. The user can select multiple options from the list. There is also an 'All' option that will select all values + +```php +use Rappasoft\LaravelLivewireTables\Views\Filters\MultiSelectDropdownFilter; + +public function filters(): array +{ + return [ + MultiSelectDropdownFilter::make('Tags') + ->options( + Tag::query() + ->orderBy('name') + ->get() + ->keyBy('id') + ->map(fn($tag) => $tag->name) + ->toArray() + ) + ->setFirstOption('All Tags'), + ]; +} +``` diff --git a/docs/filter-types/filters-multiselect.md b/docs/filter-types/filters-multiselect.md new file mode 100644 index 000000000..f6c6bfa37 --- /dev/null +++ b/docs/filter-types/filters-multiselect.md @@ -0,0 +1,27 @@ +--- +title: Multi-Select Filters +weight: 6 +--- + +## Multi-select Filters + +Multi-select filters are a list of checkboxes. The user can select multiple options from the list. There is also an 'All' option that will select all values. + +```php +use Rappasoft\LaravelLivewireTables\Views\Filters\MultiSelectFilter; + +public function filters(): array +{ + return [ + MultiSelectFilter::make('Tags') + ->options( + Tag::query() + ->orderBy('name') + ->get() + ->keyBy('id') + ->map(fn($tag) => $tag->name) + ->toArray() + ), + ]; +} +``` diff --git a/docs/filter-types/filters-number-range.md b/docs/filter-types/filters-number-range.md new file mode 100644 index 000000000..0969e5c33 --- /dev/null +++ b/docs/filter-types/filters-number-range.md @@ -0,0 +1,37 @@ +--- +title: NumberRange Filters +weight: 7 +--- + +## NumberRange Filters + +NumberRange filters allow for a minimum and maximum value to be input on a single slider. + +```php +public function filters(): array +{ + return [ + NumberRangeFilter::make('Success Rate') + ->options( + [ + 'min' => 0, + 'max' => 100, + ] + ) + ->config([ + 'minRange' => 0, + 'maxRange' => 100, + 'suffix' => '%', + ]) + ->filter(function (Builder $builder, array $values) { + $builder->where('users.success_rate', '>=', intval($values['min'])) + ->where('users.success_rate', '<=', intval($values['max'])); + }), + + ]; +} +``` + +The default values should be set in the options() method. + +You may also specify a minimum and maximum range in the config() options, and should you wish to use real values instead of a percentage, you can change the "suffix" to a metric of your choosing. diff --git a/docs/filter-types/filters-number.md b/docs/filter-types/filters-number.md new file mode 100644 index 000000000..3b629dd0a --- /dev/null +++ b/docs/filter-types/filters-number.md @@ -0,0 +1,25 @@ +--- +title: Number Filters +weight: 8 +--- + +## Number Filters + +Number filters are just HTML number inputs. + +```php +public function filters(): array +{ + return [ + NumberFilter::make('Amount') + ->config([ + 'min' => 0, // Minimum Value Accepted + 'max' => 100, // Maximum Value Accepted + 'placeholder' => 'Enter Number 0 - 100', // A placeholder value + ]) + ->filter(function(Builder $builder, string $value) { + $builder->where('amount', '<', $value); + }), + ]; +} +``` diff --git a/docs/filter-types/filters-select.md b/docs/filter-types/filters-select.md new file mode 100644 index 000000000..d28cfba94 --- /dev/null +++ b/docs/filter-types/filters-select.md @@ -0,0 +1,61 @@ +--- +title: Select Filters +weight: 9 +--- + +## Select Filters + +Select filters are a simple dropdown list. The user selects one choice from the list. + +```php +use Rappasoft\LaravelLivewireTables\Views\Filters\SelectFilter; + +public function filters(): array +{ + return [ + SelectFilter::make('Active') + ->options([ + '' => 'All', + 'yes' => 'Yes', + 'no' => 'No', + ]), + ]; +} +``` + +### The default value + +You should supply the first option as the default value. I.e. nothing selected, so the filter is not applied. This value should be an empty string. When this value is selected, the filter will be removed from the query and the query string. + +### Option Groups + +To use `` elements, pass a nested array of options to the select filter. + +```php +use Rappasoft\LaravelLivewireTables\Views\Filters\SelectFilter; + +public function filters(): array +{ + return [ + SelectFilter::make('Active') + ->options([ + '' => 'All', + 'Open' => [ + 1 => 'Type A', + 2 => 'Type B', + 3 => 'Type C', + ], + 'Closed' => [ + 24 => 'Type X', + 25 => 'Type Y', + 26 => 'Type Z', + ], + ]) + ->setFirstOption('All Tags'), + ]; +} +``` +To set a default "All" option at the start of the dropdown, you can do so by utilising the +``` +->setFirstOption('NAME') +``` diff --git a/docs/filter-types/filters-text.md b/docs/filter-types/filters-text.md new file mode 100644 index 000000000..649384915 --- /dev/null +++ b/docs/filter-types/filters-text.md @@ -0,0 +1,24 @@ +--- +title: Text Filters +weight: 10 +--- + +## Text Filters + +Text filters are just HTML text fields. + +```php +public function filters(): array +{ + return [ + TextFilter::make('Name') + ->config([ + 'placeholder' => 'Search Name', + 'maxlength' => '25', + ]) + ->filter(function(Builder $builder, string $value) { + $builder->where('users.name', 'like', '%'.$value.'%'); + }), + ]; +} +``` diff --git a/docs/filter-types/introduction.md b/docs/filter-types/introduction.md new file mode 100644 index 000000000..d509cdc39 --- /dev/null +++ b/docs/filter-types/introduction.md @@ -0,0 +1,6 @@ +--- +title: Introduction +weight: 1 +--- + +There are several Filter types available for use, offering a range of capabilities to filter your data. diff --git a/docs/filters/available-methods.md b/docs/filters/available-methods.md index 3948ae8df..1e3ede084 100644 --- a/docs/filters/available-methods.md +++ b/docs/filters/available-methods.md @@ -304,9 +304,7 @@ Example blade: ```php @aware(['component']) @props(['filter']) -@php - $theme = $component->getTheme(); -@endphp + @@ -334,28 +332,52 @@ SelectFilter::make('Active') ->setCustomFilterLabel('path.to.blade') ``` -You will receive two properties to your blade, filter (the filter instance), and theme (your chosen theme). You may access the filter layout as shown below - -Example blade: +You will receive several properties to your blade, explained here: +- $filter (the filter instance) +- $filterLayout ('slide-down' or 'popover') +- $tableName (the table name) +- $isTailwind (bool - is theme Tailwind) +- $isBootstrap (bool - is theme Bootstrap 4 or Bootstrap 5) +- $isBootstrap4 (bool - is theme Bootstrap 4) +- $isBootstrap5 (bool - is theme Bootstrap 5) +- $customLabelAttributes (array -> any customLabel attributes set using setFilterLabelAttributes()) + +Example label blade: ```php -@aware(['component']) -@props(['filter','theme']) -@php - $theme = $component->getTheme(); -@endphp -