feat: keep empty cells consistent empty
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
9751525a0c
commit
4ac56958b4
18 changed files with 263 additions and 372 deletions
|
|
@ -300,6 +300,81 @@ defmodule MvWeb.CoreComponents do
|
|||
defp badge_style_class("outline"), do: "badge-outline"
|
||||
defp badge_style_class(_), do: nil
|
||||
|
||||
@doc """
|
||||
Renders a visually empty table cell with screen-reader-only text (WCAG).
|
||||
|
||||
Use when a table cell has no value so that:
|
||||
- The cell appears empty (no dash, no "n/a").
|
||||
- Screen readers still get a meaningful label (e.g. "No cycle", "No group assignment").
|
||||
|
||||
See CODE_GUIDELINES §8 (Empty table cells) and Design Guidelines §8.6.
|
||||
|
||||
## Examples
|
||||
|
||||
<.empty_cell sr_text={gettext("No cycle")} />
|
||||
<.empty_cell sr_text={gettext("No group assignment")} />
|
||||
<.empty_cell sr_text={gettext("Not specified")} />
|
||||
"""
|
||||
attr :sr_text, :string,
|
||||
required: true,
|
||||
doc: "Text read by screen readers when the cell is visually empty"
|
||||
|
||||
def empty_cell(assigns) do
|
||||
~H"""
|
||||
<span class="sr-only">{@sr_text}</span>
|
||||
"""
|
||||
end
|
||||
|
||||
@doc """
|
||||
Renders content when value is present, otherwise an accessible empty cell.
|
||||
|
||||
Use in table cells for optional fields: when `value` is blank, only the
|
||||
screen-reader text is shown (visually empty). Otherwise the inner block is rendered.
|
||||
|
||||
Blank check: `nil`, `false`, `[]`, `""`, whitespace-only string, or `%Ash.NotLoaded{}` count as empty.
|
||||
|
||||
See CODE_GUIDELINES §8 (Empty table cells) and Design Guidelines §8.6.
|
||||
|
||||
## Examples
|
||||
|
||||
<.maybe_value value={member.membership_fee_type} empty_sr_text={gettext("No fee type")}>
|
||||
{member.membership_fee_type.name}
|
||||
</.maybe_value>
|
||||
<.maybe_value value={member.groups} empty_sr_text={gettext("No group assignment")}>
|
||||
<%= for g <- member.groups do %>
|
||||
<.badge variant="primary" style="outline">{g.name}</.badge>
|
||||
<% end %>
|
||||
</.maybe_value>
|
||||
"""
|
||||
attr :value, :any, doc: "Value to check; if blank, empty_cell is rendered"
|
||||
|
||||
attr :empty_sr_text, :string,
|
||||
default: nil,
|
||||
doc: "Screen-reader text when value is blank (default: gettext \"Not specified\")"
|
||||
|
||||
slot :inner_block, required: true
|
||||
|
||||
def maybe_value(assigns) do
|
||||
empty_sr = assigns.empty_sr_text || gettext("Not specified")
|
||||
assigns = assign(assigns, :empty_sr_text, empty_sr)
|
||||
assigns = assign(assigns, :blank?, value_blank?(assigns.value))
|
||||
|
||||
~H"""
|
||||
<%= if @blank? do %>
|
||||
<.empty_cell sr_text={@empty_sr_text} />
|
||||
<% else %>
|
||||
{render_slot(@inner_block)}
|
||||
<% end %>
|
||||
"""
|
||||
end
|
||||
|
||||
defp value_blank?(nil), do: true
|
||||
defp value_blank?(false), do: true
|
||||
defp value_blank?([]), do: true
|
||||
defp value_blank?(%Ash.NotLoaded{}), do: true
|
||||
defp value_blank?(v) when is_binary(v), do: String.trim(v) == ""
|
||||
defp value_blank?(_), do: false
|
||||
|
||||
@doc """
|
||||
Wraps content with a DaisyUI tooltip. Use for icon-only actions, truncated content,
|
||||
or status badges that need explanation (Design Guidelines §8.2).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue