Skip to content

Commit

Permalink
Create InputGroup component
Browse files Browse the repository at this point in the history
  • Loading branch information
HDinger committed Nov 24, 2023
1 parent 8705a90 commit ba8c3b5
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/early-news-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@openproject/primer-view-components': minor
---

Create OpenProject::InputGroupComponent
4 changes: 4 additions & 0 deletions app/components/primer/open_project/input_group.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
<%= text_input %>
<%= trailing_action %>
<% end %>
74 changes: 74 additions & 0 deletions app/components/primer/open_project/input_group.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# frozen_string_literal: true

module Primer
module OpenProject
# Add a general description of component here
# Add additional usage considerations or best practices that may aid the user to use the component correctly.
# @accessibility Add any accessibility considerations
class InputGroup < Primer::Component
status :open_project

# A component that will render to the right of the label.
#
# To render a clipboardCopyButton, call the `with_trailing_action_clipboard_copy_button` method, which accepts the arguments accepted by <%= link_to_component(Primer::Beta::ClipboardCopyButton) %>.
#
# To render an iconButton, call the `with_trailing_action_icon` method, which accepts the arguments accepted by <%= link_to_component(Primer::Beta::Octicon) %>.
renders_one :trailing_action, types: {
clipboard_copy_button: lambda { |**system_arguments, &block|
system_arguments[:classes] = class_names(
system_arguments[:classes],
"rounded-left-0 border-left-0"
)
Primer::Beta::ClipboardCopyButton.new(**system_arguments, &block)
},
icon: lambda { |icon: nil, **system_arguments, &block|
system_arguments[:classes] = class_names(
system_arguments[:classes],
"rounded-left-0 border-left-0"
)
Primer::Beta::IconButton.new(icon: icon, **system_arguments, &block)
}
}

# Input that is the central part of the input group
#
# Since the central use case of this component is a copyClipboard Button next to the input, it is readonly by default
#
# @param readonly [Boolean] Shall the text field be editable.
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
renders_one :text_input, lambda { |readonly: true, **system_arguments|
system_arguments[:classes] = class_names(
system_arguments[:classes],
"rounded-right-0"
)

if readonly
system_arguments[:readonly] = readonly
system_arguments[:aria] = merge_aria(
system_arguments,
{ aria: { readonly: "true" } }
)
end

Primer::Alpha::TextField.new(**system_arguments)
}

# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
def initialize(**system_arguments)
@system_arguments = system_arguments
@system_arguments[:tag] = :div
@system_arguments[:display] = :flex
@system_arguments[:align_items] = :flex_end

system_arguments[:classes] = class_names(
system_arguments[:classes],
"InputGroup"
)
end

def render?
text_input? && trailing_action?
end
end
end
end
53 changes: 53 additions & 0 deletions previews/primer/open_project/input_group_preview.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# frozen_string_literal: true

# Setup Playground to use all available component props
# Setup Features to use individual component props and combinations

module Primer
module OpenProject
# @label InputGroup
class InputGroupPreview < ViewComponent::Preview
# @label Default
# @snapshot
def default
render(Primer::OpenProject::InputGroup.new) do |menu|
menu.with_text_input(name: 'a name', label: 'My input group', value: "Copyable value")
menu.with_trailing_action_clipboard_copy_button(id: "button", value: "Copyable value", aria: { label: "Copy some text" })
end
end

# @label Playground
# @param trailing_action [Symbol] select [clipboardCopy, icon]
# @param value [String]
# @param visually_hide_label toggle
# @param readonly toggle
def playground(
trailing_action: :clipboardCopy,
value: 'Copyable value',
visually_hide_label: false,
readonly: true
)
render(Primer::OpenProject::InputGroup.new) do |menu|
menu.with_text_input(name: 'Test', label: 'My input group', visually_hide_label: visually_hide_label, value: value, readonly: readonly)

case trailing_action
when :icon
menu.with_trailing_action_icon(icon: :check, aria: { label: "Successful" })
when :clipboardCopy
menu.with_trailing_action_clipboard_copy_button(id: "button-2", value: value, aria: { label: "Copy some text" })
else
menu.with_trailing_action_clipboard_copy_button(id: "button-3", value: value, aria: { label: "Copy some text" })
end
end
end

# @label with iconButton
def icon_button
render(Primer::OpenProject::InputGroup.new) do |menu|
menu.with_text_input(name: 'a name', label: 'My input group', value: "Some value")
menu.with_trailing_action_icon(icon: :check, aria: { label: "Successful" })
end
end
end
end
end
4 changes: 4 additions & 0 deletions test/components/component_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ class PrimerComponentTest < Minitest::Test

# Components with any arguments necessary to make them render
COMPONENTS_WITH_ARGS = [
[Primer::OpenProject::InputGroup, {}, proc { |component|
menu.with_text_input(name: "a name", label: "My input group", value: "Copyable value")
menu.with_trailing_action_clipboard_copy_button(id: "button", value: "Copyable value", aria: { label: "Copy some text" })
}],
[Primer::OpenProject::GridLayout, { css_class: "grid-layout", tag: :div }, proc { |component|
component.with_area(:area) do
"Foo"
Expand Down
45 changes: 45 additions & 0 deletions test/components/primer/open_project/input_group_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true

require "components/test_helper"

class PrimerOpenProjectInputGroupTest < Minitest::Test
include Primer::ComponentTestHelpers

def test_renders
render_inline(Primer::OpenProject::InputGroup.new) do |menu|
menu.with_text_input(name: "a name", label: "My input group", value: "Copyable value")
menu.with_trailing_action_clipboard_copy_button(id: "button", value: "Copyable value", aria: { label: "Copy some text" })
end

assert_selector(".InputGroup")
assert_selector(".FormControl-input.rounded-right-0")
assert_selector("clipboard-copy.rounded-left-0.border-left-0")
end

def test_renders_icon
render_inline(Primer::OpenProject::InputGroup.new) do |menu|
menu.with_text_input(name: "a name", label: "My input group", value: "Copyable value")
menu.with_trailing_action_icon(icon: :gear, aria: { label: "Copy some text" })
end

assert_selector(".InputGroup")
assert_selector(".FormControl-input.rounded-right-0")
assert_selector(".Button--iconOnly.rounded-left-0.border-left-0")
end

def test_does_not_render_without_trailing_action
render_inline(Primer::OpenProject::InputGroup.new) do |menu|
menu.with_text_input(name: "a name", label: "My input group", value: "Copyable value")
end

refute_selector(".InputGroup")
end

def test_does_not_render_without_input
render_inline(Primer::OpenProject::InputGroup.new) do |menu|
menu.with_trailing_action_clipboard_copy_button(id: "button", value: "Copyable value", aria: { label: "Copy some text" })
end

refute_selector(".InputGroup")
end
end
11 changes: 11 additions & 0 deletions test/system/open_project/input_group_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

require "system/test_case"

class IntegrationOpenProjectInputGroupTest < System::TestCase
def test_renders_component
visit_preview(:default)

assert_selector(".InputGroup")
end
end

0 comments on commit ba8c3b5

Please sign in to comment.