primer_view_components 0.0.17 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/app/components/primer/base_component.rb +5 -2
  4. data/app/components/primer/blankslate_component.rb +3 -2
  5. data/app/components/primer/border_box_component.rb +4 -0
  6. data/app/components/primer/box_component.rb +10 -0
  7. data/app/components/primer/breadcrumb_component.rb +2 -1
  8. data/app/components/primer/button_component.rb +1 -1
  9. data/app/components/primer/button_group_component.html.erb +5 -0
  10. data/app/components/primer/button_group_component.rb +34 -0
  11. data/app/components/primer/button_marketing_component.rb +73 -0
  12. data/app/components/primer/component.rb +13 -0
  13. data/app/components/primer/counter_component.rb +11 -8
  14. data/app/components/primer/details_component.rb +10 -6
  15. data/app/components/primer/dropdown_menu_component.rb +31 -3
  16. data/app/components/primer/flash_component.rb +1 -0
  17. data/app/components/primer/flex_component.rb +10 -9
  18. data/app/components/primer/flex_item_component.rb +2 -1
  19. data/app/components/primer/heading_component.rb +7 -0
  20. data/app/components/primer/label_component.rb +4 -4
  21. data/app/components/primer/octicon_component.rb +4 -3
  22. data/app/components/primer/popover_component.rb +2 -0
  23. data/app/components/primer/progress_bar_component.rb +2 -2
  24. data/app/components/primer/spinner_component.rb +1 -2
  25. data/app/components/primer/state_component.rb +3 -3
  26. data/app/components/primer/subhead_component.rb +3 -0
  27. data/app/components/primer/timeline_item_component.rb +3 -0
  28. data/app/components/primer/tooltip_component.rb +88 -0
  29. data/app/components/primer/truncate_component.rb +41 -0
  30. data/app/components/primer/underline_nav_component.rb +26 -1
  31. data/app/components/primer/view_components.rb +4 -0
  32. data/lib/primer/class_name_helper.rb +1 -0
  33. data/lib/primer/classify.rb +127 -108
  34. data/lib/primer/fetch_or_fallback_helper.rb +1 -0
  35. data/lib/primer/join_style_arguments_helper.rb +1 -0
  36. data/lib/primer/view_components.rb +1 -0
  37. data/lib/primer/view_components/engine.rb +1 -0
  38. data/lib/primer/view_components/version.rb +1 -1
  39. metadata +41 -22
@@ -57,6 +57,7 @@ module Primer
57
57
  @system_arguments[:mb] ||= spacious ? 4 : nil
58
58
  end
59
59
 
60
+ # :nodoc
60
61
  class Actions < Primer::Slot
61
62
  attr_reader :system_arguments
62
63
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
+ # :nodoc
4
5
  class FlexComponent < Primer::Component
5
6
  JUSTIFY_CONTENT_DEFAULT = nil
6
7
  JUSTIFY_CONTENT_MAPPINGS = {
@@ -8,9 +9,9 @@ module Primer
8
9
  flex_end: "flex-justify-end",
9
10
  center: "flex-justify-center",
10
11
  space_between: "flex-justify-between",
11
- space_around: "flex-justify-around",
12
- }
13
- JUSTIFY_CONTENT_OPTIONS = [JUSTIFY_CONTENT_DEFAULT, *JUSTIFY_CONTENT_MAPPINGS.keys]
12
+ space_around: "flex-justify-around"
13
+ }.freeze
14
+ JUSTIFY_CONTENT_OPTIONS = [JUSTIFY_CONTENT_DEFAULT, *JUSTIFY_CONTENT_MAPPINGS.keys].freeze
14
15
 
15
16
  ALIGN_ITEMS_DEFAULT = nil
16
17
  ALIGN_ITEMS_MAPPINGS = {
@@ -18,18 +19,18 @@ module Primer
18
19
  end: "flex-items-end",
19
20
  center: "flex-items-center",
20
21
  baseline: "flex-items-baseline",
21
- stretch: "flex-items-stretch",
22
- }
23
- ALIGN_ITEMS_OPTIONS = [ALIGN_ITEMS_DEFAULT, *ALIGN_ITEMS_MAPPINGS.keys]
22
+ stretch: "flex-items-stretch"
23
+ }.freeze
24
+ ALIGN_ITEMS_OPTIONS = [ALIGN_ITEMS_DEFAULT, *ALIGN_ITEMS_MAPPINGS.keys].freeze
24
25
 
25
26
  INLINE_DEFAULT = false
