mirror of
https://github.com/we-promise/sure.git
synced 2026-07-12 12:55:20 +00:00
- 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
64 lines
2.1 KiB
Ruby
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
|