primer_view_components 0.0.38 → 0.0.39

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +65 -27
  3. data/app/assets/javascripts/primer_view_components.js +1 -1
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  5. data/app/components/primer/auto_complete.rb +1 -1
  6. data/app/components/primer/auto_complete/item.rb +1 -1
  7. data/app/components/primer/avatar_component.rb +22 -3
  8. data/app/components/primer/avatar_stack_component.rb +1 -1
  9. data/app/components/primer/base_button.rb +1 -1
  10. data/app/components/primer/base_component.rb +7 -6
  11. data/app/components/primer/blankslate_component.rb +4 -1
  12. data/app/components/primer/border_box_component.rb +1 -1
  13. data/app/components/primer/box_component.rb +1 -1
  14. data/app/components/primer/breadcrumb_component.rb +1 -1
  15. data/app/components/primer/button_component.html.erb +9 -0
  16. data/app/components/primer/button_component.rb +39 -5
  17. data/app/components/primer/button_group.rb +1 -1
  18. data/app/components/primer/button_marketing_component.rb +1 -1
  19. data/app/components/primer/clipboard_copy.rb +1 -1
  20. data/app/components/primer/clipboard_copy_component.js +4 -6
  21. data/app/components/primer/clipboard_copy_component.ts +4 -6
  22. data/app/components/primer/close_button.rb +4 -2
  23. data/app/components/primer/component.rb +16 -2
  24. data/app/components/primer/counter_component.rb +1 -1
  25. data/app/components/primer/details_component.rb +1 -1
  26. data/app/components/primer/dropdown/menu_component.rb +1 -1
  27. data/app/components/primer/dropdown_component.rb +1 -1
  28. data/app/components/primer/flash_component.rb +1 -1
  29. data/app/components/primer/flex_component.rb +1 -1
  30. data/app/components/primer/flex_item_component.rb +20 -1
  31. data/app/components/primer/heading_component.rb +3 -3
  32. data/app/components/primer/hidden_text_expander.rb +1 -1
  33. data/app/components/primer/icon_button.rb +48 -0
  34. data/app/components/primer/label_component.rb +1 -1
  35. data/app/components/primer/layout_component.rb +1 -1
  36. data/app/components/primer/link_component.rb +1 -1
  37. data/app/components/primer/markdown_component.rb +1 -1
  38. data/app/components/primer/menu_component.rb +1 -1
  39. data/app/components/primer/octicon_component.rb +35 -10
  40. data/app/components/primer/popover_component.rb +1 -1
  41. data/app/components/primer/progress_bar_component.rb +1 -1
  42. data/app/components/primer/spinner_component.rb +1 -1
  43. data/app/components/primer/state_component.rb +1 -1
  44. data/app/components/primer/subhead_component.rb +1 -1
  45. data/app/components/primer/tab_container_component.rb +1 -1
  46. data/app/components/primer/tab_nav_component.rb +1 -1
  47. data/app/components/primer/text_component.rb +1 -1
  48. data/app/components/primer/time_ago_component.rb +1 -1
  49. data/app/components/primer/timeline_item_component.rb +1 -1
  50. data/app/components/primer/tooltip_component.rb +1 -1
  51. data/app/components/primer/truncate.rb +1 -1
  52. data/app/components/primer/underline_nav_component.rb +1 -1
  53. data/app/lib/primer/classify.rb +7 -32
  54. data/app/lib/primer/classify/cache.rb +19 -14
  55. data/app/lib/primer/classify/flex.rb +111 -0
  56. data/app/lib/primer/classify/functional_border_colors.rb +1 -2
  57. data/app/lib/primer/fetch_or_fallback_helper.rb +2 -2
  58. data/app/lib/primer/octicon/cache.rb +38 -0
  59. data/lib/primer/view_components/version.rb +1 -1
  60. data/static/statuses.json +1 -1
  61. metadata +7 -6
  62. data/app/components/primer/button_component.rb.orig +0 -138
  63. data/app/components/primer/foo_bar.d.ts +0 -1
  64. data/app/components/primer/foo_bar.js +0 -1
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use ButtonGroup to render a series of buttons.
4
+ # Use `ButtonGroup` to render a series of buttons.
5
5
  class ButtonGroup < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use buttons for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