26
- INLINE_OPTIONS = [INLINE_DEFAULT, true]
27
+ INLINE_OPTIONS = [INLINE_DEFAULT, true].freeze
27
28
 
28
29
  FLEX_WRAP_DEFAULT = nil
29
- FLEX_WRAP_OPTIONS = [FLEX_WRAP_DEFAULT, true, false]
30
+ FLEX_WRAP_OPTIONS = [FLEX_WRAP_DEFAULT, true, false].freeze
30
31
 
31
32
  DEFAULT_DIRECTION = nil
32
- ALLOWED_DIRECTIONS = [DEFAULT_DIRECTION, :column, :column_reverse, :row, :row_reverse]
33
+ ALLOWED_DIRECTIONS = [DEFAULT_DIRECTION, :column, :column_reverse, :row, :row_reverse].freeze
33
34
 
34
35
  def initialize(
35
36
  justify_content: JUSTIFY_CONTENT_DEFAULT,
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
+ # :nodoc
4
5
  class FlexItemComponent < Primer::Component
5
6
  FLEX_AUTO_DEFAULT = false
6
- FLEX_AUTO_ALLOWED_VALUES = [FLEX_AUTO_DEFAULT, true]
7
+ FLEX_AUTO_ALLOWED_VALUES = [FLEX_AUTO_DEFAULT, true].freeze
7
8
 
8
9
  def initialize(flex_auto: FLEX_AUTO_DEFAULT, **system_arguments)
9
10
  @system_arguments = system_arguments
@@ -1,7 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
+ # Use the Heading component to wrap a component that will create a heading element
4
5
  class HeadingComponent < Primer::Component
6
+ # @example 70|Default
7
+ # <%= render(Primer::HeadingComponent.new) { "H1 Text" } %>
8
+ # <%= render(Primer::HeadingComponent.new(tag: :h2)) { "H2 Text" } %>
9
+ # <%= render(Primer::HeadingComponent.new(tag: :h3)) { "H3 Text" } %>
10
+ #
11
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
5
12
  def initialize(**system_arguments)
6
13
  @system_arguments = system_arguments
7
14
  @system_arguments[:tag] ||= :h1
@@ -9,8 +9,8 @@ module Primer
9
9
  info: "Label--info",
10
10
  success: "Label--success",
11
11
  warning: "Label--warning",
12
- danger: "Label--danger",
13
- }
12
+ danger: "Label--danger"
13
+ }.freeze
14
14
 
15
15
  DEPRECATED_SCHEME_MAPPINGS = {
16
16
  gray: "Label--gray",
@@ -23,7 +23,7 @@ module Primer
23
23
  purple: "Label--purple",
24
24
  pink: "Label--pink",
25
25
  outline: "Label--outline",
26
- green_outline: "Label--outline-green",
26
+ green_outline: "Label--outline-green"
27
27
  }.freeze
28
28
 
29
29
  SCHEME_MAPPINGS = NEW_SCHEME_MAPPINGS.merge(DEPRECATED_SCHEME_MAPPINGS)
@@ -31,7 +31,7 @@ module Primer
31
31
 
32
32
  VARIANT_MAPPINGS = {
33
33
  large: "Label--large",
34
- inline: "Label--inline",
34
+ inline: "Label--inline"
35
35
  }.freeze
36
36
  VARIANT_OPTIONS = VARIANT_MAPPINGS.keys << nil
37
37
 
@@ -10,7 +10,7 @@ module Primer
10
10
  SIZE_MAPPINGS = {
11
11
  SIZE_DEFAULT => 16,
12
12
  :medium => 32,
13
- :large => 64,
13
+ :large => 64
14
14
  }.freeze
15
15
  SIZE_OPTIONS = SIZE_MAPPINGS.keys
16
16
 
@@ -27,7 +27,8 @@ module Primer
27
27
  # @param size [Symbol] <%= one_of(Primer::OcticonComponent::SIZE_MAPPINGS) %>
28
28
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
29
29
  def initialize(icon:, size: SIZE_DEFAULT, **system_arguments)
30
- @icon, @system_arguments = icon, system_arguments
30
+ @icon = icon
31
+ @system_arguments = system_arguments
31
32
 
32
33
  @system_arguments[:class] = Primer::Classify.call(**@system_arguments)[:class]
33
34
  @system_arguments[:height] ||= SIZE_MAPPINGS[size]
@@ -39,7 +40,7 @@ module Primer
39
40
  end
40
41
 
41
42
  def call
