primer_view_components 0.0.68 → 0.0.69

Sign up to get free protection for your applications and to get access to all the features.
@@ -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/app/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).
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 | Wether to assign the `clearfix` class. |
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
  #
@@ -92,6 +92,7 @@ module Primer
92
92
  @system_arguments[:tag] = system_arguments[:tag] || :span
93
93
  @system_arguments[:classes] = class_names(
94
94
  "Truncate-text",
95
+ system_arguments[:classes],
95
96
  "Truncate-text--primary": priority,
96
97
  "Truncate-text--expandable": expandable
97
98
  )
@@ -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] Defatuls to false. If set to true, it will remove the default caret and remove style from the summary element
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 invokves a search action, the `aria-label` should be
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
@@ -93,7 +93,7 @@ module Primer
93
93
  # <ol>
94
94
  # <li>Michael Jackson</li>
95
95
  # <li>Michael Bolton</li>
96
- # <li>Michael Buble</li>
96
+ # <li>Michael Bublé</li>
97
97
  # </ol>
98
98
  #
99
99
  # <p>And an unordered task list:</p>
@@ -5,3 +5,4 @@ import './time_ago_component';
5
5
  import './local_time';
6
6
  import './image_crop';
7
7
  import './dropdown';
8
+ import './alpha/tooltip';
@@ -5,3 +5,4 @@ import './time_ago_component';
5
5
  import './local_time';
6
6
  import './image_crop';
7
7
  import './dropdown';
8
+ import './alpha/tooltip';
@@ -5,3 +5,4 @@ import './time_ago_component'
5
5
  import './local_time'
6
6
  import './image_crop'
7
7
  import './dropdown'
8
+ import './alpha/tooltip'
@@ -1,5 +1,5 @@
1
1
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
2
  <%= heading %>
3
- <%= actions %>
4
3
  <%= description %>
4
+ <%= actions %>
5
5
  <% end %>
@@ -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 succint, one-line description for the `:description` slot. For longer descriptions, omit the description slot and render a paragraph below the `Subhead`.
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 conjuction with `btn`.
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."
@@ -5,7 +5,7 @@ module Primer
5
5
  module VERSION
6
6
  MAJOR = 0
7
7
  MINOR = 0
8
- PATCH = 68
8
+ PATCH = 69
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH].join(".")
11
11
  end
@@ -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 symbole
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
- docummented_params = params.map(&:name)
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 (docummented_params & component_params).size != component_params.size
176
+ if (documented_params & component_params).size != component_params.size
175
177
  err = { arguments: {} }
176
- (component_params - docummented_params).each do |arg|
178
+ (component_params - documented_params).each do |arg|
177
179
  err[:arguments][arg] = "Not documented"
178
180
  end
179
181
 
@@ -86,7 +86,7 @@ namespace :utilities do
86
86
  classname.sub!(/^[^-]+-/, "")
87
87
  end
88
88
 
89
- # Change the rest from hypens to underscores
89
+ # Change the rest from hyphens to underscores
90
90
  classname.sub!(/-/, "_")
91
91
 
92
92
  # convert padding/margin negative values ie n7 to -7
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: Defatuls to false. If set to true, it will remove the default caret
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
@@ -6,6 +6,7 @@
6
6
  "Primer::Alpha::Layout::Sidebar": "",
7
7
  "Primer::Alpha::TabNav": "",
8
8
  "Primer::Alpha::TabPanels": "",
9
+ "Primer::Alpha::Tooltip": "",
9
10
  "Primer::Alpha::UnderlineNav": "",
10
11
  "Primer::Alpha::UnderlinePanels": "",
11
12
  "Primer::BaseButton": "",
data/static/classes.yml CHANGED
@@ -171,6 +171,7 @@
171
171
  - ".left-0"
172
172
  - ".lh-0"
173
173
  - ".list-style-none"
174
+ - ".m-2"
174
175
  - ".markdown-body"
175
176
  - ".mb-0"
176
177
  - ".mb-2"
@@ -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",