Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Drag And Scroll Laravel Package

zoltantorok/filament-drag-and-scroll

Add Shift+drag horizontal scrolling to Filament tables with this zero-config plugin. Just install via composer and call ->dragAndScroll() on your panel. Includes tooltip feedback, per-panel toggling, and 13 built-in translations.

View on GitHub
Deep Wiki
Context7

Getting Started

Check the version gate before anything else. This package only supports Filament ^5.0 (PHP ^8.1, Laravel ^11–13). If your estate is still on Filament 3 or 4, stop here — there is no compatibility path, and the package is not the thing you upgrade for.

composer require zoltantorok/filament-drag-and-scroll

Pin it explicitly rather than floating, given the single-maintainer/3-star profile:

"zoltantorok/filament-drag-and-scroll": "1.0.*"

First use case: an internal admin panel with a table wide enough to actually scroll horizontally (15+ columns, or long text columns). The package does nothing for narrow tables — verify you have a real scrolling case before wiring it up.

Enable it on exactly one panel to start:

// app/Providers/Filament/AdminPanelProvider.php
public function panel(Panel $panel): Panel
{
    return $panel
        ->default()
        ->id('admin')
        ->path('admin')
        ->login()
        ->dragAndScroll();   // <- the only change
}

Then php artisan serve (or your usual dev stack), open a wide table, hold Shift, and drag. You should get a cursor change and tooltip, and the table should scroll horizontally.

Where to look first when reading the source:

  1. src/ — the service provider and whatever registers the dragAndScroll() method on Filament\Panel (macro or trait). Read this to confirm exactly what it injects and whether it's gated by anything (env, panel id).
  2. resources/js/ — the actual shift+drag handler. This is the whole package; ~50 lines. Understand the event binding strategy (delegated vs per-node) before you trust it.
  3. resources/lang/ — the 13 locale files, keys dragToScrollHorizontally and releaseShiftToExit.
  4. composer.json — confirm the constraint and autoload shape.

Because the surface area is tiny, budget 20 minutes to read the JS. That reading is the real evaluation; the README is not.

Implementation Patterns

Per-panel opt-in via a shared base provider. If you have several panels, put the toggle in one place so behaviour is greppable and reversible:

abstract class BasePanelProvider extends PanelProvider
{
    protected function configureDragAndScroll(Panel $panel): Panel
    {
        return app()->isProduction()
            ? $panel->dragAndScroll(feature('table-drag-scroll'))  // your flag
            : $panel->dragAndScroll();
    }
}

Using ->dragAndScroll(false) explicitly is preferable to omitting the call when the method is added in a base class — it documents intent and survives someone flipping a default later.

Flag-gated rollout. Because enabling is a single chainable call, it makes a good A/B candidate. Wrap it in a config or feature flag and flip per environment:

// config/filament.php
'drag_and_scroll' => env('FILAMENT_DRAG_SCROLL', true),

// PanelProvider
->dragAndScroll(config('filament.drag_and_scroll'))

This gives you a same-day rollback without a deploy of new code, which is the entire risk argument for trying the package.

Pair it with the real fix, don't substitute. Shift+drag solves the input-device problem; it does not solve "too many columns." The higher-leverage patterns still apply and should ship alongside:

  • Column visibility + persisted toggles (->toggleable(isToggledHiddenByDefault: true))
  • Pinned/frozen key columns if your table component supports it
  • Density controls for wide-but-short tables

Treat ->dragAndScroll() as the accessibility affordance layered on top, not the column-count strategy.

Custom copy for your org's conventions. Publish the lang files and override the two keys if "Shift + drag" doesn't match your house style for hints (e.g. you already have a keyboard-shortcut legend):

php artisan vendor:publish --tag="filament-drag-and-scroll-views"

If that tag errors (see Gotchas), create the file manually:

// resources/lang/vendor/filament-drag-and-scroll/en/messages.php
return [
    'dragToScrollHorizontally' => 'Hold Shift and drag to scroll →',
    'releaseShiftToExit'       => 'Release Shift to exit drag mode',
];

