openproject-primer_view_components 0.10.0 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +87 -0
  3. data/app/assets/javascripts/app/components/primer/primer.d.ts +1 -1
  4. data/app/assets/javascripts/primer_view_components.js +1 -1
  5. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  6. data/app/assets/styles/primer_view_components.css +1 -1
  7. data/app/assets/styles/primer_view_components.css.map +1 -1
  8. data/app/components/primer/alpha/action_menu/action_menu_element.js +2 -1
  9. data/app/components/primer/alpha/action_menu/action_menu_element.ts +2 -1
  10. data/app/components/primer/alpha/check_box_group.rb +2 -0
  11. data/app/components/primer/alpha/dialog/header.rb +12 -0
  12. data/app/components/primer/alpha/dialog.rb +1 -1
  13. data/app/components/primer/alpha/nav_list/divider.rb +2 -5
  14. data/app/components/primer/alpha/nav_list/group.rb +2 -98
  15. data/app/components/primer/alpha/nav_list/heading.rb +2 -27
  16. data/app/components/primer/alpha/nav_list/item.rb +2 -147
  17. data/app/components/primer/alpha/nav_list.rb +2 -205
  18. data/app/components/primer/alpha/overlay.css +1 -1
  19. data/app/components/primer/alpha/overlay.css.map +1 -1
  20. data/app/components/primer/alpha/overlay.pcss +1 -7
  21. data/app/components/primer/alpha/overlay.rb +6 -4
  22. data/app/components/primer/alpha/radio_button_group.rb +2 -0
  23. data/app/components/primer/alpha/text_field.css +1 -1
  24. data/app/components/primer/alpha/text_field.css.json +4 -1
  25. data/app/components/primer/alpha/text_field.css.map +1 -1
  26. data/app/components/primer/alpha/text_field.pcss +18 -3
  27. data/app/components/primer/alpha/tooltip.rb +3 -1
  28. data/app/components/primer/beta/button.css +1 -1
  29. data/app/components/primer/beta/button.css.json +2 -0
  30. data/app/components/primer/beta/button.css.map +1 -1
  31. data/app/components/primer/beta/button.pcss +11 -3
  32. data/app/components/primer/beta/icon_button.html.erb +1 -1
  33. data/app/components/primer/beta/icon_button.rb +8 -1
  34. data/app/components/primer/beta/link.css +1 -1
  35. data/app/components/primer/beta/link.css.json +1 -0
  36. data/app/components/primer/beta/link.css.map +1 -1
  37. data/app/components/primer/beta/link.pcss +5 -0
  38. data/app/components/primer/beta/link.rb +2 -2
  39. data/app/components/primer/beta/nav_list/divider.rb +14 -0
  40. data/app/components/primer/beta/nav_list/group.rb +107 -0
  41. data/app/components/primer/beta/nav_list/heading.rb +36 -0
  42. data/app/components/primer/beta/nav_list/item.rb +156 -0
  43. data/app/components/primer/beta/nav_list.rb +212 -0
  44. data/app/components/primer/focus_group.js +2 -1
  45. data/app/components/primer/focus_group.ts +2 -1
  46. data/app/components/primer/open_project/border_grid/cell.html.erb +3 -0
  47. data/app/components/primer/open_project/border_grid/cell.rb +25 -0
  48. data/app/components/primer/open_project/border_grid.css +1 -0
  49. data/app/components/primer/open_project/border_grid.css.json +11 -0
  50. data/app/components/primer/open_project/border_grid.css.map +1 -0
  51. data/app/components/primer/open_project/border_grid.html.erb +7 -0
  52. data/app/components/primer/open_project/border_grid.pcss +35 -0
  53. data/app/components/primer/open_project/border_grid.rb +36 -0
  54. data/app/components/primer/open_project/drag_handle.css +1 -0
  55. data/app/components/primer/open_project/drag_handle.css.json +6 -0
  56. data/app/components/primer/open_project/drag_handle.css.map +1 -0
  57. data/app/components/primer/open_project/drag_handle.html.erb +6 -0
  58. data/app/components/primer/open_project/drag_handle.pcss +6 -0
  59. data/app/components/primer/open_project/drag_handle.rb +28 -0
  60. data/app/components/primer/open_project/flex_layout.html.erb +23 -0
  61. data/app/components/primer/open_project/flex_layout.rb +52 -0
  62. data/app/components/primer/open_project/grid_layout/area.rb +38 -0
  63. data/app/components/primer/open_project/grid_layout.html.erb +11 -0
  64. data/app/components/primer/open_project/grid_layout.rb +34 -0
  65. data/app/components/primer/open_project/page_header.css +1 -1
  66. data/app/components/primer/open_project/page_header.css.map +1 -1
  67. data/app/components/primer/open_project/page_header.pcss +4 -0
  68. data/app/components/primer/primer.d.ts +1 -1
  69. data/app/components/primer/primer.js +1 -1
  70. data/app/components/primer/primer.pcss +2 -0
  71. data/app/components/primer/primer.ts +1 -1
  72. data/app/helpers/primer/form_helper.rb +10 -0
  73. data/lib/primer/deprecations.yml +20 -0
  74. data/lib/primer/forms/check_box_group.html.erb +3 -0
  75. data/lib/primer/forms/dsl/check_box_group_input.rb +1 -5
  76. data/lib/primer/forms/dsl/check_box_input.rb +5 -0
  77. data/lib/primer/forms/dsl/radio_button_input.rb +5 -0
  78. data/lib/primer/forms/form_control.html.erb +1 -4
  79. data/lib/primer/forms/radio_button_group.html.erb +3 -0
  80. data/lib/primer/forms/utils.rb +2 -0
  81. data/lib/primer/forms/validation_message.html.erb +4 -0
  82. data/lib/primer/forms/validation_message.rb +14 -0
  83. data/lib/primer/forms.rb +16 -0
  84. data/lib/primer/view_components/version.rb +2 -2
  85. data/lib/primer/yard/component_manifest.rb +4 -0
  86. data/previews/primer/alpha/check_box_group_preview.rb +13 -0
  87. data/previews/primer/alpha/dialog_preview/with_header.html.erb +5 -0
  88. data/previews/primer/alpha/dialog_preview.rb +17 -0
  89. data/previews/primer/alpha/overlay_preview.rb +1 -1
  90. data/previews/primer/alpha/radio_button_group_preview.rb +13 -0
  91. data/previews/primer/alpha/radio_button_preview.rb +1 -1
  92. data/previews/primer/alpha/text_field_preview/input_group_leading_action_menu.html.erb +21 -0
  93. data/previews/primer/alpha/text_field_preview/input_group_leading_button.html.erb +18 -0
  94. data/previews/primer/alpha/text_field_preview/input_group_trailing_button.html.erb +18 -0
  95. data/previews/primer/alpha/text_field_preview.rb +21 -0
  96. data/previews/primer/beta/button_preview.rb +1 -1
  97. data/previews/primer/{alpha → beta}/nav_list_preview/trailing_action.html.erb +1 -1
  98. data/previews/primer/{alpha → beta}/nav_list_preview.rb +5 -5
  99. data/previews/primer/open_project/border_grid_preview.rb +42 -0
  100. data/previews/primer/open_project/drag_handle_preview.rb +23 -0
  101. data/previews/primer/open_project/flex_layout_preview.rb +73 -0
  102. data/previews/primer/open_project/grid_layout_preview.rb +37 -0
  103. data/static/arguments.json +314 -6
  104. data/static/audited_at.json +11 -0
  105. data/static/classes.json +18 -0
  106. data/static/constants.json +48 -0
  107. data/static/info_arch.json +1867 -955
  108. data/static/previews.json +273 -7
  109. data/static/statuses.json +16 -5
  110. metadata +46 -11
  111. /data/app/assets/javascripts/app/components/primer/{alpha → beta}/nav_list.d.ts +0 -0
  112. /data/app/components/primer/{alpha → beta}/nav_list/group.html.erb +0 -0
  113. /data/app/components/primer/{alpha → beta}/nav_list/item.html.erb +0 -0
  114. /data/app/components/primer/{alpha → beta}/nav_list.d.ts +0 -0
  115. /data/app/components/primer/{alpha → beta}/nav_list.html.erb +0 -0
  116. /data/app/components/primer/{alpha → beta}/nav_list.js +0 -0
  117. /data/app/components/primer/{alpha → beta}/nav_list.ts +0 -0
