mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-08-02 20:15:22 +02:00
Component namespacing (#2463)
* [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:
parent
d5b147f2cd
commit
ab6fdbbb68
182 changed files with 322 additions and 321 deletions
|
@ -1,4 +1,4 @@
|
|||
class AlertComponent < ViewComponent::Base
|
||||
class DS::Alert < DesignSystemComponent
|
||||
def initialize(message:, variant: :info)
|
||||
@message = message
|
||||
@variant = variant
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# An extension to `button_to` helper. All options are passed through to the `button_to` helper with some additional
|
||||
# options available.
|
||||
class ButtonComponent < ButtonishComponent
|
||||
class DS::Button < DS::Buttonish
|
||||
attr_reader :confirm
|
||||
|
||||
def initialize(confirm: nil, **opts)
|
|
@ -1,4 +1,4 @@
|
|||
class ButtonishComponent < ViewComponent::Base
|
||||
class DS::Buttonish < DesignSystemComponent
|
||||
VARIANTS = {
|
||||
primary: {
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
def container_classes(override_classes = nil)
|
|
@ -1,7 +1,7 @@
|
|||
<%= 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.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">
|
||||
<% if header? %>
|
||||
<%= header %>
|
|
@ -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
|
||||
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 = 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)
|
||||
end
|
||||
|
||||
|
@ -19,16 +19,16 @@ class DialogComponent < ViewComponent::Base
|
|||
|
||||
renders_many :actions, ->(cancel_action: false, **button_opts) do
|
||||
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
|
||||
button_opts
|
||||
end
|
||||
|
||||
render ButtonComponent.new(**merged_opts)
|
||||
render DS::Button.new(**merged_opts)
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
|
@ -99,11 +99,11 @@ class DialogComponent < ViewComponent::Base
|
|||
merged_opts = opts.dup
|
||||
data = merged_opts.delete(:data) || {}
|
||||
|
||||
data[:controller] = [ "dialog", "hotkey", data[:controller] ].compact.join(" ")
|
||||
data[:dialog_auto_open_value] = auto_open
|
||||
data[:dialog_reload_on_close_value] = reload_on_close
|
||||
data[:action] = [ "mousedown->dialog#clickOutside", data[:action] ].compact.join(" ")
|
||||
data[:hotkey] = "esc:dialog#close"
|
||||
data[:controller] = [ "DS--dialog", "hotkey", data[:controller] ].compact.join(" ")
|
||||
data[:DS__dialog_auto_open_value] = auto_open
|
||||
data[:DS__dialog_reload_on_close_value] = reload_on_close
|
||||
data[:action] = [ "mousedown->DS--dialog#clickOutside", data[:action] ].compact.join(" ")
|
||||
data[:hotkey] = "esc:DS--dialog#close"
|
||||
merged_opts[:data] = data
|
||||
|
||||
merged_opts
|
|
@ -1,4 +1,4 @@
|
|||
class DisclosureComponent < ViewComponent::Base
|
||||
class DS::Disclosure < DesignSystemComponent
|
||||
renders_one :summary_content
|
||||
|
||||
attr_reader :title, :align, :open, :opts
|
|
@ -1,4 +1,4 @@
|
|||
class FilledIconComponent < ViewComponent::Base
|
||||
class DS::FilledIcon < DesignSystemComponent
|
||||
attr_reader :icon, :text, :hex_color, :size, :rounded, :variant
|
||||
|
||||
VARIANTS = %i[default text surface container inverse].freeze
|
|
@ -1,6 +1,6 @@
|
|||
# An extension to `link_to` helper. All options are passed through to the `link_to` helper with some additional
|
||||
# options available.
|
||||
class LinkComponent < ButtonishComponent
|
||||
class DS::Link < DS::Buttonish
|
||||
attr_reader :frame
|
||||
|
||||
VARIANTS = VARIANTS.reverse_merge(
|
|
@ -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 %>
|
||||
<%= 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 %>
|
||||
<%= button %>
|
||||
<% elsif variant == :avatar %>
|
||||
<button data-menu-target="button">
|
||||
<button data-DS--menu-target="button">
|
||||
<div class="w-9 h-9 cursor-pointer">
|
||||
<%= render "settings/user_avatar", avatar_url: avatar_url, initials: initials %>
|
||||
</div>
|
||||
</button>
|
||||
<% 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">
|
||||
<%= header %>
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
# 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
|
||||
|
||||
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
|
||||
content_tag(:button, **options_with_target, &block)
|
||||
else
|
||||
ButtonComponent.new(**options_with_target)
|
||||
DS::Button.new(**options_with_target)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -19,7 +19,7 @@ class MenuComponent < ViewComponent::Base
|
|||
|
||||
renders_one :custom_content
|
||||
|
||||
renders_many :items, MenuItemComponent
|
||||
renders_many :items, DS::MenuItem
|
||||
|
||||
VARIANTS = %i[icon button avatar].freeze
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
class MenuItemComponent < ViewComponent::Base
|
||||
class DS::MenuItem < DesignSystemComponent
|
||||
VARIANTS = %i[link button divider].freeze
|
||||
|
||||
attr_reader :variant, :text, :icon, :href, :method, :destructive, :confirm, :frame, :opts
|
|
@ -1,4 +1,4 @@
|
|||
class TabComponent < ViewComponent::Base
|
||||
class DS::Tab < DesignSystemComponent
|
||||
attr_reader :id, :label
|
||||
|
||||
def initialize(id:, label:)
|
18
app/components/DS/tabs.html.erb
Normal file
18
app/components/DS/tabs.html.erb
Normal 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 %>
|
|
@ -1,6 +1,6 @@
|
|||
class TabsComponent < ViewComponent::Base
|
||||
class DS::Tabs < DesignSystemComponent
|
||||
renders_one :nav, ->(classes: nil) do
|
||||
Tabs::NavComponent.new(
|
||||
DS::Tabs::Nav.new(
|
||||
active_tab: active_tab,
|
||||
active_btn_classes: active_btn_classes,
|
||||
inactive_btn_classes: inactive_btn_classes,
|
||||
|
@ -13,7 +13,7 @@ class TabsComponent < ViewComponent::Base
|
|||
content_tag(
|
||||
:div,
|
||||
class: ("hidden" unless tab_id == active_tab),
|
||||
data: { id: tab_id, tabs_target: "panel" },
|
||||
data: { id: tab_id, DS__tabs_target: "panel" },
|
||||
&block
|
||||
)
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
class Tabs::NavComponent < ViewComponent::Base
|
||||
class DS::Tabs::Nav < DesignSystemComponent
|
||||
erb_template <<~ERB
|
||||
<%= tag.nav class: classes do %>
|
||||
<% btns.each do |btn| %>
|
||||
|
@ -12,7 +12,7 @@ class Tabs::NavComponent < ViewComponent::Base
|
|||
:button, label, id: id,
|
||||
type: "button",
|
||||
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
|
||||
)
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
class Tabs::PanelComponent < ViewComponent::Base
|
||||
class DS::Tabs::Panel < DesignSystemComponent
|
||||
attr_reader :tab_id
|
||||
|
||||
def initialize(tab_id:)
|
|
@ -1,4 +1,4 @@
|
|||
class ToggleComponent < ViewComponent::Base
|
||||
class DS::Toggle < DesignSystemComponent
|
||||
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)
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<div class="min-h-[800px]" data-testid="account-details">
|
||||
<% 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.each do |tab| %>
|
||||
<% nav.with_btn(id: tab, label: tab.to_s.humanize, classes: "px-6") %>
|
||||
|
|
2
app/components/design_system_component.rb
Normal file
2
app/components/design_system_component.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
class DesignSystemComponent < ViewComponent::Base
|
||||
end
|
|
@ -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 %>
|
Loading…
Add table
Add a link
Reference in a new issue