1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-21 22:29:38 +02:00

Component namespacing (#2463)
Some checks are pending
Publish Docker image / ci (push) Waiting to run
Publish Docker image / Build docker image (push) Blocked by required conditions

* [claudesquad] update from 'component-namespacing' on 18 Jul 25 07:23 EDT

* [claudesquad] update from 'component-namespacing' on 18 Jul 25 07:30 EDT

* Update stimulus controller references to use namespace

* Fix remaining tests
This commit is contained in:
Zach Gollwitzer 2025-07-18 08:30:00 -04:00 committed by GitHub
parent d5b147f2cd
commit ab6fdbbb68
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
182 changed files with 322 additions and 321 deletions

View file

@ -1,4 +1,4 @@
class AlertComponent < ViewComponent::Base class DS::Alert < DesignSystemComponent
def initialize(message:, variant: :info) def initialize(message:, variant: :info)
@message = message @message = message
@variant = variant @variant = variant

View file

@ -2,7 +2,7 @@
# An extension to `button_to` helper. All options are passed through to the `button_to` helper with some additional # An extension to `button_to` helper. All options are passed through to the `button_to` helper with some additional
# options available. # options available.
class ButtonComponent < ButtonishComponent class DS::Button < DS::Buttonish
attr_reader :confirm attr_reader :confirm
def initialize(confirm: nil, **opts) def initialize(confirm: nil, **opts)

View file

@ -1,4 +1,4 @@
class ButtonishComponent < ViewComponent::Base class DS::Buttonish < DesignSystemComponent
VARIANTS = { VARIANTS = {
primary: { primary: {
container_classes: "text-inverse bg-inverse hover:bg-inverse-hover disabled:bg-gray-500 theme-dark:disabled:bg-gray-400", container_classes: "text-inverse bg-inverse hover:bg-inverse-hover disabled:bg-gray-500 theme-dark:disabled:bg-gray-400",
@ -71,7 +71,7 @@ class ButtonishComponent < ViewComponent::Base
end end
def call def call
raise NotImplementedError, "ButtonishComponent is an abstract class and cannot be instantiated directly." raise NotImplementedError, "Buttonish is an abstract class and cannot be instantiated directly."
end end
def container_classes(override_classes = nil) def container_classes(override_classes = nil)

View file

@ -1,7 +1,7 @@
<%= wrapper_element do %> <%= wrapper_element do %>
<%= tag.dialog class: "w-full h-full bg-transparent theme-dark:backdrop:bg-alpha-black-900 backdrop:bg-overlay #{drawer? ? "lg:p-3" : "lg:p-1"}", **merged_opts do %> <%= tag.dialog class: "w-full h-full bg-transparent theme-dark:backdrop:bg-alpha-black-900 backdrop:bg-overlay #{drawer? ? "lg:p-3" : "lg:p-1"}", **merged_opts do %>
<%= tag.div class: dialog_outer_classes do %> <%= tag.div class: dialog_outer_classes do %>
<%= tag.div class: dialog_inner_classes, data: { dialog_target: "content" } do %> <%= tag.div class: dialog_inner_classes, data: { DS__dialog_target: "content" } do %>
<div class="grow overflow-y-auto py-4 space-y-4 flex flex-col"> <div class="grow overflow-y-auto py-4 space-y-4 flex flex-col">
<% if header? %> <% if header? %>
<%= header %> <%= header %>

View file

@ -1,9 +1,9 @@
class DialogComponent < ViewComponent::Base class DS::Dialog < DesignSystemComponent
renders_one :header, ->(title: nil, subtitle: nil, hide_close_icon: false, **opts, &block) do renders_one :header, ->(title: nil, subtitle: nil, hide_close_icon: false, **opts, &block) do
content_tag(:header, class: "px-4 flex flex-col gap-2", **opts) do content_tag(:header, class: "px-4 flex flex-col gap-2", **opts) do
title_div = content_tag(:div, class: "flex items-center justify-between gap-2") do title_div = content_tag(:div, class: "flex items-center justify-between gap-2") do
title = content_tag(:h2, title, class: class_names("font-medium text-primary", drawer? ? "text-lg" : "")) if title title = content_tag(:h2, title, class: class_names("font-medium text-primary", drawer? ? "text-lg" : "")) if title
close_icon = render ButtonComponent.new(variant: "icon", class: "ml-auto", icon: "x", tabindex: "-1", data: { action: "dialog#close" }) unless hide_close_icon close_icon = render DS::Button.new(variant: "icon", class: "ml-auto", icon: "x", tabindex: "-1", data: { action: "DS--dialog#close" }) unless hide_close_icon
safe_join([ title, close_icon ].compact) safe_join([ title, close_icon ].compact)
end end
@ -19,16 +19,16 @@ class DialogComponent < ViewComponent::Base
renders_many :actions, ->(cancel_action: false, **button_opts) do renders_many :actions, ->(cancel_action: false, **button_opts) do
merged_opts = if cancel_action merged_opts = if cancel_action
button_opts.merge(type: "button", data: { action: "modal#close" }) button_opts.merge(type: "button", data: { action: "DS--dialog#close" })
else else
button_opts button_opts
end end
render ButtonComponent.new(**merged_opts) render DS::Button.new(**merged_opts)
end end
renders_many :sections, ->(title:, **disclosure_opts, &block) do renders_many :sections, ->(title:, **disclosure_opts, &block) do
render DisclosureComponent.new(title: title, align: :right, **disclosure_opts) do render DS::Disclosure.new(title: title, align: :right, **disclosure_opts) do
block.call block.call
end end
end end
@ -99,11 +99,11 @@ class DialogComponent < ViewComponent::Base
merged_opts = opts.dup merged_opts = opts.dup
data = merged_opts.delete(:data) || {} data = merged_opts.delete(:data) || {}
data[:controller] = [ "dialog", "hotkey", data[:controller] ].compact.join(" ") data[:controller] = [ "DS--dialog", "hotkey", data[:controller] ].compact.join(" ")
data[:dialog_auto_open_value] = auto_open data[:DS__dialog_auto_open_value] = auto_open
data[:dialog_reload_on_close_value] = reload_on_close data[:DS__dialog_reload_on_close_value] = reload_on_close
data[:action] = [ "mousedown->dialog#clickOutside", data[:action] ].compact.join(" ") data[:action] = [ "mousedown->DS--dialog#clickOutside", data[:action] ].compact.join(" ")
data[:hotkey] = "esc:dialog#close" data[:hotkey] = "esc:DS--dialog#close"
merged_opts[:data] = data merged_opts[:data] = data
merged_opts merged_opts

View file

@ -1,4 +1,4 @@
class DisclosureComponent < ViewComponent::Base class DS::Disclosure < DesignSystemComponent
renders_one :summary_content renders_one :summary_content
attr_reader :title, :align, :open, :opts attr_reader :title, :align, :open, :opts

View file

@ -1,4 +1,4 @@
class FilledIconComponent < ViewComponent::Base class DS::FilledIcon < DesignSystemComponent
attr_reader :icon, :text, :hex_color, :size, :rounded, :variant attr_reader :icon, :text, :hex_color, :size, :rounded, :variant
VARIANTS = %i[default text surface container inverse].freeze VARIANTS = %i[default text surface container inverse].freeze

View file

@ -1,6 +1,6 @@
# An extension to `link_to` helper. All options are passed through to the `link_to` helper with some additional # An extension to `link_to` helper. All options are passed through to the `link_to` helper with some additional
# options available. # options available.
class LinkComponent < ButtonishComponent class DS::Link < DS::Buttonish
attr_reader :frame attr_reader :frame
VARIANTS = VARIANTS.reverse_merge( VARIANTS = VARIANTS.reverse_merge(

View file

@ -1,17 +1,17 @@
<%= tag.div data: { controller: "menu", menu_placement_value: placement, menu_offset_value: offset, testid: testid } do %> <%= tag.div data: { controller: "DS--menu", DS__menu_placement_value: placement, DS__menu_offset_value: offset, testid: testid } do %>
<% if variant == :icon %> <% if variant == :icon %>
<%= render ButtonComponent.new(variant: "icon", icon: icon_vertical ? "more-vertical" : "more-horizontal", data: { menu_target: "button" }) %> <%= render DS::Button.new(variant: "icon", icon: icon_vertical ? "more-vertical" : "more-horizontal", data: { DS__menu_target: "button" }) %>
<% elsif variant == :button %> <% elsif variant == :button %>
<%= button %> <%= button %>
<% elsif variant == :avatar %> <% elsif variant == :avatar %>
<button data-menu-target="button"> <button data-DS--menu-target="button">
<div class="w-9 h-9 cursor-pointer"> <div class="w-9 h-9 cursor-pointer">
<%= render "settings/user_avatar", avatar_url: avatar_url, initials: initials %> <%= render "settings/user_avatar", avatar_url: avatar_url, initials: initials %>
</div> </div>
</button> </button>
<% end %> <% end %>
<div data-menu-target="content" class="px-2 lg:px-0 max-w-full hidden z-50"> <div data-DS--menu-target="content" class="px-2 lg:px-0 max-w-full hidden z-50">
<div class="mx-auto min-w-[200px] shadow-border-xs bg-container rounded-lg"> <div class="mx-auto min-w-[200px] shadow-border-xs bg-container rounded-lg">
<%= header %> <%= header %>

View file

@ -1,15 +1,15 @@
# frozen_string_literal: true # frozen_string_literal: true
class MenuComponent < ViewComponent::Base class DS::Menu < DesignSystemComponent
attr_reader :variant, :avatar_url, :initials, :placement, :offset, :icon_vertical, :no_padding, :testid attr_reader :variant, :avatar_url, :initials, :placement, :offset, :icon_vertical, :no_padding, :testid
renders_one :button, ->(**button_options, &block) do renders_one :button, ->(**button_options, &block) do
options_with_target = button_options.merge(data: { menu_target: "button" }) options_with_target = button_options.merge(data: { DS__menu_target: "button" })
if block if block
content_tag(:button, **options_with_target, &block) content_tag(:button, **options_with_target, &block)
else else
ButtonComponent.new(**options_with_target) DS::Button.new(**options_with_target)
end end
end end
@ -19,7 +19,7 @@ class MenuComponent < ViewComponent::Base
renders_one :custom_content renders_one :custom_content
renders_many :items, MenuItemComponent renders_many :items, DS::MenuItem
VARIANTS = %i[icon button avatar].freeze VARIANTS = %i[icon button avatar].freeze

View file

@ -1,4 +1,4 @@
class MenuItemComponent < ViewComponent::Base class DS::MenuItem < DesignSystemComponent
VARIANTS = %i[link button divider].freeze VARIANTS = %i[link button divider].freeze
attr_reader :variant, :text, :icon, :href, :method, :destructive, :confirm, :frame, :opts attr_reader :variant, :text, :icon, :href, :method, :destructive, :confirm, :frame, :opts

View file

@ -1,4 +1,4 @@
class TabComponent < ViewComponent::Base class DS::Tab < DesignSystemComponent
attr_reader :id, :label attr_reader :id, :label
def initialize(id:, label:) def initialize(id:, label:)

View file

@ -0,0 +1,18 @@
<%= tag.div data: {
controller: "DS--tabs",
testid: testid,
DS__tabs_session_key_value: session_key,
DS__tabs_url_param_key_value: url_param_key,
DS__tabs_nav_btn_active_class: active_btn_classes,
DS__tabs_nav_btn_inactive_class: inactive_btn_classes
} do %>
<% if unstyled? %>
<%= content %>
<% else %>
<%= nav %>
<% panels.each do |panel| %>
<%= panel %>
<% end %>
<% end %>
<% end %>

View file

@ -1,6 +1,6 @@
class TabsComponent < ViewComponent::Base class DS::Tabs < DesignSystemComponent
renders_one :nav, ->(classes: nil) do renders_one :nav, ->(classes: nil) do
Tabs::NavComponent.new( DS::Tabs::Nav.new(
active_tab: active_tab, active_tab: active_tab,
active_btn_classes: active_btn_classes, active_btn_classes: active_btn_classes,
inactive_btn_classes: inactive_btn_classes, inactive_btn_classes: inactive_btn_classes,
@ -13,7 +13,7 @@ class TabsComponent < ViewComponent::Base
content_tag( content_tag(
:div, :div,
class: ("hidden" unless tab_id == active_tab), class: ("hidden" unless tab_id == active_tab),
data: { id: tab_id, tabs_target: "panel" }, data: { id: tab_id, DS__tabs_target: "panel" },
&block &block
) )
end end

View file

@ -1,4 +1,4 @@
class Tabs::NavComponent < ViewComponent::Base class DS::Tabs::Nav < DesignSystemComponent
erb_template <<~ERB erb_template <<~ERB
<%= tag.nav class: classes do %> <%= tag.nav class: classes do %>
<% btns.each do |btn| %> <% btns.each do |btn| %>
@ -12,7 +12,7 @@ class Tabs::NavComponent < ViewComponent::Base
:button, label, id: id, :button, label, id: id,
type: "button", type: "button",
class: class_names(btn_classes, id == active_tab ? active_btn_classes : inactive_btn_classes, classes), class: class_names(btn_classes, id == active_tab ? active_btn_classes : inactive_btn_classes, classes),
data: { id: id, action: "tabs#show", tabs_target: "navBtn" }, data: { id: id, action: "DS--tabs#show", DS__tabs_target: "navBtn" },
&block &block
) )
end end

View file

@ -1,4 +1,4 @@
class Tabs::PanelComponent < ViewComponent::Base class DS::Tabs::Panel < DesignSystemComponent
attr_reader :tab_id attr_reader :tab_id
def initialize(tab_id:) def initialize(tab_id:)

View file

@ -1,4 +1,4 @@
class ToggleComponent < ViewComponent::Base class DS::Toggle < DesignSystemComponent
attr_reader :id, :name, :checked, :disabled, :checked_value, :unchecked_value, :opts attr_reader :id, :name, :checked, :disabled, :checked_value, :unchecked_value, :opts
def initialize(id:, name: nil, checked: false, disabled: false, checked_value: "1", unchecked_value: "0", **opts) def initialize(id:, name: nil, checked: false, disabled: false, checked_value: "1", unchecked_value: "0", **opts)

View file

@ -8,7 +8,7 @@
<div class="min-h-[800px]" data-testid="account-details"> <div class="min-h-[800px]" data-testid="account-details">
<% if tabs.count > 1 %> <% if tabs.count > 1 %>
<%= render TabsComponent.new(active_tab: active_tab, url_param_key: "tab") do |tabs_container| %> <%= render DS::Tabs.new(active_tab: active_tab, url_param_key: "tab") do |tabs_container| %>
<% tabs_container.with_nav(classes: "max-w-fit") do |nav| %> <% tabs_container.with_nav(classes: "max-w-fit") do |nav| %>
<% tabs.each do |tab| %> <% tabs.each do |tab| %>
<% nav.with_btn(id: tab, label: tab.to_s.humanize, classes: "px-6") %> <% nav.with_btn(id: tab, label: tab.to_s.humanize, classes: "px-6") %>

View file

@ -0,0 +1,2 @@
class DesignSystemComponent < ViewComponent::Base
end

View file

@ -1,18 +0,0 @@
<%= tag.div data: {
controller: "tabs",
testid: testid,
tabs_session_key_value: session_key,
tabs_url_param_key_value: url_param_key,
tabs_nav_btn_active_class: active_btn_classes,
tabs_nav_btn_inactive_class: inactive_btn_classes
} do %>
<% if unstyled? %>
<%= content %>
<% else %>
<%= nav %>
<% panels.each do |panel| %>
<%= panel %>
<% end %>
<% end %>
<% end %>

View file

@ -21,7 +21,7 @@ module ApplicationHelper
if custom if custom
inline_svg_tag("#{key}.svg", class: icon_classes, **opts) inline_svg_tag("#{key}.svg", class: icon_classes, **opts)
elsif as_button elsif as_button
render ButtonComponent.new(variant: "icon", class: extra_classes, icon: key, size: size, type: "button", **opts) render DS::Button.new(variant: "icon", class: extra_classes, icon: key, size: size, type: "button", **opts)
else else
lucide_icon(key, class: icon_classes, **opts) lucide_icon(key, class: icon_classes, **opts)
end end

View file

@ -50,7 +50,7 @@ class StyledFormBuilder < ActionView::Helpers::FormBuilder
checked = object ? object.send(method) : options[:checked] checked = object ? object.send(method) : options[:checked]
@template.render( @template.render(
ToggleComponent.new( DS::Toggle.new(
id: field_id, id: field_id,
name: field_name, name: field_name,
checked: checked, checked: checked,
@ -67,7 +67,7 @@ class StyledFormBuilder < ActionView::Helpers::FormBuilder
value ||= submit_default_value value ||= submit_default_value
@template.render( @template.render(
ButtonComponent.new( DS::Button.new(
text: value, text: value,
data: (options[:data] || {}).merge({ turbo_submits_with: "Submitting..." }), data: (options[:data] || {}).merge({ turbo_submits_with: "Submitting..." }),
full_width: true full_width: true

View file

@ -41,7 +41,7 @@
<% end %> <% end %>
<% if account.draft? %> <% if account.draft? %>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Complete setup", text: "Complete setup",
href: edit_account_path(account, return_to: return_to), href: edit_account_path(account, return_to: return_to),
variant: :outline, variant: :outline,
@ -49,7 +49,7 @@
) %> ) %>
<% elsif account.active? || account.disabled? %> <% elsif account.active? || account.disabled? %>
<%= form_with model: account, url: toggle_active_account_path(account), method: :patch, data: { turbo_frame: "_top", controller: "auto-submit-form" } do |f| %> <%= form_with model: account, url: toggle_active_account_path(account), method: :patch, data: { turbo_frame: "_top", controller: "auto-submit-form" } do |f| %>
<%= render ToggleComponent.new( <%= render DS::Toggle.new(
id: "account_#{account.id}_active", id: "account_#{account.id}_active",
name: "active", name: "active",
checked: account.active?, checked: account.active?,

View file

@ -21,7 +21,7 @@
</details> </details>
<% end %> <% end %>
<%= render TabsComponent.new(active_tab: active_tab, session_key: "account_sidebar_tab", testid: "account-sidebar-tabs") do |tabs| %> <%= render DS::Tabs.new(active_tab: active_tab, session_key: "account_sidebar_tab", testid: "account-sidebar-tabs") do |tabs| %>
<% tabs.with_nav do |nav| %> <% tabs.with_nav do |nav| %>
<% nav.with_btn(id: "asset", label: "Assets") %> <% nav.with_btn(id: "asset", label: "Assets") %>
<% nav.with_btn(id: "liability", label: "Debts") %> <% nav.with_btn(id: "liability", label: "Debts") %>
@ -30,7 +30,7 @@
<% tabs.with_panel(tab_id: "asset") do %> <% tabs.with_panel(tab_id: "asset") do %>
<div class="space-y-2"> <div class="space-y-2">
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "New asset", text: "New asset",
variant: "ghost", variant: "ghost",
href: new_account_path(step: "method_select", classification: "asset"), href: new_account_path(step: "method_select", classification: "asset"),
@ -50,7 +50,7 @@
<% tabs.with_panel(tab_id: "liability") do %> <% tabs.with_panel(tab_id: "liability") do %>
<div class="space-y-2"> <div class="space-y-2">
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "New debt", text: "New debt",
variant: "ghost", variant: "ghost",
href: new_account_path(step: "method_select", classification: "liability"), href: new_account_path(step: "method_select", classification: "liability"),
@ -70,7 +70,7 @@
<% tabs.with_panel(tab_id: "all") do %> <% tabs.with_panel(tab_id: "all") do %>
<div class="space-y-2"> <div class="space-y-2">
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "New account", text: "New account",
variant: "ghost", variant: "ghost",
full_width: true, full_width: true,

View file

@ -2,7 +2,7 @@
<%= link_to new_polymorphic_path(accountable, step: "method_select", return_to: params[:return_to]), <%= link_to new_polymorphic_path(accountable, step: "method_select", return_to: params[:return_to]),
class: "flex items-center gap-4 w-full text-center focus:outline-hidden hover:bg-surface-hover focus:bg-surface-hover fg-primary border border-transparent block px-2 rounded-lg p-2" do %> class: "flex items-center gap-4 w-full text-center focus:outline-hidden hover:bg-surface-hover focus:bg-surface-hover fg-primary border border-transparent block px-2 rounded-lg p-2" do %>
<%= render FilledIconComponent.new( <%= render DS::FilledIcon.new(
icon: accountable.icon, icon: accountable.icon,
hex_color: accountable.color, hex_color: accountable.color,
) %> ) %>

View file

@ -2,7 +2,7 @@
<div id="<%= account_group.dom_id(tab: all_tab ? :all : nil, mobile: mobile) %>"> <div id="<%= account_group.dom_id(tab: all_tab ? :all : nil, mobile: mobile) %>">
<% is_open = open.nil? ? account_group.accounts.any? { |account| page_active?(account_path(account)) } : open %> <% is_open = open.nil? ? account_group.accounts.any? { |account| page_active?(account_path(account)) } : open %>
<%= render DisclosureComponent.new(align: :left, open: is_open) do |disclosure| %> <%= render DS::Disclosure.new(align: :left, open: is_open) do |disclosure| %>
<% disclosure.with_summary_content do %> <% disclosure.with_summary_content do %>
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<%= icon "chevron-right", class: "group-open:transform group-open:rotate-90" %> <%= icon "chevron-right", class: "group-open:transform group-open:rotate-90" %>
@ -51,7 +51,7 @@
</div> </div>
<div class="my-2"> <div class="my-2">
<%= render LinkComponent.new( <%= render DS::Link.new(
href: new_polymorphic_path(account_group.key, step: "method_select"), href: new_polymorphic_path(account_group.key, step: "method_select"),
text: "New #{account_group.name.downcase.singularize}", text: "New #{account_group.name.downcase.singularize}",
icon: "plus", icon: "plus",

View file

@ -3,7 +3,7 @@
<%= tag.p t(".no_accounts"), class: "text-primary mb-1 font-medium" %> <%= tag.p t(".no_accounts"), class: "text-primary mb-1 font-medium" %>
<%= tag.p t(".empty_message"), class: "text-secondary mb-4" %> <%= tag.p t(".empty_message"), class: "text-secondary mb-4" %>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: t(".new_account"), text: t(".new_account"),
href: new_account_path, href: new_account_path,
frame: :modal frame: :modal

View file

@ -1,7 +1,7 @@
<%# locals: (account:, url:) %> <%# locals: (account:, url:) %>
<% if @error_message.present? %> <% if @error_message.present? %>
<%= render AlertComponent.new(message: @error_message, variant: :error) %> <%= render DS::Alert.new(message: @error_message, variant: :error) %>
<% end %> <% end %>
<%= styled_form_with model: account, url: url, scope: :account, data: { turbo: false }, class: "flex flex-col gap-4 justify-between grow text-primary" do |form| %> <%= styled_form_with model: account, url: url, scope: :account, data: { turbo: false }, class: "flex flex-col gap-4 justify-between grow text-primary" do |form| %>

View file

@ -12,5 +12,5 @@
<% elsif account.logo.attached? %> <% elsif account.logo.attached? %>
<%= image_tag account.logo, class: "shrink-0 rounded-full #{size_classes[size]}" %> <%= image_tag account.logo, class: "shrink-0 rounded-full #{size_classes[size]}" %>
<% else %> <% else %>
<%= render FilledIconComponent.new(variant: :text, hex_color: color || account.accountable.color, text: account.name, size: size, rounded: true) %> <%= render DS::FilledIcon.new(variant: :text, hex_color: color || account.accountable.color, text: account.name, size: size, rounded: true) %>
<% end %> <% end %>

View file

@ -2,7 +2,7 @@
<h1 class="text-xl"><%= t(".accounts") %></h1> <h1 class="text-xl"><%= t(".accounts") %></h1>
<div class="flex items-center gap-5"> <div class="flex items-center gap-5">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "New account", text: "New account",
href: new_account_path(return_to: accounts_path), href: new_account_path(return_to: accounts_path),
variant: "primary", variant: "primary",

View file

@ -25,7 +25,7 @@
<%= button_to imports_path(import: { type: "AccountImport" }), <%= button_to imports_path(import: { type: "AccountImport" }),
data: { turbo_frame: :_top }, data: { turbo_frame: :_top },
class: "flex items-center gap-4 w-full text-center focus:outline-hidden hover:bg-surface-hover focus:bg-surface-hover fg-primary border border-transparent block px-2 rounded-lg p-2" do %> class: "flex items-center gap-4 w-full text-center focus:outline-hidden hover:bg-surface-hover focus:bg-surface-hover fg-primary border border-transparent block px-2 rounded-lg p-2" do %>
<%= render FilledIconComponent.new( <%= render DS::FilledIcon.new(
icon: "download", icon: "download",
hex_color: "#F79009", hex_color: "#F79009",
) %> ) %>

View file

@ -1,11 +1,11 @@
<%# locals: (title:, back_path: nil) %> <%# locals: (title:, back_path: nil) %>
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<div class="flex flex-col relative" data-controller="list-keyboard-navigation"> <div class="flex flex-col relative" data-controller="list-keyboard-navigation">
<div class="border-b border-tertiary md:border-alpha-black-25 px-4 pb-4 text-gray-800 flex items-center justify-between gap-2"> <div class="border-b border-tertiary md:border-alpha-black-25 px-4 pb-4 text-gray-800 flex items-center justify-between gap-2">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<% if back_path %> <% if back_path %>
<%= render LinkComponent.new( <%= render DS::Link.new(
variant: "icon", variant: "icon",
icon: "arrow-left", icon: "arrow-left",
href: back_path, href: back_path,

View file

@ -5,7 +5,7 @@
<div class="flex items-center justify-between mb-4" data-testid="activity-menu"> <div class="flex items-center justify-between mb-4" data-testid="activity-menu">
<%= tag.h2 t(".title"), class: "font-medium text-lg" %> <%= tag.h2 t(".title"), class: "font-medium text-lg" %>
<% unless @account.plaid_account_id.present? %> <% unless @account.plaid_account_id.present? %>
<%= render MenuComponent.new(variant: "button") do |menu| %> <%= render DS::Menu.new(variant: "button") do |menu| %>
<% menu.with_button(text: "New", variant: "secondary", icon: "plus") %> <% menu.with_button(text: "New", variant: "secondary", icon: "plus") %>
<% menu.with_item( <% menu.with_item(

View file

@ -10,7 +10,7 @@
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<h2 class="font-medium text-xl truncate <%= "animate-pulse" if account.syncing? %>"><%= title %></h2> <h2 class="font-medium text-xl truncate <%= "animate-pulse" if account.syncing? %>"><%= title %></h2>
<% if account.draft? %> <% if account.draft? %>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Complete setup", text: "Complete setup",
href: edit_account_path(account), href: edit_account_path(account),
variant: :outline, variant: :outline,

View file

@ -1,6 +1,6 @@
<%# locals: (account:) %> <%# locals: (account:) %>
<%= render MenuComponent.new(testid: "account-menu") do |menu| %> <%= render DS::Menu.new(testid: "account-menu") do |menu| %>
<% menu.with_item(variant: "link", text: "Edit", href: edit_account_path(account), icon: "pencil-line", data: { turbo_frame: :modal }) %> <% menu.with_item(variant: "link", text: "Edit", href: edit_account_path(account), icon: "pencil-line", data: { turbo_frame: :modal }) %>
<% unless account.crypto? %> <% unless account.crypto? %>

View file

@ -12,7 +12,7 @@
<% if budget_category.category.lucide_icon %> <% if budget_category.category.lucide_icon %>
<%= icon(budget_category.category.lucide_icon, color: "current") %> <%= icon(budget_category.category.lucide_icon, color: "current") %>
<% else %> <% else %>
<%= render FilledIconComponent.new( <%= render DS::FilledIcon.new(
variant: :text, variant: :text,
hex_color: budget_category.category.color, hex_color: budget_category.category.color,
text: budget_category.category.name, text: budget_category.category.name,

View file

@ -1,5 +1,5 @@
<div id="<%= dom_id(budget, :confirm_button) %>"> <div id="<%= dom_id(budget, :confirm_button) %>">
<%= render ButtonComponent.new( <%= render DS::Button.new(
text: "Confirm", text: "Confirm",
variant: "primary", variant: "primary",
full_width: true, full_width: true,

View file

@ -6,12 +6,12 @@
</p> </p>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= render ButtonComponent.new( <%= render DS::Button.new(
text: "Use defaults (recommended)", text: "Use defaults (recommended)",
href: bootstrap_categories_path, href: bootstrap_categories_path,
) %> ) %>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "New category", text: "New category",
variant: "outline", variant: "outline",
icon: "plus", icon: "plus",

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new(variant: :drawer) do |dialog| %> <%= render DS::Dialog.new(variant: :drawer) do |dialog| %>
<% dialog.with_header do %> <% dialog.with_header do %>
<div> <div>
<p class="text-sm text-secondary">Category</p> <p class="text-sm text-secondary">Category</p>
@ -119,7 +119,7 @@
<% end %> <% end %>
</ul> </ul>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "View all category transactions", text: "View all category transactions",
variant: "outline", variant: "outline",
full_width: true, full_width: true,

View file

@ -12,7 +12,7 @@
<%= format_money(budget.actual_spending_money) %> <%= format_money(budget.actual_spending_money) %>
</div> </div>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "of #{budget.budgeted_spending_money.format}", text: "of #{budget.budgeted_spending_money.format}",
variant: "secondary", variant: "secondary",
icon: "pencil", icon: "pencil",
@ -25,7 +25,7 @@
<span><%= format_money Money.new(0, budget.currency || budget.family.currency) %></span> <span><%= format_money Money.new(0, budget.currency || budget.family.currency) %></span>
</div> </div>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "New budget", text: "New budget",
size: "sm", size: "sm",
icon: "plus", icon: "plus",
@ -46,7 +46,7 @@
<%= format_money(bc.actual_spending_money) %> <%= format_money(bc.actual_spending_money) %>
</p> </p>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "of #{bc.budgeted_spending_money.format(precision: 0)}", text: "of #{bc.budgeted_spending_money.format(precision: 0)}",
variant: "secondary", variant: "secondary",
icon: "pencil", icon: "pencil",

View file

@ -3,7 +3,7 @@
<div class="flex items-center gap-1 mb-4"> <div class="flex items-center gap-1 mb-4">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<% if budget.previous_budget_param %> <% if budget.previous_budget_param %>
<%= render LinkComponent.new( <%= render DS::Link.new(
variant: "icon", variant: "icon",
icon: "chevron-left", icon: "chevron-left",
href: budget_path(budget.previous_budget_param), href: budget_path(budget.previous_budget_param),
@ -15,7 +15,7 @@
<% end %> <% end %>
<% if budget.next_budget_param %> <% if budget.next_budget_param %>
<%= render LinkComponent.new( <%= render DS::Link.new(
variant: "icon", variant: "icon",
icon: "chevron-right", icon: "chevron-right",
href: budget_path(budget.next_budget_param), href: budget_path(budget.next_budget_param),
@ -27,7 +27,7 @@
<% end %> <% end %>
</div> </div>
<%= render MenuComponent.new(variant: "button") do |menu| %> <%= render DS::Menu.new(variant: "button") do |menu| %>
<% menu.with_button class: "flex items-center gap-1 hover:bg-alpha-black-25 cursor-pointer rounded-md p-2" do %> <% menu.with_button class: "flex items-center gap-1 hover:bg-alpha-black-25 cursor-pointer rounded-md p-2" do %>
<span class="text-primary font-medium text-lg lg:text-base"><%= @budget.name %></span> <span class="text-primary font-medium text-lg lg:text-base"><%= @budget.name %></span>
<%= icon("chevron-down") %> <%= icon("chevron-down") %>
@ -39,7 +39,7 @@
<% end %> <% end %>
<div class="ml-auto"> <div class="ml-auto">
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Today", text: "Today",
variant: "outline", variant: "outline",
href: budget_path(Budget.date_to_param(Date.current)), href: budget_path(Budget.date_to_param(Date.current)),

View file

@ -4,7 +4,7 @@
<%= icon "alert-triangle", size: "lg", color: "destructive" %> <%= icon "alert-triangle", size: "lg", color: "destructive" %>
<p class="text-secondary text-sm text-center">You have over-allocated your budget. Please fix your allocations.</p> <p class="text-secondary text-sm text-center">You have over-allocated your budget. Please fix your allocations.</p>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Fix allocations", text: "Fix allocations",
variant: "secondary", variant: "secondary",
size: "sm", size: "sm",

View file

@ -38,7 +38,7 @@
<% param_key = Budget.date_to_param(date) %> <% param_key = Budget.date_to_param(date) %>
<% if Budget.budget_date_valid?(date, family: family) %> <% if Budget.budget_date_valid?(date, family: family) %>
<%= render LinkComponent.new( <%= render DS::Link.new(
variant: "ghost", variant: "ghost",
text: month_name, text: month_name,
href: budget_path(param_key), href: budget_path(param_key),

View file

@ -29,7 +29,7 @@
</p> </p>
</div> </div>
<%= render ToggleComponent.new( <%= render DS::Toggle.new(
id: "auto_fill", id: "auto_fill",
data: { data: {
action: "change->budget-form#toggleAutoFill", action: "change->budget-form#toggleAutoFill",

View file

@ -18,7 +18,7 @@
<div> <div>
<% if @budget.initialized? && @budget.available_to_allocate.positive? %> <% if @budget.initialized? && @budget.available_to_allocate.positive? %>
<%= render TabsComponent.new(active_tab: params[:tab].presence || "budgeted") do |tabs| %> <%= render DS::Tabs.new(active_tab: params[:tab].presence || "budgeted") do |tabs| %>
<% tabs.with_nav do |nav| %> <% tabs.with_nav do |nav| %>
<% nav.with_btn(id: "budgeted", label: "Budgeted") %> <% nav.with_btn(id: "budgeted", label: "Budgeted") %>
<% nav.with_btn(id: "actuals", label: "Actual") %> <% nav.with_btn(id: "actuals", label: "Actual") %>
@ -49,7 +49,7 @@
<h2 class="text-lg font-medium">Categories</h2> <h2 class="text-lg font-medium">Categories</h2>
<% if @budget.initialized? %> <% if @budget.initialized? %>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Edit", text: "Edit",
variant: "secondary", variant: "secondary",
icon: "settings-2", icon: "settings-2",

View file

@ -12,7 +12,7 @@
</div> </div>
<div class="justify-self-end"> <div class="justify-self-end">
<%= render MenuComponent.new do |menu| %> <%= render DS::Menu.new do |menu| %>
<% menu.with_item(variant: "link", text: t(".edit"), icon: "pencil", href: edit_category_path(category), data: { turbo_frame: :modal }) %> <% menu.with_item(variant: "link", text: t(".edit"), icon: "pencil", href: edit_category_path(category), data: { turbo_frame: :modal }) %>
<% if category.transactions.any? %> <% if category.transactions.any? %>

View file

@ -1,6 +1,6 @@
<%# locals: (transaction:) %> <%# locals: (transaction:) %>
<%= render MenuComponent.new(variant: "button") do |menu| %> <%= render DS::Menu.new(variant: "button") do |menu| %>
<% menu.with_button do %> <% menu.with_button do %>
<% render partial: "categories/badge", locals: { category: transaction.category } %> <% render partial: "categories/badge", locals: { category: transaction.category } %>
<% end %> <% end %>

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".edit")) %> <% dialog.with_header(title: t(".edit")) %>
<% dialog.with_body do %> <% dialog.with_body do %>
<%= render "form", category: @category, categories: @categories %> <%= render "form", category: @category, categories: @categories %>

View file

@ -2,7 +2,7 @@
<h1 class="text-primary text-xl font-medium"><%= t(".categories") %></h1> <h1 class="text-primary text-xl font-medium"><%= t(".categories") %></h1>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= render MenuComponent.new do |menu| %> <%= render DS::Menu.new do |menu| %>
<% menu.with_item( <% menu.with_item(
variant: "button", variant: "button",
text: "Delete all", text: "Delete all",
@ -12,7 +12,7 @@
confirm: CustomConfirm.for_resource_deletion("all categories", high_severity: true)) %> confirm: CustomConfirm.for_resource_deletion("all categories", high_severity: true)) %>
<% end %> <% end %>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: t(".new"), text: t(".new"),
variant: "primary", variant: "primary",
icon: "plus", icon: "plus",
@ -38,12 +38,12 @@
<div class="text-center flex flex-col items-center max-w-[500px]"> <div class="text-center flex flex-col items-center max-w-[500px]">
<p class="text-sm text-secondary mb-4"><%= t(".empty") %></p> <p class="text-sm text-secondary mb-4"><%= t(".empty") %></p>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= render ButtonComponent.new( <%= render DS::Button.new(
text: t(".bootstrap"), text: t(".bootstrap"),
href: bootstrap_categories_path, href: bootstrap_categories_path,
) %> ) %>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: t(".new"), text: t(".new"),
variant: "outline", variant: "outline",
icon: "plus", icon: "plus",

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".new_category")) %> <% dialog.with_header(title: t(".new_category")) %>
<% dialog.with_body do %> <% dialog.with_body do %>
<%= render "form", category: @category, categories: @categories %> <%= render "form", category: @category, categories: @categories %>

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".delete_category"), subtitle: t(".explanation", category_name: @category.name)) %> <% dialog.with_header(title: t(".delete_category"), subtitle: t(".explanation", category_name: @category.name)) %>
<% dialog.with_body do %> <% dialog.with_body do %>
@ -14,14 +14,14 @@
{ prompt: t(".replacement_category_prompt"), label: t(".category"), container_class: "mb-4" }, { prompt: t(".replacement_category_prompt"), label: t(".category"), container_class: "mb-4" },
data: { deletion_target: "replacementField", action: "deletion#chooseSubmitButton" } %> data: { deletion_target: "replacementField", action: "deletion#chooseSubmitButton" } %>
<%= render ButtonComponent.new( <%= render DS::Button.new(
variant: "destructive", variant: "destructive",
text: t(".delete_and_leave_uncategorized", category_name: @category.name), text: t(".delete_and_leave_uncategorized", category_name: @category.name),
full_width: true, full_width: true,
data: { deletion_target: "destructiveSubmitButton" } data: { deletion_target: "destructiveSubmitButton" }
) %> ) %>
<%= render ButtonComponent.new( <%= render DS::Button.new(
text: "Delete and reassign", text: "Delete and reassign",
data: { deletion_target: "safeSubmitButton" }, data: { deletion_target: "safeSubmitButton" },
hidden: true, hidden: true,

View file

@ -24,7 +24,7 @@
<%= render partial: "categories/badge", locals: { category: category } %> <%= render partial: "categories/badge", locals: { category: category } %>
<% end %> <% end %>
<%= render MenuComponent.new do |menu| %> <%= render DS::Menu.new do |menu| %>
<% menu.with_item(variant: "link", text: t(".edit"), icon: "pencil-line", href: edit_category_path(category), data: { turbo_frame: :modal }) %> <% menu.with_item(variant: "link", text: t(".edit"), icon: "pencil-line", href: edit_category_path(category), data: { turbo_frame: :modal }) %>
<% menu.with_item(variant: "link", text: t(".delete"), icon: "trash-2", href: new_category_deletion_path(category), data: { turbo_frame: :modal }, destructive: true) %> <% menu.with_item(variant: "link", text: t(".delete"), icon: "trash-2", href: new_category_deletion_path(category), data: { turbo_frame: :modal }, destructive: true) %>
<% end %> <% end %>

View file

@ -29,7 +29,7 @@
<div class="text-center flex flex-col items-center max-w-[500px]"> <div class="text-center flex flex-col items-center max-w-[500px]">
<p class="text-sm text-secondary font-normal mb-4"><%= t(".empty") %></p> <p class="text-sm text-secondary font-normal mb-4"><%= t(".empty") %></p>
<%= render ButtonComponent.new( <%= render DS::Button.new(
text: t(".bootstrap"), text: t(".bootstrap"),
variant: "outline", variant: "outline",
href: bootstrap_categories_path, href: bootstrap_categories_path,

View file

@ -11,7 +11,7 @@
</p> </p>
</div> </div>
<%= render MenuComponent.new(icon_vertical: true) do |menu| %> <%= render DS::Menu.new(icon_vertical: true) do |menu| %>
<% menu.with_item( <% menu.with_item(
variant: "link", variant: "link",
text: "Edit chat title", text: "Edit chat title",

View file

@ -4,7 +4,7 @@
<% path = chat.new_record? ? chats_path : chats_path(previous_chat_id: chat.id) %> <% path = chat.new_record? ? chats_path : chats_path(previous_chat_id: chat.id) %>
<div class="flex items-center gap-2 grow"> <div class="flex items-center gap-2 grow">
<%= render LinkComponent.new( <%= render DS::Link.new(
id: "chat-nav-back", id: "chat-nav-back",
variant: "icon", variant: "icon",
icon: "menu", icon: "menu",
@ -18,7 +18,7 @@
</div> </div>
</div> </div>
<%= render MenuComponent.new(icon_vertical: true) do |menu| %> <%= render DS::Menu.new(icon_vertical: true) do |menu| %>
<% menu.with_item(variant: "link", text: "Start new chat", href: new_chat_path, icon: "plus") %> <% menu.with_item(variant: "link", text: "Start new chat", href: new_chat_path, icon: "plus") %>
<% unless chat.new_record? %> <% unless chat.new_record? %>

View file

@ -10,7 +10,7 @@
<div class="flex items-center justify-between gap-2"> <div class="flex items-center justify-between gap-2">
<p class="text-xs text-red-500">Failed to generate response. Please try again.</p> <p class="text-xs text-red-500">Failed to generate response. Please try again.</p>
<%= render ButtonComponent.new( <%= render DS::Button.new(
text: "Retry", text: "Retry",
href: retry_chat_path(chat), href: retry_chat_path(chat),
) %> ) %>

View file

@ -5,7 +5,7 @@
<div class="grow flex flex-col"> <div class="grow flex flex-col">
<div class="flex items-center justify-between my-6"> <div class="flex items-center justify-between my-6">
<h1 class="text-xl font-medium">Chats</h1> <h1 class="text-xl font-medium">Chats</h1>
<%= render LinkComponent.new( <%= render DS::Link.new(
id: "new-chat", id: "new-chat",
icon: "plus", icon: "plus",
variant: "icon", variant: "icon",

View file

@ -27,7 +27,7 @@
</div> </div>
<div class="flex justify-center py-8"> <div class="flex justify-center py-8">
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Edit account details", text: "Edit account details",
variant: "ghost", variant: "ghost",
href: edit_credit_card_path(account), href: edit_credit_card_path(account),

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".edit", account: @account.name)) %> <% dialog.with_header(title: t(".edit", account: @account.name)) %>
<% dialog.with_body do %> <% dialog.with_body do %>

View file

@ -5,7 +5,7 @@
show_eu_link: @show_eu_link, show_eu_link: @show_eu_link,
accountable_type: "CreditCard" %> accountable_type: "CreditCard" %>
<% else %> <% else %>
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".title")) %> <% dialog.with_header(title: t(".title")) %>
<% dialog.with_body do %> <% dialog.with_body do %>
<%= render "credit_cards/form", account: @account, url: credit_cards_path %> <%= render "credit_cards/form", account: @account, url: credit_cards_path %>

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".edit", account: @account.name)) %> <% dialog.with_header(title: t(".edit", account: @account.name)) %>
<% dialog.with_body do %> <% dialog.with_body do %>
<%= render "form", account: @account, url: crypto_path(@account) %> <%= render "form", account: @account, url: crypto_path(@account) %>

View file

@ -5,7 +5,7 @@
show_eu_link: @show_eu_link, show_eu_link: @show_eu_link,
accountable_type: "Crypto" %> accountable_type: "Crypto" %>
<% else %> <% else %>
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".title")) %> <% dialog.with_header(title: t(".title")) %>
<% dialog.with_body do %> <% dialog.with_body do %>
<%= render "form", account: @account, url: cryptos_path %> <%= render "form", account: @account, url: cryptos_path %>

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".edit", account: @account.name)) %> <% dialog.with_header(title: t(".edit", account: @account.name)) %>
<% dialog.with_body do %> <% dialog.with_body do %>
<%= render "form", account: @account, url: depository_path(@account) %> <%= render "form", account: @account, url: depository_path(@account) %>

View file

@ -5,7 +5,7 @@
show_eu_link: @show_eu_link, show_eu_link: @show_eu_link,
accountable_type: "Depository" %> accountable_type: "Depository" %>
<% else %> <% else %>
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".title")) %> <% dialog.with_header(title: t(".title")) %>
<% dialog.with_body do %> <% dialog.with_body do %>
<%= render "depositories/form", account: @account, url: depositories_path %> <%= render "depositories/form", account: @account, url: depositories_path %>

View file

@ -13,7 +13,7 @@
</div> </div>
<div class="text-center"> <div class="text-center">
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Go back", text: "Go back",
href: "javascript:history.back()", href: "javascript:history.back()",
variant: :secondary variant: :secondary

View file

@ -37,7 +37,7 @@
<% if params[:display].present? %> <% if params[:display].present? %>
<%= hidden_field_tag :display, params[:display], id: nil %> <%= hidden_field_tag :display, params[:display], id: nil %>
<% end %> <% end %>
<%= render ButtonComponent.new( <%= render DS::Button.new(
text: t("doorkeeper.authorizations.buttons.authorize"), text: t("doorkeeper.authorizations.buttons.authorize"),
variant: :primary, variant: :primary,
size: :lg, size: :lg,
@ -59,7 +59,7 @@
<% if params[:display].present? %> <% if params[:display].present? %>
<%= hidden_field_tag :display, params[:display], id: nil %> <%= hidden_field_tag :display, params[:display], id: nil %>
<% end %> <% end %>
<%= render ButtonComponent.new( <%= render DS::Button.new(
text: t("doorkeeper.authorizations.buttons.deny"), text: t("doorkeeper.authorizations.buttons.deny"),
variant: :outline, variant: :outline,
size: :lg, size: :lg,

View file

@ -15,7 +15,7 @@
</p> </p>
</div> </div>
<div class="justify-self-end"> <div class="justify-self-end">
<%= render MenuComponent.new do |menu| %> <%= render DS::Menu.new do |menu| %>
<% menu.with_item(variant: "link", text: "Edit", href: edit_family_merchant_path(family_merchant), icon: "pencil", data: { turbo_frame: "modal" }) %> <% menu.with_item(variant: "link", text: "Edit", href: edit_family_merchant_path(family_merchant), icon: "pencil", data: { turbo_frame: "modal" }) %>
<% menu.with_item( <% menu.with_item(
variant: "button", variant: "button",

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".title")) %> <% dialog.with_header(title: t(".title")) %>
<% dialog.with_body do %> <% dialog.with_body do %>
<%= render "form", family_merchant: @family_merchant %> <%= render "form", family_merchant: @family_merchant %>

View file

@ -1,7 +1,7 @@
<header class="flex items-center justify-between"> <header class="flex items-center justify-between">
<h1 class="text-primary text-xl font-medium">Merchants</h1> <h1 class="text-primary text-xl font-medium">Merchants</h1>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "New merchant", text: "New merchant",
variant: "primary", variant: "primary",
href: new_family_merchant_path, href: new_family_merchant_path,
@ -29,7 +29,7 @@
<div class="text-center flex flex-col items-center max-w-[300px]"> <div class="text-center flex flex-col items-center max-w-[300px]">
<p class="text-primary mb-1 font-medium text-sm"><%= t(".empty") %></p> <p class="text-primary mb-1 font-medium text-sm"><%= t(".empty") %></p>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: t(".new"), text: t(".new"),
icon: "plus", icon: "plus",
href: new_family_merchant_path, href: new_family_merchant_path,

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".title")) %> <% dialog.with_header(title: t(".title")) %>
<% dialog.with_body do %> <% dialog.with_body do %>
<%= render "form", family_merchant: @family_merchant %> <%= render "form", family_merchant: @family_merchant %>

View file

@ -4,7 +4,7 @@
<div class="grid grid-cols-12 items-center text-primary text-sm font-medium p-4"> <div class="grid grid-cols-12 items-center text-primary text-sm font-medium p-4">
<div class="col-span-4 flex items-center gap-4"> <div class="col-span-4 flex items-center gap-4">
<%= render FilledIconComponent.new( <%= render DS::FilledIcon.new(
variant: :text, variant: :text,
text: currency.symbol, text: currency.symbol,
rounded: true, rounded: true,

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new(variant: "drawer") do |dialog| %> <%= render DS::Dialog.new(variant: "drawer") do |dialog| %>
<% dialog.with_header do %> <% dialog.with_header do %>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div> <div>

View file

@ -17,7 +17,7 @@
<p class="text-success text-sm">Your data has been cleaned</p> <p class="text-success text-sm">Your data has been cleaned</p>
</div> </div>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Next step", text: "Next step",
variant: "primary", variant: "primary",
href: import_confirm_path(@import), href: import_confirm_path(@import),

View file

@ -18,8 +18,8 @@
<p class="text-sm text-secondary">We found a configuration from a previous import for this account. Would you like to apply it to this import?</p> <p class="text-sm text-secondary">We found a configuration from a previous import for this account. Would you like to apply it to this import?</p>
<div class="mt-4 flex gap-2 items-center"> <div class="mt-4 flex gap-2 items-center">
<%= render LinkComponent.new(text: "Manually configure", href: import_configuration_path(@import), variant: "outline") %> <%= render DS::Link.new(text: "Manually configure", href: import_configuration_path(@import), variant: "outline") %>
<%= render ButtonComponent.new(text: "Apply template", href: apply_template_import_path(@import), method: :put, data: { turbo_frame: :_top }) %> <%= render DS::Button.new(text: "Apply template", href: apply_template_import_path(@import), method: :put, data: { turbo_frame: :_top }) %>
</div> </div>
</div> </div>
</div> </div>

View file

@ -11,7 +11,7 @@
<div class="flex items-center justify-between p-4 gap-4 text-secondary bg-red-100 border border-red-200 rounded-lg w-[650px] min-w-0 mx-auto"> <div class="flex items-center justify-between p-4 gap-4 text-secondary bg-red-100 border border-red-200 rounded-lg w-[650px] min-w-0 mx-auto">
<%= tag.p t(".no_accounts"), class: "text-sm" %> <%= tag.p t(".no_accounts"), class: "text-sm" %>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Create account", text: "Create account",
variant: "primary", variant: "primary",
href: new_account_path(return_to: import_confirm_path(import)), href: new_account_path(return_to: import_confirm_path(import)),
@ -25,7 +25,7 @@
<div class="overflow-x-auto"> <div class="overflow-x-auto">
<div class="flex items-center justify-between p-4 gap-4 text-secondary bg-yellow-100 border border-yellow-200 rounded-lg w-[650px] min-w-0 mx-auto"> <div class="flex items-center justify-between p-4 gap-4 text-secondary bg-yellow-100 border border-yellow-200 rounded-lg w-[650px] min-w-0 mx-auto">
<%= tag.p t(".unassigned_account"), class: "text-sm" %> <%= tag.p t(".unassigned_account"), class: "text-sm" %>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: t(".create_account"), text: t(".create_account"),
variant: "primary", variant: "primary",
href: new_account_path(return_to: import_confirm_path(import)), href: new_account_path(return_to: import_confirm_path(import)),
@ -59,7 +59,7 @@
</div> </div>
<div class="flex justify-center w-full"> <div class="flex justify-center w-full">
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Next", text: "Next",
variant: "primary", variant: "primary",
href: is_last_step ? import_path(import) : url_for(step: step_idx + 2), href: is_last_step ? import_path(import) : url_for(step: step_idx + 2),

View file

@ -11,7 +11,7 @@
<p class="text-secondary text-sm"><%= t(".description") %></p> <p class="text-secondary text-sm"><%= t(".description") %></p>
</div> </div>
<%= render TabsComponent.new(active_tab: params[:tab] || "csv-upload", url_param_key: "tab", testid: "import-tabs") do |tabs| %> <%= render DS::Tabs.new(active_tab: params[:tab] || "csv-upload", url_param_key: "tab", testid: "import-tabs") do |tabs| %>
<% tabs.with_nav do |nav| %> <% tabs.with_nav do |nav| %>
<% nav.with_btn(id: "csv-upload", label: "Upload CSV") %> <% nav.with_btn(id: "csv-upload", label: "Upload CSV") %>
<% nav.with_btn(id: "csv-paste", label: "Copy & Paste") %> <% nav.with_btn(id: "csv-paste", label: "Copy & Paste") %>

View file

@ -2,7 +2,7 @@
<div class="text-center flex flex-col items-center max-w-[300px] gap-4"> <div class="text-center flex flex-col items-center max-w-[300px] gap-4">
<p class="text-primary mb-1 font-medium text-sm"><%= t(".message") %></p> <p class="text-primary mb-1 font-medium text-sm"><%= t(".message") %></p>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: t(".new"), text: t(".new"),
variant: "primary", variant: "primary",
href: new_import_path, href: new_import_path,

View file

@ -11,6 +11,6 @@
<p class="text-sm text-secondary">Please check that your file format, for any errors and that all required fields are filled, then come back and try again.</p> <p class="text-sm text-secondary">Please check that your file format, for any errors and that all required fields are filled, then come back and try again.</p>
</div> </div>
<%= render ButtonComponent.new(text: "Try again", href: publish_import_path(import), full_width: true) %> <%= render DS::Button.new(text: "Try again", href: publish_import_path(import), full_width: true) %>
</div> </div>
</div> </div>

View file

@ -36,7 +36,7 @@
<% end %> <% end %>
</div> </div>
<%= render MenuComponent.new do |menu| %> <%= render DS::Menu.new do |menu| %>
<% menu.with_item(variant: "link", text: t(".view"), href: import_path(import), icon: "eye") %> <% menu.with_item(variant: "link", text: t(".view"), href: import_path(import), icon: "eye") %>
<% if import.complete? || import.revert_failed? %> <% if import.complete? || import.revert_failed? %>

View file

@ -12,8 +12,8 @@
</div> </div>
<div class="space-y-2 flex flex-col"> <div class="space-y-2 flex flex-col">
<%= render LinkComponent.new(text: "Check status", href: import_path(import), variant: "primary", full_width: true) %> <%= render DS::Link.new(text: "Check status", href: import_path(import), variant: "primary", full_width: true) %>
<%= render LinkComponent.new(text: "Back to dashboard", href: root_path, variant: "secondary", full_width: true) %> <%= render DS::Link.new(text: "Back to dashboard", href: root_path, variant: "secondary", full_width: true) %>
</div> </div>
</div> </div>
</div> </div>

View file

@ -35,5 +35,5 @@
</div> </div>
</div> </div>
<%= render ButtonComponent.new(text: "Publish import", href: publish_import_path(import), full_width: true) %> <%= render DS::Button.new(text: "Publish import", href: publish_import_path(import), full_width: true) %>
</div> </div>

View file

@ -11,7 +11,7 @@
<p class="text-sm text-secondary">Please try again or contact support.</p> <p class="text-sm text-secondary">Please try again or contact support.</p>
</div> </div>
<%= render ButtonComponent.new( <%= render DS::Button.new(
text: "Try again", text: "Try again",
full_width: true, full_width: true,
href: revert_import_path(import) href: revert_import_path(import)

View file

@ -11,7 +11,7 @@
<p class="text-sm text-secondary">Your imported data has been successfully added to the app and is now ready for use.</p> <p class="text-sm text-secondary">Your imported data has been successfully added to the app and is now ready for use.</p>
</div> </div>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Back to dashboard", text: "Back to dashboard",
variant: "primary", variant: "primary",
full_width: true, full_width: true,

View file

@ -1,7 +1,7 @@
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<h1 class="text-xl font-medium text-primary"><%= t(".title") %></h1> <h1 class="text-xl font-medium text-primary"><%= t(".title") %></h1>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "New import", text: "New import",
href: new_import_path, href: new_import_path,
icon: "plus", icon: "plus",

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".title"), subtitle: t(".description")) %> <% dialog.with_header(title: t(".title"), subtitle: t(".description")) %>
<% dialog.with_body do %> <% dialog.with_body do %>

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".edit", account: @account.name)) %> <% dialog.with_header(title: t(".edit", account: @account.name)) %>
<% dialog.with_body do %> <% dialog.with_body do %>
<%= render "investments/form", account: @account, url: investment_path(@account) %> <%= render "investments/form", account: @account, url: investment_path(@account) %>

View file

@ -5,7 +5,7 @@
show_eu_link: @show_eu_link, show_eu_link: @show_eu_link,
accountable_type: "Investment" %> accountable_type: "Investment" %>
<% else %> <% else %>
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".title")) %> <% dialog.with_header(title: t(".title")) %>
<% dialog.with_body do %> <% dialog.with_body do %>
<%= render "investments/form", account: @account, url: investments_path %> <%= render "investments/form", account: @account, url: investments_path %>

View file

@ -1,4 +1,4 @@
<%= render DialogComponent.new do |dialog| %> <%= render DS::Dialog.new do |dialog| %>
<% dialog.with_header(title: t(".title"), subtitle: t(".subtitle")) %> <% dialog.with_header(title: t(".title"), subtitle: t(".subtitle")) %>
<% dialog.with_body do %> <% dialog.with_body do %>

View file

@ -60,7 +60,7 @@
</ul> </ul>
<div class="pl-2 mt-auto mx-auto flex flex-col gap-2"> <div class="pl-2 mt-auto mx-auto flex flex-col gap-2">
<%= render ButtonComponent.new( <%= render DS::Button.new(
variant: "icon", variant: "icon",
icon: "message-circle-question", icon: "message-circle-question",
data: { action: "intercom#show" } data: { action: "intercom#show" }
@ -93,7 +93,7 @@
<p class="text-sm text-secondary"><%= Current.family.days_left_in_trial %> days remaining</p> <p class="text-sm text-secondary"><%= Current.family.days_left_in_trial %> days remaining</p>
</div> </div>
<%= render LinkComponent.new( <%= render DS::Link.new(
text: "Upgrade", text: "Upgrade",
href: upgrade_subscription_path, href: upgrade_subscription_path,
) %> ) %>

View file

@ -1,7 +1,7 @@
<%= render "layouts/shared/htmldoc" do %> <%= render "layouts/shared/htmldoc" do %>
<div class="flex flex-col h-full bg-container"> <div class="flex flex-col h-full bg-container">
<header class="flex items-center justify-between p-8"> <header class="flex items-center justify-between p-8">
<%= render LinkComponent.new( <%= render DS::Link.new(
variant: "icon", variant: "icon",
icon: "arrow-left", icon: "arrow-left",
href: content_for(:previous_path) || imports_path href: content_for(:previous_path) || imports_path
@ -11,7 +11,7 @@
<%= yield :header_nav %> <%= yield :header_nav %>
</nav> </nav>
<%= render LinkComponent.new( <%= render DS::Link.new(
variant: "icon", variant: "icon",
icon: "x", icon: "x",
href: imports_path href: imports_path

Some files were not shown because too many files have changed in this diff Show more