Files
sure/app/components/DS/button.rb
DataEnginr e75f2a0c78 Fix fee display consistency, derive fees from entries, clean schema churn
- Show principal-only transfer amounts on both sides with separate fee and total lines (fixes inconsistent gross/net convention)
- Derive displayed fee amounts from fee_transactions entries (single source of truth) instead of stored columns
- Remove stored source_fee_amount/destination_fee_amount columns from transfers table
- Add foreign key for transactions.transfer_id -> transfers.id (replaces invalid CHECK subquery)
- Move destination fee line inside destination side div for consistent layout
- Remove orphaned view_fee_transaction locale keys from 7 locale files
- Rebuild schema.rb from origin/main to eliminate unrelated column reordering churn
2026-06-28 19:47:53 +00:00

64 lines
2.1 KiB
Ruby

# frozen_string_literal: true
# An extension to `button_to` helper. All options are passed through to the `button_to` helper with some additional
# options available.
class DS::Button < DS::Buttonish
attr_reader :confirm
def initialize(confirm: nil, **opts)
super(**opts)
@confirm = confirm
end
def container(&block)
if href.present?
button_to(href, **merged_opts, &block)
else
content_tag(:button, **merged_opts, &block)
end
end
private
def merged_opts
merged_opts = opts.dup || {}
extra_classes = merged_opts.delete(:class)
data = merged_opts.delete(:data) || {}
if confirm.present?
confirm_value = confirm.respond_to?(:to_data_attribute) ? confirm.to_data_attribute : confirm
data = data.merge(turbo_confirm: confirm_value)
end
if frame.present?
data = data.merge(turbo_frame: frame)
end
# `content_tag(:button, ...)` defaults to `type="submit"` per the HTML
# spec — meaning a DS::Button rendered inside a form will steal Enter-key
# submission from the first text input. Default to `type="button"` so
# callers must opt into submit behavior explicitly. `button_to` (href
# branch) wraps the button in its own form, so submit there is correct
# and we leave its default alone.
if href.blank?
merged_opts[:type] ||= "button"
end
# Icon-only buttons have no visible text node, so screen readers fall
# back to announcing "button" with no name. Derive a humanized fallback
# from the icon key so AT users hear *something* meaningful; explicit
# `aria: { label: }` on the caller still wins.
if icon_only? && icon.present?
aria = (merged_opts[:aria] || {}).symbolize_keys
if aria[:label].blank? && merged_opts[:"aria-label"].blank?
aria[:label] = icon.to_s.tr("-_", " ").capitalize
merged_opts[:aria] = aria
end
end
merged_opts.merge(
class: class_names(container_classes, extra_classes),
data: data
)
end
end