1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-19 13:19:39 +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

@ -0,0 +1,148 @@
class ButtonishComponent < ViewComponent::Base
VARIANTS = {
primary: {
container_classes: "text-inverse bg-inverse hover:bg-inverse-hover disabled:bg-gray-500 theme-dark:disabled:bg-gray-400",
icon_classes: "fg-inverse"
},
secondary: {
container_classes: "text-secondary bg-gray-50 theme-dark:bg-gray-700 hover:bg-gray-100 theme-dark:hover:bg-gray-600 disabled:bg-gray-200 theme-dark:disabled:bg-gray-600",
icon_classes: "fg-primary"
},
destructive: {
container_classes: "text-inverse bg-red-500 theme-dark:bg-red-400 hover:bg-red-600 theme-dark:hover:bg-red-500 disabled:bg-red-200 theme-dark:disabled:bg-red-600",
icon_classes: "fg-white"
},
outline: {
container_classes: "text-primary border border-secondary bg-transparent hover:bg-surface-hover",
icon_classes: "fg-gray"
},
outline_destructive: {
container_classes: "text-destructive border border-secondary bg-transparent hover:bg-gray-100 theme-dark:hover:bg-gray-700",
icon_classes: "fg-gray"
},
ghost: {
container_classes: "text-primary bg-transparent hover:bg-gray-100 theme-dark:hover:bg-gray-700",
icon_classes: "fg-gray"
},
icon: {
container_classes: "hover:bg-gray-100 theme-dark:hover:bg-gray-700",
icon_classes: "fg-gray"
},
icon_inverse: {
container_classes: "bg-inverse hover:bg-inverse-hover",
icon_classes: "fg-inverse"
}
}.freeze
SIZES = {
sm: {
container_classes: "px-2 py-1",
icon_container_classes: "inline-flex items-center justify-center w-8 h-8",
radius_classes: "rounded-md",
text_classes: "text-sm",
icon_classes: "w-4 h-4"
},
md: {
container_classes: "px-3 py-2",
icon_container_classes: "inline-flex items-center justify-center w-9 h-9",
radius_classes: "rounded-lg",
text_classes: "text-sm",
icon_classes: "w-5 h-5"
},
lg: {
container_classes: "px-4 py-3",
icon_container_classes: "inline-flex items-center justify-center w-10 h-10",
radius_classes: "rounded-xl",
text_classes: "text-base",
icon_classes: "w-6 h-6"
}
}.freeze
attr_reader :variant, :size, :href, :icon, :icon_position, :text, :full_width, :extra_classes, :frame, :opts
def initialize(variant: :primary, size: :md, href: nil, text: nil, icon: nil, icon_position: :left, full_width: false, frame: nil, **opts)
@variant = variant.to_s.underscore.to_sym
@size = size.to_sym
@href = href
@icon = icon
@icon_position = icon_position.to_sym
@text = text
@full_width = full_width
@extra_classes = opts.delete(:class)
@frame = frame
@opts = opts
end
def call
raise NotImplementedError, "ButtonishComponent is an abstract class and cannot be instantiated directly."
end
def container_classes(override_classes = nil)
class_names(
"font-medium whitespace-nowrap",
merged_base_classes,
full_width ? "w-full justify-center" : nil,
container_size_classes,
size_data.dig(:text_classes),
variant_data.dig(:container_classes)
)
end
def container_size_classes
icon_only? ? size_data.dig(:icon_container_classes) : size_data.dig(:container_classes)
end
def icon_classes
class_names(
size_data.dig(:icon_classes),
variant_data.dig(:icon_classes)
)
end
def icon_only?
variant.in?([ :icon, :icon_inverse ])
end
private
def variant_data
self.class::VARIANTS.dig(variant)
end
def size_data
self.class::SIZES.dig(size)
end
# Make sure that user can override common classes like `hidden`
def merged_base_classes
base_display_classes = "inline-flex items-center gap-1"
base_radius_classes = size_data.dig(:radius_classes)
extra_classes_list = (extra_classes || "").split
has_display_override = extra_classes_list.any? { |c| permitted_display_override_classes.include?(c) }
has_radius_override = extra_classes_list.any? { |c| permitted_radius_override_classes.include?(c) }
base_classes = []
unless has_display_override
base_classes << base_display_classes
end
unless has_radius_override
base_classes << base_radius_classes
end
class_names(
base_classes,
extra_classes
)
end
def permitted_radius_override_classes
[ "rounded-full" ]
end
def permitted_display_override_classes
[ "hidden", "flex" ]
end
end