primer_view_components 0.0.17 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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"