42
- octicon(@icon, **@system_arguments)
43
+ octicon(@icon, { **@system_arguments })
43
44
  end
44
45
  end
45
46
  end
@@ -57,6 +57,7 @@ module Primer
57
57
  body.present?
58
58
  end
59
59
 
60
+ # :nodoc
60
61
  class Heading < Primer::Slot
61
62
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
62
63
  def initialize(**system_arguments)
@@ -70,6 +71,7 @@ module Primer
70
71
  end
71
72
  end
72
73
 
74
+ # :nodoc
73
75
  class Body < Slot
74
76
  CARET_DEFAULT = :top
75
77
  CARET_MAPPINGS = {
@@ -12,7 +12,7 @@ module Primer
12
12
  SIZE_MAPPINGS = {
13
13
  SIZE_DEFAULT => "",
14
14
  :small => "Progress--small",
15
- :large => "Progress--large",
15
+ :large => "Progress--large"
16
16
  }.freeze
17
17
 
18
18
  SIZE_OPTIONS = SIZE_MAPPINGS.keys
@@ -48,13 +48,13 @@ module Primer
48
48
  SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, SIZE_DEFAULT)]
49
49
  )
50
50
  @system_arguments[:tag] = :span
51
-
52
51
  end
53
52
 
54
53
  def render?
55
54
  items.any?
56
55
  end
57
56
 
57
+ # :nodoc
58
58
  class Item < Primer::Slot
59
59
  attr_reader :system_arguments
60
60
 
@@ -3,12 +3,11 @@
3
3
  module Primer
4
4
  # Use Primer::SpinnerComponent to let users know that content is being loaded.
5
5
  class SpinnerComponent < Primer::Component
6
-
7
6
  DEFAULT_SIZE = :medium
8
7
  SIZE_MAPPINGS = {
9
8
  :small => 16,
10
9
  DEFAULT_SIZE => 32,
11
- :large => 64,
10
+ :large => 64
12
11
  }.freeze
13
12
  SIZE_OPTIONS = SIZE_MAPPINGS.keys
14
13
  # Setting `box-sizing: content-box` allows consumers to add padding
@@ -8,19 +8,19 @@ module Primer
8
8
  COLOR_DEFAULT => "",
9
9
  :green => "State--green",
10
10
  :red => "State--red",
11
- :purple => "State--purple",
11
+ :purple => "State--purple"
12
12
  }.freeze
13
13
  COLOR_OPTIONS = COLOR_MAPPINGS.keys
14
14
 
15
15
  SIZE_DEFAULT = :default
16
16
  SIZE_MAPPINGS = {
17
17
  SIZE_DEFAULT => "",
18
- :small => "State--small",
18
+ :small => "State--small"
19
19
  }.freeze
20
20
  SIZE_OPTIONS = SIZE_MAPPINGS.keys
21
21
 
22
22
  TAG_DEFAULT = :span
23
- TAG_OPTIONS = [TAG_DEFAULT, :div, :a]
23
+ TAG_OPTIONS = [TAG_DEFAULT, :div, :a].freeze
24
24
 
25
25
  # @example 40|Default
26
26
  # <%= render(Primer::StateComponent.new(title: "title")) { "State" } %>
@@ -67,6 +67,7 @@ module Primer
67
67
  heading.present?
68
68
  end
69
69
 
70
+ # :nodoc
70
71
  class Heading < ViewComponent::Slot
71
72
  include ClassNameHelper
72
73
 
@@ -85,6 +86,7 @@ module Primer
85
86
  end
86
87
  end
87
88
 
89
+ # :nodoc
88
90
  class Actions < ViewComponent::Slot
89
91
  include ClassNameHelper
90
92
 
@@ -98,6 +100,7 @@ module Primer
98
100
  end
99
101
  end
100
102
 
103
+ # :nodoc
101
104
  class Description < ViewComponent::Slot
102
105
  include ClassNameHelper
103
106
 
@@ -36,6 +36,7 @@ module Primer
36
36
  avatar.present? || badge.present? || body.present?
37
37
  end
38
38
 
39
+ # :nodoc
39
40
  class Avatar < Primer::Slot
40
41
  attr_reader :system_arguments, :alt, :src, :size, :square
41
42
 
@@ -59,6 +60,7 @@ module Primer
59
60
  end
60
61
  end
61
62
 
63
+ # :nodoc
62
64
  class Badge < Primer::Slot
63
65
  attr_reader :system_arguments, :icon
64
66
 
