primer_view_components 0.10.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -0
- data/app/assets/javascripts/app/components/primer/alpha/tool_tip.d.ts +1 -0
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/assets/styles/primer_view_components.css +1 -1
- data/app/assets/styles/primer_view_components.css.map +1 -1
- data/app/components/primer/alpha/action_bar/item.rb +7 -4
- data/app/components/primer/alpha/action_bar.rb +2 -2
- data/app/components/primer/alpha/action_bar_element.js +2 -2
- data/app/components/primer/alpha/action_bar_element.ts +2 -2
- data/app/components/primer/alpha/action_menu/action_menu_element.js +168 -84
- data/app/components/primer/alpha/action_menu/action_menu_element.ts +204 -79
- data/app/components/primer/alpha/action_menu/list.rb +0 -2
- data/app/components/primer/alpha/segmented_control/item.html.erb +1 -8
- data/app/components/primer/alpha/segmented_control/item.rb +38 -4
- data/app/components/primer/alpha/segmented_control.css +1 -1
- data/app/components/primer/alpha/segmented_control.css.map +1 -1
- data/app/components/primer/alpha/segmented_control.pcss +3 -1
- data/app/components/primer/alpha/tool_tip.d.ts +1 -0
- data/app/components/primer/alpha/tool_tip.js +17 -2
- data/app/components/primer/alpha/tool_tip.ts +16 -0
- data/app/components/primer/beta/base_button.rb +4 -0
- data/app/components/primer/beta/button.css +1 -1
- data/app/components/primer/beta/button.css.map +1 -1
- data/app/components/primer/beta/button.pcss +6 -2
- data/app/components/primer/focus_group.js +28 -3
- data/app/components/primer/focus_group.ts +27 -1
- data/lib/primer/view_components/version.rb +1 -1
- data/previews/primer/alpha/action_menu_preview/with_actions.html.erb +5 -4
- data/previews/primer/alpha/action_menu_preview.rb +4 -1
- data/previews/primer/alpha/segmented_control_preview.rb +35 -0
- data/previews/primer/alpha/tooltip_preview/tooltip_with_dialog_moving_focus_to_input.html.erb +23 -0
- data/previews/primer/alpha/tooltip_preview.rb +5 -0
- data/previews/primer/beta/button_preview.rb +20 -2
- data/previews/primer/beta/icon_button_preview.rb +3 -0
- data/static/arguments.json +18 -1
- data/static/info_arch.json +107 -3
- data/static/previews.json +65 -0
- metadata +3 -2
@@ -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
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
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
|
-
|
145
|
-
|
146
|
-
|
147
|
-
}
|
188
|
+
})
|
189
|
+
|
190
|
+
return
|
148
191
|
}
|
149
192
|
|
150
|
-
|
193
|
+
const item = (event.target as Element).closest(menuItemSelectors.join(','))
|
194
|
+
const targetIsItem = item !== null
|
151
195
|
|
152
|
-
if (
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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
|
-
|
170
|
-
|
171
|
-
|
208
|
+
this.#activateItem(event, item)
|
209
|
+
this.#handleItemActivated(event, item)
|
210
|
+
return
|
211
|
+
}
|
172
212
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
213
|
+
if (event.type === 'include-fragment-replaced') {
|
214
|
+
this.#handleIncludeFragmentReplaced()
|
215
|
+
}
|
216
|
+
}
|
177
217
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
item.setAttribute('aria-checked', 'true')
|
182
|
-
}
|
218
|
+
#handleInvokerActivated(event: Event) {
|
219
|
+
event.preventDefault()
|
220
|
+
event.stopPropagation()
|
183
221
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
222
|
+
if (this.#isOpen()) {
|
223
|
+
this.#hide()
|
224
|
+
} else {
|
225
|
+
this.#show()
|
226
|
+
this.#firstItem?.focus()
|
227
|
+
}
|
228
|
+
}
|
189
229
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
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
|
-
|
264
|
+
const ariaChecked = item.getAttribute('aria-checked')
|
265
|
+
const checked = ariaChecked !== 'true'
|
197
266
|
|
198
|
-
|
199
|
-
|
200
|
-
|
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')) {
|
@@ -2,12 +2,5 @@
|
|
2
2
|
"SegmentedControl-item",
|
3
3
|
"SegmentedControl-item--selected": @selected
|
4
4
|
) %>" role="listitem" data-targets="segmented-control.items">
|
5
|
-
|
6
|
-
<%= render Primer::Beta::IconButton.new(icon: @icon, "aria-label": @label, **@system_arguments) %>
|
7
|
-
<% else %>
|
8
|
-
<%= render Primer::Beta::Button.new(**@system_arguments) do |button| %>
|
9
|
-
<% button.with_leading_visual_icon(icon: @icon) unless @icon.nil? %>
|
10
|
-
<%= @label %>
|
11
|
-
<% end %>
|
12
|
-
<% end %>
|
5
|
+
<%= render @button %>
|
13
6
|
</li>
|
@@ -13,16 +13,50 @@ module Primer
|
|
13
13
|
# @param selected [Boolean] Whether the item is selected
|
14
14
|
# @param icon [Symbol] The icon to use
|
15
15
|
# @param hide_labels [Symbol] Whether to only show the icon
|
16
|
-
def initialize(
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
def initialize(
|
17
|
+
label:,
|
18
|
+
selected: false,
|
19
|
+
icon: nil,
|
20
|
+
hide_labels: false,
|
21
|
+
**system_arguments
|
22
|
+
)
|
20
23
|
@selected = selected
|
21
24
|
|
22
25
|
@system_arguments = system_arguments
|
23
26
|
@system_arguments[:"data-action"] = "click:segmented-control#select" if system_arguments[:href].nil?
|
24
27
|
@system_arguments[:"aria-current"] = selected
|
25
28
|
@system_arguments[:scheme] = :invisible
|
29
|
+
|
30
|
+
if hide_labels
|
31
|
+
@button = Primer::Beta::IconButton.new(
|
32
|
+
icon: icon,
|
33
|
+
"aria-label": label,
|
34
|
+
**@system_arguments
|
35
|
+
)
|
36
|
+
else
|
37
|
+
@button = Primer::Beta::Button.new(**@system_arguments)
|
38
|
+
@button.with_leading_visual_icon(icon: icon) if icon
|
39
|
+
@button.with_content(label)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# @!parse
|
44
|
+
# # Optional trailing Label
|
45
|
+
# #
|
46
|
+
# # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Beta::Button) %>'s `with_trailing_visual_label` slot.
|
47
|
+
# renders_one(:trailing_visual_label)
|
48
|
+
|
49
|
+
# Optional trailing label.
|
50
|
+
#
|
51
|
+
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Beta::Button) %>'s `with_trailing_visual_label` slot.
|
52
|
+
def with_trailing_visual_label(**system_arguments, &block)
|
53
|
+
@button.with_trailing_visual_label(**system_arguments, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def before_render
|
59
|
+
content
|
26
60
|
end
|
27
61
|
end
|
28
62
|
end
|
@@ -1 +1 @@
|
|
1
|
-
.SegmentedControl{background-color:var(--controlTrack-bgColor-rest,var(--color-segmented-control-bg));border-radius:var(--borderRadius-medium,.375rem);display:inline-flex;list-style:none}.SegmentedControl-item{border:var(--borderWidth-thin,max(1px,.0625rem)) solid #0000;border-radius:var(--borderRadius-medium,.375rem);display:inline-flex;padding:var(--control-xsmall-paddingInline-condensed,.25rem);position:relative}.SegmentedControl-item .Button--invisible:hover:not(:disabled){background-color:var(--controlTrack-bgColor-hover,var(--color-action-list-item-default-hover-bg))}.SegmentedControl-item .Button--invisible:active:not(:disabled){background-color:var(--controlTrack-bgColor-active,var(--color-action-list-item-default-active-bg))}.SegmentedControl-item.SegmentedControl-item--selected{background-color:var(--controlKnob-bgColor-rest,var(--color-segmented-control-button-bg));border-color:var(--controlKnob-borderColor-rest,var(--color-segmented-control-button-selected-border))}.SegmentedControl-item.SegmentedControl-item--selected .Button{font-weight:var(--base-text-weight-semibold,600)}.SegmentedControl-item.SegmentedControl-item--selected .Button:hover{background-color:initial}.SegmentedControl-item.SegmentedControl-item--selected:before{border-color:#0000!important}.SegmentedControl-item.SegmentedControl-item--selected+.SegmentedControl-item:before{border-color:#0000}.SegmentedControl-item .Button-label[data-content]:before{content:attr(data-content);display:block;font-weight:var(--base-text-weight-semibold,600);height:0;visibility:hidden}.SegmentedControl-item:not(:first-child):before{border-left:var(--borderWidth-thin,max(1px,.0625rem)) solid var(--borderColor-default,var(--color-border-default));content:"";inset:0 0 0 -1px;margin-bottom:var(--control-medium-paddingBlock,.375rem);margin-top:var(--control-medium-paddingBlock,.375rem);position:absolute}.SegmentedControl-item .Button{border:0;color:var(--button-default-fgColor-rest,var(--color-btn-text));font-weight:var(--base-text-weight-normal,400);transition:none}.SegmentedControl-item .Button:focus-visible{border-radius:calc(var(--borderRadius-medium,.375rem) - 5px);outline-offset:calc(var(--control-xsmall-paddingInline-condensed,.25rem) - var(--borderWidth-thin,max(1px, .0625rem)))}.SegmentedControl-item .Button--small{height:calc(var(--control-small-size,1.75rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2);padding:0 calc(var(--control-small-paddingInline-condensed,.5rem) - var(--control-xsmall-paddingInline-condensed,.25rem))}.SegmentedControl-item .Button--small.Button--iconOnly{width:calc(var(--control-medium-size,2rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2)}.SegmentedControl-item .Button--small.Button--iconOnly:before{content:"";height:100%;left:50%;min-height:var(--control-medium-size,2rem);min-width:var(--control-medium-size,2rem);position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:100%}.SegmentedControl-item .Button--medium{height:calc(var(--control-medium-size,2rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2);padding:0 calc(var(--control-medium-paddingInline-normal,.75rem) - var(--control-xsmall-paddingInline-condensed,.25rem))}.SegmentedControl-item .Button--medium.Button--iconOnly{width:calc(var(--control-medium-size,2rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2)}.SegmentedControl-item .Button--medium.Button--iconOnly:before{content:"";height:100%;left:50%;min-height:var(--control-medium-size,2rem);min-width:var(--control-medium-size,2rem);position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:100%}.SegmentedControl-item .Button--large{height:calc(var(--control-large-size,2.5rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2);padding:0 calc(var(--control-large-paddingInline-spacious,1rem) - var(--control-xsmall-paddingInline-condensed,.25rem))}.SegmentedControl-item .Button--large.Button--iconOnly{width:calc(var(--control-large-size,2.5rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2)}.SegmentedControl-item .Button--large.Button--iconOnly:before{content:"";height:100%;left:50%;min-height:var(--control-large-size,2.5rem);min-width:var(--control-large-size,2.5rem);position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:100%}.SegmentedControl-item .Button--iconOnly{padding:initial}.SegmentedControl-item .Button--invisible.Button--invisible-noVisuals .Button-label{color:var(--button-default-fgColor-rest,var(--color-btn-text))}.SegmentedControl--fullWidth{display:flex}.SegmentedControl--fullWidth .SegmentedControl-item{flex:1;justify-content:center}.SegmentedControl--fullWidth .Button--iconOnly,.SegmentedControl--fullWidth .Button-withTooltip{width:100
|
1
|
+
.SegmentedControl{background-color:var(--controlTrack-bgColor-rest,var(--color-segmented-control-bg));border-radius:var(--borderRadius-medium,.375rem);display:inline-flex;list-style:none}.SegmentedControl-item{border:var(--borderWidth-thin,max(1px,.0625rem)) solid #0000;border-radius:var(--borderRadius-medium,.375rem);display:inline-flex;padding:var(--control-xsmall-paddingInline-condensed,.25rem);position:relative}.SegmentedControl-item .Button--invisible:hover:not(:disabled){background-color:var(--controlTrack-bgColor-hover,var(--color-action-list-item-default-hover-bg))}.SegmentedControl-item .Button--invisible:active:not(:disabled){background-color:var(--controlTrack-bgColor-active,var(--color-action-list-item-default-active-bg))}.SegmentedControl-item.SegmentedControl-item--selected{background-color:var(--controlKnob-bgColor-rest,var(--color-segmented-control-button-bg));border-color:var(--controlKnob-borderColor-rest,var(--color-segmented-control-button-selected-border))}.SegmentedControl-item.SegmentedControl-item--selected .Button{font-weight:var(--base-text-weight-semibold,600)}.SegmentedControl-item.SegmentedControl-item--selected .Button:hover{background-color:initial}.SegmentedControl-item.SegmentedControl-item--selected:before{border-color:#0000!important}.SegmentedControl-item.SegmentedControl-item--selected+.SegmentedControl-item:before{border-color:#0000}.SegmentedControl-item .Button-label[data-content]:before{content:attr(data-content);display:block;font-weight:var(--base-text-weight-semibold,600);height:0;visibility:hidden}.SegmentedControl-item:not(:first-child):before{border-left:var(--borderWidth-thin,max(1px,.0625rem)) solid var(--borderColor-default,var(--color-border-default));content:"";inset:0 0 0 -1px;margin-bottom:var(--control-medium-paddingBlock,.375rem);margin-top:var(--control-medium-paddingBlock,.375rem);position:absolute}.SegmentedControl-item .Button{border:0;color:var(--button-default-fgColor-rest,var(--color-btn-text));font-weight:var(--base-text-weight-normal,400);transition:none}.SegmentedControl-item .Button:focus-visible{border-radius:calc(var(--borderRadius-medium,.375rem) - 5px);outline-offset:calc(var(--control-xsmall-paddingInline-condensed,.25rem) - var(--borderWidth-thin,max(1px, .0625rem)))}.SegmentedControl-item .Button--small{height:calc(var(--control-small-size,1.75rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2);padding:0 calc(var(--control-small-paddingInline-condensed,.5rem) - var(--control-xsmall-paddingInline-condensed,.25rem))}.SegmentedControl-item .Button--small.Button--iconOnly{width:calc(var(--control-medium-size,2rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2)}.SegmentedControl-item .Button--small.Button--iconOnly:before{content:"";height:100%;left:50%;min-height:var(--control-medium-size,2rem);min-width:var(--control-medium-size,2rem);position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:100%}.SegmentedControl-item .Button--medium{height:calc(var(--control-medium-size,2rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2);padding:0 calc(var(--control-medium-paddingInline-normal,.75rem) - var(--control-xsmall-paddingInline-condensed,.25rem))}.SegmentedControl-item .Button--medium.Button--iconOnly{width:calc(var(--control-medium-size,2rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2)}.SegmentedControl-item .Button--medium.Button--iconOnly:before{content:"";height:100%;left:50%;min-height:var(--control-medium-size,2rem);min-width:var(--control-medium-size,2rem);position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:100%}.SegmentedControl-item .Button--large{height:calc(var(--control-large-size,2.5rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2);padding:0 calc(var(--control-large-paddingInline-spacious,1rem) - var(--control-xsmall-paddingInline-condensed,.25rem))}.SegmentedControl-item .Button--large.Button--iconOnly{width:calc(var(--control-large-size,2.5rem) - var(--control-xsmall-paddingInline-condensed,.25rem)*2 - var(--borderWidth-thin,max(1px, .0625rem))*2)}.SegmentedControl-item .Button--large.Button--iconOnly:before{content:"";height:100%;left:50%;min-height:var(--control-large-size,2.5rem);min-width:var(--control-large-size,2.5rem);position:absolute;top:50%;transform:translateX(-50%) translateY(-50%);width:100%}.SegmentedControl-item .Button--iconOnly{padding:initial}.SegmentedControl-item .Button--invisible.Button--invisible-noVisuals .Button-label{color:var(--button-default-fgColor-rest,var(--color-btn-text))}.SegmentedControl--fullWidth{display:flex}.SegmentedControl--fullWidth .SegmentedControl-item{flex:1;justify-content:center}.SegmentedControl--fullWidth .Button--iconOnly,.SegmentedControl--fullWidth .Button-withTooltip{display:flex;justify-content:center;width:100%!important}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["segmented_control.pcss","<no source>"],"names":[],"mappings":"AAEA,kBAGE,mFAAqF,CACrF,gDAAyC,CAHzC,mBAAoB,CACpB,eAGF,CAEA,uBAGE,4DAAiD,CACjD,gDAAyC,CAFzC,mBAAoB,CAGpB,4DAAsD,CAJtD,iBAkIF,CA3HI,+DACE,iGACF,CAEA,gEACE,mGACF,CAIF,uDACE,yFAA2F,CAC3F,sGAiBF,CAfE,+DACE,gDAKF,CAHE,qEACE,wBACF,CAGF,8DACE,4BACF,CAEA,qFACE,kBACF,CAIF,0DAKE,0BAA2B,CAJ3B,aAAc,CAEd,gDAA6C,CAD7C,QAAS,CAET,iBAEF,CAIE,gDAME,kHAAqE,CADrE,UAAW,CAHX,gBAAiB,CAEjB,wDAAiD,CADjD,qDAA8C,CAF9C,iBAMF,CAIF,+BACE,QAAS,CAGT,8DAAyC,CAFzC,8CAA2C,CAC3C,eAOF,CAJE,6CAEE,4DAAqD,CADrD,sHAEF,CAGF,sCACE,sJAEC,CACD,yHAWF,CATE,uDACE,mJAOF,CAFI,8DC9FR,WAAA,YAAA,SAAA,2CAAA,0CAAA,kBAAA,QAAA,4CAAA,UD8FoF,CAKlF,uCACE,oJAEC,CACD,wHAWF,CATE,wDACE,mJAOF,CAFI,+DC/GR,WAAA,YAAA,SAAA,2CAAA,0CAAA,kBAAA,QAAA,4CAAA,UD+GoF,CAKlF,sCACE,qJAEC,CACD,uHAWF,CATE,uDACE,oJAOF,CAFI,8DChIR,WAAA,YAAA,SAAA,4CAAA,2CAAA,kBAAA,QAAA,4CAAA,UDgIkF,CAKhF,yCACE,eACF,CAEA,oFACE,8DACF,CAIF,6BACE,
|
1
|
+
{"version":3,"sources":["segmented_control.pcss","<no source>"],"names":[],"mappings":"AAEA,kBAGE,mFAAqF,CACrF,gDAAyC,CAHzC,mBAAoB,CACpB,eAGF,CAEA,uBAGE,4DAAiD,CACjD,gDAAyC,CAFzC,mBAAoB,CAGpB,4DAAsD,CAJtD,iBAkIF,CA3HI,+DACE,iGACF,CAEA,gEACE,mGACF,CAIF,uDACE,yFAA2F,CAC3F,sGAiBF,CAfE,+DACE,gDAKF,CAHE,qEACE,wBACF,CAGF,8DACE,4BACF,CAEA,qFACE,kBACF,CAIF,0DAKE,0BAA2B,CAJ3B,aAAc,CAEd,gDAA6C,CAD7C,QAAS,CAET,iBAEF,CAIE,gDAME,kHAAqE,CADrE,UAAW,CAHX,gBAAiB,CAEjB,wDAAiD,CADjD,qDAA8C,CAF9C,iBAMF,CAIF,+BACE,QAAS,CAGT,8DAAyC,CAFzC,8CAA2C,CAC3C,eAOF,CAJE,6CAEE,4DAAqD,CADrD,sHAEF,CAGF,sCACE,sJAEC,CACD,yHAWF,CATE,uDACE,mJAOF,CAFI,8DC9FR,WAAA,YAAA,SAAA,2CAAA,0CAAA,kBAAA,QAAA,4CAAA,UD8FoF,CAKlF,uCACE,oJAEC,CACD,wHAWF,CATE,wDACE,mJAOF,CAFI,+DC/GR,WAAA,YAAA,SAAA,2CAAA,0CAAA,kBAAA,QAAA,4CAAA,UD+GoF,CAKlF,sCACE,qJAEC,CACD,uHAWF,CATE,uDACE,oJAOF,CAFI,8DChIR,WAAA,YAAA,SAAA,4CAAA,2CAAA,kBAAA,QAAA,4CAAA,UDgIkF,CAKhF,yCACE,eACF,CAEA,oFACE,8DACF,CAIF,6BACE,YAcF,CAZE,oDACE,MAAO,CACP,sBACF,CAGA,gGAGE,YAAa,CACb,sBAAuB,CAFvB,oBAGF","file":"segmented_control.css","sourcesContent":["/* SegmentedControl */\n\n.SegmentedControl {\n display: inline-flex;\n list-style: none;\n background-color: var(--controlTrack-bgColor-rest, var(--color-segmented-control-bg));\n border-radius: var(--borderRadius-medium);\n}\n\n.SegmentedControl-item {\n position: relative;\n display: inline-flex;\n border: var(--borderWidth-thin) solid transparent;\n border-radius: var(--borderRadius-medium);\n padding: var(--control-xsmall-paddingInline-condensed);\n\n & .Button--invisible {\n &:hover:not(:disabled) {\n background-color: var(--controlTrack-bgColor-hover, var(--color-action-list-item-default-hover-bg));\n }\n\n &:active:not(:disabled) {\n background-color: var(--controlTrack-bgColor-active, var(--color-action-list-item-default-active-bg));\n }\n }\n\n /* Selected ---------------------------------------- */\n &.SegmentedControl-item--selected {\n background-color: var(--controlKnob-bgColor-rest, var(--color-segmented-control-button-bg));\n border-color: var(--controlKnob-borderColor-rest, var(--color-segmented-control-button-selected-border));\n\n & .Button {\n font-weight: var(--base-text-weight-semibold);\n\n &:hover {\n background-color: transparent;\n }\n }\n\n &::before {\n border-color: transparent !important;\n }\n\n & + .SegmentedControl-item::before {\n border-color: transparent;\n }\n }\n\n /* renders a visibly hidden \"copy\" of the text in bold, reserving box space for when text becomes bold on selected */\n & .Button-label[data-content]::before {\n display: block;\n height: 0;\n font-weight: var(--base-text-weight-semibold);\n visibility: hidden;\n content: attr(data-content);\n }\n\n /* Separator lines */\n &:not(:first-child) {\n &::before {\n position: absolute;\n inset: 0 0 0 -1px;\n margin-top: var(--control-medium-paddingBlock);\n margin-bottom: var(--control-medium-paddingBlock);\n content: '';\n border-left: var(--borderWidth-thin) solid var(--borderColor-default);\n }\n }\n\n /* Button ----------------------------------------- */\n & .Button {\n border: 0;\n font-weight: var(--base-text-weight-normal);\n transition: none;\n color: var(--button-default-fgColor-rest);\n\n &:focus-visible {\n outline-offset: calc(var(--control-xsmall-paddingInline-condensed) - var(--borderWidth-thin));\n border-radius: calc(var(--borderRadius-medium) - 5px);\n }\n }\n\n & .Button--small {\n height: calc(\n var(--control-small-size) - var(--control-xsmall-paddingInline-condensed) * 2 - var(--borderWidth-thin) * 2\n );\n padding: 0 calc(var(--control-small-paddingInline-condensed) - var(--control-xsmall-paddingInline-condensed));\n\n &.Button--iconOnly {\n width: calc(\n var(--control-medium-size) - var(--control-xsmall-paddingInline-condensed) * 2 - var(--borderWidth-thin) * 2\n );\n\n &::before {\n @mixin minTouchTarget var(--control-medium-size), var(--control-medium-size);\n }\n }\n }\n\n & .Button--medium {\n height: calc(\n var(--control-medium-size) - var(--control-xsmall-paddingInline-condensed) * 2 - var(--borderWidth-thin) * 2\n );\n padding: 0 calc(var(--control-medium-paddingInline-normal) - var(--control-xsmall-paddingInline-condensed));\n\n &.Button--iconOnly {\n width: calc(\n var(--control-medium-size) - var(--control-xsmall-paddingInline-condensed) * 2 - var(--borderWidth-thin) * 2\n );\n\n &::before {\n @mixin minTouchTarget var(--control-medium-size), var(--control-medium-size);\n }\n }\n }\n\n & .Button--large {\n height: calc(\n var(--control-large-size) - var(--control-xsmall-paddingInline-condensed) * 2 - var(--borderWidth-thin) * 2\n );\n padding: 0 calc(var(--control-large-paddingInline-spacious) - var(--control-xsmall-paddingInline-condensed));\n\n &.Button--iconOnly {\n width: calc(\n var(--control-large-size) - var(--control-xsmall-paddingInline-condensed) * 2 - var(--borderWidth-thin) * 2\n );\n\n &::before {\n @mixin minTouchTarget var(--control-large-size), var(--control-large-size);\n }\n }\n }\n\n & .Button--iconOnly {\n padding: initial;\n }\n\n & .Button--invisible.Button--invisible-noVisuals .Button-label {\n color: var(--button-default-fgColor-rest);\n }\n}\n\n/* fullWidth */\n.SegmentedControl--fullWidth {\n display: flex;\n\n & .SegmentedControl-item {\n flex: 1;\n justify-content: center;\n }\n\n /* is .Button-withTooltip used anywhere? can't find use of it */\n & .Button--iconOnly,\n & .Button-withTooltip {\n width: 100% !important;\n display: flex;\n justify-content: center;\n }\n}\n",null]}
|
@@ -3,6 +3,7 @@ type Direction = 'n' | 's' | 'e' | 'w' | 'ne' | 'se' | 'nw' | 'sw';
|
|
3
3
|
declare class ToolTipElement extends HTMLElement {
|
4
4
|
#private;
|
5
5
|
styles(): string;
|
6
|
+
get showReason(): "focus" | "mouse";
|
6
7
|
get htmlFor(): string;
|
7
8
|
set htmlFor(value: string);
|
8
9
|
get type(): 'description' | 'label';
|
@@ -9,7 +9,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
10
10
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
11
11
|
};
|
12
|
-
var _ToolTipElement_instances, _ToolTipElement_abortController, _ToolTipElement_align, _ToolTipElement_side, _ToolTipElement_allowUpdatePosition, _ToolTipElement_update, _ToolTipElement_updateControlReference, _ToolTipElement_updateDirection, _ToolTipElement_updatePosition;
|
12
|
+
var _ToolTipElement_instances, _ToolTipElement_abortController, _ToolTipElement_align, _ToolTipElement_side, _ToolTipElement_allowUpdatePosition, _ToolTipElement_showReason, _ToolTipElement_update, _ToolTipElement_updateControlReference, _ToolTipElement_updateDirection, _ToolTipElement_updatePosition;
|
13
13
|
import '@oddbird/popover-polyfill';
|
14
14
|
import { getAnchoredPosition } from '@primer/behaviors';
|
15
15
|
const isPopoverOpen = (() => {
|
@@ -60,6 +60,15 @@ function closeOpenTooltips(except) {
|
|
60
60
|
function focusOutListener() {
|
61
61
|
closeOpenTooltips();
|
62
62
|
}
|
63
|
+
function focusInListener(event) {
|
64
|
+
setTimeout(() => {
|
65
|
+
for (const tooltip of openTooltips) {
|
66
|
+
if (isPopoverOpen(tooltip) && tooltip.showReason === 'focus' && tooltip.control !== event.target) {
|
67
|
+
tooltip.hidePopover();
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}, 0);
|
71
|
+
}
|
63
72
|
const tooltips = new Set();
|
64
73
|
const openTooltips = new Set();
|
65
74
|
class ToolTipElement extends HTMLElement {
|
@@ -70,6 +79,7 @@ class ToolTipElement extends HTMLElement {
|
|
70
79
|
_ToolTipElement_align.set(this, 'center');
|
71
80
|
_ToolTipElement_side.set(this, 'outside-bottom');
|
72
81
|
_ToolTipElement_allowUpdatePosition.set(this, false);
|
82
|
+
_ToolTipElement_showReason.set(this, 'mouse');
|
73
83
|
}
|
74
84
|
styles() {
|
75
85
|
return `
|
@@ -203,6 +213,9 @@ class ToolTipElement extends HTMLElement {
|
|
203
213
|
}
|
204
214
|
`;
|
205
215
|
}
|
216
|
+
get showReason() {
|
217
|
+
return __classPrivateFieldGet(this, _ToolTipElement_showReason, "f");
|
218
|
+
}
|
206
219
|
get htmlFor() {
|
207
220
|
return this.getAttribute('for') || '';
|
208
221
|
}
|
@@ -269,6 +282,7 @@ class ToolTipElement extends HTMLElement {
|
|
269
282
|
signal
|
270
283
|
});
|
271
284
|
this.ownerDocument.addEventListener('focusout', focusOutListener);
|
285
|
+
this.ownerDocument.addEventListener('focusin', focusInListener);
|
272
286
|
this.ownerDocument.addEventListener('keydown', this, { signal });
|
273
287
|
}
|
274
288
|
disconnectedCallback() {
|
@@ -293,6 +307,7 @@ class ToolTipElement extends HTMLElement {
|
|
293
307
|
const shouldHide = isMouseLeaveFromButton || isEscapeKeydown || isMouseDownOnButton || isOpeningOtherPopover;
|
294
308
|
await Promise.resolve();
|
295
309
|
if (!showing && shouldShow && !isPopoverOpen(this)) {
|
310
|
+
__classPrivateFieldSet(this, _ToolTipElement_showReason, event.type === 'mouseenter' ? 'mouse' : 'focus', "f");
|
296
311
|
this.showPopover();
|
297
312
|
}
|
298
313
|
else if (showing && shouldHide && isPopoverOpen(this)) {
|
@@ -313,7 +328,7 @@ class ToolTipElement extends HTMLElement {
|
|
313
328
|
}
|
314
329
|
}
|
315
330
|
}
|
316
|
-
_ToolTipElement_abortController = new WeakMap(), _ToolTipElement_align = new WeakMap(), _ToolTipElement_side = new WeakMap(), _ToolTipElement_allowUpdatePosition = new WeakMap(), _ToolTipElement_instances = new WeakSet(), _ToolTipElement_update = function _ToolTipElement_update(isOpen) {
|
331
|
+
_ToolTipElement_abortController = new WeakMap(), _ToolTipElement_align = new WeakMap(), _ToolTipElement_side = new WeakMap(), _ToolTipElement_allowUpdatePosition = new WeakMap(), _ToolTipElement_showReason = new WeakMap(), _ToolTipElement_instances = new WeakSet(), _ToolTipElement_update = function _ToolTipElement_update(isOpen) {
|
317
332
|
if (isOpen) {
|
318
333
|
openTooltips.add(this);
|
319
334
|
this.classList.remove(TOOLTIP_SR_ONLY_CLASS);
|
@@ -53,6 +53,16 @@ function focusOutListener() {
|
|
53
53
|
closeOpenTooltips()
|
54
54
|
}
|
55
55
|
|
56
|
+
function focusInListener(event: Event) {
|
57
|
+
setTimeout(() => {
|
58
|
+
for (const tooltip of openTooltips) {
|
59
|
+
if (isPopoverOpen(tooltip) && tooltip.showReason === 'focus' && tooltip.control !== event.target) {
|
60
|
+
tooltip.hidePopover()
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}, 0)
|
64
|
+
}
|
65
|
+
|
56
66
|
const tooltips = new Set<ToolTipElement>()
|
57
67
|
const openTooltips = new Set<ToolTipElement>()
|
58
68
|
class ToolTipElement extends HTMLElement {
|
@@ -193,6 +203,10 @@ class ToolTipElement extends HTMLElement {
|
|
193
203
|
#align: AnchorAlignment = 'center'
|
194
204
|
#side: AnchorSide = 'outside-bottom'
|
195
205
|
#allowUpdatePosition = false
|
206
|
+
#showReason: 'focus' | 'mouse' = 'mouse'
|
207
|
+
get showReason() {
|
208
|
+
return this.#showReason
|
209
|
+
}
|
196
210
|
|
197
211
|
get htmlFor(): string {
|
198
212
|
return this.getAttribute('for') || ''
|
@@ -270,6 +284,7 @@ class ToolTipElement extends HTMLElement {
|
|
270
284
|
signal
|
271
285
|
})
|
272
286
|
this.ownerDocument.addEventListener('focusout', focusOutListener)
|
287
|
+
this.ownerDocument.addEventListener('focusin', focusInListener)
|
273
288
|
this.ownerDocument.addEventListener('keydown', this, {signal})
|
274
289
|
}
|
275
290
|
|
@@ -297,6 +312,7 @@ class ToolTipElement extends HTMLElement {
|
|
297
312
|
|
298
313
|
await Promise.resolve()
|
299
314
|
if (!showing && shouldShow && !isPopoverOpen(this)) {
|
315
|
+
this.#showReason = event.type === 'mouseenter' ? 'mouse' : 'focus'
|
300
316
|
this.showPopover()
|
301
317
|
} else if (showing && shouldHide && isPopoverOpen(this)) {
|
302
318
|
this.hidePopover()
|
@@ -19,12 +19,14 @@ module Primer
|
|
19
19
|
# @param type [Symbol] <%= one_of(Primer::Beta::BaseButton::TYPE_OPTIONS) %>
|
20
20
|
# @param block [Boolean] Whether button is full-width with `display: block`.
|
21
21
|
# @param disabled [Boolean] Whether or not the button is disabled. If true, this option forces `tag:` to `:button`.
|
22
|
+
# @param inactive [Boolean] Whether the button looks visually disabled, but can still accept all the same interactions as an enabled button.
|
22
23
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
23
24
|
def initialize(
|
24
25
|
tag: DEFAULT_TAG,
|
25
26
|
type: DEFAULT_TYPE,
|
26
27
|
block: false,
|
27
28
|
disabled: false,
|
29
|
+
inactive: false,
|
28
30
|
**system_arguments
|
29
31
|
)
|
30
32
|
@system_arguments = system_arguments
|
@@ -37,6 +39,8 @@ module Primer
|
|
37
39
|
"btn-block" => block
|
38
40
|
)
|
39
41
|
|
42
|
+
@system_arguments[:"aria-disabled"] = true if inactive
|
43
|
+
|
40
44
|
@disabled = disabled
|
41
45
|
return unless @disabled
|
42
46
|
|