primer_view_components 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  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/assets/styles/primer_view_components.css +3 -3
  6. data/app/assets/styles/primer_view_components.css.map +1 -1
  7. data/app/components/primer/alpha/action_list/form_wrapper.html.erb +10 -0
  8. data/app/components/primer/alpha/action_list/form_wrapper.rb +61 -0
  9. data/app/components/primer/alpha/action_list/item.html.erb +41 -36
  10. data/app/components/primer/alpha/action_list/item.rb +16 -2
  11. data/app/components/primer/alpha/action_list.css +1 -1
  12. data/app/components/primer/alpha/action_list.css.map +1 -1
  13. data/app/components/primer/alpha/action_list.html.erb +5 -0
  14. data/app/components/primer/alpha/action_list.pcss +37 -37
  15. data/app/components/primer/alpha/action_list.rb +17 -0
  16. data/app/components/primer/alpha/action_menu/action_menu_element.d.ts +7 -1
  17. data/app/components/primer/alpha/action_menu/action_menu_element.js +55 -3
  18. data/app/components/primer/alpha/action_menu/action_menu_element.ts +70 -2
  19. data/app/components/primer/alpha/action_menu/list.rb +9 -11
  20. data/app/components/primer/alpha/action_menu.rb +50 -12
  21. data/app/components/primer/alpha/auto_complete.css +1 -1
  22. data/app/components/primer/alpha/auto_complete.css.map +1 -1
  23. data/app/components/primer/alpha/auto_complete.pcss +2 -2
  24. data/app/components/primer/alpha/banner.css +1 -1
  25. data/app/components/primer/alpha/banner.css.map +1 -1
  26. data/app/components/primer/alpha/banner.pcss +7 -7
  27. data/app/components/primer/alpha/dialog.css +1 -1
  28. data/app/components/primer/alpha/dialog.css.map +1 -1
  29. data/app/components/primer/alpha/dialog.pcss +33 -32
  30. data/app/components/primer/alpha/dropdown.css +1 -1
  31. data/app/components/primer/alpha/dropdown.css.map +1 -1
  32. data/app/components/primer/alpha/dropdown.pcss +12 -11
  33. data/app/components/primer/alpha/layout.css +1 -1
  34. data/app/components/primer/alpha/layout.css.map +1 -1
  35. data/app/components/primer/alpha/layout.pcss +4 -4
  36. data/app/components/primer/alpha/menu.css +1 -1
  37. data/app/components/primer/alpha/menu.css.map +1 -1
  38. data/app/components/primer/alpha/menu.pcss +20 -20
  39. data/app/components/primer/alpha/segmented_control.css +1 -1
  40. data/app/components/primer/alpha/segmented_control.css.map +1 -1
  41. data/app/components/primer/alpha/segmented_control.pcss +27 -38
  42. data/app/components/primer/alpha/tab_nav.css +1 -1
  43. data/app/components/primer/alpha/tab_nav.css.map +1 -1
  44. data/app/components/primer/alpha/tab_nav.pcss +12 -12
  45. data/app/components/primer/alpha/text_field.css +3 -3
  46. data/app/components/primer/alpha/text_field.css.map +1 -1
  47. data/app/components/primer/alpha/text_field.pcss +74 -88
  48. data/app/components/primer/alpha/toggle_switch.css +1 -1
  49. data/app/components/primer/alpha/toggle_switch.css.map +1 -1
  50. data/app/components/primer/alpha/toggle_switch.pcss +9 -9
  51. data/app/components/primer/alpha/underline_nav.css +1 -1
  52. data/app/components/primer/alpha/underline_nav.css.map +1 -1
  53. data/app/components/primer/alpha/underline_nav.pcss +7 -7
  54. data/app/components/primer/beta/auto_complete/item.html.erb +9 -9
  55. data/app/components/primer/beta/auto_complete/item.rb +17 -13
  56. data/app/components/primer/beta/auto_complete.rb +1 -1
  57. data/app/components/primer/beta/avatar.css +1 -1
  58. data/app/components/primer/beta/avatar.css.map +1 -1
  59. data/app/components/primer/beta/avatar.pcss +2 -2
  60. data/app/components/primer/beta/avatar_stack.css +1 -1
  61. data/app/components/primer/beta/avatar_stack.css.map +1 -1
  62. data/app/components/primer/beta/avatar_stack.pcss +5 -5
  63. data/app/components/primer/beta/blankslate.css +1 -1
  64. data/app/components/primer/beta/blankslate.css.map +1 -1
  65. data/app/components/primer/beta/blankslate.pcss +13 -13
  66. data/app/components/primer/beta/border_box.css +1 -1
  67. data/app/components/primer/beta/border_box.css.json +1 -1
  68. data/app/components/primer/beta/border_box.css.map +1 -1
  69. data/app/components/primer/beta/border_box.pcss +41 -39
  70. data/app/components/primer/beta/button.css +1 -1
  71. data/app/components/primer/beta/button.css.map +1 -1
  72. data/app/components/primer/beta/button.pcss +25 -25
  73. data/app/components/primer/beta/counter.css +1 -1
  74. data/app/components/primer/beta/counter.css.map +1 -1
  75. data/app/components/primer/beta/counter.pcss +3 -3
  76. data/app/components/primer/beta/flash.css +1 -1
  77. data/app/components/primer/beta/flash.css.map +1 -1
  78. data/app/components/primer/beta/flash.pcss +10 -11
  79. data/app/components/primer/beta/label.css +1 -1
  80. data/app/components/primer/beta/label.css.map +1 -1
  81. data/app/components/primer/beta/label.pcss +2 -2
  82. data/app/components/primer/beta/popover.css +1 -1
  83. data/app/components/primer/beta/popover.css.map +1 -1
  84. data/app/components/primer/beta/popover.pcss +4 -4
  85. data/app/components/primer/beta/state.css +1 -1
  86. data/app/components/primer/beta/state.css.map +1 -1
  87. data/app/components/primer/beta/state.pcss +5 -5
  88. data/app/components/primer/beta/subhead.css +1 -1
  89. data/app/components/primer/beta/subhead.css.map +1 -1
  90. data/app/components/primer/beta/subhead.pcss +4 -4
  91. data/app/components/primer/beta/timeline_item.css +1 -1
  92. data/app/components/primer/beta/timeline_item.css.map +1 -1
  93. data/app/components/primer/beta/timeline_item.pcss +13 -13
  94. data/app/components/primer/beta/truncate.css +1 -1
  95. data/app/components/primer/beta/truncate.css.map +1 -1
  96. data/app/components/primer/beta/truncate.pcss +1 -1
  97. data/lib/postcss_mixins/activeIndicatorLine.pcss +1 -1
  98. data/lib/primer/view_components/linters/disallow_component_css_counter.rb +1 -1
  99. data/lib/primer/view_components/version.rb +1 -1
  100. data/lib/primer/yard/component_manifest.rb +1 -0
  101. data/previews/primer/alpha/action_menu_preview/multiple_select_form.html.erb +13 -0
  102. data/previews/primer/alpha/action_menu_preview/single_select_form.html.erb +13 -0
  103. data/previews/primer/alpha/action_menu_preview/submitting_forms.html.erb +15 -0
  104. data/previews/primer/alpha/action_menu_preview.rb +46 -2
  105. data/static/arguments.json +37 -2
  106. data/static/audited_at.json +1 -0
  107. data/static/constants.json +18 -1
  108. data/static/info_arch.json +102 -17
  109. data/static/previews.json +20 -0
  110. data/static/statuses.json +1 -0
  111. metadata +7 -2
@@ -82,6 +82,7 @@ module Primer
82
82
  # @param scheme [Symbol] <%= one_of(Primer::Alpha::ActionList::SCHEME_OPTIONS) %> `inset` children are offset (vertically and horizontally) from list edges. `full` (default) children are flush (vertically and horizontally) with list edges.
83
83
  # @param show_dividers [Boolean] Display a divider above each item in the list when it does not follow a header or divider.
84
84
  # @param select_variant [Symbol] How items may be selected in the list. <%= one_of(Primer::Alpha::ActionList::SELECT_VARIANT_OPTIONS) %>
