# frozen_string_literal: true module Ariadne # Use `ClipboardCopyComponent` to copy element text content or input values to the clipboard. # # @accessibility # Always set an accessible label to help the user interact with the component. class ClipboardCopyComponent < Ariadne::Component DEFAULT_TAG = :"clipboard-copy" DEFAULT_CLASSES = LinkComponent::DEFAULT_ACTIONABLE_CLASSES DATA_CONTROLLER = "clipboard-copy-component" DATA_ACTION = "click->clipboard-copy-component#copy" # `Tooltip` that appears on mouse hover or keyboard focus over the button. Use tooltips sparingly and as a last resort. # **Important:** This tooltip defaults to `type: :description`. In a few scenarios, `type: :label` may be more appropriate. # Consult the <%= link_to_component(Ariadne::TooltipComponent) %> documentation for more information. # # @param tag [Symbol, String] The rendered tag name # @param text [String] The text content of the tooltip. This should be brief and no longer than a sentence. # @param direction [Symbol] <%= one_of(Ariadne::TooltipComponent::VALID_PLACEMENTS) %> # @param classes [String] <%= link_to_classes_docs %> # @param attributes [Hash] Same arguments as <%= link_to_component(Ariadne::TooltipComponent) %>. renders_one :tooltip, lambda { |tag: Ariadne::TooltipComponent::DEFAULT_TAG, text:, direction: Ariadne::TooltipComponent::DEFAULT_PLACEMENT, type: Ariadne::TooltipComponent::TYPE_DEFAULT, classes: "", attributes: {}| raise ArgumentError, "CopyClipboardComponents with a tooltip must have a unique `id` set on the `CopyClipboardComponent`." if @id.blank? @data_tooltip_direction = { "data-tooltip-component-direction": direction } Ariadne::TooltipComponent.new(tag: tag, for_id: @id, text: text, direction: direction, type: type, classes: classes, attributes: attributes) } # @example Default # <%= render(Ariadne::ClipboardCopyComponent.new(value: "Text to copy", aria_label: "Copy text to the system clipboard" )) %> # # @example With text instead of icons # <%= render(Ariadne::ClipboardCopyComponent.new(value: "Text to copy", aria_label: "Copy text to the system clipboard" )) do %> # Click to copy! # <% end %> # # @example Copying from an element # <%= render(Ariadne::ClipboardCopyComponent.new(for_id: "blob-path", aria_label: "Copy text to the system clipboard" )) %> #
src/index.js
# # @param tag [Symbol, String] The rendered tag name # @param classes [String] <%= link_to_classes_docs %> # @param value [String] Text to copy into the users clipboard when they click the component. # @param for_id [String] If `value` is not provided, the element with this id will be copied. # @param aria_label [String] Text for accessibility. Can also be passed in as part of `attributes`, but it must be present. # @param attributes [Hash] <%= link_to_attributes_docs %> def initialize(tag: DEFAULT_TAG, value: "", for_id: nil, aria_label: "", classes: "", attributes: {}) @attributes = attributes @value = value @attributes[:"aria-label"] = aria_label @attributes[:for] ||= for_id @id = @attributes[:id] validate! @classes = class_names(DEFAULT_CLASSES, classes) @tag = check_incoming_tag(DEFAULT_TAG, tag) @attributes[:value] = value if value.present? end private def validate! validate_aria_label! raise ArgumentError, "Must provide either `value` or `for`" if @value.blank? && @attributes[:for].blank? raise ArgumentError, "Must provide only `value` or `for`, not both" if @value.present? && @attributes[:for].present? end DATA_CONTROLLERS_WITH_TOOLTIPS = { "data-controller": "#{DATA_CONTROLLER} #{Ariadne::TooltipComponent::DATA_CONTROLLER}", "data-action": "#{DATA_ACTION} #{Ariadne::TooltipComponent::DATA_ACTION}", "data-tooltip-component-target": "trigger", } DATA_CONTROLLERS = { "data-controller": DATA_CONTROLLER.to_s, "data-action": DATA_ACTION, } def controller_data return DATA_CONTROLLERS_WITH_TOOLTIPS if tooltip.present? DATA_CONTROLLERS end end end