openproject-primer_view_components 0.18.1 → 0.20.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 +61 -0
- data/app/assets/javascripts/app/components/primer/alpha/action_bar_element.d.ts +3 -2
- data/app/assets/javascripts/app/components/primer/alpha/action_menu/action_menu_element.d.ts +20 -0
- data/app/assets/javascripts/app/components/primer/beta/nav_list.d.ts +0 -11
- data/app/assets/javascripts/app/components/primer/beta/nav_list_group_element.d.ts +19 -0
- data/app/assets/javascripts/app/components/primer/primer.d.ts +2 -0
- data/app/assets/javascripts/app/components/primer/scrollable_region.d.ts +13 -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.css +1 -1
- data/app/components/primer/alpha/action_bar.css.map +1 -1
- data/app/components/primer/alpha/action_bar.pcss +8 -6
- data/app/components/primer/alpha/action_bar_element.d.ts +3 -2
- data/app/components/primer/alpha/action_bar_element.js +80 -97
- data/app/components/primer/alpha/action_bar_element.ts +84 -89
- data/app/components/primer/alpha/action_list/item.rb +13 -1
- data/app/components/primer/alpha/action_list.css +1 -1
- data/app/components/primer/alpha/action_list.css.json +1 -0
- data/app/components/primer/alpha/action_list.css.map +1 -1
- data/app/components/primer/alpha/action_list.pcss +3 -1
- data/app/components/primer/alpha/action_list.rb +5 -4
- data/app/components/primer/alpha/action_menu/action_menu_element.d.ts +20 -0
- data/app/components/primer/alpha/action_menu/action_menu_element.js +92 -15
- data/app/components/primer/alpha/action_menu/action_menu_element.ts +115 -13
- data/app/components/primer/alpha/action_menu/group.rb +23 -0
- data/app/components/primer/alpha/action_menu/heading.rb +17 -0
- data/app/components/primer/alpha/action_menu/list.html.erb +1 -0
- data/app/components/primer/alpha/action_menu/list.rb +62 -51
- data/app/components/primer/alpha/action_menu/list_wrapper.rb +40 -0
- data/app/components/primer/alpha/action_menu.rb +38 -1
- data/app/components/primer/alpha/banner.html.erb +1 -1
- data/app/components/primer/alpha/banner.rb +5 -1
- data/app/components/primer/alpha/dialog.html.erb +3 -1
- data/app/components/primer/alpha/dialog.rb +5 -1
- data/app/components/primer/alpha/layout.css +1 -1
- data/app/components/primer/alpha/layout.css.map +1 -1
- data/app/components/primer/alpha/modal_dialog.ts +1 -1
- data/app/components/primer/alpha/overlay.css +1 -1
- data/app/components/primer/alpha/overlay.css.json +4 -2
- data/app/components/primer/alpha/overlay.css.map +1 -1
- data/app/components/primer/alpha/overlay.pcss +12 -2
- data/app/components/primer/alpha/text_field.css +1 -1
- data/app/components/primer/alpha/text_field.css.map +1 -1
- data/app/components/primer/alpha/text_field.pcss +4 -3
- data/app/components/primer/alpha/tool_tip.js +22 -5
- data/app/components/primer/alpha/tool_tip.ts +24 -5
- data/app/components/primer/alpha/underline_nav.css +1 -1
- data/app/components/primer/alpha/underline_nav.css.map +1 -1
- data/app/components/primer/base_component.rb +20 -18
- data/app/components/primer/beta/auto_complete/auto_complete.html.erb +1 -7
- data/app/components/primer/beta/auto_complete/item.rb +1 -1
- data/app/components/primer/beta/auto_complete.rb +6 -1
- data/app/components/primer/beta/base_button.rb +2 -3
- data/app/components/primer/beta/blankslate.css +1 -1
- data/app/components/primer/beta/blankslate.css.map +1 -1
- data/app/components/primer/beta/blankslate.pcss +3 -3
- data/app/components/primer/beta/button.css +1 -1
- data/app/components/primer/beta/button.css.json +9 -8
- data/app/components/primer/beta/button.css.map +1 -1
- data/app/components/primer/beta/button.pcss +15 -11
- data/app/components/primer/beta/nav_list/group.html.erb +7 -5
- data/app/components/primer/beta/nav_list/group.rb +2 -2
- data/app/components/primer/beta/nav_list.d.ts +0 -11
- data/app/components/primer/beta/nav_list.js +2 -85
- data/app/components/primer/beta/nav_list.ts +1 -85
- data/app/components/primer/beta/nav_list_group_element.d.ts +19 -0
- data/app/components/primer/beta/nav_list_group_element.js +108 -0
- data/app/components/primer/beta/nav_list_group_element.ts +97 -0
- data/app/components/primer/beta/relative_time.rb +4 -4
- data/app/components/primer/component.rb +3 -0
- data/app/components/primer/primer.d.ts +2 -0
- data/app/components/primer/primer.js +2 -0
- data/app/components/primer/primer.ts +2 -0
- data/app/components/primer/scrollable_region.d.ts +13 -0
- data/app/components/primer/scrollable_region.js +52 -0
- data/app/components/primer/scrollable_region.ts +48 -0
- data/app/lib/primer/experimental_render_helpers.rb +32 -0
- data/app/lib/primer/experimental_slot_helpers.rb +30 -0
- data/lib/primer/classify/utilities.rb +3 -4
- data/lib/primer/view_components/version.rb +2 -2
- data/lib/primer/yard/lookbook_pages_backend.rb +2 -2
- data/previews/primer/alpha/action_menu_preview/in_scroll_container.html.erb +11 -0
- data/previews/primer/alpha/action_menu_preview.rb +80 -7
- data/previews/primer/alpha/banner_preview.rb +3 -2
- data/previews/primer/alpha/dialog_preview/with_auto_complete.html.erb +8 -0
- data/previews/primer/alpha/dialog_preview.rb +17 -0
- data/previews/primer/beta/blankslate_preview/inside_flex_container.html.erb +6 -0
- data/previews/primer/beta/blankslate_preview.rb +3 -0
- data/previews/primer/beta/nav_list_preview.rb +10 -1
- data/static/arguments.json +92 -1
- data/static/audited_at.json +4 -1
- data/static/classes.json +3 -0
- data/static/constants.json +9 -0
- data/static/info_arch.json +256 -52
- data/static/previews.json +52 -0
- data/static/statuses.json +3 -0
- metadata +19 -2
@@ -12,6 +12,17 @@ type SelectedItem = {
|
|
12
12
|
const validSelectors = ['[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]']
|
13
13
|
const menuItemSelectors = validSelectors.map(selector => `:not([hidden]) > ${selector}`)
|
14
14
|
|
15
|
+
export type ItemActivatedEvent = {
|
16
|
+
item: Element
|
17
|
+
checked: boolean
|
18
|
+
}
|
19
|
+
|
20
|
+
declare global {
|
21
|
+
interface HTMLElementEventMap {
|
22
|
+
itemActivated: CustomEvent<ItemActivatedEvent>
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
15
26
|
@controller
|
16
27
|
export class ActionMenuElement extends HTMLElement {
|
17
28
|
@target
|
@@ -82,7 +93,7 @@ export class ActionMenuElement extends HTMLElement {
|
|
82
93
|
results.push({
|
83
94
|
label: labelEl?.textContent,
|
84
95
|
value: selectedItem?.getAttribute('data-value'),
|
85
|
-
element: selectedItem
|
96
|
+
element: selectedItem,
|
86
97
|
})
|
87
98
|
}
|
88
99
|
|
@@ -96,41 +107,46 @@ export class ActionMenuElement extends HTMLElement {
|
|
96
107
|
this.addEventListener('mouseover', this, {signal})
|
97
108
|
this.addEventListener('focusout', this, {signal})
|
98
109
|
this.addEventListener('mousedown', this, {signal})
|
110
|
+
this.popoverElement?.addEventListener('toggle', this, {signal})
|
99
111
|
this.#setDynamicLabel()
|
100
112
|
this.#updateInput()
|
101
113
|
this.#softDisableItems()
|
102
114
|
|
103
115
|
if (this.includeFragment) {
|
104
116
|
this.includeFragment.addEventListener('include-fragment-replaced', this, {
|
105
|
-
signal
|
117
|
+
signal,
|
106
118
|
})
|
107
119
|
}
|
108
120
|
}
|
109
121
|
|
122
|
+
disconnectedCallback() {
|
123
|
+
this.#abortController.abort()
|
124
|
+
}
|
125
|
+
|
110
126
|
#softDisableItems() {
|
111
127
|
const {signal} = this.#abortController
|
112
128
|
|
113
|
-
for (const item of this
|
129
|
+
for (const item of this.querySelectorAll(validSelectors.join(','))) {
|
114
130
|
item.addEventListener('click', this.#potentiallyDisallowActivation.bind(this), {signal})
|
115
131
|
item.addEventListener('keydown', this.#potentiallyDisallowActivation.bind(this), {signal})
|
116
132
|
}
|
117
133
|
}
|
118
134
|
|
119
|
-
|
120
|
-
|
135
|
+
// returns true if activation was prevented
|
136
|
+
#potentiallyDisallowActivation(event: Event): boolean {
|
137
|
+
if (!this.#isActivation(event)) return false
|
121
138
|
|
122
139
|
const item = (event.target as HTMLElement).closest(menuItemSelectors.join(','))
|
123
|
-
if (!item) return
|
140
|
+
if (!item) return false
|
124
141
|
|
125
142
|
if (item.getAttribute('aria-disabled')) {
|
126
143
|
event.preventDefault()
|
127
144
|
event.stopPropagation()
|
128
145
|
event.stopImmediatePropagation()
|
146
|
+
return true
|
129
147
|
}
|
130
|
-
}
|
131
148
|
|
132
|
-
|
133
|
-
this.#abortController.abort()
|
149
|
+
return false
|
134
150
|
}
|
135
151
|
|
136
152
|
#isKeyboardActivation(event: Event): boolean {
|
@@ -167,6 +183,10 @@ export class ActionMenuElement extends HTMLElement {
|
|
167
183
|
const targetIsInvoker = this.invokerElement?.contains(event.target as HTMLElement)
|
168
184
|
const eventIsActivation = this.#isActivation(event)
|
169
185
|
|
186
|
+
if (event.type === 'toggle' && (event as ToggleEvent).newState === 'open') {
|
187
|
+
this.#firstItem?.focus()
|
188
|
+
}
|
189
|
+
|
170
190
|
if (targetIsInvoker && event.type === 'mousedown') {
|
171
191
|
this.#invokerBeingClicked = true
|
172
192
|
return
|
@@ -202,6 +222,8 @@ export class ActionMenuElement extends HTMLElement {
|
|
202
222
|
const targetIsItem = item !== null
|
203
223
|
|
204
224
|
if (targetIsItem && eventIsActivation) {
|
225
|
+
if (this.#potentiallyDisallowActivation(event)) return
|
226
|
+
|
205
227
|
const dialogInvoker = item.closest('[data-show-dialog-id]')
|
206
228
|
|
207
229
|
if (dialogInvoker) {
|
@@ -214,7 +236,7 @@ export class ActionMenuElement extends HTMLElement {
|
|
214
236
|
}
|
215
237
|
|
216
238
|
this.#activateItem(event, item)
|
217
|
-
this.#handleItemActivated(
|
239
|
+
this.#handleItemActivated(item)
|
218
240
|
|
219
241
|
// Pressing the space key on a button or link will cause the page to scroll unless preventDefault()
|
220
242
|
// is called. While calling preventDefault() appears to have no effect on link navigation, it skips
|
@@ -244,7 +266,6 @@ export class ActionMenuElement extends HTMLElement {
|
|
244
266
|
this.#hide()
|
245
267
|
} else {
|
246
268
|
this.#show()
|
247
|
-
this.#firstItem?.focus()
|
248
269
|
}
|
249
270
|
}
|
250
271
|
|
@@ -263,7 +284,7 @@ export class ActionMenuElement extends HTMLElement {
|
|
263
284
|
dialog.addEventListener('cancel', handleDialogClose, {signal})
|
264
285
|
}
|
265
286
|
|
266
|
-
#handleItemActivated(
|
287
|
+
#handleItemActivated(item: Element) {
|
267
288
|
// Hide popover after current event loop to prevent changes in focus from
|
268
289
|
// altering the target of the event. Not doing this specifically affects
|
269
290
|
// <a> tags. It causes the event to be sent to the currently focused element
|
@@ -304,6 +325,11 @@ export class ActionMenuElement extends HTMLElement {
|
|
304
325
|
}
|
305
326
|
|
306
327
|
this.#updateInput()
|
328
|
+
this.dispatchEvent(
|
329
|
+
new CustomEvent('itemActivated', {
|
330
|
+
detail: {item: item.parentElement, checked: this.isItemChecked(item.parentElement)},
|
331
|
+
}),
|
332
|
+
)
|
307
333
|
}
|
308
334
|
|
309
335
|
#activateItem(event: Event, item: Element) {
|
@@ -410,9 +436,85 @@ export class ActionMenuElement extends HTMLElement {
|
|
410
436
|
return this.querySelector(menuItemSelectors.join(','))
|
411
437
|
}
|
412
438
|
|
413
|
-
get
|
439
|
+
get items(): HTMLElement[] {
|
414
440
|
return Array.from(this.querySelectorAll(menuItemSelectors.join(',')))
|
415
441
|
}
|
442
|
+
|
443
|
+
getItemById(itemId: string): HTMLElement | null {
|
444
|
+
return this.querySelector(`li[data-item-id="${itemId}"`)
|
445
|
+
}
|
446
|
+
|
447
|
+
isItemDisabled(item: Element | null): boolean {
|
448
|
+
if (item) {
|
449
|
+
return item.classList.contains('ActionListItem--disabled')
|
450
|
+
} else {
|
451
|
+
return false
|
452
|
+
}
|
453
|
+
}
|
454
|
+
|
455
|
+
disableItem(item: Element | null) {
|
456
|
+
if (item) {
|
457
|
+
item.classList.add('ActionListItem--disabled')
|
458
|
+
item.querySelector('.ActionListContent')!.setAttribute('aria-disabled', 'true')
|
459
|
+
}
|
460
|
+
}
|
461
|
+
|
462
|
+
enableItem(item: Element | null) {
|
463
|
+
if (item) {
|
464
|
+
item.classList.remove('ActionListItem--disabled')
|
465
|
+
item.querySelector('.ActionListContent')!.removeAttribute('aria-disabled')
|
466
|
+
}
|
467
|
+
}
|
468
|
+
|
469
|
+
isItemHidden(item: Element | null): boolean {
|
470
|
+
if (item) {
|
471
|
+
return item.hasAttribute('hidden')
|
472
|
+
} else {
|
473
|
+
return false
|
474
|
+
}
|
475
|
+
}
|
476
|
+
|
477
|
+
hideItem(item: Element | null) {
|
478
|
+
if (item) {
|
479
|
+
item.setAttribute('hidden', 'hidden')
|
480
|
+
}
|
481
|
+
}
|
482
|
+
|
483
|
+
showItem(item: Element | null) {
|
484
|
+
if (item) {
|
485
|
+
item.removeAttribute('hidden')
|
486
|
+
}
|
487
|
+
}
|
488
|
+
|
489
|
+
isItemChecked(item: Element | null) {
|
490
|
+
if (item) {
|
491
|
+
return item.querySelector('.ActionListContent')!.getAttribute('aria-checked') === 'true'
|
492
|
+
} else {
|
493
|
+
return false
|
494
|
+
}
|
495
|
+
}
|
496
|
+
|
497
|
+
checkItem(item: Element | null) {
|
498
|
+
if (item && (this.selectVariant === 'single' || this.selectVariant === 'multiple')) {
|
499
|
+
const itemContent = item.querySelector('.ActionListContent')!
|
500
|
+
const ariaChecked = itemContent.getAttribute('aria-checked') === 'true'
|
501
|
+
|
502
|
+
if (!ariaChecked) {
|
503
|
+
this.#handleItemActivated(itemContent)
|
504
|
+
}
|
505
|
+
}
|
506
|
+
}
|
507
|
+
|
508
|
+
uncheckItem(item: Element | null) {
|
509
|
+
if (item && (this.selectVariant === 'single' || this.selectVariant === 'multiple')) {
|
510
|
+
const itemContent = item.querySelector('.ActionListContent')!
|
511
|
+
const ariaChecked = itemContent.getAttribute('aria-checked') === 'true'
|
512
|
+
|
513
|
+
if (ariaChecked) {
|
514
|
+
this.#handleItemActivated(itemContent)
|
515
|
+
}
|
516
|
+
}
|
517
|
+
}
|
416
518
|
}
|
417
519
|
|
418
520
|
if (!window.customElements.get('action-menu')) {
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Primer
|
5
|
+
module Alpha
|
6
|
+
class ActionMenu
|
7
|
+
# This component is part of <%= link_to_component(Primer::Alpha::ActionMenu) %> and should not be
|
8
|
+
# used as a standalone component.
|
9
|
+
class Group < Primer::Alpha::ActionList
|
10
|
+
# Heading text rendered above the list of items.
|
11
|
+
#
|
12
|
+
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::ActionMenu::Heading) %>.
|
13
|
+
def with_heading(**system_arguments, &block)
|
14
|
+
super(component_klass: Primer::Alpha::ActionMenu::Heading, **system_arguments, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def with_divider
|
18
|
+
raise "ActionMenu groups cannot have dividers"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module Alpha
|
5
|
+
class ActionMenu
|
6
|
+
# Heading used to describe groups within an action menu.
|
7
|
+
class Heading < Primer::Alpha::ActionList::Heading
|
8
|
+
def initialize(**)
|
9
|
+
super
|
10
|
+
|
11
|
+
# Headings don't make sense in a menu context, so use div instead
|
12
|
+
@tag = :div
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render(@list) %>
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# typed: true
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module Primer
|
@@ -6,72 +5,84 @@ module Primer
|
|
6
5
|
class ActionMenu
|
7
6
|
# This component is part of <%= link_to_component(Primer::Alpha::ActionMenu) %> and should not be
|
8
7
|
# used as a standalone component.
|
9
|
-
class List < Primer::
|
8
|
+
class List < Primer::Component
|
10
9
|
DEFAULT_ITEM_TAG = :button
|
11
10
|
ITEM_TAG_OPTIONS = [:a, :"clipboard-copy", DEFAULT_ITEM_TAG].freeze
|
12
11
|
|
13
|
-
|
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.
|
16
|
-
# @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::ActionList::Item) %>, or whatever class is passed as the `component_klass` argument.
|
17
|
-
def with_item(data: {}, **system_arguments, &block)
|
18
|
-
system_arguments = organize_arguments(data: data, **system_arguments)
|
12
|
+
attr_reader :items
|
19
13
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
14
|
+
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::ActionList) %>
|
15
|
+
def initialize(**system_arguments)
|
16
|
+
@items = []
|
17
|
+
@has_group = false
|
24
18
|
|
25
|
-
|
26
|
-
#
|
27
|
-
# @param src [String] The source url of the avatar image.
|
28
|
-
# @param username [String] The username associated with the avatar.
|
29
|
-
# @param full_name [String] Optional. The user's full name.
|
30
|
-
# @param full_name_scheme [Symbol] Optional. How to display the user's full name. <%= one_of(Primer::Alpha::ActionList::Item::DESCRIPTION_SCHEME_OPTIONS) %>
|
31
|
-
# @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.
|
32
|
-
# @param avatar_arguments [Hash] Optional. The arguments accepted by <%= link_to_component(Primer::Beta::Avatar) %>.
|
33
|
-
# @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::ActionList::Item) %>, or whatever class is passed as the `component_klass` argument.
|
34
|
-
def with_avatar_item(src:, username:, full_name: nil, full_name_scheme: Primer::Alpha::ActionList::Item::DEFAULT_DESCRIPTION_SCHEME, data: {}, avatar_arguments: {}, **system_arguments, &block)
|
35
|
-
system_arguments = organize_arguments(data: data, **system_arguments)
|
36
|
-
|
37
|
-
super(src: src, username: username, full_name: full_name, full_name_scheme: full_name_scheme, avatar_arguments: avatar_arguments, **system_arguments) do |item|
|
38
|
-
evaluate_block(item, &block)
|
39
|
-
end
|
19
|
+
@list = Primer::Alpha::ActionMenu::ListWrapper.new(**system_arguments)
|
40
20
|
end
|
41
21
|
|
42
|
-
|
43
|
-
|
44
|
-
def initialize(menu_id:, **system_arguments, &block)
|
45
|
-
@menu_id = menu_id
|
22
|
+
def with_group(**system_arguments, &block)
|
23
|
+
@has_group = true
|
46
24
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
25
|
+
@items << {
|
26
|
+
type: :group,
|
27
|
+
kwargs: system_arguments,
|
28
|
+
block: block
|
29
|
+
}
|
30
|
+
end
|
51
31
|
|
52
|
-
|
53
|
-
|
54
|
-
|
32
|
+
def with_item(**system_arguments, &block)
|
33
|
+
@items << {
|
34
|
+
type: :item,
|
35
|
+
kwargs: organize_arguments(**system_arguments),
|
36
|
+
block: block
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def with_avatar_item(**system_arguments, &block)
|
41
|
+
@items << {
|
42
|
+
type: :avatar_item,
|
43
|
+
kwargs: organize_arguments(**system_arguments),
|
44
|
+
block: block
|
45
|
+
}
|
46
|
+
end
|
55
47
|
|
56
|
-
|
48
|
+
def with_divider(**system_arguments, &block)
|
49
|
+
@items << {
|
50
|
+
type: :divider,
|
51
|
+
kwargs: system_arguments,
|
52
|
+
block: block
|
53
|
+
}
|
57
54
|
end
|
58
55
|
|
59
56
|
private
|
60
57
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
#
|
65
|
-
# Handle blocks that originate from C code such as `&:method` by checking
|
66
|
-
# source_location. Such blocks don't allow access to their receiver.
|
67
|
-
return unless block&.source_location
|
58
|
+
def contains_group?
|
59
|
+
@has_group
|
60
|
+
end
|
68
61
|
|
69
|
-
|
62
|
+
def before_render
|
63
|
+
content
|
64
|
+
|
65
|
+
@items.each do |item|
|
66
|
+
case item[:type]
|
67
|
+
when :divider, :group
|
68
|
+
add_item(item, to: @list)
|
69
|
+
else
|
70
|
+
if contains_group?
|
71
|
+
@list.with_group do |group|
|
72
|
+
add_item(item, to: group)
|
73
|
+
end
|
74
|
+
else
|
75
|
+
add_item(item, to: @list)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
70
80
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
81
|
+
def add_item(item, to:)
|
82
|
+
parent = to
|
83
|
+
mtd = :"with_#{item[:type]}"
|
84
|
+
parent.send(mtd, **item[:kwargs]) do |item_instance|
|
85
|
+
evaluate_block(item_instance, &item[:block])
|
75
86
|
end
|
76
87
|
end
|
77
88
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module Alpha
|
5
|
+
class ActionMenu
|
6
|
+
# This component is part of <%= link_to_component(Primer::Alpha::ActionMenu) %> and should not be
|
7
|
+
# used as a standalone component.
|
8
|
+
class ListWrapper < Primer::Alpha::ActionList
|
9
|
+
add_polymorphic_slot_type(
|
10
|
+
slot_name: :items,
|
11
|
+
type: :group,
|
12
|
+
callable: lambda { |**system_arguments|
|
13
|
+
Primer::Alpha::ActionMenu::Group.new(
|
14
|
+
**system_arguments,
|
15
|
+
role: :group,
|
16
|
+
select_variant: @select_variant
|
17
|
+
)
|
18
|
+
}
|
19
|
+
)
|
20
|
+
|
21
|
+
# @param menu_id [String] ID of the parent menu.
|
22
|
+
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::ActionList) %>
|
23
|
+
def initialize(menu_id:, **system_arguments)
|
24
|
+
@menu_id = menu_id
|
25
|
+
|
26
|
+
system_arguments[:aria] = merge_aria(
|
27
|
+
system_arguments,
|
28
|
+
{ aria: { labelledby: "#{@menu_id}-button" } }
|
29
|
+
)
|
30
|
+
|
31
|
+
system_arguments[:role] = :menu
|
32
|
+
system_arguments[:scheme] = :inset
|
33
|
+
system_arguments[:id] = "#{@menu_id}-list"
|
34
|
+
|
35
|
+
super(**system_arguments)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -128,6 +128,39 @@ module Primer
|
|
128
128
|
#
|
129
129
|
# Additional information around the keyboard functionality and implementation can be found on the
|
130
130
|
# [WAI-ARIA Authoring Practices](https://www.w3.org/TR/wai-aria-practices-1.2/#menu).
|
131
|
+
#
|
132
|
+
# ### JavaScript API
|
133
|
+
#
|
134
|
+
# `ActionList`s render an `<action-list>` custom element that exposes behavior to the client. For all these methods,
|
135
|
+
# `itemId` refers to the value of the `item_id:` argument (see below) that is used to populate the `data-item-id` HTML
|
136
|
+
# attribute.
|
137
|
+
#
|
138
|
+
# #### Query methods
|
139
|
+
#
|
140
|
+
# * `getItemById(itemId: string): Element`: Returns the item's HTML `<li>` element. The return value can be passed as the `item` argument to the other methods listed below.
|
141
|
+
# * `isItemChecked(item: Element): boolean`: Returns `true` if the item is checked, `false` otherwise.
|
142
|
+
# * `isItemHidden(item: Element): boolean`: Returns `true` if the item is hidden, `false` otherwise.
|
143
|
+
# * `isItemDisabled(item: Element): boolean`: Returns `true` if the item is disabled, `false` otherwise.
|
144
|
+
#
|
145
|
+
# #### State methods
|
146
|
+
#
|
147
|
+
# * `showItem(item: Element)`: Shows the item, i.e. makes it visible.
|
148
|
+
# * `hideItem(item: Element)`: Hides the item, i.e. makes it invisible.
|
149
|
+
# * `enableItem(item: Element)`: Enables the item, i.e. makes it clickable by the mouse and keyboard.
|
150
|
+
# * `disableItem(item: Element)`: Disables the item, i.e. makes it unclickable by the mouse and keyboard.
|
151
|
+
# * `checkItem(item: Element)`: Checks the item. Only has an effect in single- and multi-select modes.
|
152
|
+
# * `uncheckItem(item: Element)`: Unchecks the item. Only has an effect in multi-select mode, since items cannot be unchecked in single-select mode.
|
153
|
+
#
|
154
|
+
# #### Events
|
155
|
+
#
|
156
|
+
# The `<action-menu>` element fires an `itemActivated` event whenever an item is activated (eg. clicked) via the mouse or keyboard.
|
157
|
+
#
|
158
|
+
# ```typescript
|
159
|
+
# document.querySelector("action-menu").addEventListener("itemActivated", (event: ItemActivatedEvent) => {
|
160
|
+
# event.item // Element: the <li> item that was activated
|
161
|
+
# event.checked // boolean: whether or not the result of the activation checked the item
|
162
|
+
# })
|
163
|
+
# ```
|
131
164
|
class ActionMenu < Primer::Component
|
132
165
|
status :alpha
|
133
166
|
|
@@ -175,7 +208,7 @@ module Primer
|
|
175
208
|
|
176
209
|
@system_arguments[:preload] = true if @src.present? && preload?
|
177
210
|
|
178
|
-
select_variant = fetch_or_fallback(SELECT_VARIANT_OPTIONS, select_variant, DEFAULT_SELECT_VARIANT)
|
211
|
+
@select_variant = fetch_or_fallback(SELECT_VARIANT_OPTIONS, select_variant, DEFAULT_SELECT_VARIANT)
|
179
212
|
|
180
213
|
@system_arguments[:tag] = :"action-menu"
|
181
214
|
@system_arguments[:"data-select-variant"] = select_variant
|
@@ -243,6 +276,10 @@ module Primer
|
|
243
276
|
@list.with_avatar_item(**system_arguments, &block)
|
244
277
|
end
|
245
278
|
|
279
|
+
def with_group(**system_arguments, &block)
|
280
|
+
@list.with_group(**system_arguments, &block)
|
281
|
+
end
|
282
|
+
|
246
283
|
private
|
247
284
|
|
248
285
|
def before_render
|
@@ -55,17 +55,21 @@ module Primer
|
|
55
55
|
:hide
|
56
56
|
].freeze
|
57
57
|
|
58
|
+
DEFAULT_DISMISS_LABEL = "Dismiss"
|
59
|
+
|
58
60
|
# @param full [Boolean] Whether the component should take up the full width of the screen.
|
59
61
|
# @param full_when_narrow [Boolean] Whether the component should take up the full width of the screen when rendered inside smaller viewports.
|
60
62
|
# @param dismiss_scheme [Symbol] Whether the component can be dismissed with an "x" button. <%= one_of(Primer::Alpha::Banner::DISMISS_SCHEMES) %>
|
63
|
+
# @param dismiss_label [String] The aria-label text of the dismiss "x" button
|
61
64
|
# @param description [String] Description text rendered underneath the message.
|
62
65
|
# @param icon [Symbol] The name of an <%= link_to_octicons %> icon to use. If no icon is provided, a default one will be chosen based on the scheme.
|
63
66
|
# @param scheme [Symbol] <%= one_of(Primer::Alpha::Banner::SCHEME_MAPPINGS.keys) %>
|
64
67
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
65
|
-
def initialize(full: false, full_when_narrow: false, dismiss_scheme: DEFAULT_DISMISS_SCHEME, description: nil, icon: nil, scheme: DEFAULT_SCHEME, **system_arguments)
|
68
|
+
def initialize(full: false, full_when_narrow: false, dismiss_scheme: DEFAULT_DISMISS_SCHEME, dismiss_label: DEFAULT_DISMISS_LABEL, description: nil, icon: nil, scheme: DEFAULT_SCHEME, **system_arguments)
|
66
69
|
@scheme = fetch_or_fallback(SCHEME_MAPPINGS.keys, scheme, DEFAULT_SCHEME)
|
67
70
|
@icon = icon || DEFAULT_ICONS[@scheme]
|
68
71
|
@dismiss_scheme = dismiss_scheme
|
72
|
+
@dismiss_label = dismiss_label
|
69
73
|
@description = description
|
70
74
|
|
71
75
|
@system_arguments = deny_tag_argument(**system_arguments)
|
@@ -133,7 +133,7 @@ module Primer
|
|
133
133
|
@system_arguments, {
|
134
134
|
aria: {
|
135
135
|
disabled: true,
|
136
|
-
labelledby:
|
136
|
+
labelledby: labelledby,
|
137
137
|
describedby: "#{@id}-description"
|
138
138
|
}
|
139
139
|
}
|
@@ -155,6 +155,10 @@ module Primer
|
|
155
155
|
with_header unless header?
|
156
156
|
with_body unless body?
|
157
157
|
end
|
158
|
+
|
159
|
+
def labelledby
|
160
|
+
"#{@id}-title"
|
161
|
+
end
|
158
162
|
end
|
159
163
|
end
|
160
164
|
end
|
@@ -1 +1 @@
|
|
1
|
-
.Layout{
|
1
|
+
.Layout{display:grid;--Layout-sidebar-width:220px;--Layout-gutter:16px;grid-auto-flow:column;grid-template-columns:auto 0 minmax(0,calc(100% - var(--Layout-sidebar-width) - var(--Layout-gutter)));grid-gap:var(--Layout-gutter)}@media (max-width:calc(544px - 0.02px)){.Layout{grid-auto-flow:row;grid-template-columns:1fr!important}.Layout .Layout-divider,.Layout .Layout-main,.Layout .Layout-sidebar{grid-column:1!important;width:100%!important}.Layout.Layout--sidebarPosition-flowRow-start .Layout-sidebar{grid-row:1}.Layout.Layout--sidebarPosition-flowRow-end .Layout-sidebar,.Layout.Layout--sidebarPosition-flowRow-start .Layout-main{grid-row:2/span 2}.Layout.Layout--sidebarPosition-flowRow-end .Layout-main{grid-row:1}.Layout.Layout--sidebarPosition-flowRow-none .Layout-sidebar{display:none}.Layout.Layout--divided{--Layout-gutter:0}.Layout.Layout--divided .Layout-divider{grid-row:2;height:1px}.Layout.Layout--divided .Layout-divider.Layout-divider--flowRow-hidden{display:none}.Layout.Layout--divided .Layout-divider.Layout-divider--flowRow-shallow{background:var(--bgColor-inset,var(--color-canvas-inset));border-color:var(--borderColor-default,var(--color-border-default));border-style:solid;border-width:var(--borderWidth-thin,max(1px,.0625rem)) 0;height:8px;margin-right:0}.Layout.Layout--divided .Layout-main,.Layout.Layout--divided.Layout--sidebarPosition-flowRow-end .Layout-sidebar{grid-row:3/span 1}.Layout.Layout--divided.Layout--sidebarPosition-flowRow-end .Layout-main{grid-row:1}}@media (max-width:calc(768px - 0.02px)){.Layout.Layout--flowRow-until-md{grid-auto-flow:row;grid-template-columns:1fr!important}.Layout.Layout--flowRow-until-md .Layout-divider,.Layout.Layout--flowRow-until-md .Layout-main,.Layout.Layout--flowRow-until-md .Layout-sidebar{grid-column:1!important;width:100%!important}.Layout.Layout--flowRow-until-md.Layout--sidebarPosition-flowRow-start .Layout-sidebar{grid-row:1}.Layout.Layout--flowRow-until-md.Layout--sidebarPosition-flowRow-end .Layout-sidebar,.Layout.Layout--flowRow-until-md.Layout--sidebarPosition-flowRow-start .Layout-main{grid-row:2/span 2}.Layout.Layout--flowRow-until-md.Layout--sidebarPosition-flowRow-end .Layout-main{grid-row:1}.Layout.Layout--flowRow-until-md.Layout--sidebarPosition-flowRow-none .Layout-sidebar{display:none}.Layout.Layout--flowRow-until-md.Layout--divided{--Layout-gutter:0}.Layout.Layout--flowRow-until-md.Layout--divided .Layout-divider{grid-row:2;height:1px}.Layout.Layout--flowRow-until-md.Layout--divided .Layout-divider.Layout-divider--flowRow-hidden{display:none}.Layout.Layout--flowRow-until-md.Layout--divided .Layout-divider.Layout-divider--flowRow-shallow{background:var(--bgColor-inset,var(--color-canvas-inset));border-color:var(--borderColor-default,var(--color-border-default));border-style:solid;border-width:var(--borderWidth-thin,max(1px,.0625rem)) 0;height:8px;margin-right:0}.Layout.Layout--flowRow-until-md.Layout--divided .Layout-main,.Layout.Layout--flowRow-until-md.Layout--divided.Layout--sidebarPosition-flowRow-end .Layout-sidebar{grid-row:3/span 1}.Layout.Layout--flowRow-until-md.Layout--divided.Layout--sidebarPosition-flowRow-end .Layout-main{grid-row:1}}@media (max-width:calc(1012px - 0.02px)){.Layout.Layout--flowRow-until-lg{grid-auto-flow:row;grid-template-columns:1fr!important}.Layout.Layout--flowRow-until-lg .Layout-divider,.Layout.Layout--flowRow-until-lg .Layout-main,.Layout.Layout--flowRow-until-lg .Layout-sidebar{grid-column:1!important;width:100%!important}.Layout.Layout--flowRow-until-lg.Layout--sidebarPosition-flowRow-start .Layout-sidebar{grid-row:1}.Layout.Layout--flowRow-until-lg.Layout--sidebarPosition-flowRow-end .Layout-sidebar,.Layout.Layout--flowRow-until-lg.Layout--sidebarPosition-flowRow-start .Layout-main{grid-row:2/span 2}.Layout.Layout--flowRow-until-lg.Layout--sidebarPosition-flowRow-end .Layout-main{grid-row:1}.Layout.Layout--flowRow-until-lg.Layout--sidebarPosition-flowRow-none .Layout-sidebar{display:none}.Layout.Layout--flowRow-until-lg.Layout--divided{--Layout-gutter:0}.Layout.Layout--flowRow-until-lg.Layout--divided .Layout-divider{grid-row:2;height:1px}.Layout.Layout--flowRow-until-lg.Layout--divided .Layout-divider.Layout-divider--flowRow-hidden{display:none}.Layout.Layout--flowRow-until-lg.Layout--divided .Layout-divider.Layout-divider--flowRow-shallow{background:var(--bgColor-inset,var(--color-canvas-inset));border-color:var(--borderColor-default,var(--color-border-default));border-style:solid;border-width:var(--borderWidth-thin,max(1px,.0625rem)) 0;height:8px;margin-right:0}.Layout.Layout--flowRow-until-lg.Layout--divided .Layout-main,.Layout.Layout--flowRow-until-lg.Layout--divided.Layout--sidebarPosition-flowRow-end .Layout-sidebar{grid-row:3/span 1}.Layout.Layout--flowRow-until-lg.Layout--divided.Layout--sidebarPosition-flowRow-end .Layout-main{grid-row:1}}.Layout .Layout-sidebar{grid-column:1}.Layout .Layout-divider{display:none}.Layout .Layout-main{grid-column:2/span 2}@media (min-width:1012px){.Layout{--Layout-gutter:24px}}.Layout.Layout--gutter-none{--Layout-gutter:0px}.Layout.Layout--gutter-condensed{--Layout-gutter:16px}@media (min-width:1012px){.Layout.Layout--gutter-spacious{--Layout-gutter:32px}}@media (min-width:1280px){.Layout.Layout--gutter-spacious{--Layout-gutter:40px}}@media (min-width:544px){.Layout{--Layout-sidebar-width:220px}}@media (min-width:768px){.Layout{--Layout-sidebar-width:256px}}@media (min-width:1012px){.Layout{--Layout-sidebar-width:296px}}@media (min-width:768px){.Layout.Layout--sidebar-narrow{--Layout-sidebar-width:240px}}@media (min-width:1012px){.Layout.Layout--sidebar-narrow{--Layout-sidebar-width:256px}.Layout.Layout--sidebar-wide{--Layout-sidebar-width:320px}}@media (min-width:1280px){.Layout.Layout--sidebar-wide{--Layout-sidebar-width:336px}}.Layout.Layout--sidebarPosition-start .Layout-sidebar{grid-column:1}.Layout.Layout--sidebarPosition-start .Layout-main{grid-column:2/span 2}.Layout.Layout--sidebarPosition-end{grid-template-columns:minmax(0,calc(100% - var(--Layout-sidebar-width) - var(--Layout-gutter))) 0 auto}.Layout.Layout--sidebarPosition-end .Layout-main{grid-column:1}.Layout.Layout--sidebarPosition-end .Layout-sidebar{grid-column:2/span 2}.Layout.Layout--divided .Layout-divider{background:var(--borderColor-default,var(--color-border-default));display:block;grid-column:2;margin-right:-1px;width:1px}.Layout.Layout--divided .Layout-main,.Layout.Layout--divided.Layout--sidebarPosition-end .Layout-sidebar{grid-column:3/span 1}.Layout.Layout--divided.Layout--sidebarPosition-end .Layout-main{grid-column:1}.Layout-divider{display:none;width:1px}.Layout-sidebar{width:var(--Layout-sidebar-width)}.Layout-main{min-width:0}.Layout-main .Layout-main-centered-lg,.Layout-main .Layout-main-centered-md,.Layout-main .Layout-main-centered-xl{margin-left:auto;margin-right:auto}.Layout-main .Layout-main-centered-lg>.container-lg,.Layout-main .Layout-main-centered-lg>.container-md,.Layout-main .Layout-main-centered-lg>.container-xl,.Layout-main .Layout-main-centered-md>.container-lg,.Layout-main .Layout-main-centered-md>.container-md,.Layout-main .Layout-main-centered-md>.container-xl,.Layout-main .Layout-main-centered-xl>.container-lg,.Layout-main .Layout-main-centered-xl>.container-md,.Layout-main .Layout-main-centered-xl>.container-xl{margin-left:0}.Layout-main .Layout-main-centered-md{max-width:calc(var(--breakpoint-medium,48rem) + var(--Layout-sidebar-width) + var(--Layout-gutter))}.Layout-main .Layout-main-centered-lg{max-width:calc(var(--breakpoint-large,63.25rem) + var(--Layout-sidebar-width) + var(--Layout-gutter))}.Layout-main .Layout-main-centered-xl{max-width:calc(var(--breakpoint-xlarge,80rem) + var(--Layout-sidebar-width) + var(--Layout-gutter))}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["layout.pcss"],"names":[],"mappings":"AAgFA,
|
1
|
+
{"version":3,"sources":["layout.pcss"],"names":[],"mappings":"AAgFA,QACE,YAAa,CAEb,4BAA6B,CAC7B,oBAAqB,CAoBrB,qBAAsB,CACtB,sGAAwG,CACxG,6BAyHF,CA7IE,wCANF,QA7EE,kBAAmB,CACnB,mCA+NF,CA7NE,qEAIE,uBAAyB,CADzB,oBAEF,CAGE,8DACE,UACF,CAQA,uHACE,iBACF,CAEA,yDACE,UACF,CAIA,6DACE,YACF,CAGF,wBAoBA,iBAJA,CAMA,wCAEE,UAAW,CADX,UAeF,CAZE,uEACE,YACF,CAEA,wEAGE,yDAAgC,CAChC,mEAAwC,CACxC,kBAAmB,CACnB,wDAAuC,CALvC,UAAW,CACX,cAKF,CA7BE,iHACE,iBACF,CAEA,yEACE,UACF,CAmCJ,CAGE,wCADF,iCAvFA,kBAAmB,CACnB,mCA0FA,CAxFA,gJAIE,uBAAyB,CADzB,oBAEF,CAGE,uFACE,UACF,CAQA,yKACE,iBACF,CAEA,kFACE,UACF,CAIA,sFACE,YACF,CAGF,iDAoBA,iBAJA,CAMA,iEAEE,UAAW,CADX,UAeF,CAZE,gGACE,YACF,CAEA,iGAGE,yDAAgC,CAChC,mEAAwC,CACxC,kBAAmB,CACnB,wDAAuC,CALvC,UAAW,CACX,cAKF,CA7BE,mKACE,iBACF,CAEA,kGACE,UACF,CAwCF,CAIA,yCADF,iCA7FA,kBAAmB,CACnB,mCAgGA,CA9FA,gJAIE,uBAAyB,CADzB,oBAEF,CAGE,uFACE,UACF,CAQA,yKACE,iBACF,CAEA,kFACE,UACF,CAIA,sFACE,YACF,CAGF,iDAoBA,iBAJA,CAMA,iEAEE,UAAW,CADX,UAeF,CAZE,gGACE,YACF,CAEA,iGAGE,yDAAgC,CAChC,mEAAwC,CACxC,kBAAmB,CACnB,wDAAuC,CALvC,UAAW,CACX,cAKF,CA7BE,mKACE,iBACF,CAEA,kGACE,UACF,CA8CF,CASF,wBACE,aACF,CAEA,wBACE,YACF,CAEA,qBACE,oBACF,CAIA,0BA1CF,QA2CI,oBAwGJ,CAvGE,CAEA,4BAEE,mBACF,CAEA,iCACE,oBACF,CAGE,0BADF,gCAEI,oBAMJ,CALE,CAEA,0BALF,gCAMI,oBAEJ,CADE,CAIF,yBAlEF,QAmEI,4BAgFJ,CA/EE,CAEA,yBAtEF,QAuEI,4BA4EJ,CA3EE,CAEA,0BA1EF,QA2EI,4BAwEJ,CAvEE,CAGE,yBADF,+BAEI,4BAMJ,CALE,CAEA,0BALF,+BAMI,4BAEJ,CAEA,6BAEI,4BAMJ,CAXE,CAQA,0BALF,6BAMI,4BAEJ,CADE,CAMA,sDACE,aACF,CAEA,mDACE,oBACF,CAGF,oCACE,sGASF,CAPE,iDACE,aACF,CAEA,oDACE,oBACF,CAMA,wCAKE,iEAAsC,CAJtC,aAAc,CACd,aAAc,CAEd,iBAAkB,CADlB,SAGF,CAOE,yGACE,oBACF,CAEA,iEACE,aACF,CAKN,gBACE,YAAa,CACb,SACF,CAEA,gBACE,iCACF,CAEA,aACE,WA4BF,CAxBE,kHAIE,gBAAiB,CADjB,iBAQF,CALE,odAGE,aACF,CAGF,sCACE,mGACF,CAEA,sCACE,qGACF,CAEA,sCACE,mGACF","file":"layout.css","sourcesContent":["/* Layout */\n\n@define-mixin flow-as-row {\n grid-auto-flow: row;\n grid-template-columns: 1fr !important;\n\n & .Layout-sidebar,\n & .Layout-divider,\n & .Layout-main {\n width: 100% !important;\n grid-column: 1 !important;\n }\n\n &.Layout--sidebarPosition-flowRow-start {\n & .Layout-sidebar {\n grid-row: 1;\n }\n\n & .Layout-main {\n grid-row: 2 / span 2;\n }\n }\n\n &.Layout--sidebarPosition-flowRow-end {\n & .Layout-sidebar {\n grid-row: 2 / span 2;\n }\n\n & .Layout-main {\n grid-row: 1;\n }\n }\n\n &.Layout--sidebarPosition-flowRow-none {\n & .Layout-sidebar {\n display: none;\n }\n }\n\n &.Layout--divided {\n @mixin flow-as-row-divider;\n\n & .Layout-main {\n grid-row: 3 / span 1;\n }\n\n &.Layout--sidebarPosition-flowRow-end {\n & .Layout-sidebar {\n grid-row: 3 / span 1;\n }\n\n & .Layout-main {\n grid-row: 1;\n }\n }\n }\n}\n\n@define-mixin flow-as-row-divider {\n --Layout-gutter: 0;\n\n & .Layout-divider {\n height: 1px;\n grid-row: 2;\n\n &.Layout-divider--flowRow-hidden {\n display: none;\n }\n\n &.Layout-divider--flowRow-shallow {\n height: 8px;\n margin-right: 0;\n background: var(--bgColor-inset);\n border-color: var(--borderColor-default);\n border-style: solid;\n border-width: var(--borderWidth-thin) 0;\n }\n }\n}\n\n.Layout {\n display: grid;\n\n --Layout-sidebar-width: 220px;\n --Layout-gutter: 16px;\n\n @media (max-width: calc(544px - 0.02px)) {\n @mixin flow-as-row;\n }\n\n &.Layout--flowRow-until-md {\n @media (max-width: calc(768px - 0.02px)) {\n @mixin flow-as-row;\n }\n }\n\n &.Layout--flowRow-until-lg {\n @media (max-width: calc(1012px - 0.02px)) {\n @mixin flow-as-row;\n }\n }\n\n /* Flow as column */\n\n grid-auto-flow: column;\n grid-template-columns: auto 0 minmax(0, calc(100% - var(--Layout-sidebar-width) - var(--Layout-gutter))); /* sidebar column, separator, main column */\n grid-gap: var(--Layout-gutter);\n\n & .Layout-sidebar {\n grid-column: 1;\n }\n\n & .Layout-divider {\n display: none;\n }\n\n & .Layout-main {\n grid-column: 2 / span 2;\n }\n\n /* Gutter spacing */\n\n @media (min-width: 1012px) {\n --Layout-gutter: 24px;\n }\n\n &.Layout--gutter-none {\n /* stylelint-disable-next-line length-zero-no-unit */\n --Layout-gutter: 0px; /* Neds px in value */\n }\n\n &.Layout--gutter-condensed {\n --Layout-gutter: 16px;\n }\n\n &.Layout--gutter-spacious {\n @media (min-width: 1012px) {\n --Layout-gutter: 32px;\n }\n\n @media (min-width: 1280px) {\n --Layout-gutter: 40px;\n }\n }\n\n /* Sidebar width */\n @media (min-width: 544px) {\n --Layout-sidebar-width: 220px;\n }\n\n @media (min-width: 768px) {\n --Layout-sidebar-width: 256px;\n }\n\n @media (min-width: 1012px) {\n --Layout-sidebar-width: 296px;\n }\n\n &.Layout--sidebar-narrow {\n @media (min-width: 768px) {\n --Layout-sidebar-width: 240px;\n }\n\n @media (min-width: 1012px) {\n --Layout-sidebar-width: 256px;\n }\n }\n\n &.Layout--sidebar-wide {\n @media (min-width: 1012px) {\n --Layout-sidebar-width: 320px;\n }\n\n @media (min-width: 1280px) {\n --Layout-sidebar-width: 336px;\n }\n }\n\n /* Sidebar position */\n\n &.Layout--sidebarPosition-start {\n & .Layout-sidebar {\n grid-column: 1;\n }\n\n & .Layout-main {\n grid-column: 2 / span 2;\n }\n }\n\n &.Layout--sidebarPosition-end {\n grid-template-columns: minmax(0, calc(100% - var(--Layout-sidebar-width) - var(--Layout-gutter))) 0 auto;\n\n & .Layout-main {\n grid-column: 1;\n }\n\n & .Layout-sidebar {\n grid-column: 2 / span 2;\n }\n }\n\n /* Sidebar divider */\n\n &.Layout--divided {\n & .Layout-divider {\n display: block;\n grid-column: 2;\n width: 1px;\n margin-right: -1px;\n background: var(--borderColor-default);\n }\n\n & .Layout-main {\n grid-column: 3 / span 1;\n }\n\n &.Layout--sidebarPosition-end {\n & .Layout-sidebar {\n grid-column: 3 / span 1;\n }\n\n & .Layout-main {\n grid-column: 1;\n }\n }\n }\n}\n\n.Layout-divider {\n display: none;\n width: 1px;\n}\n\n.Layout-sidebar {\n width: var(--Layout-sidebar-width);\n}\n\n.Layout-main {\n min-width: 0;\n\n /* Centered main column\n ** FIXME: right-aligned sidebar */\n & .Layout-main-centered-md,\n & .Layout-main-centered-lg,\n & .Layout-main-centered-xl {\n margin-right: auto;\n margin-left: auto;\n\n & > .container-md,\n & > .container-lg,\n & > .container-xl {\n margin-left: 0;\n }\n }\n\n & .Layout-main-centered-md {\n max-width: calc(var(--breakpoint-medium) + var(--Layout-sidebar-width) + var(--Layout-gutter));\n }\n\n & .Layout-main-centered-lg {\n max-width: calc(var(--breakpoint-large) + var(--Layout-sidebar-width) + var(--Layout-gutter));\n }\n\n & .Layout-main-centered-xl {\n max-width: calc(var(--breakpoint-xlarge) + var(--Layout-sidebar-width) + var(--Layout-gutter));\n }\n}\n"]}
|