85
+ # @param form_arguments [Hash] Allows an `ActionList` to act as a select list in multi- and single-select modes. Pass the `builder:` and `name:` options to this hash. `builder:` should be an instance of `ActionView::Helpers::FormBuilder`, which are created by the standard Rails `#form_with` and `#form_for` helpers. The `name:` option is the desired name of the field that will be included in the params sent to the server on form submission. *NOTE*: Consider using an <%= link_to_component(Primer::Alpha::ActionMenu) %> instead of using this feature directly.
85
86
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
86
87
  def initialize(
87
88
  id: self.class.generate_id,
@@ -90,6 +91,7 @@ module Primer
90
91
  scheme: DEFAULT_SCHEME,
91
92
  show_dividers: false,
92
93
  select_variant: DEFAULT_SELECT_VARIANT,
94
+ form_arguments: {},
93
95
  **system_arguments
94
96
  )
95
97
  @system_arguments = system_arguments
@@ -111,6 +113,13 @@ module Primer
111
113
  @system_arguments[:role] = @role
112
114
 
113
115
  @list_wrapper_arguments = {}
116
+
117
+ @form_builder = form_arguments[:builder]
118
+ @input_name = form_arguments[:name]
119
+
120
+ return unless required_form_arguments_given? && !allows_selection?
121
+
122
+ raise ArgumentError, "lists/menus that act as form inputs must also allow item selection (please pass the `select_variant:` option)"
114
123
  end
115
124
 
116
125
  # @private
@@ -158,6 +167,14 @@ module Primer
158
167
  @system_arguments[:role] == :menu
159
168
  end
160
169
 
170
+ def required_form_arguments_given?
171
+ @form_builder && @input_name
172
+ end
173
+
174
+ def acts_as_form_input?
175
+ required_form_arguments_given? && allows_selection?
176
+ end
177
+
161
178
  # @private
162
179
  def will_add_item(_item); end
163
180
  end
@@ -1,5 +1,10 @@
1
1
  import '@github/include-fragment-element';
