LiveFilter (LiveFilter v0.1.8)

Copy Markdown View Source

Composable filter UI library for Phoenix LiveView.

Provides builder functions for defining filterable fields that produce LiveFilter.FilterConfig structs.

Example

filters = [
  LiveFilter.text(:search, label: "Search", always_on: true, custom_param: "search"),
  LiveFilter.select(:status, label: "Status", options: ~w(pending active shipped)),
  LiveFilter.multi_select(:tags, label: "Tags", options: ~w(urgent bug feature)),
  LiveFilter.date_range(:inserted_at, label: "Created"),
  LiveFilter.boolean(:urgent, label: "Urgent")
]

Summary

Functions

Creates an async select filter config for search-as-you-type selection.

Convenience function component that renders LiveFilter.Bar.

Creates a boolean filter config.

Creates a date filter config.

Creates a date range filter config.

Creates a datetime filter config.

Creates a datetime range filter config.

Parses URL params into filter state using the provided config.

Initializes LiveFilter state on a socket.

Creates a multi-select filter config.

Creates a number filter config.

Parses pagination from URL params using PostgREST limit/offset parameters.

Convenience function component that renders LiveFilter.Paginator.

Creates a radio group filter config.

Creates a single-select filter config.

Creates a text filter config.

Builds a path with raw (non-encoded) query string from a params map.

Functions

async_select(field, opts \\ [])

@spec async_select(
  atom(),
  keyword()
) :: LiveFilter.FilterConfig.t()

Creates an async select filter config for search-as-you-type selection.

Default operators: [:eq], default: :eq.

Requires :search_fn and :load_label_fn callbacks.

Callbacks

  • :search_fn - fn(query, context) -> [{value, label}] — called when user types in the dropdown
  • :load_label_fn - fn(value, context) -> {:ok, label} | :error — called to resolve display label from a stored value (e.g., on URL reload)

Options

  • :min_chars - Minimum characters before searching (default: 1)
  • :debounce - Debounce delay in ms (default: 200)
  • :placeholder - Search input placeholder (default: "Search...")
  • :empty_message - Message when no results found (default: "No results found")

bar(assigns)

Convenience function component that renders LiveFilter.Bar.

Options

  • :mode - Filter display mode: :basic (default) or :command
  • :theme - Theme preset: :default, :minimal, or :bordered
  • :variant - Chip border style: :outline (default), :ghost, :soft, or custom class string

Example

<LiveFilter.bar filter={@livefilter} />
<LiveFilter.bar filter={@livefilter} mode={:command} />
<LiveFilter.bar filter={@livefilter} mode={:command} theme={:bordered} />
<LiveFilter.bar filter={@livefilter} variant={:ghost} />

Attributes

  • filter (:map) (required)
  • mode (:atom) - Defaults to :basic.
  • theme (:atom) - Defaults to :default.
  • variant (:atom) - Chip border style: :outline (default), :ghost, or :soft. Defaults to :outline.

boolean(field, opts \\ [])

@spec boolean(
  atom(),
  keyword()
) :: LiveFilter.FilterConfig.t()

Creates a boolean filter config.

Default operators: [:is], default: :is.

Options

  • :true_label - Label for true state (default: "Yes")
  • :false_label - Label for false state (default: "No")
  • :any_label - Label for null/any state (default: "Any")
  • :nullable - Enable 3-state (true/false/any) mode (default: false)

date(field, opts \\ [])

@spec date(
  atom(),
  keyword()
) :: LiveFilter.FilterConfig.t()

Creates a date filter config.

Default operators: [:eq, :gt, :gte, :lt, :lte], default: :eq.

date_range(field, opts \\ [])

@spec date_range(
  atom(),
  keyword()
) :: LiveFilter.FilterConfig.t()

Creates a date range filter config.

Default operators: [:gte_lte], default: :gte_lte.

Use this for :date schema fields. For :utc_datetime or :utc_datetime_usec fields, use datetime_range/2 instead.

datetime(field, opts \\ [])

@spec datetime(
  atom(),
  keyword()
) :: LiveFilter.FilterConfig.t()

Creates a datetime filter config.

Default operators: [:eq, :gt, :gte, :lt, :lte], default: :eq.

