last penguin ui port
This commit is contained in:
@@ -109,12 +109,8 @@
|
||||
<!-- Penguin animated hamburger (bars ↔ X) in our ghost-square shell -->
|
||||
<button type="button" @click="showSidebar = !showSidebar" :aria-expanded="showSidebar" aria-label="{{ t(key='menu', lang=lang | default(value='sk')) }}"
|
||||
class="inline-flex size-9 shrink-0 items-center justify-center rounded-radius bg-transparent text-secondary transition hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-secondary active:opacity-100 active:outline-offset-0 md:hidden dark:text-secondary-dark dark:focus-visible:outline-secondary-dark">
|
||||
<svg x-show="!showSidebar" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
|
||||
</svg>
|
||||
<svg x-cloak x-show="showSidebar" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
|
||||
</svg>
|
||||
{{ ui::icon(name="hamburger", size="size-6", attrs='x-show="!showSidebar"') }}
|
||||
{{ ui::icon(name="close", size="size-6", attrs='x-cloak x-show="showSidebar"') }}
|
||||
</button>
|
||||
|
||||
<span class="text-sm font-semibold text-on-surface-strong dark:text-on-surface-dark-strong">
|
||||
|
||||
@@ -67,7 +67,8 @@
|
||||
class="sticky top-0 z-30 border-b border-outline bg-surface/95 backdrop-blur dark:border-outline-dark dark:bg-surface-dark/95">
|
||||
<nav x-data="{ mobile: false }" class="mx-auto flex max-w-7xl items-center gap-4 px-4 py-3">
|
||||
<!-- category sidebar toggle (mobile only) -->
|
||||
{{ ui::icon_button(aria_label=t(key='categories', lang=lang | default(value='sk')), attrs='@click="cats = !cats" :aria-expanded="cats"', extra="lg:hidden", icon='<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" /></svg>') }}
|
||||
{% set hamburger_icon = ui::icon(name="hamburger", size="size-6") %}
|
||||
{{ ui::icon_button(aria_label=t(key='categories', lang=lang | default(value='sk')), attrs='@click="cats = !cats" :aria-expanded="cats"', extra="lg:hidden", icon=hamburger_icon) }}
|
||||
<a href="/"
|
||||
class="text-lg font-bold tracking-tight text-on-surface-strong dark:text-on-surface-dark-strong">
|
||||
{{ t(key="brand", lang=lang | default(value='sk')) }}
|
||||
@@ -98,9 +99,7 @@
|
||||
aria-label="{{ t(key='cart-title', lang=lang | default(value='sk')) }}"
|
||||
title="{{ t(key='cart-title', lang=lang | default(value='sk')) }}"
|
||||
class="relative inline-flex size-9 shrink-0 items-center justify-center rounded-radius bg-transparent text-secondary transition hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-secondary active:opacity-100 active:outline-offset-0 dark:text-secondary-dark dark:focus-visible:outline-secondary-dark">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 3h1.386c.51 0 .955.343 1.087.835l.383 1.437M7.5 14.25a3 3 0 0 0-3 3h15.75m-12.75-3h11.218c1.121-2.3 2.1-4.684 2.924-7.138a60.114 60.114 0 0 0-16.536-1.84M7.5 14.25 5.106 5.272M6 20.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Zm12.75 0a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z" />
|
||||
</svg>
|
||||
{{ ui::icon(name="cart") }}
|
||||
<span x-show="count > 0" x-cloak x-text="count"
|
||||
class="absolute -right-1 -top-1 inline-flex min-w-4 items-center justify-center rounded-full bg-primary px-1 text-[10px] font-semibold leading-4 text-on-primary dark:bg-primary-dark dark:text-on-primary-dark"></span>
|
||||
</a>
|
||||
@@ -113,12 +112,8 @@
|
||||
our ghost-square icon-button shell for consistency with cart/gear -->
|
||||
<button type="button" @click="mobile = !mobile" :aria-expanded="mobile" aria-label="{{ t(key='menu', lang=lang | default(value='sk')) }}"
|
||||
class="inline-flex size-9 shrink-0 items-center justify-center rounded-radius bg-transparent text-secondary transition hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-secondary active:opacity-100 active:outline-offset-0 md:hidden dark:text-secondary-dark dark:focus-visible:outline-secondary-dark">
|
||||
<svg x-show="!mobile" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
|
||||
</svg>
|
||||
<svg x-cloak x-show="mobile" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
|
||||
</svg>
|
||||
{{ ui::icon(name="hamburger", size="size-6", attrs='x-show="!mobile"') }}
|
||||
{{ ui::icon(name="close", size="size-6", attrs='x-cloak x-show="mobile"') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -60,6 +60,25 @@
|
||||
{% if href %}<a href="{{ href }}"{% else %}<button type="{{ type }}"{% endif %}{% if aria_label %} aria-label="{{ aria_label }}" title="{{ aria_label }}"{% endif %} class="inline-flex shrink-0 items-center justify-center rounded-radius bg-transparent {{ size }} transition hover:opacity-75 focus-visible:outline-2 focus-visible:outline-offset-2 active:opacity-100 active:outline-offset-0 disabled:cursor-not-allowed disabled:opacity-75 {{ cls }} {{ extra }}" {{ attrs | safe }}>{{ icon | safe }}{% if sr %}<span class="sr-only">{{ sr }}</span>{% endif %}</{% if href %}a{% else %}button{% endif %}>
|
||||
{%- endmacro icon_button %}
|
||||
|
||||
{# Inline icon set — the Heroicons-style SVGs that were duplicated across
|
||||
base.html / admin/base.html (hamburger, close, cart). Penguin ships no icon
|
||||
library, so this is pure dedup, not a port. `size` sets the box (default
|
||||
size-5), `extra` adds classes, `attrs` is raw (x-show / x-cloak etc.). Icons
|
||||
are decorative: aria-hidden is baked in — put the accessible name on the
|
||||
enclosing button/link. The chevron dropdown arrows (checkout, _sidebar) stay
|
||||
inline at their call sites because they carry nested-quote Alpine :class
|
||||
bindings (see the attrs note at the top of this file). name ∈
|
||||
hamburger (default) | close | cart. #}
|
||||
{% macro icon(name, size="size-5", extra="", attrs="") -%}
|
||||
{%- if name == "cart" -%}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="{{ size }}{% if extra %} {{ extra }}{% endif %}" aria-hidden="true" {{ attrs | safe }}><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 3h1.386c.51 0 .955.343 1.087.835l.383 1.437M7.5 14.25a3 3 0 0 0-3 3h15.75m-12.75-3h11.218c1.121-2.3 2.1-4.684 2.924-7.138a60.114 60.114 0 0 0-16.536-1.84M7.5 14.25 5.106 5.272M6 20.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Zm12.75 0a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z" /></svg>
|
||||
{%- elif name == "close" -%}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="{{ size }}{% if extra %} {{ extra }}{% endif %}" aria-hidden="true" {{ attrs | safe }}><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /></svg>
|
||||
{%- else -%}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="{{ size }}{% if extra %} {{ extra }}{% endif %}" aria-hidden="true" {{ attrs | safe }}><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" /></svg>
|
||||
{%- endif -%}
|
||||
{%- endmacro icon %}
|
||||
|
||||
{# Compact danger alert (form/inline errors). Adapted from
|
||||
penguinui/alert/default-alert.html (danger variant), trimmed to a single line
|
||||
with the danger icon. #}
|
||||
|
||||
@@ -378,26 +378,27 @@ from the build. If the build ever balloons, check that exclusion is intact.
|
||||
|
||||
---
|
||||
|
||||
## 19. Inline SVG Icons — LOW PRIORITY
|
||||
## 19. Inline SVG Icons — MOSTLY DONE
|
||||
**Penguin UI: none (Penguin uses Heroicons-equivalent inline SVGs)**
|
||||
|
||||
> **Priority: LOW** | ~50 lines,8 distinct icons.
|
||||
> Penguin doesn't provide an icon library. Icons are already inlined where used.
|
||||
> Possible follow-up: extract into a `ui::icon(name)` macro for dedup, but
|
||||
> this is purely cosmetic — no functional gain.
|
||||
> **Priority: LOW.** Penguin ships no icon library, so this is dedup, not a port.
|
||||
> The repeated hamburger / close / cart SVGs are now centralized in the
|
||||
> `ui::icon(name, size, extra, attrs)` macro (`macros/ui.html`); call sites use
|
||||
> `{{ ui::icon(name="cart") }}` etc. The chevron dropdown arrows stay inline by
|
||||
> design — they carry nested-quote Alpine `:class` / `x-bind:class` bindings,
|
||||
> which Tera macro args can't pass cleanly (see the attrs note atop `ui.html`).
|
||||
|
||||
| # | Location | Icon | Occurrences |
|
||||
|---|----------|------|-------------|
|
||||
| 55 | `base.html:70-72,168-170` | Hamburger (3-line menu) | 2 |
|
||||
| 56 | `base.html:104-105` | Shopping cart | 1 |
|
||||
| 57 | `base.html:116-121` | Gear/cog (settings) | 1 |
|
||||
| # | Location | Icon | Status |
|
||||
|---|----------|------|--------|
|
||||
| 55 | `base.html` (categories + mobile toggle), `admin/base.html` (sidebar toggle) | Hamburger (3-line menu) | ✅ `ui::icon(name="hamburger")` |
|
||||
| 56 | `base.html` (mobile toggle), `admin/base.html` (sidebar toggle) | Close (X) | ✅ `ui::icon(name="close")` |
|
||||
| 57 | `base.html` (cart link) | Shopping cart | ✅ `ui::icon(name="cart")` |
|
||||
| 58 | ~~`base.html:220-221`~~ | Checkmark (toast success) | ✅ removed — now in vendored toast component |
|
||||
| 59 | `checkout.html:62-64,115-117` | Chevron-down (dropdown arrow) | 2 |
|
||||
| 60 | `_sidebar.html:30-33` | Chevron-right (accordion expand) | 1 |
|
||||
| 61 | `admin/base.html:106-108` | Hamburger (admin sidebar toggle) | 1 |
|
||||
| 62 | `admin/base.html:121-125` | Gear/cog (admin settings) | 1 |
|
||||
| 59 | `checkout.html:61,110` | Chevron-down (dropdown arrow) | inline — nested-quote `:class` binding |
|
||||
| 60 | `_sidebar.html:35` | Chevron-down (accordion expand, rotates) | inline — nested-quote `x-bind:class` binding |
|
||||
| 61 | `settings_dropdown.html` | Gear/cog (settings) | inline in `ui::icon_button` call (shared partial; single use) |
|
||||
|
||||
All are raw inline `<svg>` with hardcoded `<path d="...">` — no icon library, no partials.
|
||||
Remaining inline `<svg>` are the rotating chevrons (kept inline on purpose, above).
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user