1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-08-08 23:15:24 +02:00

Pre-launch design sync with Figma spec (#2154)

* Add lookbook + viewcomponent, organize design system file

* Build menu component

* Button updates

* More button fixes

* Replace all menus with new ViewComponent

* Checkpoint: fix tests, all buttons and menus converted

* Split into Link and Button components for clarity

* Button cleanup

* Simplify custom confirmation configuration in views

* Finalize button, link component API

* Add toggle field to custom form builder + Component

* Basic tabs component

* Custom tabs, convert all menu / tab instances in app

* Gem updates

* Centralized icon helper

* Update all icon usage to central helper

* Lint fixes

* Centralize all disclosure instances

* Dialog replacements

* Consolidation of all dialog styles

* Test fixes

* Fix app layout issues, move to component with slots

* Layout simplification

* Flakey test fix

* Fix dashboard mobile issues

* Finalize homepage

* Lint fixes

* Fix shadows and borders in dark mode

* Fix tests

* Remove stale class

* Fix filled icon logic

* Move transparent? to public interface
This commit is contained in:
Zach Gollwitzer 2025-04-30 18:14:22 -04:00 committed by GitHub
parent 1aafed5f8b
commit 90a9546f32
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
291 changed files with 4143 additions and 3104 deletions

View file

@ -8,7 +8,7 @@
<div class="flex gap-2 mb-4">
<div class="grow">
<div class="flex items-center px-3 py-2 gap-2 border border-secondary rounded-lg focus-within:ring-secondary focus-within:border-secondary">
<%= lucide_icon("search", class: "w-5 h-5 text-secondary") %>
<%= icon("search") %>
<%= form.text_field :search,
placeholder: "Search transactions ...",
value: @q[:search],
@ -16,13 +16,20 @@
"data-auto-submit-form-target": "auto" %>
</div>
</div>
<div data-controller="menu" class="relative">
<button id="transaction-filters-button" data-menu-target="button" type="button" class="btn btn--outline flex items-center gap-2">
<%= lucide_icon("list-filter", class: "w-5 h-5 text-secondary") %>
<p class="text-sm font-medium text-primary md:block hidden">Filter</p>
</button>
<%= render "transactions/searches/menu", form: form %>
</div>
<%= render MenuComponent.new(variant: "button", no_padding: true) do |menu| %>
<% menu.with_button(
id: "transaction-filters-button",
type: "button",
text: "Filter",
variant: "outline",
icon: "list-filter",
data: { menu_target: "button" }
) %>
<% menu.with_custom_content do %>
<%= render "transactions/searches/menu", form: form %>
<% end %>
<% end %>
</div>
<% end %>

View file

@ -1,47 +1,46 @@
<%# locals: (form:) %>
<div
id="transaction-filters-menu"
data-menu-target="content"
data-controller="tabs"
data-tabs-active-class="bg-surface text-primary"
data-tabs-default-tab-value="<%= get_default_transaction_search_filter[:key] %>"
class="hidden absolute flex flex-col md:flex-row z-10 h-auto md:h-80 w-full md:w-[540px] top-12 right-0 shadow-border-xs bg-container rounded-lg overflow-hidden">
<div class="flex w-full md:w-44 flex-row md:flex-col items-start p-3 text-sm font-medium text-secondary border-b md:border-b-0 md:border-r border-secondary overflow-x-auto md:overflow-x-visible">
<% transaction_search_filters.each do |filter| %>
<button
class="flex text-secondary hover:bg-container-inset items-center gap-2 px-3 rounded-md py-2 min-w-max md:w-full"
type="button"
data-id="<%= filter[:key] %>"
data-tabs-target="btn"
data-action="tabs#select">
<%= lucide_icon(filter[:icon], class: "w-5 h-5") %>
<span class="text-sm font-medium"><%= t(".#{filter[:key]}") %></span>
</button>
<% end %>
</div>
<div class="flex flex-col grow">
<div class="grow p-3 border-b border-secondary overflow-y-auto max-h-[50vh] md:max-h-none">
<%= render TabsComponent.new(
variant: :unstyled,
active_tab: get_default_transaction_search_filter[:key],
active_btn_classes: "bg-surface text-primary",
inactive_btn_classes: "text-secondary hover:bg-container-inset"
) do |tabs| %>
<div id="transaction-filters-menu" class="flex flex-col md:flex-row h-[50vh] lg:max-h-auto z-10 md:h-80 w-full md:w-[540px] top-12 right-0 overflow-hidden">
<%= tabs.with_nav(classes: "shrink-0 flex w-full md:w-44 flex-row md:flex-col items-start p-3 text-sm font-medium text-secondary border-b md:border-b-0 md:border-r border-secondary overflow-x-auto md:overflow-x-visible") do |nav| %>
<% transaction_search_filters.each do |filter| %>
<div id="<%= filter[:key] %>" data-tabs-target="tab">
<%= render partial: get_transaction_search_filter_partial_path(filter), locals: { form: form } %>
</div>
<%= nav.with_btn(id: filter[:key], label: filter[:label], classes: "w-full px-3 py-2 flex gap-2 items-center rounded-md") do %>
<%= icon(filter[:icon]) %>
<%= tag.span(filter[:label], class: "text-sm font-medium") %>
<% end %>
<% end %>
</div>
<% end %>
<div class="flex justify-between items-center gap-2 bg-container p-3">
<div>
<% if @q.present? %>
<%= link_to t(".clear_filters"), transactions_path(clear_filters: true), class: "btn btn--ghost" %>
<div class="flex flex-col grow overflow-y-auto">
<div class="grow p-3 border-b border-secondary overflow-y-auto">
<% transaction_search_filters.each do |filter| %>
<%= tabs.with_panel(tab_id: filter[:key]) do %>
<%= render partial: get_transaction_search_filter_partial_path(filter), locals: { form: form } %>
<% end %>
<% end %>
</div>
<div>
<%= button_tag type: "reset", data: { action: "menu#close" }, class: "py-2 px-3 bg-container-inset rounded-lg text-sm text-primary font-medium" do %>
<%= t(".cancel") %>
<% end %>
<%= form.submit t(".apply"), name: nil, class: "py-2 px-3 bg-primary hover:bg-primary-dark rounded-lg text-sm text-primary font-medium cursor-pointer" %>
<div class="flex justify-between items-center gap-2 bg-container p-3 shrink-0">
<div>
<% if @q.present? %>
<%= render LinkComponent.new(
text: t(".clear_filters"),
variant: "ghost",
href: transactions_path(clear_filters: true),
) %>
<% end %>
</div>
<div>
<%= render ButtonComponent.new(text: t(".cancel"), type: "button", variant: "ghost", data: { action: "menu#close" }) %>
<%= render ButtonComponent.new(text: t(".apply")) %>
</div>
</div>
</div>
</div>
</div>
<% end %>

View file

@ -2,7 +2,7 @@
<div data-controller="list-filter">
<div class="relative">
<input type="search" autocomplete="off" placeholder="Filter accounts" data-list-filter-target="input" data-action="input->list-filter#filter" class="block w-full border border-secondary rounded-md py-2 pl-10 pr-3 bg-container focus:ring-gray-500 sm:text-sm">
<%= lucide_icon("search", class: "w-5 h-5 text-secondary absolute inset-y-0 left-2 top-1/2 transform -translate-y-1/2") %>
<%= icon("search", class: "absolute inset-y-0 left-2 top-1/2 transform -translate-y-1/2") %>
</div>
<div class="my-2" id="list" data-list-filter-target="list">
<% Current.family.accounts.alphabetically.each do |account| %>

View file

@ -2,7 +2,7 @@
<div data-controller="list-filter">
<div class="relative">
<input type="search" autocomplete="off" placeholder="Filter category" data-list-filter-target="input" data-action="input->list-filter#filter" class="block w-full bg-container border border-secondary rounded-md py-2 pl-10 pr-3 focus:ring-gray-500 sm:text-sm">
<%= lucide_icon("search", class: "w-5 h-5 text-secondary absolute inset-y-0 left-2 top-1/2 transform -translate-y-1/2") %>
<%= icon("search", class: "absolute inset-y-0 left-2 top-1/2 transform -translate-y-1/2") %>
</div>
<div class="my-2" id="list" data-list-filter-target="list">
<% family_categories.each do |category| %>

View file

@ -2,7 +2,7 @@
<div data-controller="list-filter">
<div class="relative">
<input type="search" autocomplete="off" placeholder="Filter merchants" data-list-filter-target="input" data-action="input->list-filter#filter" class="block w-full bg-container border border-secondary rounded-md py-2 pl-10 pr-3 focus:ring-gray-500 sm:text-sm">
<%= lucide_icon("search", class: "w-5 h-5 text-secondary absolute inset-y-0 left-2 top-1/2 transform -translate-y-1/2") %>
<%= icon("search", class: "absolute inset-y-0 left-2 top-1/2 transform -translate-y-1/2") %>
</div>
<div class="my-2" id="list" data-list-filter-target="list">
<% Current.family.assigned_merchants.alphabetically.each do |merchant| %>
@ -16,7 +16,14 @@
merchant.name,
nil %>
<%= form.label :merchants, value: merchant.name, class: "text-sm text-primary flex items-center gap-2" do %>
<%= circle_logo(merchant.name, hex: merchant.color, size: "sm") %>
<%= render FilledIconComponent.new(
variant: :text,
hex_color: merchant.color,
text: merchant.name,
size: "sm",
rounded: true
) %>
<%= merchant.name %>
<% end %>
</div>

View file

@ -2,7 +2,7 @@
<div data-controller="list-filter">
<div class="relative">
<input type="search" autocomplete="off" placeholder="Filter tags" data-list-filter-target="input" data-action="input->list-filter#filter" class="block w-full bg-container border border-secondary rounded-md py-2 pl-10 pr-3 focus:ring-gray-500 sm:text-sm">
<%= lucide_icon("search", class: "w-5 h-5 text-secondary absolute inset-y-0 left-2 top-1/2 transform -translate-y-1/2") %>
<%= icon("search", class: "absolute inset-y-0 left-2 top-1/2 transform -translate-y-1/2") %>
</div>
<div class="my-2" id="list" data-list-filter-target="list">
<% Current.family.tags.alphabetically.each do |tag| %>
@ -16,7 +16,14 @@
tag.name,
nil %>
<%= form.label :tags, value: tag.name, class: "text-sm text-primary flex items-center gap-2" do %>
<%= circle_logo(tag.name, hex: tag.color || Tag::UNCATEGORIZED_COLOR, size: "sm") %>
<%= render FilledIconComponent.new(
variant: :text,
hex_color: tag.color || Tag::UNCATEGORIZED_COLOR,
text: tag.name,
size: "sm",
rounded: true
) %>
<%= tag.name %>
<% end %>
</div>