@@ -18,7 +18,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
18
18
  var _ActionMenuElement_instances, _ActionMenuElement_abortController, _ActionMenuElement_originalLabel, _ActionMenuElement_inputName, _ActionMenuElement_setDynamicLabel, _ActionMenuElement_updateInput, _ActionMenuElement_isActivationKeydown, _ActionMenuElement_firstItem_get;
19
19
  import { controller, target } from '@github/catalyst';
20
20
  import '@oddbird/popover-polyfill';
21
- const menuItemSelectors = ['[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]'];
21
+ const validSelectors = ['[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]'];
22
+ const menuItemSelectors = validSelectors.map(selector => `:not([hidden]) > ${selector}`);
22
23
  let ActionMenuElement = class ActionMenuElement extends HTMLElement {
23
24
  constructor() {
24
25
  super(...arguments);
@@ -9,7 +9,8 @@ type SelectedItem = {
9
9
  element: Element
10
10
  }
11
11
 
12
- const menuItemSelectors = ['[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]']
12
+ const validSelectors = ['[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]']
13
+ const menuItemSelectors = validSelectors.map(selector => `:not([hidden]) > ${selector}`)
13
14
 
14
15
  @controller
15
16
  export class ActionMenuElement extends HTMLElement {
@@ -23,6 +23,8 @@ module Primer
23
23
  # @param label [String] Label text displayed above the input.
24
24
  # @param hidden [Boolean] When set to `true`, visually hides the group.
25
25
  # @param caption [String] A string describing the field and what sorts of input it expects. Displayed below the group.
26
+ # @param invalid [Boolean] If set to `true`, the input will be marked as invalid. Implied if `validation_message` is truthy. This option is set to `true` automatically if the model object associated with the form reports that the input is invalid via Rails validations. It is provided for cases where the form does not have an associated model. If the input is invalid as determined by Rails validations, setting `invalid` to `false` will have no effect.
27
+ # @param validation_message [String] A string displayed between the caption and the input indicating the input's contents are invalid. This option is, by default, set to the first Rails validation message for the input (assuming the form is associated with a model object). Use `validation_message` to override the default or to provide a validation message in case there is no associated model object.
26
28
  # @param label_arguments [Hash] Attributes that will be passed to Rails' `builder.label` method. These can be HTML attributes or any of the other label options Rails supports. They will appear as HTML attributes on the `<label>` tag.
27
29
 
28
30
  # @!method check_box
@@ -9,10 +9,19 @@ module Primer
9
9
  status :alpha
10
10
  audited_at "2022-10-10"
11
11
 
12
+ DEFAULT_VARIANT = :medium
13
+ VARIANT_MAPPINGS = {
14
+ DEFAULT_VARIANT => "",
15
+ :large => "Overlay-header--large"
16
+ }.freeze
17
+ VARIANT_OPTIONS = VARIANT_MAPPINGS.keys
18
+
19
+ # @param id [String] The HTML element's ID value.
12
20
  # @param title [String] Describes the content of the dialog.
13
21
  # @param subtitle [String] Provides dditional context for the dialog, also setting the `aria-describedby` attribute.
14
22
  # @param show_divider [Boolean] Show a divider between the header and body.
15
23
  # @param visually_hide_title [Boolean] Visually hide the `title` while maintaining a label for assistive technologies.
24
+ # @param variant [Symbol] <%= one_of(Primer::Alpha::Dialog::Header::VARIANT_OPTIONS) %>
16
25
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
17
26
  def initialize(
18
27
  id:,
@@ -20,6 +29,7 @@ module Primer
20
29
  subtitle: nil,
21
30
  show_divider: false,
22
31
  visually_hide_title: false,
32
+ variant: DEFAULT_VARIANT,
23
33
  **system_arguments
24
34
  )
25
35
  @id = id
@@ -28,8 +38,10 @@ module Primer
28
38
  @visually_hide_title = visually_hide_title
29
39
  @system_arguments = deny_tag_argument(**system_arguments)
30
40
  @system_arguments[:tag] = :div
41
+
31
42
  @system_arguments[:classes] = class_names(
32
43
  "Overlay-header",
44
+ VARIANT_MAPPINGS[fetch_or_fallback(VARIANT_OPTIONS, variant, DEFAULT_VARIANT)],
33
45
  { "Overlay-header--divided": show_divider },
34
46
  system_arguments[:classes]
35
47
  )
@@ -74,7 +74,7 @@ module Primer
74
74
  #
75
75
  # @param show_divider [Boolean] Show a divider between the header and body.
76
76
  # @param visually_hide_title [Boolean] Visually hide the `title` while maintaining a label for assistive technologies.
77
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
77
+ # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::Dialog::Header) %>.
78
78
  renders_one :header, lambda { |show_divider: false, visually_hide_title: @visually_hide_title, **system_arguments|
79
79
  Primer::Alpha::Dialog::Header.new(
80
80
  id: @id,
@@ -3,11 +3,8 @@
3
3
  module Primer
4
4
  module Alpha
5
5
  class NavList
6
- # Separator with optional text rendered above groups or between individual items.
7
- class Divider < Primer::Alpha::ActionList::Divider
8
- def kind
9
- :divider
10
- end
6
+ class Divider < Beta::NavList::Divider
7
+ status :deprecated
11
8
  end
12
9
  end
13
10
  end
@@ -3,104 +3,8 @@
3
3
  module Primer
4
4
  module Alpha
5
5
  class NavList
6
- # A logical grouping of navigation links with an optional heading.
7
- #
8
- # See <%= link_to_component(Primer::Alpha::NavList) %> for usage examples.
9
- class Group < ActionList
10
- # A special "show more" list item that appears at the bottom of the group. Clicking
11
- # the item will fetch the next page of results from the URL passed in the `src` argument
12
- # and append the resulting chunk of HTML to the group.
13
- #
14
- # @param src [String] The URL to query for additional pages of list items.
15
- # @param pages [Integer] The total number of pages in the result set.
16
- # @param component_klass [Class] A component class to use instead of the default `Primer::Alpha::NavList::Item` class.
17
- # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Item) %>.
18
- renders_one :show_more_item, lambda { |src:, pages:, component_klass: NavList::Item, **system_arguments|
19
- system_arguments[:classes] = class_names(
20
- @item_classes,
21
- system_arguments[:classes]
22
- )
23
- system_arguments[:tag] = :div
24
- system_arguments[:id] ||= self.class.generate_id(base_name: "item")
25
- system_arguments[:hidden] = true
26
- system_arguments[:href] = "#"
27
- system_arguments[:data] ||= {}
28
- system_arguments[:data][:target] = "nav-list.showMoreItem"
29
- system_arguments[:data][:action] = "click:nav-list#showMore"
30
- system_arguments[:data][:current_page] = "1"
31
- system_arguments[:data][:total_pages] = pages.to_s
32
- system_arguments[:label_arguments] = {
33
- **system_arguments[:label_arguments] || {},
34
- color: :accent
35
- }
36
-
37
- system_arguments[:content_arguments] = {
38
- **system_arguments[:content_arguments] || {},
39
- tag: :button
40
- }
41
-
42
- system_arguments[:content_arguments][:data] = merge_data(
43
- system_arguments[:content_arguments],
44
- data: { list_id: id }
45
- )
46
-
47
- component_klass.new(list: self, src: src, **system_arguments)
48
- }
49
-
50
- # @private
51
- def self.custom_element_name
52
- Primer::Alpha::NavList.custom_element_name
53
- end
54
-
55
- # @param selected_item_id [Symbol] The ID of the currently selected item. Used internally.
56
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
57
- def initialize(selected_item_id: nil, **system_arguments)
58
- @system_arguments = system_arguments
59
- @selected_item_id = selected_item_id
60
-
61
- super(**@system_arguments)
62
- end
63
-
64
- # Cause this group to show its list of sub items when rendered.
65
- # :nocov:
66
- def expand!
67
- @expanded = true
68
- end
69
- # :nocov:
70
-
71
- # @!parse
72
- # # Items.
73
- # #
74
- # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Item) %>.
75
- # renders_many :items
76
-
77
- # @private
78
- def build_item(component_klass: NavList::Item, **system_arguments)
79
- super(
80
- component_klass: component_klass,
81
- selected_item_id: @selected_item_id,
82
- **system_arguments
83
- )
84
- end
85
-
86
- # @private
87
- def build_avatar_item(component_klass: NavList::Item, **system_arguments)
88
- super(
89
- component_klass: component_klass,
90
- selected_item_id: @selected_item_id,
91
- **system_arguments
92
- )
93
- end
94
-
95
- def kind
96
- :group
97
- end
98
-
99
- def before_render
100
- super
101
-
102
- raise ArgumentError, "NavList groups are required to have headings" unless heading?
103
- end
6
+ class Group < Beta::NavList::Group
7
+ status :deprecated
104
8
  end
105
9
  end
106
10
  end
@@ -3,33 +3,8 @@
3
3
  module Primer
4
4
  module Alpha
5
5
  class NavList
6
- # The heading placed above a `NavList`'s items.
7
- #
8
- # See <%= link_to_component(Primer::Alpha::NavList) %> for usage examples.
9
- class Heading < Primer::Component
10
- attr_reader :title, :id, :heading_level, :system_arguments
11
-
12
- # @param title [String] The text content of the heading.
13
- # @param id [String] The value of the ID HTML attribute. Auto-generated by default.
14
- # @param heading_level [Integer] The heading level, i.e. 2 for an `<h2>`, 3 for an `<h3>`, etc.
15
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
16
- def initialize(title:, id: self.class.generate_id, heading_level: 2, **system_arguments)
17
- @title = title
18
- @id = id
19
- @heading_level = heading_level
20
- @system_arguments = system_arguments
21
- end
22
-
23
- def call
24
- render(
25
- Primer::BaseComponent.new(
26
- tag: :"h#{heading_level}",
27
- id: id,
28
- classes: "ActionListHeader",
29
- **system_arguments
30
- ).with_content(title)
31
- )
32
- end
6
+ class Heading < Beta::NavList::Heading
7
+ status :deprecated
33
8
  end
34
9
  end
35
10
  end
@@ -3,153 +3,8 @@
3
3
  module Primer
4
4
  module Alpha
5
5
  class NavList
6
- # Items are rendered as styled links. They can optionally include leading and/or trailing visuals,
7
- # such as icons, avatars, and counters. Items are selected by ID. IDs can be specified via the
8
- # `selected_item_ids` argument, which accepts a list of valid IDs for the item. Items can also
9
- # themselves contain sub items. Sub items are rendered collapsed by default.
10
- class Item < Primer::Alpha::ActionList::Item
11
- attr_reader :selected_by_ids, :sub_item
12
-
13
- # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::ActionList::Item) %>.
14
- renders_many :items, lambda { |**system_arguments|
15
- raise "Items can only be nested 2 levels deep" if sub_item?
16
-
17
- @list.build_item(parent: self, sub_item: true, **system_arguments).tap do |item|
18
- @list.will_add_item(item)
19
- end
20
- }
21
-
22
- # Whether or not this item is nested under a parent item.
23
- #
24
- # @return [Boolean]
25
- alias sub_item? sub_item
26
-
27
- # @param selected_item_id [Symbol] The ID of the currently selected list item. Used internally.
28
- # @param selected_by_ids [Array<Symbol>] The list of IDs that select this item. In other words, if the `selected_item_id` attribute on the parent `NavList` is set to one of these IDs, the item will appear selected.
29
- # @param expanded [Boolean] Whether this item shows (expands) or hides (collapses) its list of sub items.
30
- # @param sub_item [Boolean] Whether or not this item is nested under a parent item. Used internally.
31
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
32
- def initialize(selected_item_id: nil, selected_by_ids: [], sub_item: false, expanded: false, **system_arguments)
33
- @selected_item_id = selected_item_id
34
- @selected_by_ids = Array(selected_by_ids)
35
- @expanded = expanded
36
- @sub_item = sub_item
37
-
38
- system_arguments[:classes] = class_names(
39
- system_arguments[:classes],
40
- "ActionListItem--subItem" => @sub_item
41
- )
42
-
43
- @sub_list_arguments = {
44
- classes: class_names(
45
- "ActionList",
46
- "ActionList--subGroup"
47
- )
48
- }
49
-
50
- @list = system_arguments[:list]
51
-
52
- @sub_list_arguments["data-action"] = "keydown:#{@list.custom_element_name}#handleItemWithSubItemKeydown" if @list
53
-
54
- overrides = { "data-item-id": @selected_by_ids.join(" ") }
55
-
56
- super(**system_arguments, **overrides)
57
- end
58
-
59
- def active?
60
- item_active?(self) && items.empty?
61
- end
62
-
63
- # Cause this item to show its list of sub items when rendered.
64
- def expand!
65
- @expanded = true
66
- end
67
-
68
- def before_render
69
- if active_sub_item?
70
- expand!
71
-
72
- @content_arguments[:classes] = class_names(
73
- @content_arguments[:classes],
74
- "ActionListContent--hasActiveSubItem"
75
- )
76
- else
77
- @system_arguments[:classes] = class_names(
78
- @system_arguments[:classes],
79
- "ActionListItem--navActive" => active?
80
- )
81
- end
82
-
83
- @content_arguments[:"aria-current"] = "page" if active?
84
-
85
- super
86
-
87
- raise "Cannot render a trailing action for an item with subitems" if items.present? && trailing_action.present?
88
-
89
- raise "Cannot pass `selected_by_ids:` for an item with subitems, since parent items cannot be selected" if items.present? && @selected_by_ids.present?
90
-
91
- return if items.blank?
92
-
93
- @sub_list_arguments[:aria] = merge_aria(
94
- @sub_list_arguments,
95
- { aria: { labelledby: id } }
96
- )
97
-
98
- raise ArgumentError, "Items with sub-items cannot have hrefs" if href.present?
99
-
100
- @content_arguments[:tag] = :button
101
- @content_arguments[:"aria-expanded"] = @expanded.to_s
102
- @content_arguments[:"data-action"] = "
103
- click:#{@list.custom_element_name}#handleItemWithSubItemClick
104
- keydown:#{@list.custom_element_name}#handleItemWithSubItemKeydown
105
- "
106
-
107
- with_private_trailing_action_icon(:"chevron-down", classes: "ActionListItem-collapseIcon")
108
-
109
- @system_arguments[:classes] = class_names(
110
- @system_arguments[:classes],
111
- "ActionListItem--hasSubItem"
112
- )
113
- end
114
-
115
- def kind
116
- :item
117
- end
118
-
119
- private
120
-
121
- # Normally it would be easier to simply ask each item for its active status, eg.
122
- # items.any?(&:active?), but unfortunately the view context is not set on each
123
- # item until _after_ the parent's before_render, etc methods have been called.
124
- # This means helper methods like current_page? will blow up with an error, since
125
- # `helpers` is simply an alias for the view context (i.e. an instance of
126
- # ActionView::Base). Since we know the view context for the parent object must
127
- # be set before `before_render` is invoked, we can call helper methods here in
128
- # the parent and bypass the problem entirely. Maybe not the most OO approach,
129
- # but it works.
130
- def item_active?(item)
131
- if item.selected_by_ids.present?
132
- item.selected_by_ids.include?(@selected_item_id)
133
- elsif item.href
134
- current_page?(item.href)
135
- else
136
- # :nocov:
137
- false
138
- # :nocov:
139
- end
140
- end
141
-
142
- def active_sub_item?
143
- items.any? { |subitem| item_active?(subitem) }
144
- end
145
-
146
- def current_page?(url)
147
- helpers.current_page?(url)
148
- end
149
-
150
- def list_class
151
- Primer::Alpha::NavList
152
- end
6
+ class Item < Beta::NavList::Item
7
+ status :deprecated
153
8
  end
154
9
  end
155
10
  end
@@ -2,211 +2,8 @@
2
2
 
3
3
  module Primer
4
4
  module Alpha
5
- # `NavList` provides a simple way to render side navigation, i.e. navigation
6
- # that appears to the left or right side of some main content. Each group in a
7
- # nav list is a list of links.
8
- #
9
- # Nav list groups can contain sub items. Rather than navigating to a URL, groups
10
- # with sub items expand and collapse on click. To indicate this functionality, the
11
- # group will automatically render with a trailing chevron icon that changes direction
12
- # when the group expands and collapses.
13
- #
14
- # Nav list items appear visually active when selected. Each nav item must have one
15
- # or more ID values that determine which item will appear selected. Use the
16
- # `selected_item_id` argument to select the appropriate item.
17
- class NavList < Primer::Component
18
- status :alpha
19
- audited_at "2023-07-10"
20
-
21
- # @private
22
- def self.custom_element_name
23
- "nav-list"
24
- end
25
-
26
- # The heading for the list at large. Accepts the arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Heading) %>.
27
- #
28
- renders_one :heading, Primer::Alpha::NavList::Heading
29
-
30
- # @!parse
31
- # # Adds an item to the list.
32
- # #
33
- # # @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::Alpha::NavList::Item) %>
34
- # # @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::NavList::Item) %>, or whatever class is passed as the `component_klass` argument.
35
- # def with_item(component_klass: Primer::Alpha::NavList::Item, **system_arguments, &block)
36
- # end
37
-
38
- # @!parse
39
- # # Adds an avatar item to the list. Avatar items are a convenient way to accessibly add an item with a leading avatar image.
40
- # #
41
- # # @param src [String] The source url of the avatar image.
42
- # # @param username [String] The username associated with the avatar.
43
- # # @param full_name [String] Optional. The user's full name.
44
- # # @param full_name_scheme [Symbol] Optional. How to display the user's full name. <%= one_of(Primer::Alpha::ActionList::Item::DESCRIPTION_SCHEME_OPTIONS) %>
45
- # # @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::Alpha::NavList::Item) %>
46
- # # @param avatar_arguments [Hash] Optional. The arguments accepted by <%= link_to_component(Primer::Beta::Avatar) %>
47
- # # @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::NavList::Item) %>, or whatever class is passed as the `component_klass` argument.
48
- # def with_avatar_item(src:, username:, full_name: nil, full_name_scheme: Primer::Alpha::ActionList::Item::DEFAULT_DESCRIPTION_SCHEME, component_klass: Primer::Alpha::NavList::Item, avatar_arguments: {}, **system_arguments, &block)
49
- # end
50
-
51
- # @!parse
52
- # # Adds a group to the list. A group is a list of links and a (required) heading.
53
- # #
54
- # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Group) %>.
55
- # def with_group(**system_arguments, &block)
56
- # end
57
-
58
- # @!parse
59
- # # Adds a divider to the list. Dividers visually separate items and groups.
60
- # #
61
- # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Divider) %>.
62
- # def with_divider(**system_arguments, &block)
63
- # end
64
-
65
- # Items. Items can be individual items, dividers, or groups. See the documentation for `#with_item`, `#with_divider`, and `#with_group` respectively for more information.
66
- #
67
- renders_many :items, types: {
68
- item: {
69
- renders: lambda { |**system_arguments, &block|
70
- build_item(**system_arguments, &block)
71
- },
72
-
73
- as: :item
74
- },
75
-
76
- avatar_item: {
77
- renders: lambda { |**system_arguments|
78
- build_avatar_item(**system_arguments)
79
- },
80
-
81
- as: :avatar_item
82
- },
83
-
84
- divider: {
85
- renders: Primer::Alpha::NavList::Divider,
86
- as: :divider
87
- },
88
-
89
- group: {
90
- renders: lambda { |**system_arguments, &block|
91
- Primer::Alpha::NavList::Group.new(
92
- selected_item_id: @selected_item_id,
93
- **system_arguments,
94
- &block
95
- )
96
- },
97
-
98
- as: :group
99
- }
100
- }
101
-
102
- # @param selected_item_id [Symbol] The ID of the currently selected item. The default is `nil`, meaning no item is selected.
103
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
104
- def initialize(selected_item_id: nil, **system_arguments)
105
- @system_arguments = system_arguments
106
- @selected_item_id = selected_item_id
107
- end
108
-
109
- # Builds a new item but does not add it to the list. Use this method
110
- # instead of the `#with_item` slot if you need to render an item outside
111
- # the context of a list, eg. if rendering additional items to append to
112
- # an existing list, perhaps via a separate HTTP request.
113
- #
114
- # @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::Alpha::NavList::Item) %>
115
- # @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::NavList::Item) %>, or whatever class is passed as the `component_klass` argument.
116
- def build_item(component_klass: Primer::Alpha::NavList::Item, **system_arguments, &block)
117
- component_klass.new(
118
- list: top_level_group,
119
- selected_item_id: @selected_item_id,
120
- **system_arguments,
121
- &block
122
- )
123
- end
124
-
125
- # Builds a new avatar item but does not add it to the list. Avatar items
126
- # are a convenient way to accessibly add an item with a leading avatar
127
- # image. Use this method instead of the `#with_avatar_item` slot if you
128
- # need to render an avatar item outside the context of a list, eg. if
129
- # rendering additional items to append to an existing list, perhaps via
130
- # a separate HTTP request.
131
- #
132
- # @param src [String] The source url of the avatar image.
133
- # @param username [String] The username associated with the avatar.
134
- # @param full_name [String] Optional. The user's full name.
135
- # @param full_name_scheme [Symbol] Optional. How to display the user's full name. <%= one_of(Primer::Alpha::ActionList::Item::DESCRIPTION_SCHEME_OPTIONS) %>
136
- # @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::Alpha::NavList::Item) %>
137
- # @param avatar_arguments [Hash] Optional. The arguments accepted by <%= link_to_component(Primer::Beta::Avatar) %>
138
- # @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::NavList::Item) %>, or whatever class is passed as the `component_klass` argument.
139
- def build_avatar_item(src:, username:, full_name: nil, full_name_scheme: Primer::Alpha::ActionList::Item::DEFAULT_DESCRIPTION_SCHEME, component_klass: Primer::Alpha::NavList::Item, avatar_arguments: {}, **system_arguments)
140
- component_klass.new(
141
- list: top_level_group,
142
- selected_item_id: @selected_item_id,
143
- label: username,
144
- description_scheme: full_name_scheme,
145
- **system_arguments
146
- ).tap do |item|
147
- item.with_leading_visual_raw_content do
148
- # no alt text necessary
149
- item.render(Primer::Beta::Avatar.new(src: src, **avatar_arguments, role: :presentation, size: 16))
150
- end
151
-
152
- item.with_description_content(full_name) if full_name
153
- end
154
- end
155
-
156
- private
157
-
158
- def before_render
159
- if heading?
160
- raise ArgumentError, "Please don't set an aria-label if a heading is provided" if aria(:label, @system_arguments)
161
-
162
- @system_arguments[:aria] = merge_aria(
163
- @system_arguments,
164
- { aria: { labelledby: heading.id } }
165
- )
166
- else
167
- raise ArgumentError, "When no heading is provided, an aria-label must be given" unless aria(:label, @system_arguments)
168
- end
169
- end
170
-
171
- # Lists that contain top-level items (i.e. items outside of a group) should be wrapped in a <ul>
172
- def render_outer_list?
173
- items.any? { |item| !group?(item) }
174
- end
175
-
176
- def render_divider_between?(item1, item2)
177
- return false if either_is_divider?(item1, item2)
178
-
179
- both_are_groups?(item1, item2) || heterogeneous?(item1, item2)
180
- end
181
-
182
- def both_are_groups?(item1, item2)
183
- group?(item1) && group?(item2)
184
- end
185
-
186
- def heterogeneous?(item1, item2)
187
- kind(item1) != kind(item2)
188
- end
189
-
190
- def either_is_divider?(item1, item2)
191
- divider?(item1) || divider?(item2)
192
- end
193
-
194
- def group?(item)
195
- kind(item) == :group
196
- end
197
-
198
- def divider?(item)
199
- kind(item) == :divider
200
- end
201
-
202
- def kind(item)
203
- item.respond_to?(:kind) ? item.kind : :item
204
- end
205
-
206
- def top_level_group
207
- # dummy group for the list: argument in the item slot above
208
- @top_level_group ||= Primer::Alpha::NavList::Group.new(selected_item_id: @selected_item_id)
209
- end
5
+ class NavList < Beta::NavList
6
+ status :deprecated
210
7
  end
211
8
  end
212
9
  end
@@ -1 +1 @@
1
- anchored-position[popover]{border-width:0;inset:auto;min-width:192px;overflow:visible;padding:0;position:absolute}.Overlay{display:flex}anchored-position[popover]:not(.\:popover-open){display:none}anchored-position.not-anchored::-webkit-backdrop{background-color:var(--overlay-backdrop-bgColor,var(--color-neutral-muted))}anchored-position.not-anchored::backdrop{background-color:var(--overlay-backdrop-bgColor,var(--color-neutral-muted))}@supports selector(:popover-open){anchored-position[popover]:not(.\:popover-open){display:revert}}@supports selector(:open){anchored-position[popover]:not(.\:popover-open){display:revert}}
1
+ anchored-position[popover]{background:none;border-width:0;inset:auto;min-width:192px;overflow:visible;padding:0;position:absolute}.Overlay{display:flex}anchored-position[popover]:not(.\:popover-open){display:none}anchored-position.not-anchored::-webkit-backdrop{background-color:var(--overlay-backdrop-bgColor,var(--color-neutral-muted))}anchored-position.not-anchored::backdrop{background-color:var(--overlay-backdrop-bgColor,var(--color-neutral-muted))}@supports selector(:popover-open){anchored-position[popover]:not(.\:popover-open){display:revert}}
@@ -1 +1 @@
1
- {"version":3,"sources":["overlay.pcss"],"names":[],"mappings":"AAAA,2BACE,cAAe,CAIf,UAAW,CADX,eAAgB,CAEhB,gBAAiB,CAJjB,SAAU,CACV,iBAIF,CAEA,SACE,YACF,CAEA,gDACE,YACF,CAEA,iDACE,2EACF,CAFA,yCACE,2EACF,CAGA,kCACE,gDACE,cACF,CACF,CAGA,0BACE,gDACI,cACJ,CACF","file":"overlay.css","sourcesContent":["anchored-position[popover] {\n border-width: 0;\n padding: 0;\n position: absolute;\n min-width: 192px;\n inset: auto;\n overflow: visible;\n}\n\n.Overlay {\n display: flex;\n}\n\nanchored-position[popover]:not(.\\:popover-open) {\n display: none;\n}\n\nanchored-position.not-anchored::backdrop {\n background-color: var(--overlay-backdrop-bgColor, var(--color-neutral-muted));\n}\n\n/* This reverts the declaration above for native popover, where `:popover-open` is supported */\n@supports selector(:popover-open) {\n anchored-position[popover]:not(.\\:popover-open) {\n display: revert;\n }\n}\n\n/* This reverts the declaration above for native popover, where `:open` is supported (Chrome 113, Safari TP) */\n@supports selector(:open) {\n anchored-position[popover]:not(.\\:popover-open) {\n display: revert;\n }\n}\n"]}
1
+ {"version":3,"sources":["overlay.pcss"],"names":[],"mappings":"AAAA,2BAOE,eAAgB,CANhB,cAAe,CAIf,UAAW,CADX,eAAgB,CAEhB,gBAAiB,CAJjB,SAAU,CACV,iBAKF,CAEA,SACE,YACF,CAEA,gDACE,YACF,CAEA,iDACE,2EACF,CAFA,yCACE,2EACF,CAGA,kCACE,gDACE,cACF,CACF","file":"overlay.css","sourcesContent":["anchored-position[popover] {\n border-width: 0;\n padding: 0;\n position: absolute;\n min-width: 192px;\n inset: auto;\n overflow: visible;\n background: none;\n}\n\n.Overlay {\n display: flex;\n}\n\nanchored-position[popover]:not(.\\:popover-open) {\n display: none;\n}\n\nanchored-position.not-anchored::backdrop {\n background-color: var(--overlay-backdrop-bgColor, var(--color-neutral-muted));\n}\n\n/* This reverts the declaration above for native popover, where `:popover-open` is supported */\n@supports selector(:popover-open) {\n anchored-position[popover]:not(.\\:popover-open) {\n display: revert;\n }\n}\n"]}
@@ -5,6 +5,7 @@ anchored-position[popover] {
5
5
  min-width: 192px;
6
6
  inset: auto;
7
7
  overflow: visible;
8
+ background: none;
8
9
  }
9
10
 
10
11
  .Overlay {
@@ -25,10 +26,3 @@ anchored-position.not-anchored::backdrop {
25
26
  display: revert;
26
27
  }
27
28
  }
28
-
29
- /* This reverts the declaration above for native popover, where `:open` is supported (Chrome 113, Safari TP) */
30
- @supports selector(:open) {
31
- anchored-position[popover]:not(.\:popover-open) {
32
- display: revert;
33
- }
34
- }
@@ -178,10 +178,12 @@ module Primer
178
178
  end
179
179
 
180
180
  def before_render
181
- if header?
182
- @system_arguments[:aria][:labelledby] ||= title_id
183
- else
184
- @system_arguments[:aria][:label] = @title
181
+ if @system_arguments[:role].present?
182
+ if header?
183
+ @system_arguments[:aria][:labelledby] ||= title_id
184
+ else
185
+ @system_arguments[:aria][:label] = @title
186
+ end
185
187
  end
186
188
  with_body unless body?
187
189
  end
@@ -23,6 +23,8 @@ module Primer
23
23
  # @param label [String] Label text displayed above the input.
24
24
  # @param hidden [Boolean] When set to `true`, visually hides the group.
25
25
  # @param caption [String] A string describing the field and what sorts of input it expects. Displayed below the group.
26
+ # @param invalid [Boolean] If set to `true`, the input will be marked as invalid. Implied if `validation_message` is truthy. This option is set to `true` automatically if the model object associated with the form reports that the input is invalid via Rails validations. It is provided for cases where the form does not have an associated model. If the input is invalid as determined by Rails validations, setting `invalid` to `false` will have no effect.
27
+ # @param validation_message [String] A string displayed between the caption and the input indicating the input's contents are invalid. This option is, by default, set to the first Rails validation message for the input (assuming the form is associated with a model object). Use `validation_message` to override the default or to provide a validation message in case there is no associated model object.
26
28
  # @param label_arguments [Hash] Attributes that will be passed to Rails' `builder.label` method. These can be HTML attributes or any of the other label options Rails supports. They will appear as HTML attributes on the `<label>` tag.
27
29
 
28
30
  # @!method radio_button