@@ -76,6 +78,7 @@ module Primer
76
78
  end
77
79
  end
78
80
 
81
+ # :nodoc
79
82
  class Body < Primer::Slot
80
83
  attr_reader :system_arguments
81
84
 
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # The Tooltip component is a wrapper component that will apply a tooltip to the provided content.
5
+ class TooltipComponent < Primer::Component
6
+ DIRECTION_DEFAULT = :n
7
+ ALIGN_DEFAULT = :default
8
+ MULTILINE_DEFAULT = false
9
+ DELAY_DEFAULT = false
10
+
11
+ ALIGN_MAPPING = {
12
+ ALIGN_DEFAULT => "",
13
+ :left_1 => "tooltipped-align-left-1",
14
+ :right_1 => "tooltipped-align-right-1",
15
+ :left_2 => "tooltipped-align-left-2",
16
+ :right_2 => "tooltipped-align-right-2"
17
+ }.freeze
18
+
19
+ DIRECTION_OPTIONS = [DIRECTION_DEFAULT] + %i[
20
+ nw
21
+ ne
22
+ w
23
+ e
24
+ sw
25
+ s
26
+ se
27
+ ]
28
+
29
+ # @example 100|Default
30
+ # <div class="pt-5">
31
+ # <%= render(Primer::TooltipComponent.new(label: "Even bolder")) { "Default Bold Text" } %>
32
+ # </div>
33
+ #
34
+ # @example 100|Wrapping another component
35
+ # <div class="pt-5">
36
+ # <%= render(Primer::TooltipComponent.new(label: "Even bolder")) do %>
37
+ # <%= render(Primer::ButtonComponent.new) { "Bold Button" } %>
38
+ # <% end %>
39
+ # </div>
40
+ #
41
+ # @example 100|With a direction
42
+ # <div class="pt-5">
43
+ # <%= render(Primer::TooltipComponent.new(label: "Even bolder", direction: :s)) { "Bold Text With a Direction" } %>
44
+ # </div>
45
+ #
46
+ # @example 100|With an alignment
47
+ # <div class="pt-5">
48
+ # <%= render(Primer::TooltipComponent.new(label: "Even bolder", direction: :s, alignment: :right_1)) { "Bold Text With an Alignment" } %>
49
+ # </div>
50
+ #
51
+ # @example 100|Without a delay
52
+ # <div class="pt-5">
53
+ # <%= render(Primer::TooltipComponent.new(label: "Even bolder", direction: :s, no_delay: true)) { "Bold Text without a delay" } %>
54
+ # </div>
55
+ #
56
+ # @param label [String] the text to appear in the tooltip
57
+ # @param direction [String] Direction of the tooltip. <%= one_of(Primer::TooltipComponent::DIRECTION_OPTIONS) %>
58
+ # @param align [String] Align tooltips to the left or right of an element, combined with a `direction` to specify north or south. <%= one_of(Primer::TooltipComponent::ALIGN_MAPPING.keys) %>
59
+ # @param multiline [Boolean] Use this when you have long content
60
+ # @param no_delay [Boolean] By default the tooltips have a slight delay before appearing. Set true to override this
61
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
62
+ def initialize(
63
+ label:,
64
+ direction: DIRECTION_DEFAULT,
65
+ align: ALIGN_DEFAULT,
66
+ multiline: MULTILINE_DEFAULT,
67
+ no_delay: DELAY_DEFAULT,
68
+ **system_arguments
69
+ )
70
+ @system_arguments = system_arguments
71
+ @system_arguments[:tag] ||= :span
72
+ @system_arguments[:aria] = { label: label }
73
+
74
+ @system_arguments[:classes] = class_names(
75
+ @system_arguments[:classes],
76
+ "tooltipped",
77
+ "tooltipped-#{fetch_or_fallback(DIRECTION_OPTIONS, direction, DIRECTION_DEFAULT)}",
78
+ ALIGN_MAPPING[fetch_or_fallback(ALIGN_MAPPING.keys, align, ALIGN_DEFAULT)],
79
+ "tooltipped-no-delay" => fetch_or_fallback_boolean(no_delay, DELAY_DEFAULT),
80
+ "tooltipped-multiline" => fetch_or_fallback_boolean(multiline, MULTILINE_DEFAULT)
81
+ )
82
+ end
83
+
84
+ def call
85
+ render(Primer::BaseComponent.new(**@system_arguments)) { content }
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use TruncateComponent to shorten overflowing text with an ellipsis.
5
+ class TruncateComponent < Primer::Component
6
+ # @example 25|Default
7
+ # <div class="col-2">
8
+ # <%= render(Primer::TruncateComponent.new(tag: :p)) { "branch-name-that-is-really-long" } %>
9
+ # </div>
10
+ #
11
+ # @example 25|Inline
12
+ # <%= render(Primer::TruncateComponent.new(tag: :span, inline: true)) { "branch-name-that-is-really-long" } %>
13
+ #
14
+ # @example 25|Expandable
15
+ # <%= render(Primer::TruncateComponent.new(tag: :span, inline: true, expandable: true)) { "branch-name-that-is-really-long" } %>
16
+ #
17
+ # @example 25|Custom size
18
+ # <%= render(Primer::TruncateComponent.new(tag: :span, inline: true, expandable: true, max_width: 100)) { "branch-name-that-is-really-long" } %>
19
+ #
20
+ # @param inline [Boolean] Whether the element is inline (or inline-block).
21
+ # @param expandable [Boolean] Whether the entire string should be revealed on hover. Can only be used in conjunction with `inline`.
22
+ # @param max_width [Integer] Sets the max-width of the text.
23
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
24
+ def initialize(inline: false, expandable: false, max_width: nil, **system_arguments)
25
+ @system_arguments = system_arguments
26
+ @system_arguments[:tag] ||= :div
27
+ @system_arguments[:classes] = class_names(
28
+ @system_arguments[:classes],
29
+ "css-truncate",
30
+ "css-truncate-overflow" => !inline,
31
+ "css-truncate-target" => inline,
32
+ "expandable" => inline && expandable
33
+ )
34
+ @system_arguments[:style] = join_style_arguments(@system_arguments[:style], "max-width: #{max_width}px;") unless max_width.nil?
35
+ end
36
+
37
+ def call
38
+ render(Primer::BaseComponent.new(**@system_arguments)) { content }
39
+ end
40
+ end
41
+ end
@@ -1,12 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
+ # Use the UnderlineNav component to style navigation with a minimal
5
+ # underlined selected state, typically used for navigation placed at the top
6
+ # of the page.
4
7
  class UnderlineNavComponent < Primer::Component
