> For the complete documentation index, see [llms.txt](https://walksy.gitbook.io/walksylib-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://walksy.gitbook.io/walksylib-docs/using/lists-and-pages.md).

# Lists and Pages

## String list

A free-form list of strings the user can add to and remove from.

```java
Options.ofStringList("Friends", () -> friends, List.of(), value -> friends = new ArrayList<>(value))
    .reorderable()
    .noSpaces()
    .build();
```

| Method                     | What it does                                 |
| -------------------------- | -------------------------------------------- |
| `.reorderable()`           | Entries can be dragged into a new order.     |
| `.allowDuplicates()`       | The same entry can be added more than once.  |
| `.noSpaces()`              | Strips spaces from new entries.              |
| `.nameRule(EntryNameRule)` | Custom cleaning for new entries (see below). |

## Selection list

Like a string list, except the user picks from a set of values, with search, labels and icons.

```java
Options.ofSelectionList("Affected Entities", () -> entities, List.of("minecraft:player"), value -> entities = value, ListEntries.entities()).build();
```

### Built-in entry sources

| Source                                | Values                                          |
| ------------------------------------- | ----------------------------------------------- |
| `ListEntries.items()`                 | Every item, with its icon                       |
| `ListEntries.blocks()`                | Every block, with its icon                      |
| `ListEntries.entities()`              | Every entity type                               |
| `ListEntries.particles()`             | Every particle type, with its sprite            |
| `ListEntries.sounds()`                | Every sound event                               |
| `ListEntries.onlinePlayers()`         | Players currently online (custom names allowed) |
| `ListEntries.of(values)`              | Your own fixed list                             |
| `ListEntries.of(values, label, icon)` | Your own list with display labels and icons     |

Values are stored as registry IDs, such as `minecraft:player`.

## Entry name rules

`EntryNameRule` cleans what the user types before it's added:

```java
.nameRule(EntryNameRule.spacesTo('_').maxLength(16))
.nameRule(EntryNameRule.allow("a-z0-9_"))
```

Rules can be chained with `.and(...)`.

## Page

A selector that switches between fixed sets of options. The value is the selected page ID.

```java
Options.ofPage("Style", () -> style, "Simple", value -> style = value)
    .page("Simple", simpleOptions...)
    .page("Advanced", advancedOptions...)
    .build();
```

## Page list

A list of **user-created pages**, each with its own options. Use it for kits, profiles, per-entity settings and similar. The value is the list of page names. The `options` factory builds the options for each page from its name.

```java
//epic clientkits code
Options.ofPageList("Kits", () -> kitNames, List.of(), value -> kitNames = new ArrayList<>(value))
    .newEntryName("Kit")
    .noSpaces()
    .options(name -> List.of(
        Options.ofInventory("Items", () -> kit(name), new ItemInventory(), value -> KITS.put(name, value)).build(),
        Options.ofButton("Copy Kit", () -> copyKit(name)).build()))
    .onRenamed((from, to) -> KITS.put(to, KITS.remove(from)))
    .onRemoved(KITS::remove)
    .build();
```

| Method                               | What it does                                       |
| ------------------------------------ | -------------------------------------------------- |
| `.options(name -> List<Option<?>>)`  | The options shown on each page.                    |
| `.groups(name -> List<OptionGroup>)` | Same, but grouped.                                 |
| `.newEntryName("Kit")`               | Name stem for new pages ("Kit", "Kit 2", …).       |
| `.onRenamed((from, to) -> …)`        | Move your data when a page is renamed.             |
| `.onRemoved(name -> …)`              | Clean up your data when a page is deleted.         |
| `.namesOnly()`                       | Pages have no options, only a list of names.       |
| `.readOnlyNames()`                   | Users can't rename pages.                          |
| `.entries(ListEntries)`              | New pages are picked from a list instead of typed. |

{% hint style="info" %}
Your data is keyed by page name, so always handle `onRenamed` and `onRemoved`. Otherwise renamed pages lose their settings and deleted pages leave stale data behind.
{% endhint %}