2
- declare type SelectVariant = 'single' | 'multiple' | null;
2
+ declare type SelectVariant = 'none' | 'single' | 'multiple' | null;
3
+ declare type SelectedItem = {
4
+ label: string | null | undefined;
5
+ value: string | null | undefined;
6
+ element: Element;
7
+ };
3
8
  export declare class ActionMenuElement extends HTMLElement {
4
9
  #private;
5
10
  get selectVariant(): SelectVariant;
@@ -11,6 +16,7 @@ export declare class ActionMenuElement extends HTMLElement {
11
16
  get popoverElement(): HTMLElement | null;
12
17
  get invokerElement(): HTMLElement | null;
13
18
  get invokerLabel(): HTMLElement | null;
19
+ get selectedItems(): SelectedItem[];
14
20
  connectedCallback(): void;
15
21
  disconnectedCallback(): void;
16
22
  handleEvent(event: Event): void;
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _ActionMenuElement_instances, _ActionMenuElement_abortController, _ActionMenuElement_originalLabel, _ActionMenuElement_setDynamicLabel, _ActionMenuElement_isEnterKeydown, _ActionMenuElement_firstItem_get;
12
+ var _ActionMenuElement_instances, _ActionMenuElement_abortController, _ActionMenuElement_originalLabel, _ActionMenuElement_inputName, _ActionMenuElement_setDynamicLabel, _ActionMenuElement_updateInput, _ActionMenuElement_isEnterKeydown, _ActionMenuElement_firstItem_get;
13
13
  import '@github/include-fragment-element';
14
14
  const popoverSelector = (() => {
15
15
  try {
@@ -27,6 +27,7 @@ export class ActionMenuElement extends HTMLElement {
27
27
  _ActionMenuElement_instances.add(this);
28
28
  _ActionMenuElement_abortController.set(this, void 0);
29
29
  _ActionMenuElement_originalLabel.set(this, '');
30
+ _ActionMenuElement_inputName.set(this, '');
30
31
  }
31
32
  get selectVariant() {
32
33
  return this.getAttribute('data-select-variant');
@@ -73,6 +74,19 @@ export class ActionMenuElement extends HTMLElement {
73
74
  return null;
74
75
  return this.invokerElement.querySelector('.Button-label');
75
76
  }
77
+ get selectedItems() {
78
+ const selectedItems = this.querySelectorAll('[aria-checked=true]');
79
+ const results = [];
80
+ for (const selectedItem of selectedItems) {
81
+ const labelEl = selectedItem.querySelector('.ActionListItem-label');
82
+ results.push({
83
+ label: labelEl === null || labelEl === void 0 ? void 0 : labelEl.textContent,
84
+ value: selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.getAttribute('data-value'),
85
+ element: selectedItem
86
+ });
87
+ }
88
+ return results;
89
+ }
76
90
  connectedCallback() {
77
91
  const { signal } = (__classPrivateFieldSet(this, _ActionMenuElement_abortController, new AbortController(), "f"));
78
92
  this.addEventListener('keydown', this, { signal });
@@ -80,6 +94,7 @@ export class ActionMenuElement extends HTMLElement {
80
94
  this.addEventListener('mouseover', this, { signal });
81
95
  this.addEventListener('focusout', this, { signal });
82
96
  __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_setDynamicLabel).call(this);
97
+ __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_updateInput).call(this);
83
98
  }
84
99
  disconnectedCallback() {
85
100
  __classPrivateFieldGet(this, _ActionMenuElement_abortController, "f").abort();
@@ -116,6 +131,7 @@ export class ActionMenuElement extends HTMLElement {
116
131
  }
117
132
  __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_setDynamicLabel).call(this);
118
133
  }
134
+ __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_updateInput).call(this);
119
135
  if (event instanceof KeyboardEvent && event.target instanceof HTMLButtonElement) {
120
136
  // prevent buttons from being clicked twice
121
137
  event.preventDefault();
@@ -132,15 +148,15 @@ export class ActionMenuElement extends HTMLElement {
132
148
  }
133
149
  }
134
150
  }
135
- _ActionMenuElement_abortController = new WeakMap(), _ActionMenuElement_originalLabel = new WeakMap(), _ActionMenuElement_instances = new WeakSet(), _ActionMenuElement_setDynamicLabel = function _ActionMenuElement_setDynamicLabel() {
151
+ _ActionMenuElement_abortController = new WeakMap(), _ActionMenuElement_originalLabel = new WeakMap(), _ActionMenuElement_inputName = new WeakMap(), _ActionMenuElement_instances = new WeakSet(), _ActionMenuElement_setDynamicLabel = function _ActionMenuElement_setDynamicLabel() {
136
152
  if (!this.dynamicLabel)
137
153
  return;
138
154
  const invokerLabel = this.invokerLabel;
139
155
  if (!invokerLabel)
140
156
  return;
157
+ __classPrivateFieldSet(this, _ActionMenuElement_originalLabel, __classPrivateFieldGet(this, _ActionMenuElement_originalLabel, "f") || (invokerLabel.textContent || ''), "f");
141
158
  const itemLabel = this.querySelector('[aria-checked=true] .ActionListItem-label');
142
159
  if (itemLabel && this.dynamicLabel) {
143
- __classPrivateFieldSet(this, _ActionMenuElement_originalLabel, __classPrivateFieldGet(this, _ActionMenuElement_originalLabel, "f") || (invokerLabel.textContent || ''), "f");
144
160
  const prefixSpan = document.createElement('span');
145
161
  prefixSpan.classList.add('color-fg-muted');
146
162
  const contentSpan = document.createElement('span');
@@ -151,6 +167,42 @@ _ActionMenuElement_abortController = new WeakMap(), _ActionMenuElement_originalL
151
167
  else {
152
168
  invokerLabel.textContent = __classPrivateFieldGet(this, _ActionMenuElement_originalLabel, "f");
153
169
  }
170
+ }, _ActionMenuElement_updateInput = function _ActionMenuElement_updateInput() {
171
+ if (this.selectVariant === 'single') {
172
+ const input = this.querySelector(`[data-list-inputs=true] input`);
173
+ if (!input)
174
+ return;
175
+ const selectedItem = this.selectedItems[0];
176
+ if (selectedItem) {
177
+ input.value = (selectedItem.value || selectedItem.label || '').trim();
178
+ input.removeAttribute('disabled');
179
+ }
180
+ else {
181
+ input.setAttribute('disabled', 'disabled');
182
+ }
183
+ }
184
+ else if (this.selectVariant !== 'none') {
185
+ // multiple select variant
186
+ const inputList = this.querySelector('[data-list-inputs=true]');
187
+ if (!inputList)
188
+ return;
189
+ const inputs = inputList.querySelectorAll('input');
190
+ if (inputs.length > 0) {
191
+ __classPrivateFieldSet(this, _ActionMenuElement_inputName, __classPrivateFieldGet(this, _ActionMenuElement_inputName, "f") || inputs[0].name, "f");
192
+ }
193
+ for (const selectedItem of this.selectedItems) {
194
+ const newInput = document.createElement('input');
195
+ newInput.setAttribute('data-list-input', 'true');
196
+ newInput.type = 'hidden';
197
+ newInput.autocomplete = 'off';
198
+ newInput.name = __classPrivateFieldGet(this, _ActionMenuElement_inputName, "f");
199
+ newInput.value = (selectedItem.value || selectedItem.label || '').trim();
200
+ inputList.append(newInput);
201
+ }
202
+ for (const input of inputs) {
203
+ input.remove();
204
+ }
205
+ }
154
206
  }, _ActionMenuElement_isEnterKeydown = function _ActionMenuElement_isEnterKeydown(event) {
155
207
  return (event instanceof KeyboardEvent &&
156
208
  event.type === 'keydown' &&
@@ -9,13 +9,19 @@ const popoverSelector = (() => {
9
9
  }
10
10
  })()
11
11
 
12
- type SelectVariant = 'single' | 'multiple' | null
12
+ type SelectVariant = 'none' | 'single' | 'multiple' | null
13
+ type SelectedItem = {
14
+ label: string | null | undefined
15
+ value: string | null | undefined
16
+ element: Element
17
+ }
13
18
 
14
19
  const menuItemSelectors = ['[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]']
15
20
 
16
21
  export class ActionMenuElement extends HTMLElement {
17
22
  #abortController: AbortController
18
23
  #originalLabel = ''
24
+ #inputName = ''
19
25
 
20
26
  get selectVariant(): SelectVariant {
21
27
  return this.getAttribute('data-select-variant') as SelectVariant
@@ -65,6 +71,23 @@ export class ActionMenuElement extends HTMLElement {
65
71
  return this.invokerElement.querySelector('.Button-label')
66
72
  }
67
73
 
74
+ get selectedItems(): SelectedItem[] {
75
+ const selectedItems = this.querySelectorAll('[aria-checked=true]')
76
+ const results: SelectedItem[] = []
77
+
78
+ for (const selectedItem of selectedItems) {
79
+ const labelEl = selectedItem.querySelector('.ActionListItem-label')
80
+
81
+ results.push({
82
+ label: labelEl?.textContent,
83
+ value: selectedItem?.getAttribute('data-value'),
84
+ element: selectedItem
85
+ })
86
+ }
87
+
88
+ return results
89
+ }
90
+
68
91
  connectedCallback() {
69
92
  const {signal} = (this.#abortController = new AbortController())
70
93
  this.addEventListener('keydown', this, {signal})
@@ -72,6 +95,7 @@ export class ActionMenuElement extends HTMLElement {
72
95
  this.addEventListener('mouseover', this, {signal})
73
96
  this.addEventListener('focusout', this, {signal})
74
97
  this.#setDynamicLabel()
98
+ this.#updateInput()
75
99
  }
76
100
 
77
101
  disconnectedCallback() {
@@ -108,6 +132,9 @@ export class ActionMenuElement extends HTMLElement {
108
132
  }
109
133
  this.#setDynamicLabel()
110
134
  }
135
+
136
+ this.#updateInput()
137
+
111
138
  if (event instanceof KeyboardEvent && event.target instanceof HTMLButtonElement) {
112
139
  // prevent buttons from being clicked twice
113
140
  event.preventDefault()
@@ -128,9 +155,9 @@ export class ActionMenuElement extends HTMLElement {
128
155
  if (!this.dynamicLabel) return
129
156
  const invokerLabel = this.invokerLabel
130
157
  if (!invokerLabel) return
158
+ this.#originalLabel ||= invokerLabel.textContent || ''
131
159
  const itemLabel = this.querySelector('[aria-checked=true] .ActionListItem-label')
132
160
  if (itemLabel && this.dynamicLabel) {
133
- this.#originalLabel ||= invokerLabel.textContent || ''
134
161
  const prefixSpan = document.createElement('span')
135
162
  prefixSpan.classList.add('color-fg-muted')
136
163
  const contentSpan = document.createElement('span')
@@ -142,6 +169,47 @@ export class ActionMenuElement extends HTMLElement {
142
169
  }
143
170
  }
144
171
 
172
+ #updateInput() {
173
+ if (this.selectVariant === 'single') {
174
+ const input = this.querySelector(`[data-list-inputs=true] input`) as HTMLInputElement | null
175
+ if (!input) return
176
+
177
+ const selectedItem = this.selectedItems[0]
178
+
179
+ if (selectedItem) {
180
+ input.value = (selectedItem.value || selectedItem.label || '').trim()
181
+ input.removeAttribute('disabled')
182
+ } else {
183
+ input.setAttribute('disabled', 'disabled')
184
+ }
185
+ } else if (this.selectVariant !== 'none') {
186
+ // multiple select variant
187
+ const inputList = this.querySelector('[data-list-inputs=true]')
188
+ if (!inputList) return
189
+
190
+ const inputs = inputList.querySelectorAll('input')
191
+
192
+ if (inputs.length > 0) {
193
+ this.#inputName ||= (inputs[0] as HTMLInputElement).name
194
+ }
195
+
196
+ for (const selectedItem of this.selectedItems) {
197
+ const newInput = document.createElement('input')
198
+ newInput.setAttribute('data-list-input', 'true')
199
+ newInput.type = 'hidden'
200
+ newInput.autocomplete = 'off'
201
+ newInput.name = this.#inputName
202
+ newInput.value = (selectedItem.value || selectedItem.label || '').trim()
203
+
204
+ inputList.append(newInput)
205
+ }
206
+
207
+ for (const input of inputs) {
208
+ input.remove()
209
+ }
210
+ }
211
+ }
212
+
145
213
  #isEnterKeydown(event: Event): boolean {
146
214
  return (
147
215
  event instanceof KeyboardEvent &&
@@ -12,18 +12,16 @@ module Primer
12
12
 
13
13
  # Adds a new item to the list.
14
14
  #
15
+ # @param data [Hash] When the menu is used as a form input (see the <%= link_to_component(Primer::Alpha::ActionMenu) %> docs), the label is submitted to the server by default. However, if the `data: { value: }` or `"data-value":` attribute is provided, it will be sent to the server instead.
15
16
  # @param system_arguments [Hash] The same arguments accepted by <%= link_to_component(Primer::Alpha::ActionList::Item) %>.
16
- def with_item(**system_arguments, &block)
17
+ def with_item(data: {}, **system_arguments, &block)
17
18
  content_arguments = system_arguments.delete(:content_arguments) || {}
18
19
 
19
- content_arguments[:tag] =
20
- if system_arguments[:tag] && ITEM_TAG_OPTIONS.include?(system_arguments[:tag])
21
- system_arguments[:tag]
22
- elsif system_arguments[:href] && !system_arguments[:disabled]
23
- :a
24
- else
25
- DEFAULT_ITEM_TAG
26
- end
20
+ # rubocop:disable Style/IfUnlessModifier
21
+ if system_arguments[:tag] && ITEM_TAG_OPTIONS.include?(system_arguments[:tag])
22
+ content_arguments[:tag] = system_arguments[:tag]
23
+ end
24
+ # rubocop:enable Style/IfUnlessModifier
27
25
 
28
26
  # disallow setting item's tag
29
27
  system_arguments.delete(:tag)
@@ -51,7 +49,7 @@ module Primer
51
49
  content_arguments[:disabled] = "" if content_arguments[:tag] == :button
52
50
  end
53
51
 
54
- super(**system_arguments, content_arguments: content_arguments) do |item|
52
+ super(data: data, **system_arguments, content_arguments: content_arguments) do |item|
55
53
  # Prevent double renders by using the capture method on the component
56
54
  # that originally received the block.
57
55
  #
@@ -70,7 +68,7 @@ module Primer
70
68
  end
71
69
 
72
70
  # @param menu_id [String] ID of the parent menu.
73
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
71
+ # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::ActionList) %>
74
72
  def initialize(menu_id:, **system_arguments, &block)
75
73
  @menu_id = menu_id
76
74
 
@@ -3,9 +3,9 @@
3
3
 
4
4
  module Primer
5
5
  module Alpha
6
- # The ActionMenu should be used when a user can select a single option triggering an action from a list of items. Primer will automatically nest an `Item` within a presentational `<li>` tag.
6
+ # ActionMenu is used for actions, navigation, to display secondary options, or single/multi select lists. They appear when users interact with buttons, actions, or other controls.
7
7
  #
8
- # The only allowed elements for the `Item` components are: `:a`, `:button`, and `:clipboard-copy`. If one isn't selected, a fallback `:span` will be used. To add functionality, use a `.js` class to create the functionality, or an `onclick` handler.
8
+ # The only allowed elements for the `Item` components are: `:a`, `:button`, and `:clipboard-copy`. The default is `:button`.
9
9
  #
10
10
  # @accessibility
11
11
  # The action for the menu item needs to be on the element with `role="menuitem"`. Semantics are removed for everything nested inside of it. When a menu item is selected, the menu will close immediately.
@@ -39,6 +39,9 @@ module Primer
39
39
  # <% c.with_item(tag: :"clipboard-copy", value: "Text to copy") do %>
40
40
  # Copy Text
41
41
  # <% end %>
42
+ # <% c.with_item(href: "https://google.com", form_arguments: { name: "foo", value: "bar", method: :post }) do %>
43
+ # Submit form
44
+ # <% end %>
42
45
  # <% end %>
43
46
  #
44
47
  # @example With caret
@@ -271,24 +274,50 @@ module Primer
271
274
  # <% c.with_show_button(icon: :"kebab-horizontal", "aria-label": "Menu") %>
272
275
  # <% end %>
273
276
  #
277
+ # @example Using a single-select ActionMenu as a form input
278
+ # <%= form_with(url: action_menu_form_action_path) do |f| %>
279
+ # <%= render(Primer::Alpha::ActionMenu.new(select_variant: :single, dynamic_label: true, dynamic_label_prefix: "Strategy", form_arguments: { builder: f, name: "foo" })) do |menu| %>
280
+ # <% menu.with_show_button { "Strategy" } %>
281
+ # <% menu.with_item(label: "Fast forward", data: { value: "fast_forward" }) %>
282
+ # <% menu.with_item(label: "Recursive", data: { value: "recursive" }) %>
283
+ # <% menu.with_item(label: "Ours", data: { value: "ours" }) %>
284
+ # <% menu.with_item(label: "Resolve", data: { value: "resolve" }) %>
285
+ # <% end %>
286
+ # <% end %>
287
+ #
288
+ # @example Using a multi-select ActionMenu as a form input
289
+ # <%= form_with(url: action_menu_form_action_path) do |f| %>
290
+ # <%= render(Primer::Alpha::ActionMenu.new(select_variant: :multiple, form_arguments: { builder: f, name: "foo" })) do |menu| %>
291
+ # <% menu.with_show_button { "Strategy" } %>
292
+ # <% menu.with_item(label: "Fast forward", data: { value: "fast_forward" }) %>
293
+ # <% menu.with_item(label: "Recursive", data: { value: "recursive" }) %>
294
+ # <% menu.with_item(label: "Ours", data: { value: "ours" }) %>
295
+ # <% menu.with_item(label: "Resolve", data: { value: "resolve" }) %>
296
+ # <% end %>
297
+ # <% end %>
298
+ #
274
299
  # @param menu_id [String] Id of the menu.
275
300
  # @param anchor_align [Symbol] <%= one_of(Primer::Alpha::Overlay::ANCHOR_ALIGN_OPTIONS) %>.
276
301
  # @param anchor_side [Symbol] <%= one_of(Primer::Alpha::Overlay::ANCHOR_SIDE_OPTIONS) %>.
302
+ # @param size [Symbol] <%= one_of(Primer::Alpha::Overlay::SIZE_OPTIONS) %>.
277
303
  # @param src [String] Used with an `include-fragment` element to load menu content from the given source URL.
278
304
  # @param preload [Boolean] When true, and src is present, loads the `include-fragment` on trigger hover.
279
305
  # @param dynamic_label [Boolean] Whether or not to display the text of the currently selected item in the show button.
280
306
  # @param dynamic_label_prefix [String] If provided, the prefix is prepended to the dynamic label and displayed in the show button.
281
- # @param select_variant [Symbol]. <%= one_of(Primer::Alpha::ActionMenu::SELECT_VARIANT_OPTIONS) %>.
307
+ # @param select_variant [Symbol] <%= one_of(Primer::Alpha::ActionMenu::SELECT_VARIANT_OPTIONS) %>
308
+ # @param form_arguments [Hash] Allows an `ActionMenu` to act as a select list in multi- and single-select modes. Pass the `builder:` and `name:` options to this hash. `builder:` should be an instance of `ActionView::Helpers::FormBuilder`, which are created by the standard Rails `#form_with` and `#form_for` helpers. The `name:` option is the desired name of the field that will be included in the params sent to the server on form submission.
282
309
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>.
283
310
  def initialize(
284
311
  menu_id: self.class.generate_id,
285
312
  anchor_align: Primer::Alpha::Overlay::DEFAULT_ANCHOR_ALIGN,
286
313
  anchor_side: Primer::Alpha::Overlay::DEFAULT_ANCHOR_SIDE,
314
+ size: Primer::Alpha::Overlay::DEFAULT_SIZE,
287
315
  src: nil,
288
316
  preload: DEFAULT_PRELOAD,
289
317
  dynamic_label: false,
290
318
  dynamic_label_prefix: nil,
291
319
  select_variant: DEFAULT_SELECT_VARIANT,
320
+ form_arguments: {},
292
321
  **system_arguments
293
322
  )
294
323
  @menu_id = menu_id
@@ -310,15 +339,23 @@ module Primer
310
339
  title: "Menu",
311
340
  visually_hide_title: true,
312
341
  anchor_align: anchor_align,
313
- anchor_side: anchor_side
342
+ anchor_side: anchor_side,
343
+ size: size
314
344
  )
315
345
 
316
346
  @list = Primer::Alpha::ActionMenu::List.new(
317
347
  menu_id: @menu_id,
318
- select_variant: select_variant
348
+ select_variant: select_variant,
349
+ form_arguments: form_arguments
319
350
  )
320
351
  end
321
352
 
353
+ # @!parse
354
+ # # Button to activate the menu.
355
+ # #
356
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::Overlay) %>'s `show_button` slot.
357
+ # renders_one(:show_button)
358
+
322
359
  # Button to activate the menu.
323
360
  #
324
361
  # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::Overlay) %>'s `show_button` slot.
@@ -326,6 +363,12 @@ module Primer
326
363
  @overlay.with_show_button(**system_arguments, id: "#{@menu_id}-button", controls: "#{@menu_id}-list", &block)
327
364
  end
328
365
 
366
+ # @!parse
367
+ # # Adds a new item to the list.
368
+ # #
369
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::ActionList::Item) %>.
370
+ # renders_many(:items)
371
+
329
372
  # Adds a new item to the list.
330
373
  #
331
374
  # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::ActionList::Item) %>.
@@ -333,11 +376,6 @@ module Primer
333
376
  @list.with_item(**system_arguments, &block)
334
377
  end
335
378
 
336
- # Retrieves the list of items.
337
- def items
338
- @list.items
339
- end
340
-
341
379
  # Adds a divider to the list.
342
380
  #
343
381
  # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::ActionList) %>'s `divider` slot.
@@ -350,11 +388,11 @@ module Primer
350
388
  def before_render
351
389
  content
352
390
 
353
- raise ArgumentError, "`items` cannot be set when `src` is specified" if @src.present? && items.any?
391
+ raise ArgumentError, "`items` cannot be set when `src` is specified" if @src.present? && @list.items.any?
354
392
  end
355
393
 
356
394
  def render?
357
- items.any? || @src.present?
395
+ @list.items.any? || @src.present?
358
396
  end
359
397
  end
360
398
  end
@@ -1 +1 @@
1
- .autocomplete-label-stacked{display:block;margin-bottom:6px}.autocomplete-label-inline{display:inline;margin-right:6px}@media (max-width:543.98px){.autocomplete-label-inline{display:block;margin-bottom:6px}}.autocomplete-body{display:inline;position:relative}.autocomplete-embedded-icon-wrap{align-items:center;display:inline-flex;padding:4px 8px}.autocomplete-embedded-icon-wrap:focus-within{border-color:var(--color-accent-fg);box-shadow:inset 0 0 0 1px var(--color-accent-fg);outline:none}.autocomplete-embedded-icon-wrap .form-control{border:none;box-shadow:none;margin-left:8px;padding:0}.autocomplete-embedded-icon-wrap .form-control:focus{box-shadow:none}.autocomplete-embedded-icon-wrap .form-control:focus-visible{box-shadow:none}.autocomplete-results{background:var(--color-canvas-overlay);border:var(--primer-borderWidth-thin,1px) solid var(--color-border-default);border-radius:var(--primer-borderRadius-medium,6px);box-shadow:var(--color-shadow-medium);font-size:13px;left:0;list-style:none;max-height:20em;min-width:100%;overflow-y:auto;position:absolute;width:max-content;z-index:99}.autocomplete-item{background-color:var(--color-canvas-overlay);border:0;color:var(--color-fg-default);cursor:pointer;display:block;font-weight:var(--base-text-weight-semibold,600);overflow:hidden;padding:4px 8px;text-align:left;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;width:100%}.autocomplete-item:hover{background-color:var(--color-accent-emphasis);color:var(--color-fg-on-emphasis);text-decoration:none}.autocomplete-item:hover *{color:inherit!important}.autocomplete-item.navigation-focus,.autocomplete-item.selected,.autocomplete-item[aria-selected=true]{background-color:var(--color-accent-emphasis);color:var(--color-fg-on-emphasis);text-decoration:none}.autocomplete-item.navigation-focus *,.autocomplete-item.selected *,.autocomplete-item[aria-selected=true] *{color:inherit!important}
1
+ .autocomplete-label-stacked{display:block;margin-bottom:6px}.autocomplete-label-inline{display:inline;margin-right:6px}@media (max-width:543.98px){.autocomplete-label-inline{display:block;margin-bottom:6px}}.autocomplete-body{display:inline;position:relative}.autocomplete-embedded-icon-wrap{align-items:center;display:inline-flex;padding:4px 8px}.autocomplete-embedded-icon-wrap:focus-within{border-color:var(--color-accent-fg);box-shadow:inset 0 0 0 1px var(--color-accent-fg);outline:none}.autocomplete-embedded-icon-wrap .form-control{border:none;box-shadow:none;margin-left:8px;padding:0}.autocomplete-embedded-icon-wrap .form-control:focus{box-shadow:none}.autocomplete-embedded-icon-wrap .form-control:focus-visible{box-shadow:none}.autocomplete-results{background:var(--color-canvas-overlay);border:var(--borderWidth-thin,1px) solid var(--color-border-default);border-radius:var(--borderRadius-medium,6px);box-shadow:var(--color-shadow-medium);font-size:13px;left:0;list-style:none;max-height:20em;min-width:100%;overflow-y:auto;position:absolute;width:max-content;z-index:99}.autocomplete-item{background-color:var(--color-canvas-overlay);border:0;color:var(--color-fg-default);cursor:pointer;display:block;font-weight:var(--base-text-weight-semibold,600);overflow:hidden;padding:4px 8px;text-align:left;text-decoration:none;text-overflow:ellipsis;white-space:nowrap;width:100%}.autocomplete-item:hover{background-color:var(--color-accent-emphasis);color:var(--color-fg-on-emphasis);text-decoration:none}.autocomplete-item:hover *{color:inherit!important}.autocomplete-item.navigation-focus,.autocomplete-item.selected,.autocomplete-item[aria-selected=true]{background-color:var(--color-accent-emphasis);color:var(--color-fg-on-emphasis);text-decoration:none}.autocomplete-item.navigation-focus *,.autocomplete-item.selected *,.autocomplete-item[aria-selected=true] *{color:inherit!important}
@@ -1 +1 @@
1
- {"version":3,"sources":["auto_complete.pcss","../../../../lib/postcss_mixins/focusBoxShadowInset.pcss"],"names":[],"mappings":"AAMA,4BACE,aAAc,CACd,iBACF,CAGA,2BACE,cAAe,CACf,gBACF,CAGA,4BACE,2BACE,aAAc,CACd,iBACF,CACF,CAGA,mBAEE,cAAe,CADf,iBAEF,CAGA,iCAGE,kBAAmB,CAFnB,mBAAoB,CACpB,eAuBF,CApBE,8CCnCA,mCAAoC,CAEpC,iDAAmD,CADnD,YDsCA,CAEA,+CAGE,WAAY,CACZ,eAAgB,CAFhB,eAAgB,CADhB,SAYF,CAPE,qDACE,eACF,CAEA,6DACE,eACF,CAKJ,sBAUE,sCAAuC,CACvC,2EAA6E,CAC7E,mDAAqD,CACrD,qCAAsC,CALtC,cAAe,CANf,MAAO,CAOP,eAAgB,CAHhB,eAAgB,CADhB,cAAe,CAEf,eAAgB,CANhB,iBAAkB,CAGlB,iBAAkB,CADlB,UAWF,CAKA,mBAYE,4CAA6C,CAC7C,QAAS,CAPT,6BAA8B,CAK9B,cAAe,CAVf,aAAc,CAId,gDAAkD,CADlD,eAAgB,CADhB,eAAgB,CAIhB,eAAgB,CAChB,oBAAqB,CACrB,sBAAuB,CACvB,kBAAmB,CARnB,UAoCF,CAvBE,yBAGE,6CAA8C,CAF9C,iCAAkC,CAClC,oBAOF,CAHE,2BACE,uBACF,CAGF,uGAKE,6CAA8C,CAF9C,iCAAkC,CAClC,oBAOF,CAHE,6GACE,uBACF","file":"auto_complete.css","sourcesContent":["/* autocomplete */\n\n/* This file can be deprecated when AutoComplete is upstreamed to PVC + rolled out to dotcom https://github.com/github/primer/issues/796\n** AutoComplete relies on FormControl, Overlay and ActionList CSS */\n\n/* Stacked label (default) */\n.autocomplete-label-stacked {\n display: block;\n margin-bottom: 6px;\n}\n\n/* Inline label (non-default) */\n.autocomplete-label-inline {\n display: inline;\n margin-right: 6px;\n}\n\n/* Switch to stacked at smaller viewport */\n@media (max-width: 543.98px) {\n .autocomplete-label-inline {\n display: block;\n margin-bottom: 6px;\n }\n}\n\n/* Wrapper for the input and result elements to ensure alignment */\n.autocomplete-body {\n position: relative;\n display: inline;\n}\n\n/* Wrapper and conditional styles for when an icon is added */\n.autocomplete-embedded-icon-wrap {\n display: inline-flex;\n padding: 4px 8px;\n align-items: center;\n\n &:focus-within {\n border-color: var(--color-accent-fg);\n\n @mixin focusBoxShadowInset;\n }\n\n & .form-control {\n padding: 0;\n margin-left: 8px;\n border: none;\n box-shadow: none;\n\n &:focus {\n box-shadow: none;\n }\n\n &:focus-visible {\n box-shadow: none;\n }\n }\n}\n\n/* A pop up list of items used to show autocompleted results */\n.autocomplete-results {\n position: absolute;\n left: 0;\n z-index: 99;\n width: max-content;\n min-width: 100%;\n max-height: 20em;\n overflow-y: auto;\n font-size: 13px;\n list-style: none;\n background: var(--color-canvas-overlay);\n border: var(--primer-borderWidth-thin, 1px) solid var(--color-border-default);\n border-radius: var(--primer-borderRadius-medium, 6px);\n box-shadow: var(--color-shadow-medium);\n}\n\n/* One of the items that appears within an autocomplete group\n** Bold black text on white background */\n\n.autocomplete-item {\n display: block;\n width: 100%;\n padding: 4px 8px;\n overflow: hidden;\n font-weight: var(--base-text-weight-semibold, 600);\n color: var(--color-fg-default);\n text-align: left;\n text-decoration: none;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n background-color: var(--color-canvas-overlay);\n border: 0;\n\n &:hover {\n color: var(--color-fg-on-emphasis);\n text-decoration: none;\n background-color: var(--color-accent-emphasis);\n\n /* Inherit color on all child elements to ensure enough contrast */\n & * {\n color: inherit !important;\n }\n }\n\n &.selected,\n &[aria-selected='true'],\n &.navigation-focus {\n color: var(--color-fg-on-emphasis);\n text-decoration: none;\n background-color: var(--color-accent-emphasis);\n\n /* Inherit color on all child elements to ensure enough contrast */\n & * {\n color: inherit !important;\n }\n }\n}\n","/* inset box-shadow for form controls */\n@define-mixin focusBoxShadowInset $outlineWidth: 1px, $outlineColor: var(--color-accent-fg) {\n border-color: var(--color-accent-fg);\n outline: none;\n box-shadow: inset 0 0 0 $outlineWidth $outlineColor;\n}\n"]}
1
+ {"version":3,"sources":["auto_complete.pcss","../../../../lib/postcss_mixins/focusBoxShadowInset.pcss"],"names":[],"mappings":"AAMA,4BACE,aAAc,CACd,iBACF,CAGA,2BACE,cAAe,CACf,gBACF,CAGA,4BACE,2BACE,aAAc,CACd,iBACF,CACF,CAGA,mBAEE,cAAe,CADf,iBAEF,CAGA,iCAGE,kBAAmB,CAFnB,mBAAoB,CACpB,eAuBF,CApBE,8CCnCA,mCAAoC,CAEpC,iDAAmD,CADnD,YDsCA,CAEA,+CAGE,WAAY,CACZ,eAAgB,CAFhB,eAAgB,CADhB,SAYF,CAPE,qDACE,eACF,CAEA,6DACE,eACF,CAKJ,sBAUE,sCAAuC,CACvC,oEAAsE,CACtE,4CAA8C,CAC9C,qCAAsC,CALtC,cAAe,CANf,MAAO,CAOP,eAAgB,CAHhB,eAAgB,CADhB,cAAe,CAEf,eAAgB,CANhB,iBAAkB,CAGlB,iBAAkB,CADlB,UAWF,CAKA,mBAYE,4CAA6C,CAC7C,QAAS,CAPT,6BAA8B,CAK9B,cAAe,CAVf,aAAc,CAId,gDAAkD,CADlD,eAAgB,CADhB,eAAgB,CAIhB,eAAgB,CAChB,oBAAqB,CACrB,sBAAuB,CACvB,kBAAmB,CARnB,UAoCF,CAvBE,yBAGE,6CAA8C,CAF9C,iCAAkC,CAClC,oBAOF,CAHE,2BACE,uBACF,CAGF,uGAKE,6CAA8C,CAF9C,iCAAkC,CAClC,oBAOF,CAHE,6GACE,uBACF","file":"auto_complete.css","sourcesContent":["/* autocomplete */\n\n/* This file can be deprecated when AutoComplete is upstreamed to PVC + rolled out to dotcom https://github.com/github/primer/issues/796\n** AutoComplete relies on FormControl, Overlay and ActionList CSS */\n\n/* Stacked label (default) */\n.autocomplete-label-stacked {\n display: block;\n margin-bottom: 6px;\n}\n\n/* Inline label (non-default) */\n.autocomplete-label-inline {\n display: inline;\n margin-right: 6px;\n}\n\n/* Switch to stacked at smaller viewport */\n@media (max-width: 543.98px) {\n .autocomplete-label-inline {\n display: block;\n margin-bottom: 6px;\n }\n}\n\n/* Wrapper for the input and result elements to ensure alignment */\n.autocomplete-body {\n position: relative;\n display: inline;\n}\n\n/* Wrapper and conditional styles for when an icon is added */\n.autocomplete-embedded-icon-wrap {\n display: inline-flex;\n padding: 4px 8px;\n align-items: center;\n\n &:focus-within {\n border-color: var(--color-accent-fg);\n\n @mixin focusBoxShadowInset;\n }\n\n & .form-control {\n padding: 0;\n margin-left: 8px;\n border: none;\n box-shadow: none;\n\n &:focus {\n box-shadow: none;\n }\n\n &:focus-visible {\n box-shadow: none;\n }\n }\n}\n\n/* A pop up list of items used to show autocompleted results */\n.autocomplete-results {\n position: absolute;\n left: 0;\n z-index: 99;\n width: max-content;\n min-width: 100%;\n max-height: 20em;\n overflow-y: auto;\n font-size: 13px;\n list-style: none;\n background: var(--color-canvas-overlay);\n border: var(--borderWidth-thin, 1px) solid var(--color-border-default);\n border-radius: var(--borderRadius-medium, 6px);\n box-shadow: var(--color-shadow-medium);\n}\n\n/* One of the items that appears within an autocomplete group\n** Bold black text on white background */\n\n.autocomplete-item {\n display: block;\n width: 100%;\n padding: 4px 8px;\n overflow: hidden;\n font-weight: var(--base-text-weight-semibold, 600);\n color: var(--color-fg-default);\n text-align: left;\n text-decoration: none;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n background-color: var(--color-canvas-overlay);\n border: 0;\n\n &:hover {\n color: var(--color-fg-on-emphasis);\n text-decoration: none;\n background-color: var(--color-accent-emphasis);\n\n /* Inherit color on all child elements to ensure enough contrast */\n & * {\n color: inherit !important;\n }\n }\n\n &.selected,\n &[aria-selected='true'],\n &.navigation-focus {\n color: var(--color-fg-on-emphasis);\n text-decoration: none;\n background-color: var(--color-accent-emphasis);\n\n /* Inherit color on all child elements to ensure enough contrast */\n & * {\n color: inherit !important;\n }\n }\n}\n","/* inset box-shadow for form controls */\n@define-mixin focusBoxShadowInset $outlineWidth: 1px, $outlineColor: var(--color-accent-fg) {\n border-color: var(--color-accent-fg);\n outline: none;\n box-shadow: inset 0 0 0 $outlineWidth $outlineColor;\n}\n"]}
@@ -69,8 +69,8 @@
69
69
  font-size: 13px;
70
70
  list-style: none;
71
71
  background: var(--color-canvas-overlay);
72
- border: var(--primer-borderWidth-thin, 1px) solid var(--color-border-default);
73
- border-radius: var(--primer-borderRadius-medium, 6px);
72
+ border: var(--borderWidth-thin, 1px) solid var(--color-border-default);
73
+ border-radius: var(--borderRadius-medium, 6px);
74
74
  box-shadow: var(--color-shadow-medium);
75
75
  }
76
76
 
@@ -1 +1 @@
1
- .Banner{background-image:linear-gradient(var(--color-accent-subtle),var(--color-accent-subtle));border:var(--primer-borderWidth-thin,max(1px,.0625rem)) solid var(--color-accent-muted);border-radius:var(--primer-borderRadius-medium,6px);color:var(--color-fg-default);display:grid;grid-auto-flow:column;grid-template-areas:"visual message actions close";grid-template-columns:min-content 1fr minmax(0,auto) min-content;grid-template-rows:min-content;padding:var(--base-size-8,8px);position:relative}@media (max-width:543.98px){.Banner{grid-template-areas:"visual message close" ". actions actions";grid-template-columns:min-content 1fr min-content;grid-template-rows:min-content min-content}.Banner .Banner-actions{margin:var(--base-size-8,8px) 0 0 var(--base-size-8,8px)}}.Banner .Banner-visual{align-self:start;display:grid;grid-area:visual;padding:var(--base-size-6,6px) var(--base-size-8,8px)}.Banner .Banner-visual>.octicon{margin-block:calc(var(--base-size-4, 4px)/2)}.Banner .Banner-visual>*{align-self:center}.Banner .Banner-message{align-self:center;grid-area:message;padding:var(--base-size-6,6px) var(--base-size-8,8px)}.Banner .Banner-message p:last-child{margin-bottom:0}.Banner .Banner-message .Banner-title:not(:only-child){font-weight:var(--base-text-weight-semibold,600);margin-bottom:0}.Banner .Banner-actions{grid-area:actions}.Banner .Banner-actions:last-child{align-self:center}.Banner .Banner-close{grid-area:close;margin-left:var(--primer-controlStack-medium-gap-condensed,8px)}.Banner .Banner-visual .octicon{color:var(--color-accent-fg)}.Banner.Banner--warning{background-image:linear-gradient(var(--color-attention-subtle),var(--color-attention-subtle));border-color:var(--color-attention-muted);color:var(--color-fg-default)}.Banner.Banner--warning .Banner-visual .octicon{color:var(--color-attention-fg)}.Banner.Banner--error{background-image:linear-gradient(var(--color-danger-subtle),var(--color-danger-subtle));border-color:var(--color-danger-muted);color:var(--color-fg-default)}.Banner.Banner--error .Banner-visual .octicon{color:var(--color-danger-fg)}.Banner.Banner--success{background-image:linear-gradient(var(--color-success-subtle),var(--color-success-subtle));border-color:var(--color-success-muted);color:var(--color-fg-default)}.Banner.Banner--success .Banner-visual .octicon{color:var(--color-success-fg)}.Banner.Banner--full{border-left:0;border-radius:0;border-right:0;margin-top:calc(var(--primer-borderWidth-thin, max(1px, .0625rem))*-1)}@media (max-width:767.98px){.Banner.Banner--full-whenNarrow{border-left:0;border-radius:0;border-right:0;margin-top:calc(var(--primer-borderWidth-thin, max(1px, .0625rem))*-1)}}
1
+ .Banner{background-image:linear-gradient(var(--color-accent-subtle),var(--color-accent-subtle));border:var(--borderWidth-thin,max(1px,.0625rem)) solid var(--color-accent-muted);border-radius:var(--borderRadius-medium,6px);color:var(--color-fg-default);display:grid;grid-auto-flow:column;grid-template-areas:"visual message actions close";grid-template-columns:min-content 1fr minmax(0,auto) min-content;grid-template-rows:min-content;padding:var(--base-size-8,8px);position:relative}@media (max-width:543.98px){.Banner{grid-template-areas:"visual message close" ". actions actions";grid-template-columns:min-content 1fr min-content;grid-template-rows:min-content min-content}.Banner .Banner-actions{margin:var(--base-size-8,8px) 0 0 var(--base-size-8,8px)}}.Banner .Banner-visual{align-self:start;display:grid;grid-area:visual;padding:var(--base-size-6,6px) var(--base-size-8,8px)}.Banner .Banner-visual>.octicon{margin-block:calc(var(--base-size-4, 4px)/2)}.Banner .Banner-visual>*{align-self:center}.Banner .Banner-message{align-self:center;grid-area:message;padding:var(--base-size-6,6px) var(--base-size-8,8px)}.Banner .Banner-message p:last-child{margin-bottom:0}.Banner .Banner-message .Banner-title:not(:only-child){font-weight:var(--base-text-weight-semibold,600);margin-bottom:0}.Banner .Banner-actions{grid-area:actions}.Banner .Banner-actions:last-child{align-self:center}.Banner .Banner-close{grid-area:close;margin-left:var(--controlStack-medium-gap-condensed,8px)}.Banner .Banner-visual .octicon{color:var(--color-accent-fg)}.Banner.Banner--warning{background-image:linear-gradient(var(--color-attention-subtle),var(--color-attention-subtle));border-color:var(--color-attention-muted);color:var(--color-fg-default)}.Banner.Banner--warning .Banner-visual .octicon{color:var(--color-attention-fg)}.Banner.Banner--error{background-image:linear-gradient(var(--color-danger-subtle),var(--color-danger-subtle));border-color:var(--color-danger-muted);color:var(--color-fg-default)}.Banner.Banner--error .Banner-visual .octicon{color:var(--color-danger-fg)}.Banner.Banner--success{background-image:linear-gradient(var(--color-success-subtle),var(--color-success-subtle));border-color:var(--color-success-muted);color:var(--color-fg-default)}.Banner.Banner--success .Banner-visual .octicon{color:var(--color-success-fg)}.Banner.Banner--full{border-left:0;border-radius:0;border-right:0;margin-top:calc(var(--borderWidth-thin, max(1px, .0625rem))*-1)}@media (max-width:767.98px){.Banner.Banner--full-whenNarrow{border-left:0;border-radius:0;border-right:0;margin-top:calc(var(--borderWidth-thin, max(1px, .0625rem))*-1)}}
@@ -1 +1 @@
1
- {"version":3,"sources":["banner.pcss"],"names":[],"mappings":"AAEA,QAKE,uFAAyF,CACzF,uFAA2F,CAC3F,mDAAqD,CAHrD,6BAA8B,CAF9B,YAAa,CAMb,qBAAsB,CACtB,kDAAmD,CACnD,gEAAiE,CACjE,8BAA+B,CAR/B,8BAAgC,CAFhC,iBA0HF,CA7GE,4BAdF,QAeI,8DAEqB,CACrB,iDAAkD,CAClD,0CAwGJ,CAtGI,wBACI,wDACJ,CACF,CAIA,uBAIE,gBAAiB,CAHjB,YAAa,CAEb,gBAAiB,CADjB,qDAWF,CAPE,gCACE,4CACF,CAEA,yBACE,iBACF,CAGF,wBAGE,iBAAkB,CADlB,iBAAkB,CADlB,qDAYF,CARE,qCACE,eACF,CAEA,uDAEE,gDAAkD,CADlD,eAEF,CAGF,wBACE,iBAKF,CAHE,mCACE,iBACF,CAIF,sBACE,eAAgB,CAChB,+DACF,CAEA,gCACE,4BACF,CAEA,wBAEE,6FAA+F,CAC/F,yCAA0C,CAF1C,6BAOF,CAHE,gDACE,+BACF,CAGF,sBAEE,uFAAyF,CACzF,sCAAuC,CAFvC,6BAOF,CAHE,8CACE,4BACF,CAGF,wBAEE,yFAA2F,CAC3F,uCAAwC,CAFxC,6BAOF,CAHE,gDACE,6BACF,CAKF,qBAGE,aAAc,CACd,eAAgB,CAFhB,cAAe,CADf,sEAIF,CAEA,4BACE,gCAGE,aAAc,CACd,eAAgB,CAFhB,cAAe,CADf,sEAIF,CACF","file":"banner.css","sourcesContent":["/* Banner alert */\n\n.Banner {\n position: relative;\n display: grid;\n padding: var(--base-size-8, 8px);\n color: var(--color-fg-default);\n background-image: linear-gradient(var(--color-accent-subtle), var(--color-accent-subtle));\n border: var(--primer-borderWidth-thin, max(1px, 0.0625rem)) solid var(--color-accent-muted);\n border-radius: var(--primer-borderRadius-medium, 6px);\n grid-auto-flow: column;\n grid-template-areas: 'visual message actions close';\n grid-template-columns: min-content 1fr minmax(0,auto) min-content;\n grid-template-rows: min-content;\n\n /* `sm` breakpoint variantion */\n @media (max-width: 543.98px) {\n grid-template-areas:\n 'visual message close'\n '. actions actions';\n grid-template-columns: min-content 1fr min-content;\n grid-template-rows: min-content min-content;\n\n & .Banner-actions {\n margin: var(--base-size-8, 8px) 0 0 var(--base-size-8, 8px);\n }\n }\n\n /* Elements */\n\n & .Banner-visual {\n display: grid;\n padding: var(--base-size-6, 6px) var(--base-size-8, 8px);\n grid-area: visual;\n align-self: start;\n\n & > .octicon {\n margin-block: calc(var(--base-size-4, 4px) / 2);\n }\n\n & > * {\n align-self: center;\n }\n }\n\n & .Banner-message {\n padding: var(--base-size-6, 6px) var(--base-size-8, 8px);\n grid-area: message;\n align-self: center;\n\n & p:last-child {\n margin-bottom: 0;\n }\n\n & .Banner-title:not(:only-child) {\n margin-bottom: 0;\n font-weight: var(--base-text-weight-semibold, 600);\n }\n }\n\n & .Banner-actions {\n grid-area: actions;\n\n &:last-child {\n align-self: center;\n }\n }\n\n /* is this used anywhere? could not find any use, but unsure */\n & .Banner-close {\n grid-area: close;\n margin-left: var(--primer-controlStack-medium-gap-condensed, 8px);\n }\n\n & .Banner-visual .octicon {\n color: var(--color-accent-fg);\n }\n\n &.Banner--warning {\n color: var(--color-fg-default);\n background-image: linear-gradient(var(--color-attention-subtle), var(--color-attention-subtle));\n border-color: var(--color-attention-muted);\n\n & .Banner-visual .octicon {\n color: var(--color-attention-fg);\n }\n }\n\n &.Banner--error {\n color: var(--color-fg-default);\n background-image: linear-gradient(var(--color-danger-subtle), var(--color-danger-subtle));\n border-color: var(--color-danger-muted);\n\n & .Banner-visual .octicon {\n color: var(--color-danger-fg);\n }\n }\n\n &.Banner--success {\n color: var(--color-fg-default);\n background-image: linear-gradient(var(--color-success-subtle), var(--color-success-subtle));\n border-color: var(--color-success-muted);\n\n & .Banner-visual .octicon {\n color: var(--color-success-fg);\n }\n }\n\n /* Full-width */\n\n &.Banner--full {\n margin-top: calc(var(--primer-borderWidth-thin, max(1px, 0.0625rem)) * -1);\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n }\n\n @media (max-width: 767.98px) {\n &.Banner--full-whenNarrow {\n margin-top: calc(var(--primer-borderWidth-thin, max(1px, 0.0625rem)) * -1);\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["banner.pcss"],"names":[],"mappings":"AAEA,QAKE,uFAAyF,CACzF,gFAAoF,CACpF,4CAA8C,CAH9C,6BAA8B,CAF9B,YAAa,CAMb,qBAAsB,CACtB,kDAAmD,CACnD,gEAAkE,CAClE,8BAA+B,CAR/B,8BAAgC,CAFhC,iBA0HF,CA7GE,4BAdF,QAeI,8DAEqB,CACrB,iDAAkD,CAClD,0CAwGJ,CAtGI,wBACE,wDACF,CACF,CAIA,uBAIE,gBAAiB,CAHjB,YAAa,CAEb,gBAAiB,CADjB,qDAWF,CAPE,gCACE,4CACF,CAEA,yBACE,iBACF,CAGF,wBAGE,iBAAkB,CADlB,iBAAkB,CADlB,qDAYF,CARE,qCACE,eACF,CAEA,uDAEE,gDAAkD,CADlD,eAEF,CAGF,wBACE,iBAKF,CAHE,mCACE,iBACF,CAIF,sBACE,eAAgB,CAChB,wDACF,CAEA,gCACE,4BACF,CAEA,wBAEE,6FAA+F,CAC/F,yCAA0C,CAF1C,6BAOF,CAHE,gDACE,+BACF,CAGF,sBAEE,uFAAyF,CACzF,sCAAuC,CAFvC,6BAOF,CAHE,8CACE,4BACF,CAGF,wBAEE,yFAA2F,CAC3F,uCAAwC,CAFxC,6BAOF,CAHE,gDACE,6BACF,CAKF,qBAGE,aAAc,CACd,eAAgB,CAFhB,cAAe,CADf,+DAIF,CAEA,4BACE,gCAGE,aAAc,CACd,eAAgB,CAFhB,cAAe,CADf,+DAIF,CACF","file":"banner.css","sourcesContent":["/* Banner alert */\n\n.Banner {\n position: relative;\n display: grid;\n padding: var(--base-size-8, 8px);\n color: var(--color-fg-default);\n background-image: linear-gradient(var(--color-accent-subtle), var(--color-accent-subtle));\n border: var(--borderWidth-thin, max(1px, 0.0625rem)) solid var(--color-accent-muted);\n border-radius: var(--borderRadius-medium, 6px);\n grid-auto-flow: column;\n grid-template-areas: 'visual message actions close';\n grid-template-columns: min-content 1fr minmax(0, auto) min-content;\n grid-template-rows: min-content;\n\n /* `sm` breakpoint variantion */\n @media (max-width: 543.98px) {\n grid-template-areas:\n 'visual message close'\n '. actions actions';\n grid-template-columns: min-content 1fr min-content;\n grid-template-rows: min-content min-content;\n\n & .Banner-actions {\n margin: var(--base-size-8, 8px) 0 0 var(--base-size-8, 8px);\n }\n }\n\n /* Elements */\n\n & .Banner-visual {\n display: grid;\n padding: var(--base-size-6, 6px) var(--base-size-8, 8px);\n grid-area: visual;\n align-self: start;\n\n & > .octicon {\n margin-block: calc(var(--base-size-4, 4px) / 2);\n }\n\n & > * {\n align-self: center;\n }\n }\n\n & .Banner-message {\n padding: var(--base-size-6, 6px) var(--base-size-8, 8px);\n grid-area: message;\n align-self: center;\n\n & p:last-child {\n margin-bottom: 0;\n }\n\n & .Banner-title:not(:only-child) {\n margin-bottom: 0;\n font-weight: var(--base-text-weight-semibold, 600);\n }\n }\n\n & .Banner-actions {\n grid-area: actions;\n\n &:last-child {\n align-self: center;\n }\n }\n\n /* is this used anywhere? could not find any use, but unsure */\n & .Banner-close {\n grid-area: close;\n margin-left: var(--controlStack-medium-gap-condensed, 8px);\n }\n\n & .Banner-visual .octicon {\n color: var(--color-accent-fg);\n }\n\n &.Banner--warning {\n color: var(--color-fg-default);\n background-image: linear-gradient(var(--color-attention-subtle), var(--color-attention-subtle));\n border-color: var(--color-attention-muted);\n\n & .Banner-visual .octicon {\n color: var(--color-attention-fg);\n }\n }\n\n &.Banner--error {\n color: var(--color-fg-default);\n background-image: linear-gradient(var(--color-danger-subtle), var(--color-danger-subtle));\n border-color: var(--color-danger-muted);\n\n & .Banner-visual .octicon {\n color: var(--color-danger-fg);\n }\n }\n\n &.Banner--success {\n color: var(--color-fg-default);\n background-image: linear-gradient(var(--color-success-subtle), var(--color-success-subtle));\n border-color: var(--color-success-muted);\n\n & .Banner-visual .octicon {\n color: var(--color-success-fg);\n }\n }\n\n /* Full-width */\n\n &.Banner--full {\n margin-top: calc(var(--borderWidth-thin, max(1px, 0.0625rem)) * -1);\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n }\n\n @media (max-width: 767.98px) {\n &.Banner--full-whenNarrow {\n margin-top: calc(var(--borderWidth-thin, max(1px, 0.0625rem)) * -1);\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n }\n }\n}\n"]}
@@ -6,11 +6,11 @@
6
6
  padding: var(--base-size-8, 8px);
7
7
  color: var(--color-fg-default);
8
8
  background-image: linear-gradient(var(--color-accent-subtle), var(--color-accent-subtle));
9
- border: var(--primer-borderWidth-thin, max(1px, 0.0625rem)) solid var(--color-accent-muted);
10
- border-radius: var(--primer-borderRadius-medium, 6px);
9
+ border: var(--borderWidth-thin, max(1px, 0.0625rem)) solid var(--color-accent-muted);
10
+ border-radius: var(--borderRadius-medium, 6px);
11
11
  grid-auto-flow: column;
12
12
  grid-template-areas: 'visual message actions close';
13
- grid-template-columns: min-content 1fr minmax(0,auto) min-content;
13
+ grid-template-columns: min-content 1fr minmax(0, auto) min-content;
14
14
  grid-template-rows: min-content;
15
15
 
16
16
  /* `sm` breakpoint variantion */
@@ -22,7 +22,7 @@
22
22
  grid-template-rows: min-content min-content;
23
23
 
24
24
  & .Banner-actions {
25
- margin: var(--base-size-8, 8px) 0 0 var(--base-size-8, 8px);
25
+ margin: var(--base-size-8, 8px) 0 0 var(--base-size-8, 8px);
26
26
  }
27
27
  }
28
28
 
@@ -69,7 +69,7 @@
69
69
  /* is this used anywhere? could not find any use, but unsure */
70
70
  & .Banner-close {
71
71
  grid-area: close;
72
- margin-left: var(--primer-controlStack-medium-gap-condensed, 8px);
72
+ margin-left: var(--controlStack-medium-gap-condensed, 8px);
73
73
  }
74
74
 
75
75
  & .Banner-visual .octicon {
@@ -109,7 +109,7 @@
109
109
  /* Full-width */
110
110
 
111
111
  &.Banner--full {
112
- margin-top: calc(var(--primer-borderWidth-thin, max(1px, 0.0625rem)) * -1);
112
+ margin-top: calc(var(--borderWidth-thin, max(1px, 0.0625rem)) * -1);
113
113
  border-right: 0;
114
114
  border-left: 0;
115
115
  border-radius: 0;
@@ -117,7 +117,7 @@
117
117
 
118
118
  @media (max-width: 767.98px) {
119
119
  &.Banner--full-whenNarrow {
120
- margin-top: calc(var(--primer-borderWidth-thin, max(1px, 0.0625rem)) * -1);
120
+ margin-top: calc(var(--borderWidth-thin, max(1px, 0.0625rem)) * -1);
121
121
  border-right: 0;
122
122
  border-left: 0;
123
123
  border-radius: 0;