primer_view_components 0.1.6 → 0.1.7

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