4
+ # Use `ButtonMarketing` for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
5
5
  class ButtonMarketingComponent < Primer::Component
6
6
  DEFAULT_SCHEME = :default
7
7
  SCHEME_MAPPINGS = {
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use ClipboardCopy to copy element text content or input values to the clipboard.
4
+ # Use `ClipboardCopy` to copy element text content or input values to the clipboard.
5
5
  class ClipboardCopy < Primer::Component
6
6
  status :alpha
7
7
 
@@ -10,12 +10,10 @@ function toggleSVG(svg) {
10
10
  // Toggle a copy button.
11
11
  function toggleCopyButton(button) {
12
12
  const [clippyIcon, checkIcon] = button.querySelectorAll('.octicon');
13
- if (clippyIcon) {
14
- toggleSVG(clippyIcon);
15
- }
16
- if (checkIcon) {
17
- toggleSVG(checkIcon);
18
- }
13
+ if (!clippyIcon || !checkIcon)
14
+ return;
15
+ toggleSVG(clippyIcon);
16
+ toggleSVG(checkIcon);
19
17
  }
20
18
  document.addEventListener('clipboard-copy', function ({ target }) {
21
19
  if (!(target instanceof HTMLElement))
@@ -12,12 +12,10 @@ function toggleSVG(svg: SVGElement) {
12
12
  function toggleCopyButton(button: HTMLElement) {
13
13
  const [clippyIcon, checkIcon] = button.querySelectorAll<SVGElement>('.octicon')
14
14
 
15
- if (clippyIcon) {
16
- toggleSVG(clippyIcon)
17
- }
18
- if (checkIcon) {
19
- toggleSVG(checkIcon)
20
- }
15
+ if (!clippyIcon || !checkIcon) return
16
+
17
+ toggleSVG(clippyIcon)
18
+ toggleSVG(checkIcon)
21
19
  }
22
20
 
23
21
  document.addEventListener('clipboard-copy', function ({target}) {
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use CloseButton to render an `×` without default button styles.
4
+ # Use `CloseButton` to render an `×` without default button styles.
5
5
  #
6
6
  # @accessibility
7
- # CloseButton has a default `aria-label` of "Close" to provides assistive technologies with an accessible label.
7
+ # `CloseButton` has a default `aria-label` of "Close" to provides assistive technologies with an accessible label.
8
8
  # You may choose to override this label with something more descriptive via [system_arguments][0].
9
9
  # [0]: https://primer.style/view-components/system-arguments#html-attributes
10
10
  class CloseButton < Primer::Component
11
+ status :beta
12
+
11
13
  DEFAULT_TYPE = :button
12
14
  TYPE_OPTIONS = [DEFAULT_TYPE, :submit].freeze
13
15
 
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "octicons_helper/helper"
4
3
  require "view_component/version"
5
4
 
6
5
  module Primer
@@ -9,10 +8,25 @@ module Primer
9
8
  include ViewComponent::SlotableV2 unless ViewComponent::VERSION::STRING.to_f >= 2.28
10
9
  include ClassNameHelper
11
10
  include FetchOrFallbackHelper
12
- include OcticonsHelper
13
11
  include TestSelectorHelper
14
12
  include JoinStyleArgumentsHelper
15
13
  include ViewHelper
16
14
  include Status::Dsl
15
+
16
+ private
17
+
18
+ def deprecated_component_warning(new_class: nil, version: nil)
19
+ return if Rails.env.production? || silence_deprecations?
20
+
21
+ message = "#{self.class.name} is deprecated"
22
+ message += " and will be removed in v#{version}." if version
23
+ message += " Use #{new_class.name} instead." if new_class
24
+
25
+ ActiveSupport::Deprecation.warn(message)
26
+ end
27
+
28
+ def silence_deprecations?
29
+ Rails.application.config.primer_view_components.silence_deprecations
30
+ end
17
31
  end
18
32
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use Primer::CounterComponent to add a count to navigational elements and buttons.
4
+ # Use `CounterComponent` to add a count to navigational elements and buttons.
5
5
  class CounterComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use DetailsComponent to reveal content after clicking a button.
4
+ # Use `DetailsComponent` to reveal content after clicking a button.
5
5
  class DetailsComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Primer
4
4
  module Dropdown
5
- # This component is part of `Primer::DropdownComponent` and should not be
5
+ # This component is part of `Dropdown` and should not be
6
6
  # used as a standalone component.
7
7
  class MenuComponent < Primer::Component
8
8
  SCHEME_DEFAULT = :default
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Dropdowns are lightweight context menus for housing navigation and actions.
4
+ # `Dropdown` is a lightweight context menu for housing navigation and actions.
5
5
  # They're great for instances where you don't need the full power (and code) of the select menu.
6
6
  class DropdownComponent < Primer::Component
7
7
  # Required trigger for the dropdown. Only accepts a content.
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use the Flash component to inform users of successful or pending actions.
4
+ # Use `Flash` to inform users of successful or pending actions.
5
5
  class FlashComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use FlexComponent to make an element lay out its content using the flexbox model.
4
+ # Use `Flex` to make an element lay out its content using the flexbox model.
5
5
  # Before using these utilities, you should be familiar with CSS3 Flexible Box
6
6
  # spec. If you are not, check out MDN's guide [Using CSS Flexible
7
7
  # Boxes](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox).
@@ -1,9 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use FlexItemComponent to specify the ability of a flex item to alter its
4
+ # Use `FlexItem` to specify the ability of a flex item to alter its
5
5
  # dimensions to fill available space
6
+ #
7
+ # @deprecated
8
+ # Use <%= link_to_component(Primer::BoxComponent) %> instead.
9
+ #
10
+ # **Before**:
11
+ #
12
+ # ```erb
13
+ # <%%= render Primer::FlexItemComponent.new(flex_auto: :auto) %>
14
+ # ```
15
+ #
16
+ # **After**:
17
+ #
18
+ # ```erb
19
+ # <%%= render Primer::BoxComponent.new(flex: :auto) %>
20
+ # ```
6
21
  class FlexItemComponent < Primer::Component
22
+ status :deprecated
23
+
7
24
  FLEX_AUTO_DEFAULT = false
8
25
  FLEX_AUTO_ALLOWED_VALUES = [FLEX_AUTO_DEFAULT, true].freeze
9
26
 
@@ -21,6 +38,8 @@ module Primer
21
38
  # @param flex_auto [Boolean] Fills available space and auto-sizes based on the content. Defaults to <%= Primer::FlexItemComponent::FLEX_AUTO_DEFAULT %>
22
39
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
23
40
  def initialize(flex_auto: FLEX_AUTO_DEFAULT, **system_arguments)
41
+ deprecated_component_warning(new_class: Primer::BoxComponent, version: "0.0.39")
42
+
24
43
  @system_arguments = system_arguments
25
44
  @system_arguments[:classes] =
26
45
  class_names(
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Heading can be used to communicate page organization and hierarchy.
4
+ # `Heading` can be used to communicate page organization and hierarchy.
5
5
  #
6
6
  # - Set tag to one of `:h1`, `:h2`, `:h3`, `:h4`, `:h5`, `:h6` based on what is
7
7
  # appropriate for the page context.
8
- # - Use Heading as the title of a section or sub section.
9
- # - Do not use Heading for styling alone. To style text without conveying heading semantics,
8
+ # - Use `Heading` as the title of a section or sub section.
9
+ # - Do not use `Heading` for styling alone. To style text without conveying heading semantics,
10
10
  # consider using <%= link_to_component(Primer::TextComponent) %> with relevant <%= link_to_typography_docs %>.
11
11
  # - Do not jump heading levels. For instance, do not follow a `<h1>` with an `<h3>`. Heading levels should
12
12
  # increase by one in ascending order.
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use HiddenTextExpander to indicate and toggle hidden text.
4
+ # Use `HiddenTextExpander` to indicate and toggle hidden text.
5
5
  class HiddenTextExpander < Primer::Component
6
6
  # @example Default
7
7
  # <%= render(Primer::HiddenTextExpander.new) %>
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use `IconButton` to render Icon-only buttons without the default button styles.
5
+ #
6
+ # @accessibility
7
+ # `IconButton` requires an `aria-label`, which will provide assistive technologies with an accessible label.
8
+ class IconButton < Primer::Component
9
+ DEFAULT_SCHEME = :default
10
+ SCHEME_MAPPINGS = {
11
+ DEFAULT_SCHEME => "",
12
+ :danger => "btn-octicon-danger"
13
+ }.freeze
14
+ SCHEME_OPTIONS = SCHEME_MAPPINGS.keys
15
+ # @example Default
16
+ #
17
+ # <%= render(Primer::IconButton.new(icon: :search, "aria-label": "Search")) %>
18
+ #
19
+ # @example Schemes
20
+ #
21
+ # <%= render(Primer::IconButton.new(icon: :search, "aria-label": "Search")) %>
22
+ # <%= render(Primer::IconButton.new(icon: :trash, "aria-label": "Delete", scheme: :danger)) %>
23
+ #
24
+ # @param scheme [Symbol] <%= one_of(Primer::IconButton::SCHEME_OPTIONS) %>
25
+ # @param icon [String] Name of <%= link_to_octicons %> to use.
26
+ # @param tag [Symbol] <%= one_of(Primer::BaseButton::TAG_OPTIONS) %>
27
+ # @param type [Symbol] <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
28
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
29
+ def initialize(scheme: DEFAULT_SCHEME, icon:, **system_arguments)
30
+ @icon = icon
31
+
32
+ @system_arguments = system_arguments
33
+ @system_arguments[:classes] = class_names(
34
+ "btn-octicon",
35
+ SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)],
36
+ system_arguments[:classes]
37
+ )
38
+
39
+ raise ArgumentError, "`aria-label` is required." if @system_arguments[:"aria-label"].nil? && !Rails.env.production?
40
+ end
41
+
42
+ def call
43
+ render(Primer::BaseButton.new(**@system_arguments)) do
44
+ render(Primer::OcticonComponent.new(icon: @icon))
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use labels to add contextual metadata to a design.
4
+ # Use `Label` to add contextual metadata to a design.
5
5
  class LabelComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use Layout to build a main/sidebar layout.
4
+ # Use `Layout` to build a main/sidebar layout.
5
5
  class LayoutComponent < Primer::Component
6
6
  # The main content
7
7
  #
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use links for moving from one page to another. The Link component styles anchor tags with default blue styling and hover text-decoration.
4
+ # Use `Link` for navigating from one page to another. `Link` styles anchor tags with default blue styling and hover text-decoration.
5
5
  class LinkComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use MarkdownComponent to wrap markdown content
4
+ # Use `Markdown` to wrap markdown content
5
5
  class MarkdownComponent < Primer::Component
6
6
  # @example Default
7
7
  # <%= render(Primer::MarkdownComponent.new) do %>
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use menus to create vertical lists of navigational links.
4
+ # Use `Menu` to create vertical lists of navigational links.
5
5
  class MenuComponent < Primer::Component
6
6
  # Optional menu heading
7
7
  #
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "octicons"
4
+
3
5
  module Primer
4
- # Renders an [Octicon](https://primer.style/octicons/) with <%= link_to_system_arguments_docs %>.
6
+ # `Octicon` renders an <%= link_to_octicons %> with <%= link_to_system_arguments_docs %>.
5
7
  class OcticonComponent < Primer::Component
6
8
  status :beta
7
9
 
@@ -23,24 +25,47 @@ module Primer
23
25
  # @example Large
24
26
  # <%= render(Primer::OcticonComponent.new("x", size: :large)) %>
25
27
  #
26
- # @param icon [String] Name of [Octicon](https://primer.style/octicons/) to use.
28
+ # @param icon [String] Name of <%= link_to_octicons %> to use.
27
29
  # @param size [Symbol] <%= one_of(Primer::OcticonComponent::SIZE_MAPPINGS) %>
28
30
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
29
31
  def initialize(icon_name = nil, icon: nil, size: SIZE_DEFAULT, **system_arguments)
30
- @icon = icon_name || icon
32
+ icon_key = icon_name || icon
33
+ cache_key = [icon_key, size, system_arguments.slice(:height, :width)].join("_")
34
+
31
35
  @system_arguments = system_arguments
36
+ @system_arguments[:tag] = :svg
37
+ @system_arguments[:aria] ||= {}
38
+
39
+ if @system_arguments[:aria][:label] || @system_arguments[:"aria-label"]
40
+ @system_arguments[:role] = "img"
41
+ else
42
+ @system_arguments[:aria][:hidden] = true
43
+ end
32
44
 
33
- @system_arguments[:class] = Primer::Classify.call(**@system_arguments)[:class]
34
- @system_arguments[:height] ||= SIZE_MAPPINGS[size]
45
+ if (cache_icon = Primer::Octicon::Cache.read(cache_key))
46
+ @icon = cache_icon
47
+ else
48
+ # Filter out classify options to prevent them from becoming invalid html attributes.
49
+ # Note height and width are both classify options and valid html attributes.
50
+ octicon_options = {
51
+ height: SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, SIZE_DEFAULT)]
52
+ }.merge(@system_arguments.slice(:height, :width))
35
53
 
36
- # Filter out classify options to prevent them from becoming invalid html attributes.
37
- # Note height and width are both classify options and valid html attributes.
38
- octicon_helper_options = @system_arguments.slice(:height, :width)
39
- @system_arguments = add_test_selector(@system_arguments).except(*Primer::Classify::VALID_KEYS, :classes).merge(octicon_helper_options)
54
+ @icon = Octicons::Octicon.new(icon_key, octicon_options)
55
+ Primer::Octicon::Cache.set(cache_key, @icon)
56
+ end
57
+
58
+ @system_arguments[:classes] = class_names(
59
+ @icon.options[:class],
60
+ @system_arguments[:classes]
61
+ )
62
+ @system_arguments.merge!(@icon.options.except(:class, :'aria-hidden'))
40
63
  end
41
64
 
42
65
  def call
43
- octicon(@icon, { **@system_arguments })
66
+ render(Primer::BaseComponent.new(**@system_arguments)) { @icon.path.html_safe } # rubocop:disable Rails/OutputSafety
44
67
  end
68
+
69
+ Primer::Octicon::Cache.preload!
45
70
  end
46
71
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use popovers to bring attention to specific user interface elements, typically to suggest an action or to guide users through a new experience.
4
+ # Use `Popover` to bring attention to specific user interface elements, typically to suggest an action or to guide users through a new experience.
5
5
  #
6
6
  # By default, the popover renders with absolute positioning, meaning it should usually be wrapped in an element with a relative position in order to be positioned properly. To render the popover with relative positioning, use the relative property.
7
7
  class PopoverComponent < Primer::Component
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use ProgressBar to visualize task completion.
4
+ # Use `ProgressBar` to visualize task completion.
5
5
  class ProgressBarComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Use Primer::SpinnerComponent to let users know that content is being loaded.
4
+ # Use `Spinner` to let users know that content is being loaded.
5
5
  class SpinnerComponent < Primer::Component
6
6
  status :beta
7
7
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- # Component for rendering the status of an item.
4
+ # Use `State` for rendering the status of an item.
5
5
  class StateComponent < Primer::Component
6
6
  status :beta
7
7