Options

  • :time_format - Time display format: :twelve_hour (default) or :twenty_four_hour
  • :minute_step - Minute increment step: 1 (default), 5, 15, or 30

datetime_range(field, opts \\ [])

@spec datetime_range(
  atom(),
  keyword()
) :: LiveFilter.FilterConfig.t()

Creates a datetime range filter config.

Default operators: [:gte_lte], default: :gte_lte.

Similar to date_range/2 but generates full ISO8601 datetime values with start-of-day (00:00:00Z) and end-of-day (23:59:59Z) times. Use this for :utc_datetime or :utc_datetime_usec schema fields.

from_params(params, config)

@spec from_params(map(), [LiveFilter.FilterConfig.t()]) ::
  {[LiveFilter.Filter.t()], map()}

Parses URL params into filter state using the provided config.

Returns {filters, remaining_params}.

init(socket, config, filters \\ [], opts \\ [])

Initializes LiveFilter state on a socket.

Assigns :livefilter with config, filters, and a unique ID. Accepts an optional context: keyword that is stored and passed to async_select callbacks.

multi_select(field, opts \\ [])

@spec multi_select(
  atom(),
  keyword()
) :: LiveFilter.FilterConfig.t()

Creates a multi-select filter config.

Default operators: [:cs, :ov], default: :cs. Requires :options or :options_fn.

Note: Uses array containment operators for Postgres array columns:

  • :cs - contains (@>) - array contains all selected values
  • :ov - overlaps (&&) - array contains any of the selected values

number(field, opts \\ [])

@spec number(
  atom(),
  keyword()
) :: LiveFilter.FilterConfig.t()

Creates a number filter config.

Default operators: [:eq, :neq, :gt, :gte, :lt, :lte], default: :eq.

pagination_from_params(params, opts \\ [])

@spec pagination_from_params(
  map(),
  keyword()
) :: {LiveFilter.Pagination.t(), map()}

Parses pagination from URL params using PostgREST limit/offset parameters.

Returns {pagination, remaining_params}.

Options

  • :default_limit - Default items per page (default: 25)
  • :max_limit - Maximum allowed limit value (default: 100)
  • :limit_options - Available per-page options for UI dropdown (default: [10, 25, 50, 100])

Example

{pagination, remaining} = LiveFilter.pagination_from_params(params, default_limit: 25)
# pagination.limit => 25
# pagination.offset => 0

# With URL ?limit=50&offset=100
{pagination, remaining} = LiveFilter.pagination_from_params(%{"limit" => "50", "offset" => "100"})
# pagination.limit => 50
# pagination.offset => 100

paginator(assigns)

Convenience function component that renders LiveFilter.Paginator.

Example

<LiveFilter.paginator pagination={@pagination} />
<LiveFilter.paginator pagination={@pagination} class="mt-4" />

Attributes

radio_group(field, opts \\ [])

@spec radio_group(
  atom(),
  keyword()
) :: LiveFilter.FilterConfig.t()

Creates a radio group filter config.

Default operators: [:eq], default: :eq. Requires :options or :options_fn.

Options

  • :style - Display style: :pills (default) or :radios
  • :inline_threshold - Max options to show inline as pills (default: 4)
  • :options - List of options (required)

select(field, opts \\ [])

@spec select(
  atom(),
  keyword()
) :: LiveFilter.FilterConfig.t()

Creates a single-select filter config.

Default operators: [:eq, :neq], default: :eq. Requires :options or :options_fn.

text(field, opts \\ [])

@spec text(
  atom(),
  keyword()
) :: LiveFilter.FilterConfig.t()

Creates a text filter config.

Default operators: [:ilike, :eq, :neq, :like], default: :ilike.

to_path(base_path, params)

@spec to_path(String.t(), map()) :: String.t()

Builds a path with raw (non-encoded) query string from a params map.

Use this instead of ~p"/path?#{params}" to avoid percent-encoding special characters like {, }, and ,.

Example

# In handle_info:
path = LiveFilter.to_path("/tasks", all_params)
{:noreply, push_patch(socket, to: path)}

# Produces: /tasks?tags=ov.{testing,bug}
# Instead of: /tasks?tags=ov.%7Btesting%2Cbug%7D