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
[HR][/HR]
Quick start — a 28-slot shop
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:
[HR][/HR]
Install
To depend on Folio from your own plugin, add to your plugin.yml:
And get the registry:
InventoryRegistry registry = ( (InventoryPagePlugin ) Bukkit. getPluginManager ( )
. getPlugin ( "Folio" ) ). registry ( ) ;
[HR][/HR]
Requirements
Design defaults
License: MIT
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 ) ) ;
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
- Drop folio-1.0.0.jar into plugins/
- Restart the server
- Run /foliodemo shop in-game
To depend on Folio from your own plugin, add to your plugin.yml:
Code (Text):
depend: [Folio]
Code (Java):
InventoryRegistry registry = ( (InventoryPagePlugin ) Bukkit. getPluginManager ( )
. getPlugin ( "Folio" ) ). registry ( ) ;
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
Quick facts
- Edition: Minecraft Java
- File type: .jar
- Minecraft version listed: 1.21
- How to install: Install the matching mod loader (Forge, Fabric or NeoForge) for your Minecraft version. → Download the .jar. → Put it in the .minecraft/mods folder and launch that loader profile.
- Where to get it: Opens on Spigot — not every file is mirrored on our own servers.
Install steps are the general flow for this file type — How to install Minecraft Java mods & modpacks walks through it step by step.
Folio is a free Minecraft Java mod. Compatible with Minecraft 1.21. Downloaded 12 times (via Spigot). Download it and open it directly in the game.