# `Cinder.UrlSync`
[🔗](https://github.com/sevenseacat/cinder/blob/v0.12.1/lib/cinder/url_sync.ex#L1)

Simple URL synchronization helper for collection components.

This module provides an easy way to enable URL state synchronization
for Cinder collection components with minimal setup.

## Usage

1. Add `use Cinder.UrlSync` to your LiveView
2. Call `Cinder.UrlSync.handle_params/3` in your `handle_params/3` callback
3. Pass `url_state={@url_state}` to your collection component
4. That's it! The helper handles all URL updates automatically.

## Example

    defmodule MyAppWeb.UsersLive do
      use MyAppWeb, :live_view
      use Cinder.UrlSync

      def mount(_params, _session, socket) do
        {:ok, assign(socket, :current_user, get_current_user())}
      end

      def handle_params(params, uri, socket) do
        socket = Cinder.UrlSync.handle_params(params, uri, socket)
        {:noreply, socket}
      end

      def render(assigns) do
        ~H"""
        <Cinder.collection
          resource={MyApp.User}
          actor={@current_user}
          url_state={@url_state}
        >
          <:col :let={user} field="name" filter sort>{user.name}</:col>
          <:col :let={user} field="email" filter>{user.email}</:col>
        </Cinder.collection>
        """
      end
    end

The helper automatically:
- Handles `:table_state_change` messages from collection components
- Updates the URL with new collection state
- Preserves other URL parameters
- Works with any number of collection components on the same page

## Custom URL Parameters

The URL sync helper automatically preserves custom (non-collection) query parameters
while managing collection state. The collection component knows which parameters it manages
(filters, page, sort, page_size, search) and will preserve any other parameters
in the URL.

For example:

    # URL with custom params and collection state
    /users?tab=overview&view=grid&name=john&page=2

    # When "name" filter is cleared, custom params are preserved
    /users?tab=overview&view=grid&page=2

    # When navigating to a different page, custom params remain
    /users?tab=overview&view=grid&page=3

You can use any parameter names for custom state without worrying about conflicts
with collection parameters. The collection automatically tracks which filter fields it manages
and will only remove those when filters are cleared.

# `__using__`
*macro* 

Adds URL sync support to a LiveView.

This macro injects the necessary `handle_info/2` callback to handle
collection state changes and update the URL accordingly.

# `build_url`

Builds a new URL by merging collection state with existing query parameters.

This function is extracted for testing purposes. It builds the URL that
would be pushed by `update_url/3`.

## Parameters

- `encoded_state` - Map of URL parameters from collection state
- `current_uri` - Optional current URI string to use for path resolution
- `socket` - Optional socket for fallback path resolution

## Returns

A string representing the new URL with merged query parameters

# `extract_collection_state`

Extracts collection state from URL parameters using empty columns list.

This function provides a simplified extraction that works without column
metadata. It preserves page and sort information but may not fully decode
filters (which is why we also preserve raw params in handle_params).

## Parameters

- `params` - URL parameters map

## Returns

Map with `:filters`, `:current_page`, and `:sort_by` keys

# `extract_url_state`

Extracts complete URL state from URL parameters for use with collection components.

This function can be used in `handle_params/3` to initialize
URL state for collection components.

## Example

    def handle_params(params, _uri, socket) do
      url_state = Cinder.UrlSync.extract_url_state(params)
      socket = assign(socket, :url_state, url_state)
      {:noreply, socket}
    end

# `get_url_state`

Helper to get the URL state for passing to collection components.

Use this to get the URL state object created by `handle_params/3`.

## Example

    def render(assigns) do
      ~H"""
      <Cinder.collection
        resource={Album}
        actor={@current_user}
        url_state={@url_state}
        theme="minimal"
      >
        <:col :let={album} field="name" filter="text">{album.name}</:col>
        <:col :let={album} field="artist.name" filter="text">{album.artist.name}</:col>
      </Cinder.collection>
      """
    end

The URL state object contains:
- filters: Raw URL parameters for proper filter decoding
- current_page: Current page number
- sort_by: Sort configuration
- uri: Current URI

# `handle_params`

Helper function to handle collection state in LiveView handle_params.

This function extracts URL parameters and creates a URL state object that
can be passed to collection components. It should be called from your LiveView's
`handle_params/3` callback.

## Parameters

- `params` - URL parameters from `handle_params/3`
- `uri` - Current URI from `handle_params/3` (optional but recommended)
- `socket` - The LiveView socket

## Returns

Updated socket with `:url_state` assign containing:
- `filters` - Raw URL parameters for proper filter decoding
- `current_page` - Current page number
- `sort_by` - Sort configuration
- `uri` - Current URI for URL generation

## Example

    def handle_params(params, uri, socket) do
      socket = Cinder.UrlSync.handle_params(params, uri, socket)
      {:noreply, socket}
    end

    def render(assigns) do
      ~H"""
      <Cinder.collection
        resource={MyApp.User}
        actor={@current_user}
        url_state={@url_state}
      >
        <:col :let={user} field="name" filter sort>{user.name}</:col>
      </Cinder.collection>
      """
    end

The `@url_state` assign will be available for use with the collection component.

# `update_url`

Updates the LiveView socket with new URL parameters.

This function preserves the current path and updates only the query parameters
with the new collection state.

## Parameters

- `socket` - The LiveView socket
- `encoded_state` - Map of URL parameters from collection state
- `current_uri` - Optional current URI string to use for path resolution

## Returns

Updated socket with URL changed via `push_patch/2`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
