primer_view_components 0.0.96 → 0.0.97
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -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_list/action-list-selection.pcss +92 -0
- data/app/components/primer/alpha/action_list/action-list.pcss +620 -0
- data/app/components/primer/alpha/action_list/divider.rb +35 -0
- data/app/components/primer/alpha/action_list/heading.html.erb +8 -0
- data/app/components/primer/alpha/action_list/heading.rb +38 -0
- data/app/components/primer/alpha/action_list/item.html.erb +39 -0
- data/app/components/primer/alpha/action_list/item.rb +230 -0
- data/app/components/primer/alpha/action_list.html.erb +15 -0
- data/app/components/primer/alpha/action_list.rb +112 -0
- data/app/components/primer/alpha/dialog/header.rb +1 -1
- data/app/components/primer/alpha/nav_list/item.html.erb +13 -0
- data/app/components/primer/alpha/nav_list/item.rb +89 -0
- data/app/components/primer/alpha/nav_list/section.html.erb +3 -0
- data/app/components/primer/alpha/nav_list/section.rb +88 -0
- data/app/components/primer/alpha/nav_list.d.ts +25 -0
- data/app/components/primer/alpha/nav_list.html.erb +10 -0
- data/app/components/primer/alpha/nav_list.js +130 -0
- data/app/components/primer/alpha/nav_list.rb +112 -0
- data/app/components/primer/alpha/nav_list.ts +129 -0
- data/app/components/primer/primer.d.ts +1 -0
- data/app/components/primer/primer.js +1 -0
- data/app/components/primer/primer.pcss +1 -0
- data/app/components/primer/primer.ts +1 -0
- data/lib/postcss_mixins/activeIndicatorLine.pcss +11 -0
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/tasks/docs.rake +51 -22
- data/lib/yard/docs_helper.rb +3 -3
- data/static/arguments.json +267 -3
- data/static/audited_at.json +7 -0
- data/static/constants.json +76 -0
- data/static/statuses.json +7 -0
- metadata +21 -4
- data/app/components/primer/experimental/action_bar.d.ts +0 -14
- data/app/components/primer/experimental/action_bar.js +0 -141
@@ -0,0 +1,130 @@
|
|
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
|
+
/* eslint-disable custom-elements/expose-class-on-global */
|
8
|
+
import { controller, target, targets } from '@github/catalyst';
|
9
|
+
let NavListElement = class NavListElement extends HTMLElement {
|
10
|
+
connectedCallback() {
|
11
|
+
this.setShowMoreItemState();
|
12
|
+
}
|
13
|
+
get showMoreDisabled() {
|
14
|
+
return this.showMoreItem.hasAttribute('aria-disabled');
|
15
|
+
}
|
16
|
+
set showMoreDisabled(value) {
|
17
|
+
if (value) {
|
18
|
+
this.showMoreItem.setAttribute('aria-disabled', 'true');
|
19
|
+
}
|
20
|
+
else {
|
21
|
+
this.showMoreItem.removeAttribute('aria-disabled');
|
22
|
+
}
|
23
|
+
this.showMoreItem.classList.toggle('disabled', value);
|
24
|
+
}
|
25
|
+
set currentPage(value) {
|
26
|
+
this.showMoreItem.setAttribute('data-current-page', value.toString());
|
27
|
+
}
|
28
|
+
get currentPage() {
|
29
|
+
return parseInt(this.showMoreItem.getAttribute('data-current-page')) || 1;
|
30
|
+
}
|
31
|
+
get totalPages() {
|
32
|
+
return parseInt(this.showMoreItem.getAttribute('data-total-pages')) || 1;
|
33
|
+
}
|
34
|
+
get paginationSrc() {
|
35
|
+
return this.showMoreItem.getAttribute('src') || '';
|
36
|
+
}
|
37
|
+
// expand collapsible item onClick
|
38
|
+
expandItem(item) {
|
39
|
+
var _a;
|
40
|
+
(_a = item.nextElementSibling) === null || _a === void 0 ? void 0 : _a.removeAttribute('data-hidden');
|
41
|
+
item.setAttribute('aria-expanded', 'true');
|
42
|
+
}
|
43
|
+
collapseItem(item) {
|
44
|
+
var _a;
|
45
|
+
(_a = item.nextElementSibling) === null || _a === void 0 ? void 0 : _a.setAttribute('data-hidden', '');
|
46
|
+
item.setAttribute('aria-expanded', 'false');
|
47
|
+
}
|
48
|
+
itemIsExpanded(item) {
|
49
|
+
if ((item === null || item === void 0 ? void 0 : item.tagName) === 'A') {
|
50
|
+
return true;
|
51
|
+
}
|
52
|
+
return (item === null || item === void 0 ? void 0 : item.getAttribute('aria-expanded')) === 'true';
|
53
|
+
}
|
54
|
+
// expand/collapse item
|
55
|
+
handleItemWithSubItemClick(e) {
|
56
|
+
const target = e.target;
|
57
|
+
if (!(target instanceof HTMLElement))
|
58
|
+
return;
|
59
|
+
const button = target.closest('button');
|
60
|
+
if (!button)
|
61
|
+
return;
|
62
|
+
if (this.itemIsExpanded(button)) {
|
63
|
+
this.collapseItem(button);
|
64
|
+
}
|
65
|
+
else {
|
66
|
+
this.expandItem(button);
|
67
|
+
}
|
68
|
+
e.stopPropagation();
|
69
|
+
}
|
70
|
+
async showMore(e) {
|
71
|
+
var _a, _b;
|
72
|
+
e.preventDefault();
|
73
|
+
if (this.showMoreDisabled)
|
74
|
+
return;
|
75
|
+
this.showMoreDisabled = true;
|
76
|
+
let html;
|
77
|
+
try {
|
78
|
+
const paginationURL = new URL(this.paginationSrc, window.location.origin);
|
79
|
+
this.currentPage++;
|
80
|
+
paginationURL.searchParams.append('page', this.currentPage.toString());
|
81
|
+
const response = await fetch(paginationURL);
|
82
|
+
if (!response.ok)
|
83
|
+
return;
|
84
|
+
html = await response.text();
|
85
|
+
if (this.currentPage === this.totalPages) {
|
86
|
+
this.showMoreItem.hidden = true;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
catch (err) {
|
90
|
+
// Ignore network errors
|
91
|
+
this.showMoreDisabled = false;
|
92
|
+
this.currentPage--;
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
const fragment = this.parseHTML(document, html);
|
96
|
+
(_a = fragment === null || fragment === void 0 ? void 0 : fragment.querySelector('li > a')) === null || _a === void 0 ? void 0 : _a.setAttribute('data-targets', 'nav-list.focusMarkers');
|
97
|
+
this.list.insertBefore(fragment, this.showMoreItem);
|
98
|
+
(_b = this.focusMarkers.pop()) === null || _b === void 0 ? void 0 : _b.focus();
|
99
|
+
this.showMoreDisabled = false;
|
100
|
+
}
|
101
|
+
setShowMoreItemState() {
|
102
|
+
if (!this.showMoreItem) {
|
103
|
+
return;
|
104
|
+
}
|
105
|
+
if (this.currentPage < this.totalPages) {
|
106
|
+
this.showMoreItem.hidden = false;
|
107
|
+
}
|
108
|
+
else {
|
109
|
+
this.showMoreItem.hidden = true;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
parseHTML(document, html) {
|
113
|
+
const template = document.createElement('template');
|
114
|
+
// eslint-disable-next-line github/no-inner-html
|
115
|
+
template.innerHTML = html;
|
116
|
+
return document.importNode(template.content, true);
|
117
|
+
}
|
118
|
+
};
|
119
|
+
__decorate([
|
120
|
+
target
|
121
|
+
], NavListElement.prototype, "list", void 0);
|
122
|
+
__decorate([
|
123
|
+
target
|
124
|
+
], NavListElement.prototype, "showMoreItem", void 0);
|
125
|
+
__decorate([
|
126
|
+
targets
|
127
|
+
], NavListElement.prototype, "focusMarkers", void 0);
|
128
|
+
NavListElement = __decorate([
|
129
|
+
controller
|
130
|
+
], NavListElement);
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module Alpha
|
5
|
+
# `NavList` provides a simple way to render side navigation, i.e. navigation
|
6
|
+
# that appears to the left or right side of some main content. Each section in a
|
7
|
+
# nav list is a list of links.
|
8
|
+
#
|
9
|
+
# Nav list sections can contain sub items. Rather than navigating to a URL, sections
|
10
|
+
# with sub items expand and collapse on click. To indicate this functionality, the
|
11
|
+
# section will automatically render with a trailing chevron icon that changes direction
|
12
|
+
# when the section expands and collapses.
|
13
|
+
#
|
14
|
+
# Nav list items appear visually active when selected. Each nav item must have one
|
15
|
+
# or more ID values that determine which item will appear selected. Use the
|
16
|
+
# `selected_item_id` argument to select the appropriate item.
|
17
|
+
class NavList < Primer::Component
|
18
|
+
status :alpha
|
19
|
+
|
20
|
+
# Sections. Each section is a list of links and an optional heading.
|
21
|
+
#
|
22
|
+
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Section) %>.
|
23
|
+
renders_many :sections, lambda { |**system_arguments|
|
24
|
+
Primer::Alpha::NavList::Section.new(selected_item_id: @selected_item_id, **system_arguments)
|
25
|
+
}
|
26
|
+
|
27
|
+
# @example Items and headings
|
28
|
+
#
|
29
|
+
# <%= render(Primer::Alpha::NavList.new(selected_item_id: :personal_info)) do |component| %>
|
30
|
+
# <% component.with_section(aria: { label: "Settings" }) do |section| %>
|
31
|
+
# <% section.with_item(label: "General", selected_by_ids: :general, href: "/settings/general") %>
|
32
|
+
# <% end %>
|
33
|
+
# <% component.with_section(aria: { label: "Account settings" }) do |section| %>
|
34
|
+
# <% section.with_heading(title: "Account Settings") %>
|
35
|
+
# <% section.with_item(label: "Personal Information", selected_by_ids: :personal_info, href: "/account/info") %>
|
36
|
+
# <% section.with_item(label: "Password", selected_by_ids: :password, href: "/account/password") %>
|
37
|
+
# <% section.with_item(label: "Billing info", selected_by_ids: :billing, href: "/account/billing") %>
|
38
|
+
# <% end %>
|
39
|
+
# <% end %>
|
40
|
+
#
|
41
|
+
# @example Leading and trailing visuals
|
42
|
+
#
|
43
|
+
# <%= render(Primer::Alpha::NavList.new(selected_item_id: :personal_info)) do |component| %>
|
44
|
+
# <% component.with_section(aria: { label: "Account settings" }) do |section| %>
|
45
|
+
# <% section.with_heading(title: "Account Settings") %>
|
46
|
+
# <% section.with_item(label: "Personal Information", selected_by_ids: :personal_info, href: "/account/info") do |item| %>
|
47
|
+
# <% item.with_leading_visual_avatar(src: "https://github.com/github.png", alt: "GitHub") %>
|
48
|
+
# <% end %>
|
49
|
+
# <% section.with_item(label: "Notifications", selected_by_ids: :notifications, href: "/account/notifications") do |item| %>
|
50
|
+
# <% item.with_leading_visual_icon(icon: :bell) %>
|
51
|
+
# <% item.with_trailing_visual_counter(count: 15) %>
|
52
|
+
# <% end %>
|
53
|
+
# <% section.with_item(label: "Billing info", selected_by_ids: :billing, href: "/account/billing") do |item| %>
|
54
|
+
# <% item.with_leading_visual_icon(icon: :package) %>
|
55
|
+
# <% item.with_trailing_visual_icon(icon: :"dot-fill", color: :attention) %>
|
56
|
+
# <% end %>
|
57
|
+
# <% end %>
|
58
|
+
# <% end %>
|
59
|
+
#
|
60
|
+
# @example Expandable sub items
|
61
|
+
#
|
62
|
+
# <%= render(Primer::Alpha::NavList.new(selected_item_id: :email_notifications)) do |component| %>
|
63
|
+
# <% component.with_section(aria: { label: "Account settings" }) do |section| %>
|
64
|
+
# <% section.with_heading(title: "Account Settings") %>
|
65
|
+
# <% section.with_item(label: "Notification settings", selected_by_ids: :notifications) do |item| %>
|
66
|
+
# <% item.with_leading_visual_icon(icon: :bell) %>
|
67
|
+
# <% item.with_item(label: "Email", selected_by_ids: :email_notifications, href: "/account/notifications/email") do |subitem| %>
|
68
|
+
# <% subitem.with_trailing_visual_icon(icon: :mail) %>
|
69
|
+
# <% end %>
|
70
|
+
# <% item.with_item(label: "SMS", selected_by_ids: :sms_notifications, href: "/account/notifications/sms") do |subitem| %>
|
71
|
+
# <% subitem.with_trailing_visual_icon(icon: :"device-mobile") %>
|
72
|
+
# <% end %>
|
73
|
+
# <% end %>
|
74
|
+
# <% section.with_item(label: "Messages", selected_by_ids: :messages) do |item| %>
|
75
|
+
# <% item.with_leading_visual_icon(icon: :bookmark) %>
|
76
|
+
# <% item.with_item(label: "Inbox", href: "/account/messages/inbox") do |subitem| %>
|
77
|
+
# <% subitem.with_trailing_visual_counter(count: 10) %>
|
78
|
+
# <% end %>
|
79
|
+
# <% item.with_item(label: "Organizer", href: "/account/messages/organizer") do |subitem| %>
|
80
|
+
# <% subitem.with_trailing_visual_label(scheme: :primary) { "New" } %>
|
81
|
+
# <% end %>
|
82
|
+
# <% end %>
|
83
|
+
# <% end %>
|
84
|
+
# <% end %>
|
85
|
+
#
|
86
|
+
# @example Trailing action
|
87
|
+
#
|
88
|
+
# <%= render(Primer::Alpha::NavList.new) do |component| %>
|
89
|
+
# <% component.with_section(aria: { label: "Favorite foods" }) do |section| %>
|
90
|
+
# <% section.with_heading(title: "My Favorite Foods") %>
|
91
|
+
# <% section.with_item(label: "Popplers", selected_by_ids: :popplers, href: "/foods/popplers") do |item| %>
|
92
|
+
# <% item.with_trailing_action(show_on_hover: false, icon: "plus", "aria-label": "Add new food", size: :medium) %>
|
93
|
+
# <% end %>
|
94
|
+
# <% section.with_item(label: "Slurm", selected_by_ids: :slurm, href: "/foods/slurm") do |item| %>
|
95
|
+
# <% item.with_trailing_action(show_on_hover: true, icon: "plus", "aria-label": "Add new food", size: :medium) %>
|
96
|
+
# <% end %>
|
97
|
+
# <% end %>
|
98
|
+
# <% end %>
|
99
|
+
#
|
100
|
+
# @param selected_item_id [Symbol] The ID of the currently selected item. The default is `nil`, meaning no item is selected.
|
101
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
102
|
+
def initialize(selected_item_id: nil, **system_arguments)
|
103
|
+
@system_arguments = system_arguments
|
104
|
+
@system_arguments[:classes] = class_names(
|
105
|
+
@system_arguments[:classes],
|
106
|
+
"ActionListWrap"
|
107
|
+
)
|
108
|
+
@selected_item_id = selected_item_id
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
/* eslint-disable custom-elements/expose-class-on-global */
|
2
|
+
import {controller, target, targets} from '@github/catalyst'
|
3
|
+
|
4
|
+
@controller
|
5
|
+
class NavListElement extends HTMLElement {
|
6
|
+
@target list: HTMLElement
|
7
|
+
@target showMoreItem: HTMLElement
|
8
|
+
@targets focusMarkers: HTMLElement[]
|
9
|
+
|
10
|
+
connectedCallback(): void {
|
11
|
+
this.setShowMoreItemState()
|
12
|
+
}
|
13
|
+
|
14
|
+
get showMoreDisabled(): boolean {
|
15
|
+
return this.showMoreItem.hasAttribute('aria-disabled')
|
16
|
+
}
|
17
|
+
|
18
|
+
set showMoreDisabled(value: boolean) {
|
19
|
+
if (value) {
|
20
|
+
this.showMoreItem.setAttribute('aria-disabled', 'true')
|
21
|
+
} else {
|
22
|
+
this.showMoreItem.removeAttribute('aria-disabled')
|
23
|
+
}
|
24
|
+
this.showMoreItem.classList.toggle('disabled', value)
|
25
|
+
}
|
26
|
+
|
27
|
+
set currentPage(value: number) {
|
28
|
+
this.showMoreItem.setAttribute('data-current-page', value.toString())
|
29
|
+
}
|
30
|
+
|
31
|
+
get currentPage(): number {
|
32
|
+
return parseInt(this.showMoreItem.getAttribute('data-current-page') as string) || 1
|
33
|
+
}
|
34
|
+
|
35
|
+
get totalPages(): number {
|
36
|
+
return parseInt(this.showMoreItem.getAttribute('data-total-pages') as string) || 1
|
37
|
+
}
|
38
|
+
|
39
|
+
get paginationSrc(): string {
|
40
|
+
return this.showMoreItem.getAttribute('src') || ''
|
41
|
+
}
|
42
|
+
|
43
|
+
// expand collapsible item onClick
|
44
|
+
expandItem(item: HTMLElement) {
|
45
|
+
item.nextElementSibling?.removeAttribute('data-hidden')
|
46
|
+
item.setAttribute('aria-expanded', 'true')
|
47
|
+
}
|
48
|
+
|
49
|
+
collapseItem(item: HTMLElement) {
|
50
|
+
item.nextElementSibling?.setAttribute('data-hidden', '')
|
51
|
+
item.setAttribute('aria-expanded', 'false')
|
52
|
+
}
|
53
|
+
|
54
|
+
itemIsExpanded(item: HTMLElement | null) {
|
55
|
+
if (item?.tagName === 'A') {
|
56
|
+
return true
|
57
|
+
}
|
58
|
+
return item?.getAttribute('aria-expanded') === 'true'
|
59
|
+
}
|
60
|
+
|
61
|
+
// expand/collapse item
|
62
|
+
handleItemWithSubItemClick(e: Event) {
|
63
|
+
const target = e.target
|
64
|
+
if (!(target instanceof HTMLElement)) return
|
65
|
+
|
66
|
+
const button = target.closest<HTMLButtonElement>('button')
|
67
|
+
if (!button) return
|
68
|
+
if (this.itemIsExpanded(button)) {
|
69
|
+
this.collapseItem(button)
|
70
|
+
} else {
|
71
|
+
this.expandItem(button)
|
72
|
+
}
|
73
|
+
|
74
|
+
e.stopPropagation()
|
75
|
+
}
|
76
|
+
|
77
|
+
private async showMore(e: Event) {
|
78
|
+
e.preventDefault()
|
79
|
+
if (this.showMoreDisabled) return
|
80
|
+
this.showMoreDisabled = true
|
81
|
+
let html
|
82
|
+
try {
|
83
|
+
const paginationURL = new URL(this.paginationSrc, window.location.origin)
|
84
|
+
this.currentPage++
|
85
|
+
paginationURL.searchParams.append('page', this.currentPage.toString())
|
86
|
+
const response = await fetch(paginationURL)
|
87
|
+
if (!response.ok) return
|
88
|
+
html = await response.text()
|
89
|
+
if (this.currentPage === this.totalPages) {
|
90
|
+
this.showMoreItem.hidden = true
|
91
|
+
}
|
92
|
+
} catch (err) {
|
93
|
+
// Ignore network errors
|
94
|
+
this.showMoreDisabled = false
|
95
|
+
this.currentPage--
|
96
|
+
return
|
97
|
+
}
|
98
|
+
const fragment = this.parseHTML(document, html)
|
99
|
+
fragment?.querySelector('li > a')?.setAttribute('data-targets', 'nav-list.focusMarkers')
|
100
|
+
this.list.insertBefore(fragment, this.showMoreItem)
|
101
|
+
this.focusMarkers.pop()?.focus()
|
102
|
+
this.showMoreDisabled = false
|
103
|
+
}
|
104
|
+
|
105
|
+
private setShowMoreItemState() {
|
106
|
+
if (!this.showMoreItem) {
|
107
|
+
return
|
108
|
+
}
|
109
|
+
|
110
|
+
if (this.currentPage < this.totalPages) {
|
111
|
+
this.showMoreItem.hidden = false
|
112
|
+
} else {
|
113
|
+
this.showMoreItem.hidden = true
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
private parseHTML(document: Document, html: string): DocumentFragment {
|
118
|
+
const template = document.createElement('template')
|
119
|
+
// eslint-disable-next-line github/no-inner-html
|
120
|
+
template.innerHTML = html
|
121
|
+
return document.importNode(template.content, true)
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
125
|
+
declare global {
|
126
|
+
interface Window {
|
127
|
+
NavListElement: typeof NavListElement
|
128
|
+
}
|
129
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
/* active indicator line for navlist items */
|
2
|
+
@define-mixin activeIndicatorLine $padding-left: calc(-1 * var(--base-size-8, 8px)) {
|
3
|
+
position: absolute;
|
4
|
+
top: calc(50% - 12px);
|
5
|
+
left: $padding-left;
|
6
|
+
width: var(--base-size-4, 4px);
|
7
|
+
height: var(--base-size-24, 24px);
|
8
|
+
content: '';
|
9
|
+
background: var(--color-accent-fg);
|
10
|
+
border-radius: var(--primer-borderRadius-medium, 6px);
|
11
|
+
}
|
data/lib/tasks/docs.rake
CHANGED
@@ -88,7 +88,14 @@ namespace :docs do
|
|
88
88
|
Primer::Alpha::TabNav,
|
89
89
|
Primer::Alpha::TabPanels,
|
90
90
|
Primer::Alpha::Tooltip,
|
91
|
-
Primer::Alpha::ToggleSwitch
|
91
|
+
Primer::Alpha::ToggleSwitch,
|
92
|
+
Primer::Alpha::ActionList,
|
93
|
+
Primer::Alpha::NavList,
|
94
|
+
Primer::Alpha::NavList::Item,
|
95
|
+
Primer::Alpha::NavList::Section,
|
96
|
+
Primer::Alpha::ActionList::Divider,
|
97
|
+
Primer::Alpha::ActionList::Heading,
|
98
|
+
Primer::Alpha::ActionList::Item
|
92
99
|
]
|
93
100
|
|
94
101
|
js_components = [
|
@@ -104,7 +111,23 @@ namespace :docs do
|
|
104
111
|
Primer::Alpha::Tooltip,
|
105
112
|
Primer::ButtonComponent,
|
106
113
|
Primer::IconButton,
|
107
|
-
Primer::LinkComponent
|
114
|
+
Primer::LinkComponent,
|
115
|
+
Primer::Alpha::ToggleSwitch,
|
116
|
+
Primer::Alpha::ActionList,
|
117
|
+
Primer::Alpha::NavList,
|
118
|
+
Primer::Alpha::NavList::Section
|
119
|
+
]
|
120
|
+
|
121
|
+
components_without_examples = [
|
122
|
+
# ActionList is a base component that should not be used by itself
|
123
|
+
Primer::Alpha::ActionList,
|
124
|
+
Primer::Alpha::ActionList::Divider,
|
125
|
+
Primer::Alpha::ActionList::Heading,
|
126
|
+
Primer::Alpha::ActionList::Item,
|
127
|
+
|
128
|
+
# Examples can be seen in the NavList docs
|
129
|
+
Primer::Alpha::NavList::Item,
|
130
|
+
Primer::Alpha::NavList::Section
|
108
131
|
]
|
109
132
|
|
110
133
|
all_components = Primer::Component.descendants - [Primer::BaseComponent]
|
@@ -212,7 +235,9 @@ namespace :docs do
|
|
212
235
|
args_for_components << component_args
|
213
236
|
|
214
237
|
# Slots V2 docs
|
215
|
-
slot_v2_methods = documentation.meths.select
|
238
|
+
slot_v2_methods = documentation.meths.select do |mtd|
|
239
|
+
(mtd[:renders_one] || mtd[:renders_many]) && mtd.tag(:private).nil?
|
240
|
+
end
|
216
241
|
|
217
242
|
if slot_v2_methods.any?
|
218
243
|
f.puts
|
@@ -220,7 +245,7 @@ namespace :docs do
|
|
220
245
|
|
221
246
|
slot_v2_methods.each do |slot_documentation|
|
222
247
|
f.puts
|
223
|
-
f.puts("### `#{slot_documentation.name
|
248
|
+
f.puts("### `#{slot_documentation.name}`")
|
224
249
|
|
225
250
|
if slot_documentation.base_docstring.to_s.present?
|
226
251
|
f.puts
|
@@ -240,26 +265,30 @@ namespace :docs do
|
|
240
265
|
end
|
241
266
|
end
|
242
267
|
|
243
|
-
|
244
|
-
|
245
|
-
f.puts
|
246
|
-
f.puts("## Examples")
|
268
|
+
example_tags = initialize_method.tags(:example)
|
247
269
|
|
248
|
-
|
249
|
-
name, description, code = parse_example_tag(tag)
|
270
|
+
if example_tags.any?
|
250
271
|
f.puts
|
251
|
-
f.puts("
|
252
|
-
|
272
|
+
f.puts("## Examples")
|
273
|
+
|
274
|
+
example_tags.each do |tag|
|
275
|
+
name, description, code = parse_example_tag(tag)
|
276
|
+
f.puts
|
277
|
+
f.puts("### #{name}")
|
278
|
+
if description
|
279
|
+
f.puts
|
280
|
+
f.puts(view_context.render(inline: description.squish))
|
281
|
+
end
|
253
282
|
f.puts
|
254
|
-
|
283
|
+
html = view_context.render(inline: code)
|
284
|
+
f.puts("<Example src=\"#{html.tr('"', "\'").delete("\n")}\" />")
|
285
|
+
f.puts
|
286
|
+
f.puts("```erb")
|
287
|
+
f.puts(code.to_s)
|
288
|
+
f.puts("```")
|
255
289
|
end
|
256
|
-
|
257
|
-
|
258
|
-
f.puts("<Example src=\"#{html.tr('"', "\'").delete("\n")}\" />")
|
259
|
-
f.puts
|
260
|
-
f.puts("```erb")
|
261
|
-
f.puts(code.to_s)
|
262
|
-
f.puts("```")
|
290
|
+
else
|
291
|
+
errors << { component.name => { example: "No examples found" } } unless components_without_examples.include?(component)
|
263
292
|
end
|
264
293
|
end
|
265
294
|
end
|
@@ -454,12 +483,12 @@ namespace :docs do
|
|
454
483
|
end
|
455
484
|
|
456
485
|
def docs_metadata(component)
|
457
|
-
|
486
|
+
status_module, short_name, class_name = status_module_and_short_name(component)
|
458
487
|
status_path = status_module.nil? ? "" : "#{status_module}/"
|
459
488
|
status = component.status.to_s
|
460
489
|
|
461
490
|
{
|
462
|
-
title:
|
491
|
+
title: class_name,
|
463
492
|
component_id: short_name.underscore,
|
464
493
|
status: status.capitalize,
|
465
494
|
source: source_url(component),
|
data/lib/yard/docs_helper.rb
CHANGED
@@ -44,10 +44,10 @@ module YARD
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def link_to_component(component)
|
47
|
-
|
47
|
+
status_module, short_name, class_name = status_module_and_short_name(component)
|
48
48
|
status_path = status_module.nil? ? "" : "#{status_module}/"
|
49
49
|
|
50
|
-
"[#{
|
50
|
+
"[#{class_name}](/components/#{status_path}#{short_name.downcase})"
|
51
51
|
end
|
52
52
|
|
53
53
|
def link_to_octicons
|
@@ -62,7 +62,7 @@ module YARD
|
|
62
62
|
name_with_status = component.name.gsub(/Primer::|Component/, "")
|
63
63
|
|
64
64
|
m = name_with_status.match(/(?<status>Beta|Alpha|Deprecated)?(?<_colons>::)?(?<name>.*)/)
|
65
|
-
[m[:status]&.downcase, m[:name].gsub("::", "")]
|
65
|
+
[m[:status]&.downcase, m[:name].gsub("::", ""), m[:name]]
|
66
66
|
end
|
67
67
|
|
68
68
|
def pretty_value(val)
|