live_table polish: border color, control layout, row clicks, pagination
- Tailwind source(none) wasn't scanning deps, so shadcn tokens (border-border, bg-muted, text-foreground, ...) used by live_table and sutra_ui weren't generated, leaving `border` to fall back to currentcolor — a heavy dark border around every table in light mode. Add @source directives for deps/live_table/lib and deps/sutra_ui/lib. - Drop the hardcoded width:100% on the outer .select wrapper so the per-page selector's Tailwind w-24 wins instead of stretching across the header and overlapping the search box. - Make whole rows clickable: global click delegator in app.ts forwards tr clicks to the first <a href> in the row (the Actions "View" link), skipping inner interactive elements. cursor + hover highlight added. - Replace the default Prev/Next footer with a daisyUI .join/.btn-based pager (MicrowavepropWeb.LiveTableFooter), wired up globally via :live_table defaults so it applies to every live_table at once.
This commit is contained in:
parent
aff27aff7b
commit
a8d4d70abe
5 changed files with 103 additions and 3 deletions
|
|
@ -8,6 +8,8 @@
|
|||
@source "../css";
|
||||
@source "../js";
|
||||
@source "../../lib/microwaveprop_web";
|
||||
@source "../../deps/live_table/lib";
|
||||
@source "../../deps/sutra_ui/lib";
|
||||
|
||||
/* live_table / sutra_ui compat: maps shadcn tokens live_table uses to
|
||||
daisyUI base colors and provides component CSS for the SutraUI
|
||||
|
|
|
|||
|
|
@ -31,11 +31,13 @@
|
|||
--color-ring: var(--color-primary);
|
||||
}
|
||||
|
||||
/* SutraUI Select — used by live_table for the per-page selector. */
|
||||
/* SutraUI Select — used by live_table for the per-page selector.
|
||||
No width: 100% here — Tailwind width utilities (e.g. `w-24`) on the
|
||||
component must win, otherwise the per-page select overflows the header
|
||||
row and overlaps the search box. */
|
||||
*:not(select).select {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.select-trigger {
|
||||
|
|
@ -301,6 +303,26 @@
|
|||
/* live_table outer container should have a visible surface + border. */
|
||||
#live-table table { background: var(--color-base-100); }
|
||||
|
||||
/* Clickable rows: whole-row click delegates to the first <a> in the row
|
||||
(typically the Actions column's "View" link). The cursor + hover tint
|
||||
make it feel interactive; the actual navigation is wired up in app.ts. */
|
||||
#live-table tbody tr[id] {
|
||||
cursor: pointer;
|
||||
transition: background-color 120ms ease;
|
||||
}
|
||||
|
||||
#live-table tbody tr[id]:hover {
|
||||
background: color-mix(in oklch, var(--color-primary) 6%, transparent);
|
||||
}
|
||||
|
||||
#live-table tbody tr#empty-placeholder {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#live-table tbody tr#empty-placeholder:hover {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Filter bar used when filters are configured. */
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,20 @@ const liveSocket = new LiveSocket("/live", Socket, {
|
|||
hooks: {...colocatedHooks, PropagationMap, UtcClock, ContactMap, ContactsMap, ElevationProfile, WeatherMap, LocateMe, CopyLink, RoverMap, BeaconMap, BeaconsListMap, CommaNumber},
|
||||
})
|
||||
|
||||
// live_table rows are dead on their own — wire up whole-row clicks to
|
||||
// trigger the first <a href> inside that row (typically the Actions "View"
|
||||
// link). Clicks on interactive elements are ignored so inner links/buttons
|
||||
// still win.
|
||||
document.addEventListener("click", (e: MouseEvent) => {
|
||||
const target = e.target as HTMLElement | null
|
||||
if (!target) return
|
||||
if (target.closest("a, button, input, select, label, [role='option'], [role='menuitem']")) return
|
||||
const tr = target.closest("#live-table tbody tr[id]") as HTMLTableRowElement | null
|
||||
if (!tr || tr.id === "empty-placeholder") return
|
||||
const link = tr.querySelector("a[href]") as HTMLAnchorElement | null
|
||||
if (link) link.click()
|
||||
})
|
||||
|
||||
// Show progress bar on live navigation and form submits
|
||||
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
|
||||
window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@ config :esbuild,
|
|||
config :live_table,
|
||||
app: :microwaveprop,
|
||||
repo: Microwaveprop.Repo,
|
||||
pubsub: Microwaveprop.PubSub
|
||||
pubsub: Microwaveprop.PubSub,
|
||||
defaults: %{
|
||||
custom_footer: {MicrowavepropWeb.LiveTableFooter, :render}
|
||||
}
|
||||
|
||||
# Configure Elixir's Logger
|
||||
config :logger, :default_formatter,
|
||||
|
|
|
|||
59
lib/microwaveprop_web/live_table_footer.ex
Normal file
59
lib/microwaveprop_web/live_table_footer.ex
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
defmodule MicrowavepropWeb.LiveTableFooter do
|
||||
@moduledoc false
|
||||
use Phoenix.Component
|
||||
|
||||
def render(assigns) do
|
||||
options = assigns.options
|
||||
table_options = assigns.table_options
|
||||
paginate? = get_in(options, ["pagination", "paginate?"])
|
||||
mode = get_in(table_options, [:pagination, :mode])
|
||||
|
||||
assigns =
|
||||
assigns
|
||||
|> assign(:show_pagination?, paginate? && mode != :infinite_scroll)
|
||||
|> assign(:page, parse_page(get_in(options, ["pagination", "page"])))
|
||||
|> assign(:has_next_page?, get_in(options, ["pagination", :has_next_page]) || false)
|
||||
|
||||
~H"""
|
||||
<nav
|
||||
:if={@show_pagination?}
|
||||
class="flex items-center justify-between px-4 py-3 sm:px-6"
|
||||
aria-label="Pagination"
|
||||
>
|
||||
<p class="hidden sm:block text-sm opacity-60">
|
||||
Page <span class="font-medium text-base-content">{@page}</span>
|
||||
</p>
|
||||
|
||||
<div class="join">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm join-item"
|
||||
phx-click="sort"
|
||||
phx-value-page={@page - 1}
|
||||
disabled={@page == 1}
|
||||
aria-label="Previous page"
|
||||
>
|
||||
«
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm join-item btn-active pointer-events-none">
|
||||
{@page}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm join-item"
|
||||
phx-click="sort"
|
||||
phx-value-page={@page + 1}
|
||||
disabled={!@has_next_page?}
|
||||
aria-label="Next page"
|
||||
>
|
||||
»
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
"""
|
||||
end
|
||||
|
||||
defp parse_page(page) when is_integer(page), do: page
|
||||
defp parse_page(page) when is_binary(page), do: String.to_integer(page)
|
||||
defp parse_page(_), do: 1
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue