primer_view_components 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,6 +20,7 @@ export class ActionMenuElement extends HTMLElement {
20
20
  #abortController: AbortController
21
21
  #originalLabel = ''
22
22
  #inputName = ''
23
+ #invokerBeingClicked = false
23
24
 
24
25
  get selectVariant(): SelectVariant {
25
26
  return this.getAttribute('data-select-variant') as SelectVariant
@@ -52,7 +53,7 @@ export class ActionMenuElement extends HTMLElement {
52
53
  }
53
54
 
54
55
  get popoverElement(): HTMLElement | null {
55
- return this.invokerElement?.popoverTargetElement || null
56
+ return (this.invokerElement?.popoverTargetElement as HTMLElement) || null
56
57
  }
57
58
 
58
59
  get invokerElement(): HTMLButtonElement | null {
@@ -94,8 +95,10 @@ export class ActionMenuElement extends HTMLElement {
94
95
  this.addEventListener('click', this, {signal})
95
96
  this.addEventListener('mouseover', this, {signal})
96
97
  this.addEventListener('focusout', this, {signal})
98
+ this.addEventListener('mousedown', this, {signal})
97
99
  this.#setDynamicLabel()
98
100
  this.#updateInput()
101
+ this.#softDisableItems()
99
102
 
100
103
  if (this.includeFragment) {
101
104
  this.includeFragment.addEventListener('include-fragment-replaced', this, {
@@ -104,19 +107,69 @@ export class ActionMenuElement extends HTMLElement {
104
107
  }
105
108
  }
106
109
 
110
+ #softDisableItems() {
111
+ const {signal} = this.#abortController
112
+
113
+ for (const item of this.#items) {
114
+ item.addEventListener('click', this.#potentiallyDisallowActivation.bind(this), {signal})
115
+ item.addEventListener('keydown', this.#potentiallyDisallowActivation.bind(this), {signal})
116
+ }
117
+ }
118
+
119
+ #potentiallyDisallowActivation(event: Event) {
120
+ if (!this.#isActivation(event)) return
121
+
122
+ const item = (event.target as HTMLElement).closest(menuItemSelectors.join(','))
123
+ if (!item) return
124
+
125
+ if (item.getAttribute('aria-disabled')) {
126
+ event.preventDefault()
127
+ event.stopPropagation()
128
+ event.stopImmediatePropagation()
129
+ }
130
+ }
131
+
107
132
  disconnectedCallback() {
108
133
  this.#abortController.abort()
109
134
  }
110
135
 
136
+ #isKeyboardActivation(event: Event): boolean {
137
+ return (
138
+ event instanceof KeyboardEvent &&
139
+ event.type === 'keydown' &&
140
+ !(event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) &&
141
+ (event.key === 'Enter' || event.key === ' ')
142
+ )
143
+ }
144
+
145
+ #isMouseActivation(event: Event): boolean {
146
+ return event instanceof MouseEvent && event.type === 'click'
147
+ }
148
+
149
+ #isActivation(event: Event): boolean {
150
+ return this.#isMouseActivation(event) || this.#isKeyboardActivation(event)
151
+ }
152
+
111
153
  handleEvent(event: Event) {
112
- const activation = this.#isActivationKeydown(event)
113
- if (event.target === this.invokerElement && activation) {
114
- if (this.#firstItem) {
115
- event.preventDefault()
116
- this.popoverElement?.showPopover()
117
- this.#firstItem.focus()
118
- return
119
- }
154
+ const targetIsInvoker = this.invokerElement?.contains(event.target as HTMLElement)
155
+ const eventIsActivation = this.#isActivation(event)
156
+
157
+ if (targetIsInvoker && event.type === 'mousedown') {
158
+ this.#invokerBeingClicked = true
159
+ return
160
+ }
161
+
162
+ // Prevent safari bug that dismisses menu on mousedown instead of allowing
163
+ // the click event to propagate to the button
164
+ if (event.type === 'mousedown') {
165
+ event.preventDefault()
166
+ return
167
+ }
168
+
169
+ if (targetIsInvoker && eventIsActivation) {
170
+ this.#handleInvokerActivated(event)
171
+ this.#invokerBeingClicked = false
172
+ return
120
173
  }
121
174
 
122
175
  // Ignore events within dialogs within menus
@@ -124,84 +177,161 @@ export class ActionMenuElement extends HTMLElement {
124
177
  return
125
178
  }
126
179
 
127
- // If a dialog has been rendered within the menu, we do not want to hide
128
- // the entire menu, as that will also hide the Dialog. Instead we want to
129
- // show the Dialog while hiding just the visible part of the menu.
130
- if ((activation || event.type === 'click') && (event.target as HTMLElement)?.closest('[data-show-dialog-id]')) {
131
- const dialogInvoker = (event.target as HTMLElement)!.closest('[data-show-dialog-id]')
132
- const dialog = this.ownerDocument.getElementById(dialogInvoker?.getAttribute('data-show-dialog-id') || '')
133
- if (dialogInvoker && dialog && this.contains(dialogInvoker) && this.contains(dialog)) {
134
- this.querySelector<HTMLElement>('.ActionListWrap')!.style.display = 'none'
135
- const dialog_controller = new AbortController()
136
- const {signal} = dialog_controller
137
- const handleDialogClose = () => {
138
- dialog_controller.abort()
139
- this.querySelector<HTMLElement>('.ActionListWrap')!.style.display = ''
140
- if (this.popoverElement?.matches(':popover-open')) {
141
- this.popoverElement?.hidePopover()
142
- }
180
+ if (event.type === 'focusout') {
181
+ if (this.#invokerBeingClicked) return
182
+
183
+ // Give the browser time to focus the next element
184
+ requestAnimationFrame(() => {
185
+ if (!this.contains(document.activeElement) || document.activeElement === this.invokerElement) {
186
+ this.#handleFocusOut()
143
187
  }
144
- dialog.addEventListener('close', handleDialogClose, {signal})
145
- dialog.addEventListener('cancel', handleDialogClose, {signal})
146
- return
147
- }
188
+ })
189
+
190
+ return
148
191
  }
149
192
 
150
- if (!this.popoverElement?.matches(':popover-open')) return
193
+ const item = (event.target as Element).closest(menuItemSelectors.join(','))
194
+ const targetIsItem = item !== null
151
195
 
152
- if (event.type === 'include-fragment-replaced') {
153
- if (this.#firstItem) this.#firstItem.focus()
154
- } else if (activation || (event instanceof MouseEvent && event.type === 'click')) {
155
- // Hide popover after current event loop to prevent changes in focus from
156
- // altering the target of the event. Not doing this specifically affects
157
- // <a> tags. It causes the event to be sent to the currently focused element
158
- // instead of the anchor, which effectively prevents navigation, i.e. it
159
- // appears as if hitting enter does nothing. Curiously, clicking instead
160
- // works fine.
161
- if (this.selectVariant !== 'multiple') {
162
- setTimeout(() => {
163
- if (this.popoverElement?.matches(':popover-open')) {
164
- this.popoverElement?.hidePopover()
165
- }
166
- })
196
+ if (targetIsItem && eventIsActivation) {
197
+ const dialogInvoker = item.closest('[data-show-dialog-id]')
198
+
199
+ if (dialogInvoker) {
200
+ const dialog = this.ownerDocument.getElementById(dialogInvoker.getAttribute('data-show-dialog-id') || '')
201
+
202
+ if (dialog && this.contains(dialogInvoker) && this.contains(dialog)) {
203
+ this.#handleDialogItemActivated(event, dialog)
204
+ return
205
+ }
167
206
  }
168
207
 
169
- // The rest of the code below deals with single/multiple selection behavior, and should not
170
- // interfere with events fired by menu items whose behavior is specified outside the library.
171
- if (this.selectVariant !== 'multiple' && this.selectVariant !== 'single') return
208
+ this.#activateItem(event, item)
209
+ this.#handleItemActivated(event, item)
210
+ return
211
+ }
172
212
 
173
- const item = (event.target as Element).closest(menuItemSelectors.join(','))
174
- if (!item) return
175
- const ariaChecked = item.getAttribute('aria-checked')
176
- const checked = ariaChecked !== 'true'
213
+ if (event.type === 'include-fragment-replaced') {
214
+ this.#handleIncludeFragmentReplaced()
215
+ }
216
+ }
177
217
 
178
- if (this.selectVariant === 'single') {
179
- // Only check, never uncheck here. Single-select mode does not allow unchecking a checked item.
180
- if (checked) {
181
- item.setAttribute('aria-checked', 'true')
182
- }
218
+ #handleInvokerActivated(event: Event) {
219
+ event.preventDefault()
220
+ event.stopPropagation()
183
221
 
184
- for (const checkedItem of this.querySelectorAll('[aria-checked]')) {
185
- if (checkedItem !== item) {
186
- checkedItem.setAttribute('aria-checked', 'false')
187
- }
188
- }
222
+ if (this.#isOpen()) {
223
+ this.#hide()
224
+ } else {
225
+ this.#show()
226
+ this.#firstItem?.focus()
227
+ }
228
+ }
189
229
 
190
- this.#setDynamicLabel()
191
- } else {
192
- // multi-select mode allows unchecking a checked item
193
- item.setAttribute('aria-checked', `${checked}`)
230
+ #handleDialogItemActivated(event: Event, dialog: HTMLElement) {
231
+ this.querySelector<HTMLElement>('.ActionListWrap')!.style.display = 'none'
232
+ const dialog_controller = new AbortController()
233
+ const {signal} = dialog_controller
234
+ const handleDialogClose = () => {
235
+ dialog_controller.abort()
236
+ this.querySelector<HTMLElement>('.ActionListWrap')!.style.display = ''
237
+ if (this.#isOpen()) {
238
+ this.#hide()
194
239
  }
240
+ }
241
+ dialog.addEventListener('close', handleDialogClose, {signal})
242
+ dialog.addEventListener('cancel', handleDialogClose, {signal})
243
+ }
244
+
245
+ #handleItemActivated(event: Event, item: Element) {
246
+ // Hide popover after current event loop to prevent changes in focus from
247
+ // altering the target of the event. Not doing this specifically affects
248
+ // <a> tags. It causes the event to be sent to the currently focused element
249
+ // instead of the anchor, which effectively prevents navigation, i.e. it
250
+ // appears as if hitting enter does nothing. Curiously, clicking instead
251
+ // works fine.
252
+ if (this.selectVariant !== 'multiple') {
253
+ setTimeout(() => {
254
+ if (this.#isOpen()) {
255
+ this.#hide()
256
+ }
257
+ })
258
+ }
259
+
260
+ // The rest of the code below deals with single/multiple selection behavior, and should not
261
+ // interfere with events fired by menu items whose behavior is specified outside the library.
262
+ if (this.selectVariant !== 'multiple' && this.selectVariant !== 'single') return
195
263
 
196
- this.#updateInput()
264
+ const ariaChecked = item.getAttribute('aria-checked')
265
+ const checked = ariaChecked !== 'true'
197
266
 
198
- if (event instanceof KeyboardEvent && event.target instanceof HTMLButtonElement) {
199
- // prevent buttons from being clicked twice
200
- event.preventDefault()
267
+ if (this.selectVariant === 'single') {
268
+ // Only check, never uncheck here. Single-select mode does not allow unchecking a checked item.
269
+ if (checked) {
270
+ item.setAttribute('aria-checked', 'true')
271
+ }
272
+
273
+ for (const checkedItem of this.querySelectorAll('[aria-checked]')) {
274
+ if (checkedItem !== item) {
275
+ checkedItem.setAttribute('aria-checked', 'false')
276
+ }
201
277
  }
278
+
279
+ this.#setDynamicLabel()
280
+ } else {
281
+ // multi-select mode allows unchecking a checked item
282
+ item.setAttribute('aria-checked', `${checked}`)
283
+ }
284
+
285
+ this.#updateInput()
286
+
287
+ if (event instanceof KeyboardEvent && event.target instanceof HTMLButtonElement) {
288
+ // prevent buttons from being clicked twice
289
+ event.preventDefault()
290
+ return
202
291
  }
203
292
  }
204
293
 
294
+ #activateItem(event: Event, item: Element) {
295
+ const eventWillActivateByDefault =
296
+ (event instanceof MouseEvent && event.type === 'click') ||
297
+ (event instanceof KeyboardEvent &&
298
+ event.type === 'keydown' &&
299
+ !(event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) &&
300
+ event.key === 'Enter')
301
+
302
+ // if the event will result in activating the current item by default, i.e. is a
303
+ // mouse click or keyboard enter, bail out
304
+ if (eventWillActivateByDefault) return
305
+
306
+ // otherwise, event will not result in activation by default, so we stop it and
307
+ // simulate a click
308
+ event.stopPropagation()
309
+ const elem = item as HTMLElement
310
+ elem.click()
311
+ }
312
+
313
+ #handleIncludeFragmentReplaced() {
314
+ if (this.#firstItem) this.#firstItem.focus()
315
+ this.#softDisableItems()
316
+ }
317
+
318
+ // Close when focus leaves menu
319
+ #handleFocusOut() {
320
+ this.#hide()
321
+ }
322
+
323
+ #show() {
324
+ this.popoverElement?.showPopover()
325
+ }
326
+
327
+ #hide() {
328
+ this.popoverElement?.hidePopover()
329
+ }
330
+
331
+ #isOpen() {
332
+ return this.popoverElement?.matches(':popover-open')
333
+ }
334
+
205
335
  #setDynamicLabel() {
206
336
  if (!this.dynamicLabel) return
207
337
  const invokerLabel = this.invokerLabel
@@ -261,18 +391,13 @@ export class ActionMenuElement extends HTMLElement {
261
391
  }
262
392
  }
263
393
 
264
- #isActivationKeydown(event: Event): boolean {
265
- return (
266
- event instanceof KeyboardEvent &&
267
- event.type === 'keydown' &&
268
- !(event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) &&
269
- (event.key === 'Enter' || event.key === ' ')
270
- )
271
- }
272
-
273
394
  get #firstItem(): HTMLElement | null {
274
395
  return this.querySelector(menuItemSelectors.join(','))
275
396
  }
397
+
398
+ get #items(): HTMLElement[] {
399
+ return Array.from(this.querySelectorAll(menuItemSelectors.join(',')))
400
+ }
276
401
  }
277
402
 
278
403
  if (!window.customElements.get('action-menu')) {
@@ -111,8 +111,6 @@ module Primer
111
111
  system_arguments,
112
112
  { aria: { disabled: true } }
113
113
  )
114
-
115
- content_arguments[:disabled] = "" if content_arguments[:tag] == :button
116
114
  end
117
115
 
118
116
  { data: data, **system_arguments, content_arguments: content_arguments }
@@ -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 _FocusGroupElement_instances, _FocusGroupElement_abortController, _FocusGroupElement_items_get;
12
+ var _FocusGroupElement_instances, _FocusGroupElement_retainSignal, _FocusGroupElement_abortController, _FocusGroupElement_items_get;
13
13
  import '@oddbird/popover-polyfill';
14
14
  const validSelectors = ['[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]'];
15
15
  const menuItemSelector = validSelectors.map(selector => `:not([hidden]) > ${selector}`).join(', ');
@@ -19,6 +19,7 @@ export default class FocusGroupElement extends HTMLElement {
19
19
  constructor() {
20
20
  super(...arguments);
21
21
  _FocusGroupElement_instances.add(this);
22
+ _FocusGroupElement_retainSignal.set(this, null);
22
23
  _FocusGroupElement_abortController.set(this, null);
23
24
  }
24
25
  get nowrap() {
@@ -57,11 +58,35 @@ export default class FocusGroupElement extends HTMLElement {
57
58
  (_a = __classPrivateFieldGet(this, _FocusGroupElement_abortController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
58
59
  }
59
60
  handleEvent(event) {
61
+ var _a;
60
62
  const { direction, nowrap } = this;
61
63
  if (event.type === 'focusin') {
62
64
  if (this.retain && event.target instanceof Element && event.target.matches(menuItemSelector)) {
65
+ (_a = __classPrivateFieldGet(this, _FocusGroupElement_retainSignal, "f")) === null || _a === void 0 ? void 0 : _a.abort();
66
+ const { signal } = (__classPrivateFieldSet(this, _FocusGroupElement_retainSignal, new AbortController(), "f"));
63
67
  for (const item of __classPrivateFieldGet(this, _FocusGroupElement_instances, "a", _FocusGroupElement_items_get)) {
64
68
  item.setAttribute('tabindex', item === event.target ? '0' : '-1');
69
+ const popover = event.target.closest('[popover]');
70
+ if (item === event.target && (popover === null || popover === void 0 ? void 0 : popover.popover) === 'auto' && popover.closest('focus-group') === this) {
71
+ popover.addEventListener('toggle', (toggleEvent) => {
72
+ var _a, _b;
73
+ if (!(toggleEvent.target instanceof Element))
74
+ return;
75
+ if (toggleEvent.newState === 'closed') {
76
+ (_a = __classPrivateFieldGet(this, _FocusGroupElement_retainSignal, "f")) === null || _a === void 0 ? void 0 : _a.abort();
77
+ item.setAttribute('tabindex', '-1');
78
+ if (popover.id) {
79
+ const invoker = this.querySelector(`[popovertarget="${popover.id}"]`);
80
+ if (invoker) {
81
+ invoker.setAttribute('tabindex', '0');
82
+ }
83
+ else {
84
+ (_b = __classPrivateFieldGet(this, _FocusGroupElement_instances, "a", _FocusGroupElement_items_get)[0]) === null || _b === void 0 ? void 0 : _b.setAttribute('tabindex', '0');
85
+ }
86
+ }
87
+ }
88
+ }, { signal });
89
+ }
65
90
  }
66
91
  }
67
92
  }
@@ -121,7 +146,7 @@ export default class FocusGroupElement extends HTMLElement {
121
146
  let el = focusEl;
122
147
  do {
123
148
  el = el.closest(`[popover]:not(:popover-open)`);
124
- if ((el === null || el === void 0 ? void 0 : el.popover) === 'auto') {
149
+ if ((el === null || el === void 0 ? void 0 : el.popover) === 'auto' && !['ArrowRight', 'ArrowLeft'].includes(event.key)) {
125
150
  el.showPopover();
126
151
  }
127
152
  el = (el === null || el === void 0 ? void 0 : el.parentElement) || null;
@@ -131,7 +156,7 @@ export default class FocusGroupElement extends HTMLElement {
131
156
  }
132
157
  }
133
158
  }
134
- _FocusGroupElement_abortController = new WeakMap(), _FocusGroupElement_instances = new WeakSet(), _FocusGroupElement_items_get = function _FocusGroupElement_items_get() {
159
+ _FocusGroupElement_retainSignal = new WeakMap(), _FocusGroupElement_abortController = new WeakMap(), _FocusGroupElement_instances = new WeakSet(), _FocusGroupElement_items_get = function _FocusGroupElement_items_get() {
135
160
  return this.querySelectorAll(menuItemSelector);
136
161
  };
137
162
  if (!customElements.get('focus-group')) {
@@ -8,6 +8,8 @@ const getMnemonicFor = (item: Element) => item.textContent?.trim()[0].toLowerCas
8
8
  const printable = /^\S$/
9
9
 
10
10
  export default class FocusGroupElement extends HTMLElement {
11
+ #retainSignal: AbortController | null = null
12
+
11
13
  get nowrap(): boolean {
12
14
  return this.hasAttribute('nowrap')
13
15
  }
@@ -60,8 +62,32 @@ export default class FocusGroupElement extends HTMLElement {
60
62
  const {direction, nowrap} = this
61
63
  if (event.type === 'focusin') {
62
64
  if (this.retain && event.target instanceof Element && event.target.matches(menuItemSelector)) {
65
+ this.#retainSignal?.abort()
66
+ const {signal} = (this.#retainSignal = new AbortController())
63
67
  for (const item of this.#items) {
64
68
  item.setAttribute('tabindex', item === event.target ? '0' : '-1')
69
+ const popover = event.target.closest<HTMLElement>('[popover]')
70
+ if (item === event.target && popover?.popover === 'auto' && popover.closest('focus-group') === this) {
71
+ popover.addEventListener(
72
+ 'toggle',
73
+ (toggleEvent: Event) => {
74
+ if (!(toggleEvent.target instanceof Element)) return
75
+ if ((toggleEvent as ToggleEvent).newState === 'closed') {
76
+ this.#retainSignal?.abort()
77
+ item.setAttribute('tabindex', '-1')
78
+ if (popover.id) {
79
+ const invoker = this.querySelector(`[popovertarget="${popover.id}"]`)
80
+ if (invoker) {
81
+ invoker.setAttribute('tabindex', '0')
82
+ } else {
83
+ this.#items[0]?.setAttribute('tabindex', '0')
84
+ }
85
+ }
86
+ }
87
+ },
88
+ {signal}
89
+ )
90
+ }
65
91
  }
66
92
  }
67
93
  } else if (event instanceof KeyboardEvent) {
@@ -111,7 +137,7 @@ export default class FocusGroupElement extends HTMLElement {
111
137
  let el: HTMLElement | null = focusEl
112
138
  do {
113
139
  el = el.closest(`[popover]:not(:popover-open)`)
114
- if (el?.popover === 'auto') {
140
+ if (el?.popover === 'auto' && !['ArrowRight', 'ArrowLeft'].includes(event.key)) {
115
141
  el.showPopover()
116
142
  }
117
143
  el = el?.parentElement || null
@@ -5,7 +5,7 @@ module Primer
5
5
  module ViewComponents
6
6
  module VERSION
7
7
  MAJOR = 0
8
- MINOR = 10
8
+ MINOR = 11
9
9
  PATCH = 0
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
@@ -8,14 +8,15 @@
8
8
 
9
9
  <%= render(Primer::Alpha::ActionMenu.new) do |component| %>
10
10
  <% component.with_show_button { "Trigger" } %>
11
- <% component.with_item(label: "Alert", tag: :button, id: "alert-item") %>
12
- <% component.with_item(label: "Navigate", tag: :a, content_arguments: { href: action_menu_landing_path }) %>
13
- <% component.with_item(label: "Copy text", tag: :"clipboard-copy", content_arguments: { value: "Text to copy" }) %>
11
+ <% component.with_item(label: "Alert", tag: :button, id: "alert-item", disabled: disable_items) %>
12
+ <% component.with_item(label: "Navigate", tag: :a, content_arguments: { href: action_menu_landing_path }, disabled: disable_items) %>
13
+ <% component.with_item(label: "Copy text", tag: :"clipboard-copy", content_arguments: { value: "Text to copy" }, disabled: disable_items) %>
14
14
  <% component.with_item(
15
15
  label: "Submit form",
16
16
  href: action_menu_form_action_path,
17
17
  form_arguments: {
18
18
  name: "foo", value: "bar", method: :post
19
- }
19
+ },
20
+ disabled: disable_items
20
21
  ) %>
21
22
  <% end %>
@@ -216,7 +216,10 @@ module Primer
216
216
 
217
217
  # @label With actions
218
218
  #
219
- def with_actions; end
219
+ # @param disable_items toggle
220
+ def with_actions(disable_items: false)
221
+ render_with_template(locals: { disable_items: disable_items })
222
+ end
220
223
 
221
224
  # @label Single select form
222
225
  #
@@ -46,7 +46,18 @@
46
46
  "source": "https://github.com/primer/view_components/tree/main/app/components/primer/alpha/action_bar/item.rb",
47
47
  "lookbook": "https://primer.style/view-components/lookbook/inspect/primer/alpha/action_bar/item/default/",
48
48
  "parameters": [
49
-
49
+ {
50
+ "name": "item_content",
51
+ "type": "String",
52
+ "default": "N/A",
53
+ "description": "The content to render inside the item."
54
+ },
55
+ {
56
+ "name": "item_arguments",
57
+ "type": "Hash",
58
+ "default": "N/A",
59
+ "description": "[System arguments](/system-arguments)"
60
+ }
50
61
  ]
51
62
  },
52
63
  {
@@ -139,7 +139,18 @@
139
139
  "source": "https://github.com/primer/view_components/tree/main/app/components/primer/alpha/action_bar/item.rb",
140
140
  "lookbook": "https://primer.style/view-components/lookbook/inspect/primer/alpha/action_bar/item/default/",
141
141
  "parameters": [
142
-
142
+ {
143
+ "name": "item_content",
144
+ "type": "String",
145
+ "default": "N/A",
146
+ "description": "The content to render inside the item."
147
+ },
148
+ {
149
+ "name": "item_arguments",
150
+ "type": "Hash",
151
+ "default": "N/A",
152
+ "description": "{{link_to_system_arguments_docs}}"
153
+ }
143
154
  ],
144
155
  "slots": [
145
156
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: primer_view_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-28 00:00:00.000000000 Z
11
+ date: 2023-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview