Folio icon

Folio -----

Modular fluent paginated inventory GUI framework — pagination, animations, async loading, anvil-sear



Folio

A modular, fluent, builder-based paginated inventory GUI framework for Paper 1.21+.
Pure Adventure API · Java 21 · zero dependencies beyond paper-api.

Features
  • Core — InventoryPage · PagedInventory · InventoryItem · InventorySession · InventoryRegistry
  • Click — sealed ClickResult (Allow / Cancel / Close / Refresh / Navigate), per-type handlers (left/right/shift/drop/numberKey), bubbling chain (item → page → inventory), per-item cooldowns, async handlers
  • Layout — sealed Layout: LinearLayout · GridLayout · MaskLayout (text-block patterns with B / X / .)
  • Pagination — auto + manual, configurable navigation slots, MiniMessage page-indicator
  • Animation — AnimatedItem with frames, refreshEvery(Duration), slot-diffing renderer (no flicker), pauses when nobody's watching
  • Async — CompletableFuture<List<InventoryItem>> source, animated placeholder, error fallback, TTL cache, soft-cancel-on-close
  • Filter / Search — Filter predicates with AND / OR / negate, anvil-GUI live search via SearchPrompt, per-session filter state
  • Multi-player — SessionMode.SHARED — one Inventory instance, multiple viewers (co-op GUIs, auctions)
  • Form / Input — mark slots as inputSlot(...), click NOT cancelled, leftover items returned on close
  • Hotbar keys — hotbarBind(1..9, handler) — page-global number-key shortcuts
  • Persistence — .persistent("key") — page index saved in player's PersistentDataContainer, restored on rejoin
  • Permissions — PermissionGate on page and item level, auto-hide
  • Theme — central InventoryTheme (border material, sounds, MiniMessage indicator template)

[HR][/HR]

Quick start — a 28-slot shop

Code (Java):

List <InventoryItem > offers = catalog. stream ( )
       . map (o -> InventoryItem. builder ( )
               . material (o. material ( ) )
               . name ( Component. text (o. name ( ), NamedTextColor. YELLOW ) )
               . lore ( Component. text ( "Preis: " + o. price ( ) + "g", NamedTextColor. GRAY ) )
               . cooldown (Duration. ofMillis ( 500 ) )
               . clickableIf (p -> economy. balance (p ) >= o. price ( ) )
               . onLeftClick (ctx -> {
                   economy. charge (ctx. player ( ), o. price ( ) ) ;
                   ctx. player ( ). getInventory ( ). addItem (o. product ( ) ) ;
                    return ClickResult. refresh ( ) ;
                } )
               . build ( ) )
       . toList ( ) ;

InventoryPage page = InventoryPage. builder ( )
       . title ( Component. text ( "Shop", NamedTextColor. GOLD ) )
       . rows ( 6 )
       . layout (MaskLayout. of ( "" "
               BBBBBBBBB
               BXXXXXXXB
               BXXXXXXXB
               BXXXXXXXB
               BXXXXXXXB
               BBBBBBBBB
               "
"" ) )
       . navigation (NavigationButtons. builder ( )
               . firstSlot ( 45 ). previousSlot ( 47 ). pageIndicatorSlot ( 49 )
               . nextSlot ( 51 ). lastSlot ( 53 ). build ( ) )
       . items (offers )
       . build ( ) ;

registry. open (player, PagedInventory. paginate (page ) ) ;
 
[HR][/HR]

Built-in demo

The plugin ships with /foliodemo <sub> (alias /invpagedemo) — every feature live, no setup:

  • shop — 200 items · mask layout · pagination · cooldowns
  • anim — 4 slots cycling 8 wool colors
  • async — simulated DB load with animated placeholder
  • filter — toggle filter button · live re-pagination
  • shared — co-op: two players, one Inventory
  • search — anvil-GUI live search → filtered shop
  • persist — leave + rejoin → opens at the same page
  • keys — hotbar 1..9 actions while hovering
  • form — 3 input slots + emerald-confirm with validation
  • exit — clear stored persistence state

[HR][/HR]

Install

  1. Drop folio-1.0.0.jar into plugins/
  2. Restart the server
  3. Run /foliodemo shop in-game

To depend on Folio from your own plugin, add to your plugin.yml:
Code (Text):
depend: [Folio]
And get the registry:
Code (Java):

InventoryRegistry registry = ( (InventoryPagePlugin ) Bukkit. getPluginManager ( )
       . getPlugin ( "Folio" ) ). registry ( ) ;
 
[HR][/HR]

Requirements
  • Paper 1.21+ (uses MenuType.ANVIL · sealed types · pattern matching)
  • Java 21

Design defaults
  • Click + drag in top inventory always cancelled — opt-in via ClickResult.allow() (sync only)
  • Async cancel = soft-discard (no Future.cancel(true) — interrupting JDBC / HTTP is unsafe; the caller owns the future's lifecycle)
  • Refresh interval clamped to ≥ 1 tick (50 ms)
  • SHARED mode = shared items and shared cursor (predictable for co-op GUIs)
  • Indicator template lives in InventoryTheme (one place to retheme the whole plugin)

License: MIT
Resource Information
Author:
----------
Total Downloads: 9
First Release: Apr 26, 2026
Last Update: Apr 26, 2026
Category: ---------------
All-Time Rating:
0 ratings
Version -----
Released: --------------------
Downloads: ------
Version Rating:
----------------------
-- ratings