5
8
  ALIGN_DEFAULT = :left
6
- ALIGN_OPTIONS = [ALIGN_DEFAULT, :right]
9
+ ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
7
10
 
8
11
  with_content_areas :body, :actions
9
12
 
13
+ # @example 70|Default
14
+ # <%= render(Primer::UnderlineNavComponent.new) do |component| %>
15
+ # <% component.with(:body) do %>
16
+ # <%= render(Primer::LinkComponent.new(href: "#url")) { "Item 1" } %>
17
+ # <% end %>
18
+ # <% component.with(:actions) do %>
19
+ # <%= render(Primer::ButtonComponent.new) { "Button!" } %>
20
+ # <% end %>
21
+ # <% end %>
22
+ #
23
+ # @example 70|Align right
24
+ # <%= render(Primer::UnderlineNavComponent.new(align: :right)) do |component| %>
25
+ # <% component.with(:body) do %>
26
+ # <%= render(Primer::LinkComponent.new(href: "#url")) { "Item 1" } %>
27
+ # <% end %>
28
+ # <% component.with(:actions) do %>
29
+ # <%= render(Primer::ButtonComponent.new) { "Button!" } %>
30
+ # <% end %>
31
+ # <% end %>
32
+ #
33
+ # @param align [Symbol] <%= one_of(Primer::UnderlineNavComponent::ALIGN_OPTIONS) %> - Defaults to <%= Primer::UnderlineNavComponent::ALIGN_DEFAULT %>
34
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
10
35
  def initialize(align: ALIGN_DEFAULT, **system_arguments)
11
36
  @align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
12
37
 
@@ -31,6 +31,8 @@ require_relative "border_box_component"
31
31
  require_relative "box_component"
32
32
  require_relative "breadcrumb_component"
33
33
  require_relative "button_component"
34
+ require_relative "button_group_component"
35
+ require_relative "button_marketing_component"
34
36
  require_relative "counter_component"
35
37
  require_relative "details_component"
36
38
  require_relative "dropdown_menu_component"
@@ -49,4 +51,6 @@ require_relative "state_component"
49
51
  require_relative "subhead_component"
50
52
  require_relative "text_component"
51
53
  require_relative "timeline_item_component"
54
+ require_relative "tooltip_component"
55
+ require_relative "truncate_component"
52
56
  require_relative "underline_nav_component"