openproject-primer_view_components 0.60.0 → 0.61.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/app/assets/javascripts/components/primer/open_project/border_box/collapsible_header.d.ts +3 -9
- data/app/assets/javascripts/components/primer/open_project/collapsible.d.ts +11 -0
- data/app/assets/javascripts/components/primer/open_project/collapsible_section.d.ts +10 -0
- data/app/assets/javascripts/components/primer/primer.d.ts +2 -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/open_project/border_box/collapsible_header.d.ts +3 -9
- data/app/components/primer/open_project/border_box/collapsible_header.html.erb +7 -7
- data/app/components/primer/open_project/border_box/collapsible_header.js +5 -46
- data/app/components/primer/open_project/border_box/collapsible_header.rb +42 -9
- data/app/components/primer/open_project/border_box/collapsible_header.ts +5 -47
- data/app/components/primer/open_project/collapsible.d.ts +11 -0
- data/app/components/primer/open_project/collapsible.js +56 -0
- data/app/components/primer/open_project/collapsible.ts +49 -0
- data/app/components/primer/open_project/collapsible_section.css +1 -0
- data/app/components/primer/open_project/collapsible_section.css.json +6 -0
- data/app/components/primer/open_project/collapsible_section.css.map +1 -0
- data/app/components/primer/open_project/collapsible_section.d.ts +10 -0
- data/app/components/primer/open_project/collapsible_section.html.erb +25 -0
- data/app/components/primer/open_project/collapsible_section.js +16 -0
- data/app/components/primer/open_project/collapsible_section.pcss +5 -0
- data/app/components/primer/open_project/collapsible_section.rb +77 -0
- data/app/components/primer/open_project/collapsible_section.ts +15 -0
- data/app/components/primer/primer.d.ts +2 -0
- data/app/components/primer/primer.js +2 -0
- data/app/components/primer/primer.pcss +1 -0
- data/app/components/primer/primer.ts +2 -0
- data/lib/primer/view_components/version.rb +2 -2
- data/previews/primer/open_project/border_box/collapsible_header_preview/playground.html.erb +5 -4
- data/previews/primer/open_project/collapsible_section_preview/collapsed.html.erb +9 -0
- data/previews/primer/open_project/collapsible_section_preview/default.html.erb +10 -0
- data/previews/primer/open_project/collapsible_section_preview/playground.html.erb +22 -0
- data/previews/primer/open_project/collapsible_section_preview/with_additional_information.html.erb +16 -0
- data/previews/primer/open_project/collapsible_section_preview/with_caption.html.erb +14 -0
- data/previews/primer/open_project/collapsible_section_preview.rb +57 -0
- data/static/arguments.json +28 -0
- data/static/audited_at.json +1 -0
- data/static/classes.json +3 -0
- data/static/constants.json +13 -0
- data/static/info_arch.json +199 -1
- data/static/previews.json +73 -0
- data/static/statuses.json +1 -0
- metadata +22 -2
@@ -1,13 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
arrowUp: HTMLElement;
|
4
|
-
description: HTMLElement | undefined;
|
5
|
-
collapsed: string;
|
6
|
-
private _collapsed;
|
1
|
+
import { CollapsibleElement } from '../collapsible';
|
2
|
+
declare class CollapsibleHeaderElement extends CollapsibleElement {
|
7
3
|
connectedCallback(): void;
|
8
|
-
|
9
|
-
private hideAll;
|
10
|
-
private expandAll;
|
4
|
+
get baseClass(): string;
|
11
5
|
}
|
12
6
|
declare global {
|
13
7
|
interface Window {
|
@@ -1,16 +1,16 @@
|
|
1
1
|
<%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
|
2
2
|
<%= render(Primer::OpenProject::FlexLayout.new) do |flex| %>
|
3
3
|
<%= flex.with_row do %>
|
4
|
-
<%=
|
5
|
-
<% if
|
6
|
-
<%=
|
4
|
+
<%= title %>
|
5
|
+
<% if count? %>
|
6
|
+
<%= count %>
|
7
7
|
<% end %>
|
8
|
-
<%= render(Primer::Beta::Octicon.new(icon: "chevron-up", data: { target: "collapsible-header.arrowUp" })) %>
|
9
|
-
<%= render(Primer::Beta::Octicon.new(icon: "chevron-down",
|
8
|
+
<%= render(Primer::Beta::Octicon.new(icon: "chevron-up", hidden: @collapsed, data: { target: "collapsible-header.arrowUp" })) %>
|
9
|
+
<%= render(Primer::Beta::Octicon.new(icon: "chevron-down", hidden: !@collapsed, data: { target: "collapsible-header.arrowDown" })) %>
|
10
10
|
<% end %>
|
11
11
|
<%= flex.with_row do %>
|
12
|
-
<% if
|
13
|
-
<%=
|
12
|
+
<% if description? %>
|
13
|
+
<%= description %>
|
14
14
|
<% end %>
|
15
15
|
<% end %>
|
16
16
|
<% end %>
|
@@ -4,59 +4,18 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
6
|
};
|
7
|
-
import {
|
8
|
-
|
7
|
+
import { controller } from '@github/catalyst';
|
8
|
+
import { CollapsibleElement } from '../collapsible';
|
9
|
+
let CollapsibleHeaderElement = class CollapsibleHeaderElement extends CollapsibleElement {
|
9
10
|
connectedCallback() {
|
10
11
|
if (!this.closest('.Box')) {
|
11
12
|
throw new Error('No surrounding BorderBox found');
|
12
13
|
}
|
13
|
-
if (this.collapsed === 'true') {
|
14
|
-
this._collapsed = true;
|
15
|
-
this.hideAll();
|
16
|
-
}
|
17
|
-
else {
|
18
|
-
this._collapsed = false;
|
19
|
-
}
|
20
|
-
}
|
21
|
-
toggle() {
|
22
|
-
if (this._collapsed) {
|
23
|
-
this._collapsed = false;
|
24
|
-
this.expandAll();
|
25
|
-
}
|
26
|
-
else {
|
27
|
-
this._collapsed = true;
|
28
|
-
this.hideAll();
|
29
|
-
}
|
30
|
-
}
|
31
|
-
hideAll() {
|
32
|
-
this.arrowDown?.classList.remove('d-none');
|
33
|
-
this.arrowUp?.classList.add('d-none');
|
34
|
-
this.description?.classList.add('d-none');
|
35
|
-
this.classList.add('CollapsibleHeader--collapsed');
|
36
14
|
}
|
37
|
-
|
38
|
-
|
39
|
-
this.arrowUp?.classList.remove('d-none');
|
40
|
-
this.description?.classList.remove('d-none');
|
41
|
-
this.classList.remove('CollapsibleHeader--collapsed');
|
15
|
+
get baseClass() {
|
16
|
+
return 'CollapsibleHeader';
|
42
17
|
}
|
43
18
|
};
|
44
|
-
__decorate([
|
45
|
-
target
|
46
|
-
], CollapsibleHeaderElement.prototype, "arrowDown", void 0);
|
47
|
-
__decorate([
|
48
|
-
target
|
49
|
-
], CollapsibleHeaderElement.prototype, "arrowUp", void 0);
|
50
|
-
__decorate([
|
51
|
-
target
|
52
|
-
], CollapsibleHeaderElement.prototype, "description", void 0);
|
53
|
-
__decorate([
|
54
|
-
attr
|
55
|
-
], CollapsibleHeaderElement.prototype, "collapsed", void 0);
|
56
19
|
CollapsibleHeaderElement = __decorate([
|
57
20
|
controller
|
58
21
|
], CollapsibleHeaderElement);
|
59
|
-
if (!window.customElements.get('collapsible-header')) {
|
60
|
-
window.CollapsibleHeaderElement = CollapsibleHeaderElement;
|
61
|
-
window.customElements.define('collapsible-header', CollapsibleHeaderElement);
|
62
|
-
}
|
@@ -8,11 +8,46 @@ module Primer
|
|
8
8
|
class CollapsibleHeader < Primer::Component
|
9
9
|
status :open_project
|
10
10
|
|
11
|
+
# Required title
|
12
|
+
#
|
11
13
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
renders_one :title, lambda { |**system_arguments, &block|
|
15
|
+
system_arguments[:mr] ||= 2
|
16
|
+
|
17
|
+
Primer::Beta::Text.new(**system_arguments, &block)
|
18
|
+
}
|
19
|
+
|
20
|
+
# Optional count
|
21
|
+
#
|
22
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
23
|
+
renders_one :count, lambda { |**system_arguments|
|
24
|
+
system_arguments[:mr] ||= 2
|
25
|
+
system_arguments[:scheme] ||= :primary
|
26
|
+
|
27
|
+
Primer::Beta::Counter.new(**system_arguments)
|
28
|
+
}
|
29
|
+
|
30
|
+
# Optional description
|
31
|
+
#
|
32
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
33
|
+
renders_one :description, lambda { |**system_arguments, &block|
|
34
|
+
system_arguments[:color] ||= :subtle
|
35
|
+
system_arguments[:data] = merge_data(
|
36
|
+
system_arguments, {
|
37
|
+
data: {
|
38
|
+
targets: "collapsible-header.collapsibleElements"
|
39
|
+
}
|
40
|
+
}
|
41
|
+
)
|
42
|
+
system_arguments[:hidden] = @collapsed
|
43
|
+
|
44
|
+
Primer::Beta::Text.new(**system_arguments, &block)
|
45
|
+
}
|
46
|
+
|
47
|
+
|
48
|
+
# @param collapsed [Boolean] Whether the header is collapsed on initial render.
|
49
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
50
|
+
def initialize(collapsed: false, box:, **system_arguments)
|
16
51
|
@collapsed = collapsed
|
17
52
|
@box = box
|
18
53
|
@system_arguments = system_arguments
|
@@ -26,10 +61,10 @@ module Primer
|
|
26
61
|
@system_arguments[:data] = merge_data(
|
27
62
|
@system_arguments, {
|
28
63
|
data: {
|
29
|
-
action: "click:collapsible-header#toggle"
|
30
|
-
collapsed: @collapsed
|
64
|
+
action: "click:collapsible-header#toggle"
|
31
65
|
} }
|
32
66
|
)
|
67
|
+
@system_arguments[:data][:collapsed] = true if @collapsed
|
33
68
|
end
|
34
69
|
|
35
70
|
private
|
@@ -39,9 +74,7 @@ module Primer
|
|
39
74
|
end
|
40
75
|
|
41
76
|
def render?
|
42
|
-
raise ArgumentError, "Title must be present" unless
|
43
|
-
raise ArgumentError, "Description cannot be a blank string" unless @description.present? || @description.nil?
|
44
|
-
raise ArgumentError, "Count cannot be a blank string" unless @count.present? || @count.nil?
|
77
|
+
raise ArgumentError, "Title must be present" unless title?
|
45
78
|
raise ArgumentError, "This component must be called inside the header of a `Primer::Beta::BorderBox`" unless @box.present? && @box.is_a?(Primer::Beta::BorderBox)
|
46
79
|
|
47
80
|
true
|
@@ -1,53 +1,16 @@
|
|
1
|
-
import {
|
1
|
+
import {controller} from '@github/catalyst'
|
2
|
+
import {CollapsibleElement} from '../collapsible'
|
2
3
|
|
3
4
|
@controller
|
4
|
-
class CollapsibleHeaderElement extends
|
5
|
-
@target arrowDown: HTMLElement
|
6
|
-
@target arrowUp: HTMLElement
|
7
|
-
@target description: HTMLElement | undefined
|
8
|
-
|
9
|
-
@attr collapsed: string
|
10
|
-
private _collapsed: boolean
|
11
|
-
|
5
|
+
class CollapsibleHeaderElement extends CollapsibleElement {
|
12
6
|
connectedCallback() {
|
13
7
|
if (!this.closest('.Box')) {
|
14
8
|
throw new Error('No surrounding BorderBox found')
|
15
9
|
}
|
16
|
-
|
17
|
-
if (this.collapsed === 'true') {
|
18
|
-
this._collapsed = true
|
19
|
-
this.hideAll()
|
20
|
-
} else {
|
21
|
-
this._collapsed = false
|
22
|
-
}
|
23
10
|
}
|
24
11
|
|
25
|
-
|
26
|
-
|
27
|
-
this._collapsed = false
|
28
|
-
this.expandAll()
|
29
|
-
} else {
|
30
|
-
this._collapsed = true
|
31
|
-
this.hideAll()
|
32
|
-
}
|
33
|
-
}
|
34
|
-
|
35
|
-
private hideAll() {
|
36
|
-
this.arrowDown?.classList.remove('d-none')
|
37
|
-
this.arrowUp?.classList.add('d-none')
|
38
|
-
|
39
|
-
this.description?.classList.add('d-none')
|
40
|
-
|
41
|
-
this.classList.add('CollapsibleHeader--collapsed')
|
42
|
-
}
|
43
|
-
|
44
|
-
private expandAll() {
|
45
|
-
this.arrowDown?.classList.add('d-none')
|
46
|
-
this.arrowUp?.classList.remove('d-none')
|
47
|
-
|
48
|
-
this.description?.classList.remove('d-none')
|
49
|
-
|
50
|
-
this.classList.remove('CollapsibleHeader--collapsed')
|
12
|
+
get baseClass(): string {
|
13
|
+
return 'CollapsibleHeader'
|
51
14
|
}
|
52
15
|
}
|
53
16
|
|
@@ -56,8 +19,3 @@ declare global {
|
|
56
19
|
CollapsibleHeaderElement: typeof CollapsibleHeaderElement
|
57
20
|
}
|
58
21
|
}
|
59
|
-
|
60
|
-
if (!window.customElements.get('collapsible-header')) {
|
61
|
-
window.CollapsibleHeaderElement = CollapsibleHeaderElement
|
62
|
-
window.customElements.define('collapsible-header', CollapsibleHeaderElement)
|
63
|
-
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
export declare abstract class CollapsibleElement extends HTMLElement {
|
2
|
+
arrowDown: Element;
|
3
|
+
arrowUp: Element;
|
4
|
+
collapsibleElements: HTMLElement[];
|
5
|
+
collapsed: boolean;
|
6
|
+
toggle(): void;
|
7
|
+
attributeChangedCallback(name: string): void;
|
8
|
+
hideAll(): void;
|
9
|
+
expandAll(): void;
|
10
|
+
abstract get baseClass(): string;
|
11
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
|
+
};
|
7
|
+
import { attr, target, targets } from '@github/catalyst';
|
8
|
+
// eslint-disable-next-line custom-elements/expose-class-on-global
|
9
|
+
export class CollapsibleElement extends HTMLElement {
|
10
|
+
constructor() {
|
11
|
+
super(...arguments);
|
12
|
+
this.collapsed = false;
|
13
|
+
}
|
14
|
+
toggle() {
|
15
|
+
this.collapsed = !this.collapsed;
|
16
|
+
}
|
17
|
+
attributeChangedCallback(name) {
|
18
|
+
if (name === 'data-collapsed') {
|
19
|
+
if (this.collapsed) {
|
20
|
+
this.hideAll();
|
21
|
+
}
|
22
|
+
else {
|
23
|
+
this.expandAll();
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
hideAll() {
|
28
|
+
// For whatever reason, setting `hidden` directly does not work on the SVGs
|
29
|
+
this.arrowDown?.removeAttribute('hidden');
|
30
|
+
this.arrowUp?.setAttribute('hidden', '');
|
31
|
+
for (const el of this.collapsibleElements) {
|
32
|
+
el.hidden = true;
|
33
|
+
}
|
34
|
+
this.classList.add(`${this.baseClass}--collapsed`);
|
35
|
+
}
|
36
|
+
expandAll() {
|
37
|
+
this.arrowUp?.removeAttribute('hidden');
|
38
|
+
this.arrowDown?.setAttribute('hidden', '');
|
39
|
+
for (const el of this.collapsibleElements) {
|
40
|
+
el.hidden = false;
|
41
|
+
}
|
42
|
+
this.classList.remove(`${this.baseClass}--collapsed`);
|
43
|
+
}
|
44
|
+
}
|
45
|
+
__decorate([
|
46
|
+
target
|
47
|
+
], CollapsibleElement.prototype, "arrowDown", void 0);
|
48
|
+
__decorate([
|
49
|
+
target
|
50
|
+
], CollapsibleElement.prototype, "arrowUp", void 0);
|
51
|
+
__decorate([
|
52
|
+
targets
|
53
|
+
], CollapsibleElement.prototype, "collapsibleElements", void 0);
|
54
|
+
__decorate([
|
55
|
+
attr
|
56
|
+
], CollapsibleElement.prototype, "collapsed", void 0);
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import {attr, target, targets} from '@github/catalyst'
|
2
|
+
|
3
|
+
// eslint-disable-next-line custom-elements/expose-class-on-global
|
4
|
+
export abstract class CollapsibleElement extends HTMLElement {
|
5
|
+
@target arrowDown: Element
|
6
|
+
@target arrowUp: Element
|
7
|
+
@targets collapsibleElements: HTMLElement[]
|
8
|
+
|
9
|
+
@attr collapsed = false
|
10
|
+
|
11
|
+
toggle() {
|
12
|
+
this.collapsed = !this.collapsed
|
13
|
+
}
|
14
|
+
|
15
|
+
attributeChangedCallback(name: string) {
|
16
|
+
if (name === 'data-collapsed') {
|
17
|
+
if (this.collapsed) {
|
18
|
+
this.hideAll()
|
19
|
+
} else {
|
20
|
+
this.expandAll()
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
hideAll() {
|
26
|
+
// For whatever reason, setting `hidden` directly does not work on the SVGs
|
27
|
+
this.arrowDown?.removeAttribute('hidden')
|
28
|
+
this.arrowUp?.setAttribute('hidden', '')
|
29
|
+
|
30
|
+
for (const el of this.collapsibleElements) {
|
31
|
+
el.hidden = true
|
32
|
+
}
|
33
|
+
|
34
|
+
this.classList.add(`${this.baseClass}--collapsed`)
|
35
|
+
}
|
36
|
+
|
37
|
+
expandAll() {
|
38
|
+
this.arrowUp?.removeAttribute('hidden')
|
39
|
+
this.arrowDown?.setAttribute('hidden', '')
|
40
|
+
|
41
|
+
for (const el of this.collapsibleElements) {
|
42
|
+
el.hidden = false
|
43
|
+
}
|
44
|
+
|
45
|
+
this.classList.remove(`${this.baseClass}--collapsed`)
|
46
|
+
}
|
47
|
+
|
48
|
+
abstract get baseClass(): string
|
49
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
.CollapsibleSection--triggerArea{cursor:pointer}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["collapsible_section.pcss"],"names":[],"mappings":"AAEA,iCACI,cACJ","file":"collapsible_section.css","sourcesContent":["/* CSS for CollapsibleSection */\n\n.CollapsibleSection--triggerArea {\n cursor: pointer;\n}\n"]}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { CollapsibleElement } from './collapsible';
|
2
|
+
declare class CollapsibleSectionElement extends CollapsibleElement {
|
3
|
+
get baseClass(): string;
|
4
|
+
}
|
5
|
+
declare global {
|
6
|
+
interface Window {
|
7
|
+
CollapsibleSectionElement: typeof CollapsibleSectionElement;
|
8
|
+
}
|
9
|
+
}
|
10
|
+
export {};
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
|
2
|
+
<%= render(Primer::OpenProject::FlexLayout.new) do |flex| %>
|
3
|
+
<%= flex.with_row(classes: "CollapsibleSection--triggerArea",
|
4
|
+
data: { action: "click:collapsible-section#toggle" }) do %>
|
5
|
+
<%= render(Primer::OpenProject::FlexLayout.new(display: :flex, align_items: :center)) do |header| %>
|
6
|
+
<%= header.with_column do %>
|
7
|
+
<%= title %>
|
8
|
+
<% end %>
|
9
|
+
<%= header.with_column do %>
|
10
|
+
<%= caption %>
|
11
|
+
<% end %>
|
12
|
+
<%= header.with_column do %>
|
13
|
+
<%= render(Primer::Beta::Octicon.new(icon: "chevron-up", hidden: @collapsed, data: { target: "collapsible-section.arrowUp" })) %>
|
14
|
+
<%= render(Primer::Beta::Octicon.new(icon: "chevron-down", hidden: !@collapsed, data: { target: "collapsible-section.arrowDown" })) %>
|
15
|
+
<% end %>
|
16
|
+
<%= header.with_column(flex: 1, text_align: :right) do %>
|
17
|
+
<%= additional_information %>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
21
|
+
<%= flex.with_row(hidden: @collapsed, mt: 3, data: { targets: "collapsible-section.collapsibleElements" }) do %>
|
22
|
+
<%= collapsible_content %>
|
23
|
+
<% end %>
|
24
|
+
<% end %>
|
25
|
+
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
|
+
};
|
7
|
+
import { controller } from '@github/catalyst';
|
8
|
+
import { CollapsibleElement } from './collapsible';
|
9
|
+
let CollapsibleSectionElement = class CollapsibleSectionElement extends CollapsibleElement {
|
10
|
+
get baseClass() {
|
11
|
+
return 'CollapsibleSection';
|
12
|
+
}
|
13
|
+
};
|
14
|
+
CollapsibleSectionElement = __decorate([
|
15
|
+
controller
|
16
|
+
], CollapsibleSectionElement);
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module OpenProject
|
5
|
+
# A component consisting of a title and collapsible content.
|
6
|
+
# Clicking the title will hide the collapsible content
|
7
|
+
class CollapsibleSection < Primer::Component
|
8
|
+
status :open_project
|
9
|
+
|
10
|
+
TITLE_TAG_FALLBACK = :h2
|
11
|
+
TITLE_TAG_OPTIONS = [:h1, TITLE_TAG_FALLBACK, :h3, :h4, :h5, :h6, :span].freeze
|
12
|
+
|
13
|
+
# Required Title
|
14
|
+
#
|
15
|
+
# @param tag [Symbol] Customize the element type of the rendered title container.
|
16
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
17
|
+
renders_one :title, lambda { |tag: TITLE_TAG_FALLBACK, **system_arguments, &block|
|
18
|
+
system_arguments[:tag] = fetch_or_fallback(TITLE_TAG_OPTIONS, tag, TITLE_TAG_FALLBACK)
|
19
|
+
system_arguments[:font_size] ||= 3
|
20
|
+
system_arguments[:mr] ||= 2
|
21
|
+
|
22
|
+
Primer::OpenProject::Heading.new(**system_arguments, &block)
|
23
|
+
}
|
24
|
+
|
25
|
+
# Optional caption
|
26
|
+
#
|
27
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
28
|
+
renders_one :caption, lambda { |**system_arguments, &block|
|
29
|
+
system_arguments[:color] ||= :subtle
|
30
|
+
system_arguments[:mr] ||= 2
|
31
|
+
system_arguments[:display] ||= [:none, :block]
|
32
|
+
|
33
|
+
Primer::Beta::Text.new(**system_arguments, &block)
|
34
|
+
}
|
35
|
+
|
36
|
+
# Optional right-side content
|
37
|
+
#
|
38
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
39
|
+
renders_one :additional_information, lambda { |**system_arguments|
|
40
|
+
Primer::BaseComponent.new(tag: :div, **system_arguments)
|
41
|
+
}
|
42
|
+
|
43
|
+
# Required collapsible content
|
44
|
+
#
|
45
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
46
|
+
renders_one :collapsible_content, lambda { |**system_arguments|
|
47
|
+
Primer::BaseComponent.new(tag: :div, **system_arguments)
|
48
|
+
}
|
49
|
+
|
50
|
+
# @param collapsed [Boolean] Whether the section is collapsed on initial render.
|
51
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
52
|
+
def initialize(collapsed: false, **system_arguments)
|
53
|
+
@collapsed = collapsed
|
54
|
+
|
55
|
+
@system_arguments = deny_tag_argument(**system_arguments)
|
56
|
+
@system_arguments[:tag] = "collapsible-section"
|
57
|
+
@system_arguments[:classes] = class_names(
|
58
|
+
@system_arguments[:classes],
|
59
|
+
"CollapsibleSection",
|
60
|
+
"CollapsibleSection--collapsed" => @collapsed
|
61
|
+
)
|
62
|
+
|
63
|
+
@system_arguments[:data] ||= {}
|
64
|
+
@system_arguments[:data][:collapsed] = true if @collapsed
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def render?
|
70
|
+
raise ArgumentError, "Title must be present" unless title.present?
|
71
|
+
raise ArgumentError, "Collapsible content must be present" unless collapsible_content.present?
|
72
|
+
|
73
|
+
true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import {controller} from '@github/catalyst'
|
2
|
+
import {CollapsibleElement} from './collapsible'
|
3
|
+
|
4
|
+
@controller
|
5
|
+
class CollapsibleSectionElement extends CollapsibleElement {
|
6
|
+
get baseClass(): string {
|
7
|
+
return 'CollapsibleSection'
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
declare global {
|
12
|
+
interface Window {
|
13
|
+
CollapsibleSectionElement: typeof CollapsibleSectionElement
|
14
|
+
}
|
15
|
+
}
|
@@ -30,4 +30,6 @@ import './open_project/page_header_element';
|
|
30
30
|
import './open_project/zen_mode_button';
|
31
31
|
import './open_project/sub_header_element';
|
32
32
|
import './open_project/danger_dialog_form_helper';
|
33
|
+
import './open_project/collapsible';
|
33
34
|
import './open_project/border_box/collapsible_header';
|
35
|
+
import './open_project/collapsible_section';
|
@@ -30,4 +30,6 @@ import './open_project/page_header_element';
|
|
30
30
|
import './open_project/zen_mode_button';
|
31
31
|
import './open_project/sub_header_element';
|
32
32
|
import './open_project/danger_dialog_form_helper';
|
33
|
+
import './open_project/collapsible';
|
33
34
|
import './open_project/border_box/collapsible_header';
|
35
|
+
import './open_project/collapsible_section';
|
@@ -30,4 +30,6 @@ import './open_project/page_header_element'
|
|
30
30
|
import './open_project/zen_mode_button'
|
31
31
|
import './open_project/sub_header_element'
|
32
32
|
import './open_project/danger_dialog_form_helper'
|
33
|
+
import './open_project/collapsible'
|
33
34
|
import './open_project/border_box/collapsible_header'
|
35
|
+
import './open_project/collapsible_section'
|
@@ -1,10 +1,11 @@
|
|
1
1
|
<%= render(Primer::Beta::BorderBox.new) do |component| %>
|
2
2
|
<% component.with_header do %>
|
3
3
|
<%= render(Primer::OpenProject::BorderBox::CollapsibleHeader.new(box: component,
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
collapsed: collapsed)) do |header| %>
|
5
|
+
<% header.with_title { title } %>
|
6
|
+
<% header.with_count(count: count) %>
|
7
|
+
<% header.with_description { description } %>
|
8
|
+
<% end %>
|
8
9
|
<% end %>
|
9
10
|
<% component.with_body { "Body" } %>
|
10
11
|
<% component.with_row { "Row 1" } %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<%= render(Primer::OpenProject::CollapsibleSection.new(collapsed: true)) do |section| %>
|
2
|
+
<% section.with_title { "Final question" } %>
|
3
|
+
<% section.with_collapsible_content do %>
|
4
|
+
<%= render(Primer::Alpha::Banner.new(mb: 3)) { "Please take one minute time to answer this question" } %>
|
5
|
+
<%= primer_form_with(url: "/foo") do |f| %>
|
6
|
+
<%= render(RadioButtonGroupForm.new(f)) %>
|
7
|
+
<% end %>
|
8
|
+
<% end %>
|
9
|
+
<% end %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= render(Primer::OpenProject::CollapsibleSection.new) do |section| %>
|
2
|
+
<% section.with_title { "Feedback" } %>
|
3
|
+
<% section.with_collapsible_content do %>
|
4
|
+
<%= render(Primer::Alpha::Banner.new(mb: 3)) { "Please take one minute time to answer this question" } %>
|
5
|
+
<%= primer_form_with(url: "/foo") do |f| %>
|
6
|
+
<%= render(RadioButtonGroupForm.new(f)) %>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<% end %>
|
10
|
+
<% end %>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<%= render(Primer::OpenProject::CollapsibleSection.new) do |section| %>
|
2
|
+
<% section.with_title { "Advanced settings" } %>
|
3
|
+
|
4
|
+
<% if caption.present? %>
|
5
|
+
<% section.with_caption { caption } %>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<% if show_additional_information %>
|
9
|
+
<% section.with_additional_information do %>
|
10
|
+
<%= render(Primer::Beta::Link.new(href: "/")) do |component|
|
11
|
+
component.with_trailing_visual_icon(icon: :"link-external")
|
12
|
+
"More information"
|
13
|
+
end %>
|
14
|
+
<% end %>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<% section.with_collapsible_content do %>
|
18
|
+
<%= primer_form_with(url: "/foo") do |f| %>
|
19
|
+
<%= render(ArrayCheckBoxGroupForm.new(f)) %>
|
20
|
+
<% end %>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|