primer_view_components 0.0.68 → 0.0.69
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 +52 -1
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/components/primer/alpha/tooltip.d.ts +24 -0
- data/app/components/primer/alpha/tooltip.js +381 -0
- data/app/components/primer/alpha/tooltip.rb +95 -0
- data/app/components/primer/alpha/tooltip.ts +377 -0
- data/app/components/primer/base_component.rb +2 -2
- data/app/components/primer/beta/truncate.rb +1 -0
- data/app/components/primer/details_component.rb +1 -1
- data/app/components/primer/icon_button.rb +1 -1
- data/app/components/primer/markdown.rb +1 -1
- data/app/components/primer/primer.d.ts +1 -0
- data/app/components/primer/primer.js +1 -0
- data/app/components/primer/primer.ts +1 -0
- data/app/components/primer/subhead_component.html.erb +1 -1
- data/app/components/primer/subhead_component.rb +1 -1
- data/lib/primer/classify/utilities.yml +20 -0
- data/lib/primer/view_components/linters/button_component_migration_counter.rb +1 -1
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/rubocop/cop/primer/primer_octicon.rb +1 -1
- data/lib/tasks/docs.rake +7 -5
- data/lib/tasks/utilities.rake +1 -1
- data/static/arguments.yml +25 -1
- data/static/audited_at.json +1 -0
- data/static/classes.yml +1 -0
- data/static/constants.json +18 -0
- data/static/statuses.json +1 -0
- metadata +15 -11
@@ -0,0 +1,377 @@
|
|
1
|
+
import type {AnchorAlignment, AnchorSide} from '@primer/behaviors'
|
2
|
+
import {getAnchoredPosition} from '@primer/behaviors'
|
3
|
+
|
4
|
+
const TOOLTIP_OPEN_CLASS = 'tooltip-open'
|
5
|
+
|
6
|
+
type Direction = 'n' | 's' | 'e' | 'w' | 'ne' | 'se' | 'nw' | 'sw'
|
7
|
+
|
8
|
+
const DIRECTION_CLASSES = [
|
9
|
+
'tooltip-n',
|
10
|
+
'tooltip-s',
|
11
|
+
'tooltip-e',
|
12
|
+
'tooltip-w',
|
13
|
+
'tooltip-ne',
|
14
|
+
'tooltip-se',
|
15
|
+
'tooltip-nw',
|
16
|
+
'tooltip-sw'
|
17
|
+
]
|
18
|
+
|
19
|
+
class TooltipElement extends HTMLElement {
|
20
|
+
styles() {
|
21
|
+
return `
|
22
|
+
:host {
|
23
|
+
position: absolute;
|
24
|
+
z-index: 1000000;
|
25
|
+
padding: .5em .75em;
|
26
|
+
font: normal normal 11px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
27
|
+
-webkit-font-smoothing: subpixel-antialiased;
|
28
|
+
color: var(--color-fg-on-emphasis);
|
29
|
+
text-align: center;
|
30
|
+
text-decoration: none;
|
31
|
+
text-shadow: none;
|
32
|
+
text-transform: none;
|
33
|
+
letter-spacing: normal;
|
34
|
+
word-wrap: break-word;
|
35
|
+
white-space: pre;
|
36
|
+
background: var(--color-neutral-emphasis-plus);
|
37
|
+
border-radius: 6px;
|
38
|
+
opacity: 0;
|
39
|
+
max-width: 250px;
|
40
|
+
word-wrap: break-word;
|
41
|
+
white-space: normal
|
42
|
+
}
|
43
|
+
|
44
|
+
:host:before{
|
45
|
+
position: absolute;
|
46
|
+
z-index: 1000001;
|
47
|
+
color: var(--color-neutral-emphasis-plus);
|
48
|
+
content: "";
|
49
|
+
border: 6px solid transparent;
|
50
|
+
opacity: 0
|
51
|
+
}
|
52
|
+
|
53
|
+
@keyframes tooltip-appear {
|
54
|
+
from {
|
55
|
+
opacity: 0
|
56
|
+
}
|
57
|
+
to {
|
58
|
+
opacity: 1
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
:host:after{
|
63
|
+
position: absolute;
|
64
|
+
display: block;
|
65
|
+
right: 0;
|
66
|
+
left: 0;
|
67
|
+
height: 12px;
|
68
|
+
content: ""
|
69
|
+
}
|
70
|
+
|
71
|
+
:host(.${TOOLTIP_OPEN_CLASS}),
|
72
|
+
:host(.${TOOLTIP_OPEN_CLASS}):before {
|
73
|
+
animation-name: tooltip-appear;
|
74
|
+
animation-duration: .1s;
|
75
|
+
animation-fill-mode: forwards;
|
76
|
+
animation-timing-function: ease-in;
|
77
|
+
animation-delay: .4s
|
78
|
+
}
|
79
|
+
|
80
|
+
:host(.tooltip-s):before,
|
81
|
+
:host(.tooltip-se):before,
|
82
|
+
:host(.tooltip-sw):before {
|
83
|
+
right: 50%;
|
84
|
+
bottom: 100%;
|
85
|
+
margin-right: -6px;
|
86
|
+
border-bottom-color: var(--color-neutral-emphasis-plus)
|
87
|
+
}
|
88
|
+
|
89
|
+
:host(.tooltip-s):after,
|
90
|
+
:host(.tooltip-se):after,
|
91
|
+
:host(.tooltip-sw):after {
|
92
|
+
bottom: 100%
|
93
|
+
}
|
94
|
+
|
95
|
+
:host(.tooltip-n):before,
|
96
|
+
:host(.tooltip-ne):before,
|
97
|
+
:host(.tooltip-nw):before {
|
98
|
+
top: 100%;
|
99
|
+
right: 50%;
|
100
|
+
margin-right: -6px;
|
101
|
+
border-top-color: var(--color-neutral-emphasis-plus)
|
102
|
+
}
|
103
|
+
|
104
|
+
:host(.tooltip-n):after,
|
105
|
+
:host(.tooltip-ne):after,
|
106
|
+
:host(.tooltip-nw):after {
|
107
|
+
top: 100%
|
108
|
+
}
|
109
|
+
|
110
|
+
:host(.tooltip-se):before,
|
111
|
+
:host(.tooltip-ne):before {
|
112
|
+
right: auto
|
113
|
+
}
|
114
|
+
|
115
|
+
:host(.tooltip-sw):before,
|
116
|
+
:host(.tooltip-nw):before {
|
117
|
+
right: 0;
|
118
|
+
margin-right: 6px
|
119
|
+
}
|
120
|
+
|
121
|
+
:host(.tooltip-w):before {
|
122
|
+
top: 50%;
|
123
|
+
bottom: 50%;
|
124
|
+
left: 100%;
|
125
|
+
margin-top: -6px;
|
126
|
+
border-left-color: var(--color-neutral-emphasis-plus)
|
127
|
+
}
|
128
|
+
|
129
|
+
:host(.tooltip-e):before {
|
130
|
+
top: 50%;
|
131
|
+
right: 100%;
|
132
|
+
bottom: 50%;
|
133
|
+
margin-top: -6px;
|
134
|
+
border-right-color: var(--color-neutral-emphasis-plus)
|
135
|
+
}
|
136
|
+
`
|
137
|
+
}
|
138
|
+
|
139
|
+
#abortController: AbortController | undefined
|
140
|
+
#align: AnchorAlignment = 'center'
|
141
|
+
#side: AnchorSide = 'outside-bottom'
|
142
|
+
#allowUpdatePosition = false
|
143
|
+
|
144
|
+
get htmlFor(): string {
|
145
|
+
return this.getAttribute('for') || ''
|
146
|
+
}
|
147
|
+
|
148
|
+
set htmlFor(value: string) {
|
149
|
+
this.setAttribute('for', value)
|
150
|
+
}
|
151
|
+
|
152
|
+
get type(): 'description' | 'label' {
|
153
|
+
const type = this.getAttribute('data-type')
|
154
|
+
return type === 'label' ? 'label' : 'description'
|
155
|
+
}
|
156
|
+
|
157
|
+
set type(value: 'description' | 'label') {
|
158
|
+
this.setAttribute('data-type', value)
|
159
|
+
}
|
160
|
+
|
161
|
+
get direction(): Direction {
|
162
|
+
return (this.getAttribute('data-direction') || 's') as Direction
|
163
|
+
}
|
164
|
+
|
165
|
+
set direction(value: Direction) {
|
166
|
+
this.setAttribute('data-direction', value)
|
167
|
+
}
|
168
|
+
|
169
|
+
get control(): HTMLElement | null {
|
170
|
+
return this.ownerDocument.getElementById(this.htmlFor)
|
171
|
+
}
|
172
|
+
|
173
|
+
constructor() {
|
174
|
+
super()
|
175
|
+
const shadow = this.attachShadow({mode: 'open'})
|
176
|
+
shadow.innerHTML = `
|
177
|
+
<style>
|
178
|
+
${this.styles()}
|
179
|
+
</style>
|
180
|
+
<slot></slot>
|
181
|
+
`
|
182
|
+
}
|
183
|
+
|
184
|
+
connectedCallback() {
|
185
|
+
this.hidden = true
|
186
|
+
this.#allowUpdatePosition = true
|
187
|
+
|
188
|
+
if (!this.id) {
|
189
|
+
this.id = `tooltip-${Date.now()}-${(Math.random() * 10000).toFixed(0)}`
|
190
|
+
}
|
191
|
+
|
192
|
+
if (!this.control) return
|
193
|
+
|
194
|
+
this.setAttribute('role', 'tooltip')
|
195
|
+
|
196
|
+
this.#abortController?.abort()
|
197
|
+
this.#abortController = new AbortController()
|
198
|
+
const {signal} = this.#abortController
|
199
|
+
|
200
|
+
this.addEventListener('mouseleave', this, {signal})
|
201
|
+
this.control.addEventListener('mouseenter', this, {signal})
|
202
|
+
this.control.addEventListener('mouseleave', this, {signal})
|
203
|
+
this.control.addEventListener('focus', this, {signal})
|
204
|
+
this.control.addEventListener('blur', this, {signal})
|
205
|
+
this.ownerDocument.addEventListener('keydown', this, {signal})
|
206
|
+
}
|
207
|
+
|
208
|
+
disconnectedCallback() {
|
209
|
+
this.#abortController?.abort()
|
210
|
+
}
|
211
|
+
|
212
|
+
handleEvent(event: Event) {
|
213
|
+
if (!this.control) return
|
214
|
+
|
215
|
+
// Ensures that tooltip stays open when hovering between tooltip and element
|
216
|
+
// WCAG Success Criterion 1.4.13 Hoverable
|
217
|
+
if ((event.type === 'mouseenter' || event.type === 'focus') && this.hidden) {
|
218
|
+
this.hidden = false
|
219
|
+
} else if (event.type === 'blur') {
|
220
|
+
this.hidden = true
|
221
|
+
} else if (
|
222
|
+
event.type === 'mouseleave' &&
|
223
|
+
(event as MouseEvent).relatedTarget !== this.control &&
|
224
|
+
(event as MouseEvent).relatedTarget !== this
|
225
|
+
) {
|
226
|
+
this.hidden = true
|
227
|
+
} else if (event.type === 'keydown' && (event as KeyboardEvent).key === 'Escape' && !this.hidden) {
|
228
|
+
this.hidden = true
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
232
|
+
static observedAttributes = ['data-type', 'data-direction', 'id', 'hidden']
|
233
|
+
|
234
|
+
attributeChangedCallback(name: string) {
|
235
|
+
if (name === 'id' || name === 'data-type') {
|
236
|
+
if (!this.id || !this.control) return
|
237
|
+
if (this.type === 'label') {
|
238
|
+
this.control.setAttribute('aria-labelledby', this.id)
|
239
|
+
} else {
|
240
|
+
let describedBy = this.control.getAttribute('aria-describedby')
|
241
|
+
describedBy ? (describedBy = `${describedBy} ${this.id}`) : (describedBy = this.id)
|
242
|
+
this.control.setAttribute('aria-describedby', describedBy)
|
243
|
+
}
|
244
|
+
} else if (name === 'hidden') {
|
245
|
+
if (this.hidden) {
|
246
|
+
this.classList.remove(TOOLTIP_OPEN_CLASS, ...DIRECTION_CLASSES)
|
247
|
+
} else {
|
248
|
+
this.classList.add(TOOLTIP_OPEN_CLASS)
|
249
|
+
for (const tooltip of this.ownerDocument.querySelectorAll<HTMLElement>(this.tagName)) {
|
250
|
+
if (tooltip !== this) tooltip.hidden = true
|
251
|
+
}
|
252
|
+
this.#updatePosition()
|
253
|
+
}
|
254
|
+
} else if (name === 'data-direction') {
|
255
|
+
this.classList.remove(...DIRECTION_CLASSES)
|
256
|
+
const direction = this.direction
|
257
|
+
if (direction === 'n') {
|
258
|
+
this.#align = 'center'
|
259
|
+
this.#side = 'outside-top'
|
260
|
+
} else if (direction === 'ne') {
|
261
|
+
this.#align = 'start'
|
262
|
+
this.#side = 'outside-top'
|
263
|
+
} else if (direction === 'e') {
|
264
|
+
this.#align = 'center'
|
265
|
+
this.#side = 'outside-right'
|
266
|
+
} else if (direction === 'se') {
|
267
|
+
this.#align = 'start'
|
268
|
+
this.#side = 'outside-bottom'
|
269
|
+
} else if (direction === 's') {
|
270
|
+
this.#align = 'center'
|
271
|
+
this.#side = 'outside-bottom'
|
272
|
+
} else if (direction === 'sw') {
|
273
|
+
this.#align = 'end'
|
274
|
+
this.#side = 'outside-bottom'
|
275
|
+
} else if (direction === 'w') {
|
276
|
+
this.#align = 'center'
|
277
|
+
this.#side = 'outside-left'
|
278
|
+
} else if (direction === 'nw') {
|
279
|
+
this.#align = 'end'
|
280
|
+
this.#side = 'outside-top'
|
281
|
+
}
|
282
|
+
}
|
283
|
+
}
|
284
|
+
|
285
|
+
// `getAnchoredPosition` may calibrate `anchoredSide` but does not recalibrate `align`.
|
286
|
+
// Therefore, we need to determine which `align` is best based on the initial `getAnchoredPosition` calcluation.
|
287
|
+
// Related: https://github.com/primer/behaviors/issues/63
|
288
|
+
#adjustedAnchorAlignment(anchorSide: AnchorSide): AnchorAlignment | undefined {
|
289
|
+
if (!this.control) return
|
290
|
+
|
291
|
+
const tooltipPosition = this.getBoundingClientRect()
|
292
|
+
const targetPosition = this.control.getBoundingClientRect()
|
293
|
+
const tooltipWidth = tooltipPosition.width
|
294
|
+
|
295
|
+
const tooltipCenter = tooltipPosition.left + tooltipWidth / 2
|
296
|
+
const targetCenter = targetPosition.x + targetPosition.width / 2
|
297
|
+
|
298
|
+
if (Math.abs(tooltipCenter - targetCenter) < 2 || anchorSide === 'outside-left' || anchorSide === 'outside-right') {
|
299
|
+
return 'center'
|
300
|
+
} else if (tooltipPosition.left === targetPosition.left) {
|
301
|
+
return 'start'
|
302
|
+
} else if (tooltipPosition.right === targetPosition.right) {
|
303
|
+
return 'end'
|
304
|
+
} else if (tooltipCenter < targetCenter) {
|
305
|
+
if (tooltipPosition.left === 0) return 'start'
|
306
|
+
return 'end'
|
307
|
+
} else {
|
308
|
+
if (tooltipPosition.right === 0) return 'end'
|
309
|
+
return 'start'
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
313
|
+
#updatePosition() {
|
314
|
+
if (!this.control) return
|
315
|
+
if (!this.#allowUpdatePosition || this.hidden) return
|
316
|
+
|
317
|
+
const TOOLTIP_OFFSET = 10
|
318
|
+
|
319
|
+
this.style.left = `0px` // Ensures we have reliable tooltip width in `getAnchoredPosition`
|
320
|
+
let position = getAnchoredPosition(this, this.control, {
|
321
|
+
side: this.#side,
|
322
|
+
align: this.#align,
|
323
|
+
anchorOffset: TOOLTIP_OFFSET
|
324
|
+
})
|
325
|
+
let anchorSide = position.anchorSide
|
326
|
+
|
327
|
+
// We need to set tooltip position in order to determine ideal align.
|
328
|
+
this.style.top = `${position.top}px`
|
329
|
+
this.style.left = `${position.left}px`
|
330
|
+
let direction: Direction = 's'
|
331
|
+
|
332
|
+
const align = this.#adjustedAnchorAlignment(anchorSide)
|
333
|
+
if (!align) return
|
334
|
+
|
335
|
+
this.style.left = `0px` // Reset tooltip position again to ensure accurate width in `getAnchoredPosition`
|
336
|
+
position = getAnchoredPosition(this, this.control, {side: anchorSide, align, anchorOffset: TOOLTIP_OFFSET})
|
337
|
+
anchorSide = position.anchorSide
|
338
|
+
|
339
|
+
this.style.top = `${position.top}px`
|
340
|
+
this.style.left = `${position.left}px`
|
341
|
+
|
342
|
+
if (anchorSide === 'outside-left') {
|
343
|
+
direction = 'w'
|
344
|
+
} else if (anchorSide === 'outside-right') {
|
345
|
+
direction = 'e'
|
346
|
+
} else if (anchorSide === 'outside-top') {
|
347
|
+
if (align === 'center') {
|
348
|
+
direction = 'n'
|
349
|
+
} else if (align === 'start') {
|
350
|
+
direction = 'ne'
|
351
|
+
} else {
|
352
|
+
direction = 'nw'
|
353
|
+
}
|
354
|
+
} else {
|
355
|
+
if (align === 'center') {
|
356
|
+
direction = 's'
|
357
|
+
} else if (align === 'start') {
|
358
|
+
direction = 'se'
|
359
|
+
} else {
|
360
|
+
direction = 'sw'
|
361
|
+
}
|
362
|
+
}
|
363
|
+
|
364
|
+
this.classList.add(`tooltip-${direction}`)
|
365
|
+
}
|
366
|
+
}
|
367
|
+
|
368
|
+
if (!window.customElements.get('tool-tip')) {
|
369
|
+
window.TooltipElement = TooltipElement
|
370
|
+
window.customElements.define('tool-tip', TooltipElement)
|
371
|
+
}
|
372
|
+
|
373
|
+
declare global {
|
374
|
+
interface Window {
|
375
|
+
TooltipElement: typeof TooltipElement
|
376
|
+
}
|
377
|
+
}
|
@@ -5,7 +5,7 @@ require "primer/classify"
|
|
5
5
|
module Primer
|
6
6
|
# All Primer ViewComponents accept a standard set of options called system arguments, mimicking the [styled-system API](https://styled-system.com/table) used by [Primer React](https://primer.style/components/system-props).
|
7
7
|
#
|
8
|
-
# Under the hood, system arguments are [mapped](https://github.com/primer/view_components/blob/main/
|
8
|
+
# Under the hood, system arguments are [mapped](https://github.com/primer/view_components/blob/main/lib/primer/classify.rb) to Primer CSS classes, with any remaining options passed to Rails' [`content_tag`](https://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-content_tag).
|
9
9
|
#
|
10
10
|
# ## Responsive values
|
11
11
|
#
|
@@ -85,7 +85,7 @@ module Primer
|
|
85
85
|
#
|
86
86
|
# | Name | Type | Description |
|
87
87
|
# | :- | :- | :- |
|
88
|
-
# | `clearfix` | Boolean |
|
88
|
+
# | `clearfix` | Boolean | Whether to assign the `clearfix` class. |
|
89
89
|
# | `col` | Integer | Number of columns. <%= one_of(Primer::Classify::Utilities.mappings(:col)) %> |
|
90
90
|
# | `container` | Symbol | Size of the container. <%= one_of(Primer::Classify::Utilities.mappings(:container)) %> |
|
91
91
|
#
|
@@ -49,7 +49,7 @@ module Primer
|
|
49
49
|
# <% end %>
|
50
50
|
#
|
51
51
|
# @param overlay [Symbol] Dictates the type of overlay to render with. <%= one_of(Primer::DetailsComponent::OVERLAY_MAPPINGS.keys) %>
|
52
|
-
# @param reset [Boolean]
|
52
|
+
# @param reset [Boolean] Defaults to false. If set to true, it will remove the default caret and remove style from the summary element
|
53
53
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
54
54
|
def initialize(overlay: NO_OVERLAY, reset: false, **system_arguments)
|
55
55
|
@system_arguments = deny_tag_argument(**system_arguments)
|
@@ -6,7 +6,7 @@ module Primer
|
|
6
6
|
# @accessibility
|
7
7
|
# `IconButton` requires an `aria-label`, which will provide assistive technologies with an accessible label.
|
8
8
|
# The `aria-label` should describe the action to be invoked rather than the icon itself. For instance,
|
9
|
-
# if your `IconButton` renders a magnifying glass icon and
|
9
|
+
# if your `IconButton` renders a magnifying glass icon and invokes a search action, the `aria-label` should be
|
10
10
|
# `"Search"` instead of `"Magnifying glass"`.
|
11
11
|
# [Learn more about best functional image practices (WAI Images)](https://www.w3.org/WAI/tutorials/images/functional)
|
12
12
|
class IconButton < Primer::Component
|
@@ -4,7 +4,7 @@ module Primer
|
|
4
4
|
# Use `Subhead` as the start of a section. The `:heading` slot will render an `<h2>` font-sized text.
|
5
5
|
#
|
6
6
|
# - Optionally set the `:description` slot to render a short description and the `:actions` slot for a related action.
|
7
|
-
# - Use a
|
7
|
+
# - Use a succinct, one-line description for the `:description` slot. For longer descriptions, omit the description slot and render a paragraph below the `Subhead`.
|
8
8
|
# - Use the actions slot to render a related action to the right of the heading. Use <%= link_to_component(Primer::ButtonComponent) %> or <%= link_to_component(Primer::LinkComponent) %>.
|
9
9
|
#
|
10
10
|
# @accessibility
|
@@ -39,6 +39,10 @@
|
|
39
39
|
- color-fg-severe
|
40
40
|
:danger:
|
41
41
|
- color-fg-danger
|
42
|
+
:open:
|
43
|
+
- color-fg-open
|
44
|
+
:closed:
|
45
|
+
- color-fg-closed
|
42
46
|
:done:
|
43
47
|
- color-fg-done
|
44
48
|
:sponsors:
|
@@ -78,6 +82,14 @@
|
|
78
82
|
- color-bg-danger
|
79
83
|
:danger_emphasis:
|
80
84
|
- color-bg-danger-emphasis
|
85
|
+
:open:
|
86
|
+
- color-bg-open
|
87
|
+
:open_emphasis:
|
88
|
+
- color-bg-open-emphasis
|
89
|
+
:closed:
|
90
|
+
- color-bg-closed
|
91
|
+
:closed_emphasis:
|
92
|
+
- color-bg-closed-emphasis
|
81
93
|
:done:
|
82
94
|
- color-bg-done
|
83
95
|
:done_emphasis:
|
@@ -113,6 +125,14 @@
|
|
113
125
|
- color-border-danger
|
114
126
|
:danger_emphasis:
|
115
127
|
- color-border-danger-emphasis
|
128
|
+
:open:
|
129
|
+
- color-border-open
|
130
|
+
:open_emphasis:
|
131
|
+
- color-border-open-emphasis
|
132
|
+
:closed:
|
133
|
+
- color-border-closed
|
134
|
+
:closed_emphasis:
|
135
|
+
- color-border-closed-emphasis
|
116
136
|
:done:
|
117
137
|
- color-border-done
|
118
138
|
:done_emphasis:
|
@@ -15,7 +15,7 @@ module ERBLint
|
|
15
15
|
constant: "TAG_OPTIONS"
|
16
16
|
).freeze
|
17
17
|
|
18
|
-
# CloseButton component has preference when this class is seen in
|
18
|
+
# CloseButton component has preference when this class is seen in conjunction with `btn`.
|
19
19
|
DISALLOWED_CLASSES = %w[close-button].freeze
|
20
20
|
CLASSES = %w[btn btn-link].freeze
|
21
21
|
MESSAGE = "We are migrating buttons to use [Primer::ButtonComponent](https://primer.style/view-components/components/button), please try to use that instead of raw HTML."
|
@@ -207,7 +207,7 @@ module RuboCop
|
|
207
207
|
return node.source unless node.type == :str
|
208
208
|
return ":#{node.value}" unless node.value.include?("-")
|
209
209
|
|
210
|
-
# If the icon contains `-` we need to cast the string as a
|
210
|
+
# If the icon contains `-` we need to cast the string as a symbol
|
211
211
|
# E.g: `arrow-down` becomes `:"arrow-down"`
|
212
212
|
":#{node.source}"
|
213
213
|
end
|
data/lib/tasks/docs.rake
CHANGED
@@ -82,7 +82,8 @@ namespace :docs do
|
|
82
82
|
Primer::Alpha::UnderlineNav,
|
83
83
|
Primer::Alpha::UnderlinePanels,
|
84
84
|
Primer::Alpha::TabNav,
|
85
|
-
Primer::Alpha::TabPanels
|
85
|
+
Primer::Alpha::TabPanels,
|
86
|
+
Primer::Alpha::Tooltip
|
86
87
|
]
|
87
88
|
|
88
89
|
js_components = [
|
@@ -94,7 +95,8 @@ namespace :docs do
|
|
94
95
|
Primer::TabContainerComponent,
|
95
96
|
Primer::TimeAgoComponent,
|
96
97
|
Primer::Alpha::UnderlinePanels,
|
97
|
-
Primer::Alpha::TabPanels
|
98
|
+
Primer::Alpha::TabPanels,
|
99
|
+
Primer::Alpha::Tooltip
|
98
100
|
]
|
99
101
|
|
100
102
|
all_components = Primer::Component.descendants - [Primer::BaseComponent]
|
@@ -168,12 +170,12 @@ namespace :docs do
|
|
168
170
|
f.puts("| Name | Type | Default | Description |")
|
169
171
|
f.puts("| :- | :- | :- | :- |")
|
170
172
|
|
171
|
-
|
173
|
+
documented_params = params.map(&:name)
|
172
174
|
component_params = component.instance_method(:initialize).parameters.map { |p| p.last.to_s }
|
173
175
|
|
174
|
-
if (
|
176
|
+
if (documented_params & component_params).size != component_params.size
|
175
177
|
err = { arguments: {} }
|
176
|
-
(component_params -
|
178
|
+
(component_params - documented_params).each do |arg|
|
177
179
|
err[:arguments][arg] = "Not documented"
|
178
180
|
end
|
179
181
|
|
data/lib/tasks/utilities.rake
CHANGED
data/static/arguments.yml
CHANGED
@@ -95,6 +95,30 @@
|
|
95
95
|
type: Hash
|
96
96
|
default: N/A
|
97
97
|
description: "[System arguments](/system-arguments)"
|
98
|
+
- component: Tooltip
|
99
|
+
source: https://github.com/primer/view_components/tree/main/app/components/primer/alpha/tooltip.rb
|
100
|
+
parameters:
|
101
|
+
- name: for_id
|
102
|
+
type: String
|
103
|
+
default: N/A
|
104
|
+
description: The ID of the element that the tooltip should be attached to.
|
105
|
+
- name: type
|
106
|
+
type: Symbol
|
107
|
+
default: N/A
|
108
|
+
description: One of `:description` and `:label`.
|
109
|
+
- name: direction
|
110
|
+
type: Symbol
|
111
|
+
default: "`:s`"
|
112
|
+
description: One of `:e`, `:n`, `:ne`, `:nw`, `:s`, `:se`, `:sw`, or `:w`.
|
113
|
+
- name: text
|
114
|
+
type: String
|
115
|
+
default: N/A
|
116
|
+
description: The text content of the tooltip. This should be brief and no longer
|
117
|
+
than a sentence.
|
118
|
+
- name: system_arguments
|
119
|
+
type: Hash
|
120
|
+
default: N/A
|
121
|
+
description: "[System arguments](/system-arguments)"
|
98
122
|
- component: UnderlineNav
|
99
123
|
source: https://github.com/primer/view_components/tree/main/app/components/primer/alpha/underline_nav.rb
|
100
124
|
parameters:
|
@@ -453,7 +477,7 @@
|
|
453
477
|
- name: reset
|
454
478
|
type: Boolean
|
455
479
|
default: "`false`"
|
456
|
-
description:
|
480
|
+
description: Defaults to false. If set to true, it will remove the default caret
|
457
481
|
and remove style from the summary element
|
458
482
|
- name: system_arguments
|
459
483
|
type: Hash
|
data/static/audited_at.json
CHANGED
data/static/classes.yml
CHANGED
data/static/constants.json
CHANGED
@@ -138,6 +138,24 @@
|
|
138
138
|
"div"
|
139
139
|
]
|
140
140
|
},
|
141
|
+
"Primer::Alpha::Tooltip": {
|
142
|
+
"DIRECTION_DEFAULT": "s",
|
143
|
+
"DIRECTION_OPTIONS": [
|
144
|
+
"s",
|
145
|
+
"n",
|
146
|
+
"e",
|
147
|
+
"w",
|
148
|
+
"ne",
|
149
|
+
"nw",
|
150
|
+
"se",
|
151
|
+
"sw"
|
152
|
+
],
|
153
|
+
"TYPE_FALLBACK": "description",
|
154
|
+
"TYPE_OPTIONS": [
|
155
|
+
"label",
|
156
|
+
"description"
|
157
|
+
]
|
158
|
+
},
|
141
159
|
"Primer::Alpha::UnderlineNav": {
|
142
160
|
"BODY_TAG_DEFAULT": "ul",
|
143
161
|
"TAG_DEFAULT": "nav",
|
data/static/statuses.json
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
"Primer::Alpha::Layout::Sidebar": "alpha",
|
7
7
|
"Primer::Alpha::TabNav": "alpha",
|
8
8
|
"Primer::Alpha::TabPanels": "alpha",
|
9
|
+
"Primer::Alpha::Tooltip": "alpha",
|
9
10
|
"Primer::Alpha::UnderlineNav": "alpha",
|
10
11
|
"Primer::Alpha::UnderlinePanels": "alpha",
|
11
12
|
"Primer::BaseButton": "beta",
|