6.6 KiB
name, description, metadata
| name | description | metadata | ||
|---|---|---|---|---|
| ui-framework | Use this skill when working with LiveViews, UI components using the Phoenix framework, and in general ANY FILE THAT CONTAINS HTML. Use proactively when editing .heex files, LiveView modules, LiveComponents, or any component module under lib/music_library_web/components/. |
|
Project UI Conventions
Before writing or modifying UI code, follow these project-specific rules. They take precedence over the generic reference material below.
Checklist
-
Gettext all user-facing strings. Every string visible to users must be wrapped in
gettext/1orpgettext/2. After adding new strings, runmix gettext.extract --mergeto update.pot/.pofiles. -
Dark mode always paired. Every color class needs its dark variant:
text-zinc-900 dark:text-zinc-100,bg-zinc-50 dark:bg-zinc-800, etc. -
Wishlisted items get dimmed styling:
opacity-60 hover:opacity-100 transition-opacity. -
Icons inside buttons use the
iconclass — not explicit size classes likeh-5 w-5orsize-3.5. Fluxon auto-sizes icons based on the button'ssizeprop. -
Artist names use
joinphrasefrom MusicBrainz — never join artist names with a literal", ". -
Streams for all collections. Use LiveView streams, not list assigns. See the LiveView reference below for stream patterns.
Component organization
- Generic UI →
CoreComponents - Record-specific →
RecordComponents - Scrobble-specific →
ScrobbleComponents - Search-specific →
SearchComponents - Stats-specific →
StatsComponents,ChartComponents - Extract a function component when identical markup appears in 3+ places.
LiveView structure
mount/3sets@current_sectionhandle_params/3loads data and sets@page_title(via pattern-matched privatepage_title/2)handle_info/2receives LiveComponent messages- LiveComponents communicate with parent via
send(self(), {__MODULE__, msg})
Toast notifications
- In LiveViews:
put_toast(socket, :info, "message")(arity 3) - In LiveComponents:
put_toast!(:info, "message")(arity 2) - User-facing error reasons go through
ErrorMessages.friendly_message/1— neverinspect(reason)
Routes
- Three routes per resource with show modals:
:show,:edit(at/show/edit),:add_* - Modals close via
JS.patchback to the base route - Search state in URL query params via
push_patch - Conditional links:
purchased_atdetermines/collection/vs/wishlist/paths
Fluxon components
Read references/fluxon.md when you need to use a specific Fluxon component —
it contains the full attribute/slot API for each component. You can also search with:
mix usage_rules.search_docs "component_name" -p fluxon
Visual verification with Chrome DevTools
Use the Chrome DevTools MCP tools to verify UI changes in the running dev server.
When to screenshot
Take screenshots after visual changes — styling, layout, component additions or removals, responsive adjustments. Skip for logic-only changes (event handlers, assigns that don't affect rendering).
Authentication
The dev server requires login. If you get redirected to /login, fill the password
field and submit before navigating to your target page:
take_snapshotto get element UIDsfillthe password field with the dev password fromconfig/config.exs(login_passwordunder:music_library, MusicLibraryWeb)clickthe Login buttonnavigate_pageto your target route
Dark mode verification
When your change adds or modifies color classes, backgrounds, borders, or custom styling, take two screenshots:
- Default (light mode) — screenshot as-is
- Dark mode — run
evaluate_scriptwithdocument.documentElement.classList.add('dark'), then screenshot
This connects directly to the "Dark mode always paired" checklist rule. Both screenshots must look correct.
When the change is limited to Fluxon component attributes (e.g., variant, size) with
no custom color classes, dark mode is handled by the component library — a single
screenshot suffices.
Before/after comparison
For styling changes, take a screenshot before editing so you can describe what changed. This helps confirm the change had the intended effect and didn't break surrounding elements.
Worktree limitation
The dev server at the configured port serves the main repo, not a git worktree. If
you are working in a worktree, visual verification reflects the main branch state. To
verify worktree changes visually, start a separate server in the worktree with
mise run dev:worktree-setup or apply the change to the main repo first.
Additional References
Searching Documentation
mix usage_rules.search_docs "search term" -p phoenix -p phoenix_ecto -p phoenix_html -p phoenix_live_dashboard -p phoenix_live_reload -p phoenix_live_view -p fluxon
Available Mix Tasks
mix compile.phoenixmix phx- Prints Phoenix help informationmix phx.digest- Digests and compresses static filesmix phx.digest.clean- Removes old versions of static assets.mix phx.gen- Lists all available Phoenix generatorsmix phx.gen.auth- Generates authentication logic for a resourcemix phx.gen.auth.hashing_librarymix phx.gen.auth.injectormix phx.gen.auth.migrationmix phx.gen.cert- Generates a self-signed certificate for HTTPS testingmix phx.gen.channel- Generates a Phoenix channelmix phx.gen.context- Generates a context with functions around an Ecto schemamix phx.gen.embedded- Generates an embedded Ecto schema filemix phx.gen.html- Generates context and controller for an HTML resourcemix phx.gen.json- Generates context and controller for a JSON resourcemix phx.gen.live- Generates LiveView, templates, and context for a resourcemix phx.gen.notifier- Generates a notifier that delivers emails by defaultmix phx.gen.presence- Generates a Presence trackermix phx.gen.release- Generates release files and optional Dockerfile for release-based deploymentsmix phx.gen.schema- Generates an Ecto schema and migration filemix phx.gen.secret- Generates a secretmix phx.gen.socket- Generates a Phoenix socket handlermix phx.routes- Prints all routesmix phx.server- Starts applications and their serversmix compile.phoenix_live_viewmix phoenix_live_view.upgrade