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
- $theme === 'tailwind',
- 'd-block' => $theme === 'bootstrap-4' && $component->isFilterLayoutSlideDown(),
- 'mb-2' => $theme === 'bootstrap-4' && $component->isFilterLayoutPopover(),
- 'd-block display-4' => $theme === 'bootstrap-5' && $component->isFilterLayoutSlideDown(),
- 'mb-2 display-4' => $theme === 'bootstrap-5' && $component->isFilterLayoutPopover(),
- ])
+@props(['filter', 'filterLayout' => 'popover', 'tableName' => 'table', 'isTailwind' => false, 'isBootstrap' => false, 'isBootstrap4' => false, 'isBootstrap5' => false, 'customLabelAttributes' => [])
+
+
+merge($customLabelAttributes)
+ ->class(['block text-sm font-medium leading-5 text-gray-700 dark:text-white' => $isTailwind && $customLabelAttributes['default'] ?? true])
+ ->class(['d-block' => $isBootstrap && $filterLayout == 'slide-down' && $customLabelAttributes['default'] ?? true])
+ ->class(['mb-2' => $isBootstrap && $filterLayout == 'popover' && $customLabelAttributes['default'] ?? true])
+ ->except('default')
+ }}
+
>
{{ $filter->getName() }}
```
+### setFilterLabelAttributes
+Set custom attributes for a Filter Label. At present it is recommended to only use this for "class" and "style" attributes to avoid conflicts.
+
+By default, this replaces the default classes on the Filter Label wrapper, if you would like to keep them, set the default flag to true.
+
+```php
+TextFilter::make('Name')
+ ->setFilterLabelAttributes(
+ [
+ 'class' => 'text-xl',
+ 'default' => true,
+ ]
+ ),
+```
+
+
### Config
If the filter takes any config options, you can set them with the `config` method:
diff --git a/docs/filters/creating-filters.md b/docs/filters/creating-filters.md
index 0d183e8ac..e940c5952 100644
--- a/docs/filters/creating-filters.md
+++ b/docs/filters/creating-filters.md
@@ -14,185 +14,9 @@ public function filters(): array
This method will return an array of filter objects. There are a few filter types to choose from:
-## 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')
-```
-
-## 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()
- ),
- ];
-}
-```
-
-## 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'),
- ];
-}
-```
-
-## Date Filters
-
-Date filters are HTML date elements.
-
-```php
-use Rappasoft\LaravelLivewireTables\Views\Filters\DateFilter;
-
-public function filters(): array
-{
- return [
- DateFilter::make('Verified From'),
- ];
-}
-```
-
-Date filters have options to set min and max:
-
-```php
-public function filters(): array
-{
- return [
- DateFilter::make('Verified From')
- ->config([
- 'min' => '2020-01-01',
- 'max' => '2021-12-31',
- ])
- ];
-}
-```
-
-## DateTime Filters
-
-DateTime filters are HTML datetime-local elements and act the same as date filters.
-
-Make sure to look at [all available configurations](available-methods#filter-methods) on the Filter classes.
-
-## Number Filters
-
-Number filters are just HTML number inputs.
-
-```php
-public function filters(): array
-{
- return [
- NumberFilter::make('Amount')
- ->config([
- 'min' => 0,
- 'max' => 100,
- ])
- ->filter(function(Builder $builder, string $value) {
- $builder->where('amount', '<', $value);
- }),
- ];
-}
-```
-
-## 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.'%');
- }),
- ];
-}
-```
## Filter Keys
diff --git a/docs/misc/custom-markup.md b/docs/misc/custom-markup.md
index 62e1aa012..8bfb6ec86 100644
--- a/docs/misc/custom-markup.md
+++ b/docs/misc/custom-markup.md
@@ -1,6 +1,6 @@
---
title: Adding Custom Markup
-weight: 3
+weight: 4
---
If you would like to append any custom markup right before the end of the component, you may use the `customView` method and return a view.
@@ -12,4 +12,4 @@ public function customView(): string
{
return 'includes.custom';
}
-```
\ No newline at end of file
+```
diff --git a/docs/misc/debugging.md b/docs/misc/debugging.md
index c1c8f3193..fb42f5a7f 100644
--- a/docs/misc/debugging.md
+++ b/docs/misc/debugging.md
@@ -1,6 +1,6 @@
---
title: Debugging
-weight: 4
+weight: 5
---
## Configuration
diff --git a/docs/misc/loading-placeholder.md b/docs/misc/loading-placeholder.md
new file mode 100644
index 000000000..20ca7f9b5
--- /dev/null
+++ b/docs/misc/loading-placeholder.md
@@ -0,0 +1,78 @@
+---
+title: Loading Placeholder
+weight: 2
+---
+
+When running complex filters or searches, or displaying larger number of records, you can make use of the built-in Loading Placeholder, this is disabled by default.
+
+### setLoadingPlaceholderStatus
+You may pass a boolean to this, which will either enable (true) or disable (false) the loading placeholder
+
+```php
+ public function configure(): void
+ {
+ $this->setLoadingPlaceholderStatus(true);
+ }
+```
+
+### setLoadingPlaceholderEnabled
+
+Use this method to enable the loading placeholder:
+
+```php
+ public function configure(): void
+ {
+ $this->setLoadingPlaceholderEnabled();
+ }
+```
+
+### setLoadingPlaceholderDisabled
+
+Use this method to disable the loading placeholder:
+
+```php
+ public function configure(): void
+ {
+ $this->setLoadingPlaceholderDisabled();
+ }
+```
+
+### setLoadingPlaceholderContent
+
+You may use this method to set custom text for the placeholder:
+
+```php
+ public function configure(): void
+ {
+ $this->setLoadingPlaceholderContent('Text To Display');
+ }
+```
+### setLoadingPlaceHolderWrapperAttributes
+
+This method allows you to customise the attributes for the <tr> element used as a Placeholder when the table is loading. Similar to other setAttribute methods, this accepts a range of attributes, and a boolean "default", which will enable/disable the default attributes.
+
+```php
+ public function configure(): void
+ {
+ $this->setLoadingPlaceHolderWrapperAttributes([
+ 'class' => 'text-bold',
+ 'default' => false,
+ ]);
+ }
+
+```
+
+### setLoadingPlaceHolderIconAttributes
+
+This method allows you to customise the attributes for the <div> element that is used solely for the PlaceholderIcon. Similar to other setAttribute methods, this accepts a range of attributes, and a boolean "default", which will enable/disable the default attributes.
+
+```php
+ public function configure(): void
+ {
+ $this->setLoadingPlaceHolderIconAttributes([
+ 'class' => 'lds-hourglass',
+ 'default' => false,
+ ]);
+ }
+
+```
diff --git a/docs/misc/multiple-tables.md b/docs/misc/multiple-tables.md
index 026d8ca1b..2a6ac0dd4 100644
--- a/docs/misc/multiple-tables.md
+++ b/docs/misc/multiple-tables.md
@@ -1,6 +1,6 @@
---
title: Multiple Tables Same Page
-weight: 2
+weight: 3
---
This feature works for mutiple tables on the same page that are **different** components.
diff --git a/docs/misc/saving-state.md b/docs/misc/saving-state.md
new file mode 100644
index 000000000..8d85acd26
--- /dev/null
+++ b/docs/misc/saving-state.md
@@ -0,0 +1,16 @@
+---
+title: Saving Table State
+weight: 6
+---
+
+There may be occasions that you'd like to save the table state, for example if you have a complex set of filters, search parameters, or simply to remember which page you were on!
+
+You may call the following method to retrieve the state of the table:
+```
+$this->getTableStateToArray();
+```
+
+And to restore it, you should call the following method, passing the stored array.
+```
+$this->restoreStateFromArray(array $storedArray)
+```
diff --git a/docs/pagination/available-methods.md b/docs/pagination/available-methods.md
index 380d92f0e..b2a6a46d2 100644
--- a/docs/pagination/available-methods.md
+++ b/docs/pagination/available-methods.md
@@ -173,6 +173,15 @@ public function configure(): void
}
```
+You may specify `cursorPaginate` like so:
+
+```php
+public function configure(): void
+{
+ $this->setPaginationMethod('cursor');
+}
+```
+
## getPerPageDisplayedItemIds
Returns the Primary Key for the currently visible rows in an array. This should be used in a blade to ensure accuracy.
diff --git a/docs/reordering/available-methods.md b/docs/reordering/available-methods.md
index 1e8fb96c5..101848599 100644
--- a/docs/reordering/available-methods.md
+++ b/docs/reordering/available-methods.md
@@ -123,7 +123,7 @@ public function configure(): void
## setReorderMethod
-Set the method that will be called when a row is moved. (Default is `reorder`.)
+Set the method that will be called when the "Save" button is clicked. (Default is `reorder`.)
```php
public function configure(): void
diff --git a/docs/reordering/introduction.md b/docs/reordering/introduction.md
index d5832d735..38550b346 100644
--- a/docs/reordering/introduction.md
+++ b/docs/reordering/introduction.md
@@ -3,10 +3,12 @@ title: Introduction
weight: 1
---
-You must have [Livewire Sortable](https://github.com/livewire/sortable) or [Livewire Sortable.js](https://github.com/nextapps-be/livewire-sortablejs) installed for this feature.
+The previous iteration utilised third-party Sortable plugins, which are not required for Version 3.x, and are not supported in Livewire 3.x at the time of writing.
-## A warning about reordering
+## An update about reordering
-In order for reordering to work, all rows have to be loaded to the page regardless of if you have pagination on or off. So it's best to only use this feature if you have a small amount of rows to work with.
+If you have a large data set to sort, then it is recommended that you create a minimal table instance with only the required columns for performance reasons.
-The table will remember the state if was left in when reordering started and will be returned when reordering ends.
+The field keys used in the reorder() function have been updated, and allow for easier upserting/reuse of reorder code.
+
+The reorder will not be saved until you click the "Save" button.
diff --git a/docs/reordering/saving.md b/docs/reordering/saving.md
index 4801f076d..16131f10b 100644
--- a/docs/reordering/saving.md
+++ b/docs/reordering/saving.md
@@ -3,13 +3,34 @@ title: Saving
weight: 3
---
-When a row is moved, the table will call your reorder method on the component with the current order of the entire table:
+When you click the "Save" button, your ordered elements will be returned as an array, to the function you have configured.
+
+You will receive a multi-dimensional array, containing an array item per record, with the primary key, and order field.
+
+It is recommended that you perform some validation before bulk updating data, but it is in the correct format to perform upserts.
```php
-public function reorder($items): void
+public function reorder(array $items): void
{
+ // $item[$this->getPrimaryKey()] ensures that the Primary Key is used to find the User
+ // 'sort' is the name of your "sort" field in your database
+ // $item[$this->getDefaultReorderColumn()] retrieves the field, as defined in setDefaultReorderSort('FIELD', 'ORDER')
+
foreach ($items as $item) {
- User::find((int)$item['value'])->update(['sort' => (int)$item['order']]);
+ User::find($item[$this->getPrimaryKey()])->update(['sort' => (int)$item[$this->getDefaultReorderColumn()]]);
}
}
+
```
+
+If you have defined both the Primary Key, and the Order Column, and the fields match your database, then you could use an upsert(). Keep in mind that an upsert does not go through validation, and you should exercise caution with this approach
+```php
+public function reorder(array $items): void
+{
+ // First value is the array of items
+ // Second value should be the unique id (set in setPrimaryKey())
+ // Third value should be the field set in setDefaultReorderSort('FIELD', 'ORDER')
+ User::upsert($items, [$this->getPrimaryKey()], [$this->getDefaultReorderColumn()]);
+}
+
+```
\ No newline at end of file
diff --git a/docs/reordering/setup.md b/docs/reordering/setup.md
index fcebde426..5d7be6d93 100644
--- a/docs/reordering/setup.md
+++ b/docs/reordering/setup.md
@@ -18,7 +18,7 @@ public function configure(): void
## Specify your reorder method
-By default the method that will be called when a row is moved is `reorder`.
+By default the method that will be called when the save button is clicked is `reorder`.
If you want to change that:
diff --git a/docs/rows/clickable-rows.md b/docs/rows/clickable-rows.md
index 64dc64e94..3271d07d1 100644
--- a/docs/rows/clickable-rows.md
+++ b/docs/rows/clickable-rows.md
@@ -29,4 +29,27 @@ Column::make('Name')
->unclickable(),
```
-**Note:** LinkColumns are not clickable by default to preserve the intended behavior of the link.
\ No newline at end of file
+**Note:** LinkColumns are not clickable by default to preserve the intended behavior of the link.
+
+## Using wire:navigate
+
+To use wire:navigate, you should return "navigate" as the target for setTableRowUrlTarget
+
+```php
+public function configure(): void
+{
+ $this->setPrimaryKey('id')
+ ->setTableRowUrl(function($row) {
+ return route('admin.users.show', $row);
+ })
+ ->setTableRowUrlTarget(function($row) {
+ if ($row->isExternal()) {
+ return '_blank';
+ }
+
+ return 'navigate';
+ });
+}
+
+```
+
diff --git a/docs/search/available-methods.md b/docs/search/available-methods.md
index b0d20ac09..e05ce7649 100644
--- a/docs/search/available-methods.md
+++ b/docs/search/available-methods.md
@@ -92,6 +92,17 @@ public function configure(): void
// Shorthand for $this->setSearchVisibilityStatus(false)
$this->setSearchVisibilityDisabled();
}
+
+```
+## setSearchPlaceholder
+
+Set a custom placeholder for the search box
+
+```php
+public function configure(): void
+{
+ $this->setSearchPlaceholder('Enter Search Term');
+}
```
---
@@ -122,14 +133,38 @@ public function configure(): void
}
```
-## setSearchLazy
+## setSearchLive
+
+Tell Livewire to immediately update the search
+
+```php
+public function configure(): void
+{
+ // Send the search request immediately
+ $this->setSearchLive();
+}
+```
+
+## setSearchBlur
+
+Tell Livewire to update the search when focus is changed from the text box.
+
+```php
+public function configure(): void
+{
+ // Send the search request once focus changes
+ $this->setSearchBlur();
+}
+```
+
+## setSearchThrottle
-Tell Livewire to use the `lazy` modifier.
+Tell Livewire to throttle updates
```php
public function configure(): void
{
- // Send the request when the user clicks away from the search box.
- $this->setSearchLazy();
+ // Search will throttle to every 1 second
+ $this->setSearchThrottle(1000);
}
```
diff --git a/docs/start/commands.md b/docs/start/commands.md
index a9d36a78d..da02db15b 100644
--- a/docs/start/commands.md
+++ b/docs/start/commands.md
@@ -1,13 +1,13 @@
---
title: Commands
-weight: 5
+weight: 6
---
## Generating Datatable Components
To generate a new datatable component you can use the `make:datatable` command:
-Create a new datatable component called `UserTable` in `App\Http\Livewire` that uses the `App\Models\User` model.
+Create a new datatable component called `UserTable` in `App\Livewire` that uses the `App\Models\User` model.
```bash
php artisan make:datatable UserTable User
@@ -17,7 +17,7 @@ php artisan make:datatable UserTable User
You may pass a Custom Path to your model, should it not be contained within the "App" or "App\Models" namespaces:
-Create a new datatable component called `TestTable` in `App\Http\Livewire` that uses the `App\Domains\Test\Models\Example` model.
+Create a new datatable component called `TestTable` in `App\Livewire` that uses the `App\Domains\Test\Models\Example` model.
```bash
php artisan make:datatable TestTable example app/Domains/Test/Models/
diff --git a/docs/start/configuration.md b/docs/start/configuration.md
index 02aeadf18..75aef5083 100644
--- a/docs/start/configuration.md
+++ b/docs/start/configuration.md
@@ -1,6 +1,6 @@
---
title: Configuration
-weight: 3
+weight: 4
---
## Publishing Assets
@@ -15,6 +15,9 @@ php artisan vendor:publish --provider="Rappasoft\LaravelLivewireTables\LaravelLi
php artisan vendor:publish --provider="Rappasoft\LaravelLivewireTables\LaravelLivewireTablesServiceProvider" --tag=livewire-tables-views
php artisan vendor:publish --provider="Rappasoft\LaravelLivewireTables\LaravelLivewireTablesServiceProvider" --tag=livewire-tables-translations
+
+php artisan vendor:publish --provider="Rappasoft\LaravelLivewireTables\LaravelLivewireTablesServiceProvider" --tag=livewire-tables-public
+
```
The default frontend framework is Tailwind, but you also have the option to use Bootstrap 4 or Bootstrap 5 by specifying in the config file.
@@ -71,7 +74,7 @@ module.exports = {
## Alpine.js Cloak
-You must also make sure you have this Alpine style available globally:
+You must also make sure you have this Alpine style available globally. Note that this is configured by default by Livewire after 3.x
```css