Vendoring as the exit strategy. Given bus factor 1, copy resources/js into your own theme's JS and register it via a FilamentAsset/FilamentView render hook in your panel provider. That turns the dependency into a one-time read rather than an ongoing commitment. Do this if you later hit a Filament minor that breaks the binding — you own ~50 lines, not a fork.

Removal is one commit. Drop the method call, composer remove zoltantorok/filament-drag-and-scroll, clear caches. No migrations, no config, no schema. Keep that reversibility clean by not building other behaviour on top of the package's internals.

Gotchas and Tips

The translation publish tag looks wrong. The README tells you to publish translations with --tag="filament-drag-and-scroll-views" — a views tag for lang files. Release v1.0.1 is literally titled "Fixed publishing command," so this has already churned once. Verify the actual tag names in the service provider's publishes() calls before scripting it into a deploy. The manual resources/lang/vendor/.../messages.php path is the reliable fallback.

Translation cache will bite you in production. After publishing overrides, run php artisan optimize:clear (or at minimum php artisan cache:clear plus a lang cache rebuild). Locale is picked up from app()->getLocale() automatically — there's no config to set, which also means per-user locale switching depends entirely on your middleware setting the locale before the panel renders.

Livewire morphing is the critical unknown. Filament tables are re-rendered by Livewire on paginate, sort, filter, search, and record actions. If the package binds on DOMContentLoaded/document.ready without delegation or a Livewire hook (Livewire.hook('morph.updated'), livewire:navigated), drag will silently stop working after the first table refresh. Test explicitly: enable, then sort a column, paginate, apply a filter, search, and navigate away/back via SPA links — verifying the gesture after each step. This is the first thing to validate and the most likely reason to vendor.

Shift+drag collides with native text selection. Shift+click is a text-selection gesture in most browsers. Confirm the handler calls preventDefault() scoped to the table's scroll container only — otherwise you break copying cell values, which is a far more common workflow than horizontal scrolling. Test: select text in a cell, Shift+click elsewhere, Shift+drag outside the table.

Interaction collisions to check by hand:

  • Row selection (checkbox row clicks) while Shift is held
  • Column reordering, if you use a drag-to-reorder table extension
  • Any drag-and-drop file/row features in the same view
  • Browser find-in-page and Shift+wheel

CSP / nonce. If your panel ships a strict Content-Security-Policy with nonces, inline initialisation from a vendor asset will be blocked and the feature dies silently in production while working fine locally. Check the browser console on a CSP-enforcing environment. Also confirm whether assets are served from vendor/ through Filament's asset pipeline or published to public/ — asset-publish drift after a deploy (stale hashed file) produces the same "works on my machine" symptom.

It is not an accessibility remediation on its own. It adds a pointer+keyboard gesture; it does not make the scroll container keyboard-focusable or scrollable via arrow keys. If "accessibility" is the justification to your stakeholders, pair this with a real keyboard/tab-order review — WCAG 2.1.1 doesn't care about Shift+drag.

Touch devices get nothing useful. Shift+drag has no touch equivalent and is redundant on trackpads. Your mobile/tablet users need responsive column prioritisation or column toggles instead. Don't let this package close the "mobile admin" ticket.

Debugging checklist when the gesture doesn't fire:

  1. Confirm the asset actually loaded — Network tab for the package's JS/CSS.
  2. Confirm the panel provider method ran — ->dragAndScroll() returns Panel, so it chains anywhere; a false earlier in the chain is the classic cause of "nothing happens."
  3. Console for JS errors after a Livewire update (see morphing above).
  4. Test with Shift held before mousedown — some implementations require the key state at pointer-down, not mid-drag.
  5. Try a second, unrelated panel to isolate whether it's the package or your table/theme.

Release provenance. The published release date reads as future-dated. Before merging, verify the Packagist tag resolves to an auditable commit (composer show zoltantorok/filament-drag-and-scroll, then diff against the repo tag) and check whether any CI exists. No CI + no dependents + 3 stars means you are the integration test.

Keep the diff small. One composer entry, one line in a panel provider, optionally two lang strings. If a review asks for more than that, you're over-investing in a dependency you should instead be copying.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console