primer_view_components 0.0.71 → 0.0.72

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  declare type Direction = 'n' | 's' | 'e' | 'w' | 'ne' | 'se' | 'nw' | 'sw';
2
- declare class TooltipElement extends HTMLElement {
2
+ declare class ToolTipElement extends HTMLElement {
3
3
  #private;
4
4
  styles(): string;
5
5
  get htmlFor(): string;
@@ -9,7 +9,6 @@ declare class TooltipElement extends HTMLElement {
9
9
  get direction(): Direction;
10
10
  set direction(value: Direction);
11
11
  get control(): HTMLElement | null;
12
- constructor();
13
12
  connectedCallback(): void;
14
13
  disconnectedCallback(): void;
15
14
  handleEvent(event: Event): void;
@@ -18,7 +17,7 @@ declare class TooltipElement extends HTMLElement {
18
17
  }
19
18
  declare global {
20
19
  interface Window {
21
- TooltipElement: typeof TooltipElement;
20
+ ToolTipElement: typeof ToolTipElement;
22
21
  }
23
22
  }
24
23
  export {};
@@ -9,10 +9,10 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _TooltipElement_instances, _TooltipElement_abortController, _TooltipElement_align, _TooltipElement_side, _TooltipElement_allowUpdatePosition, _TooltipElement_adjustedAnchorAlignment, _TooltipElement_updatePosition;
12
+ var _ToolTipElement_instances, _ToolTipElement_abortController, _ToolTipElement_align, _ToolTipElement_side, _ToolTipElement_allowUpdatePosition, _ToolTipElement_update, _ToolTipElement_updatePosition;
13
13
  import { getAnchoredPosition } from '@primer/behaviors';
14
14
  const TOOLTIP_OPEN_CLASS = 'tooltip-open';
15
- const TOOLTIP_ARROW_EDGE_OFFSET = 10;
15
+ const TOOLTIP_ARROW_EDGE_OFFSET = 6;
16
16
  const DIRECTION_CLASSES = [
17
17
  'tooltip-n',
18
18
  'tooltip-s',
@@ -23,21 +23,14 @@ const DIRECTION_CLASSES = [
23
23
  'tooltip-nw',
24
24
  'tooltip-sw'
25
25
  ];
26
- class TooltipElement extends HTMLElement {
26
+ class ToolTipElement extends HTMLElement {
27
27
  constructor() {
28
- super();
29
- _TooltipElement_instances.add(this);
30
- _TooltipElement_abortController.set(this, void 0);
31
- _TooltipElement_align.set(this, 'center');
32
- _TooltipElement_side.set(this, 'outside-bottom');
33
- _TooltipElement_allowUpdatePosition.set(this, false);
34
- const shadow = this.attachShadow({ mode: 'open' });
35
- shadow.innerHTML = `
36
- <style>
37
- ${this.styles()}
38
- </style>
39
- <slot></slot>
40
- `;
28
+ super(...arguments);
29
+ _ToolTipElement_instances.add(this);
30
+ _ToolTipElement_abortController.set(this, void 0);
31
+ _ToolTipElement_align.set(this, 'center');
32
+ _ToolTipElement_side.set(this, 'outside-bottom');
33
+ _ToolTipElement_allowUpdatePosition.set(this, false);
41
34
  }
42
35
  styles() {
43
36
  return `
@@ -103,13 +96,13 @@ class TooltipElement extends HTMLElement {
103
96
  :host(.tooltip-s):before,
104
97
  :host(.tooltip-n):before {
105
98
  right: 50%;
99
+ margin-right: -${TOOLTIP_ARROW_EDGE_OFFSET}px;
106
100
  }
107
101
 
108
102
  :host(.tooltip-s):before,
109
103
  :host(.tooltip-se):before,
110
104
  :host(.tooltip-sw):before {
111
105
  bottom: 100%;
112
- margin-right: -${TOOLTIP_ARROW_EDGE_OFFSET}px;
113
106
  border-bottom-color: var(--color-neutral-emphasis-plus)
114
107
  }
115
108
 
@@ -123,7 +116,6 @@ class TooltipElement extends HTMLElement {
123
116
  :host(.tooltip-ne):before,
124
117
  :host(.tooltip-nw):before {
125
118
  top: 100%;
126
- margin-right: -${TOOLTIP_ARROW_EDGE_OFFSET}px;
127
119
  border-top-color: var(--color-neutral-emphasis-plus)
128
120
  }
129
121
 
@@ -186,27 +178,35 @@ class TooltipElement extends HTMLElement {
186
178
  }
187
179
  connectedCallback() {
188
180
  var _a;
181
+ const shadow = this.attachShadow({ mode: 'open' });
182
+ shadow.innerHTML = `
183
+ <style>
184
+ ${this.styles()}
185
+ </style>
186
+ <slot></slot>
187
+ `;
189
188
  this.hidden = true;
190
- __classPrivateFieldSet(this, _TooltipElement_allowUpdatePosition, true, "f");
189
+ __classPrivateFieldSet(this, _ToolTipElement_allowUpdatePosition, true, "f");
191
190
  if (!this.id) {
192
191
  this.id = `tooltip-${Date.now()}-${(Math.random() * 10000).toFixed(0)}`;
193
192
  }
194
193
  if (!this.control)
195
194
  return;
196
195
  this.setAttribute('role', 'tooltip');
197
- (_a = __classPrivateFieldGet(this, _TooltipElement_abortController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
198
- __classPrivateFieldSet(this, _TooltipElement_abortController, new AbortController(), "f");
199
- const { signal } = __classPrivateFieldGet(this, _TooltipElement_abortController, "f");
196
+ (_a = __classPrivateFieldGet(this, _ToolTipElement_abortController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
197
+ __classPrivateFieldSet(this, _ToolTipElement_abortController, new AbortController(), "f");
198
+ const { signal } = __classPrivateFieldGet(this, _ToolTipElement_abortController, "f");
200
199
  this.addEventListener('mouseleave', this, { signal });
201
200
  this.control.addEventListener('mouseenter', this, { signal });
202
201
  this.control.addEventListener('mouseleave', this, { signal });
203
202
  this.control.addEventListener('focus', this, { signal });
204
203
  this.control.addEventListener('blur', this, { signal });
205
204
  this.ownerDocument.addEventListener('keydown', this, { signal });
205
+ __classPrivateFieldGet(this, _ToolTipElement_instances, "m", _ToolTipElement_update).call(this);
206
206
  }
207
207
  disconnectedCallback() {
208
208
  var _a;
209
- (_a = __classPrivateFieldGet(this, _TooltipElement_abortController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
209
+ (_a = __classPrivateFieldGet(this, _ToolTipElement_abortController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
210
210
  }
211
211
  handleEvent(event) {
212
212
  if (!this.control)
@@ -241,109 +241,76 @@ class TooltipElement extends HTMLElement {
241
241
  this.control.setAttribute('aria-describedby', describedBy);
242
242
  }
243
243
  }
244
- else if (name === 'hidden') {
245
- if (this.hidden) {
246
- this.classList.remove(TOOLTIP_OPEN_CLASS, ...DIRECTION_CLASSES);
247
- }
248
- else {
249
- this.classList.add(TOOLTIP_OPEN_CLASS);
250
- for (const tooltip of this.ownerDocument.querySelectorAll(this.tagName)) {
251
- if (tooltip !== this)
252
- tooltip.hidden = true;
253
- }
254
- __classPrivateFieldGet(this, _TooltipElement_instances, "m", _TooltipElement_updatePosition).call(this);
255
- }
244
+ else if (this.isConnected && name === 'hidden') {
245
+ __classPrivateFieldGet(this, _ToolTipElement_instances, "m", _ToolTipElement_update).call(this);
256
246
  }
257
247
  else if (name === 'data-direction') {
258
248
  this.classList.remove(...DIRECTION_CLASSES);
259
249
  const direction = this.direction;
260
250
  if (direction === 'n') {
261
- __classPrivateFieldSet(this, _TooltipElement_align, 'center', "f");
262
- __classPrivateFieldSet(this, _TooltipElement_side, 'outside-top', "f");
251
+ __classPrivateFieldSet(this, _ToolTipElement_align, 'center', "f");
252
+ __classPrivateFieldSet(this, _ToolTipElement_side, 'outside-top', "f");
263
253
  }
264
254
  else if (direction === 'ne') {
265
- __classPrivateFieldSet(this, _TooltipElement_align, 'start', "f");
266
- __classPrivateFieldSet(this, _TooltipElement_side, 'outside-top', "f");
255
+ __classPrivateFieldSet(this, _ToolTipElement_align, 'start', "f");
256
+ __classPrivateFieldSet(this, _ToolTipElement_side, 'outside-top', "f");
267
257
  }
268
258
  else if (direction === 'e') {
269
- __classPrivateFieldSet(this, _TooltipElement_align, 'center', "f");
270
- __classPrivateFieldSet(this, _TooltipElement_side, 'outside-right', "f");
259
+ __classPrivateFieldSet(this, _ToolTipElement_align, 'center', "f");
260
+ __classPrivateFieldSet(this, _ToolTipElement_side, 'outside-right', "f");
271
261
  }
272
262
  else if (direction === 'se') {
273
- __classPrivateFieldSet(this, _TooltipElement_align, 'start', "f");
274
- __classPrivateFieldSet(this, _TooltipElement_side, 'outside-bottom', "f");
263
+ __classPrivateFieldSet(this, _ToolTipElement_align, 'start', "f");
264
+ __classPrivateFieldSet(this, _ToolTipElement_side, 'outside-bottom', "f");
275
265
  }
276
266
  else if (direction === 's') {
277
- __classPrivateFieldSet(this, _TooltipElement_align, 'center', "f");
278
- __classPrivateFieldSet(this, _TooltipElement_side, 'outside-bottom', "f");
267
+ __classPrivateFieldSet(this, _ToolTipElement_align, 'center', "f");
268
+ __classPrivateFieldSet(this, _ToolTipElement_side, 'outside-bottom', "f");
279
269
  }
280
270
  else if (direction === 'sw') {
281
- __classPrivateFieldSet(this, _TooltipElement_align, 'end', "f");
282
- __classPrivateFieldSet(this, _TooltipElement_side, 'outside-bottom', "f");
271
+ __classPrivateFieldSet(this, _ToolTipElement_align, 'end', "f");
272
+ __classPrivateFieldSet(this, _ToolTipElement_side, 'outside-bottom', "f");
283
273
  }
284
274
  else if (direction === 'w') {
285
- __classPrivateFieldSet(this, _TooltipElement_align, 'center', "f");
286
- __classPrivateFieldSet(this, _TooltipElement_side, 'outside-left', "f");
275
+ __classPrivateFieldSet(this, _ToolTipElement_align, 'center', "f");
276
+ __classPrivateFieldSet(this, _ToolTipElement_side, 'outside-left', "f");
287
277
  }
288
278
  else if (direction === 'nw') {
289
- __classPrivateFieldSet(this, _TooltipElement_align, 'end', "f");
290
- __classPrivateFieldSet(this, _TooltipElement_side, 'outside-top', "f");
279
+ __classPrivateFieldSet(this, _ToolTipElement_align, 'end', "f");
280
+ __classPrivateFieldSet(this, _ToolTipElement_side, 'outside-top', "f");
291
281
  }
292
282
  }
293
283
  }
294
284
  }
295
- _TooltipElement_abortController = new WeakMap(), _TooltipElement_align = new WeakMap(), _TooltipElement_side = new WeakMap(), _TooltipElement_allowUpdatePosition = new WeakMap(), _TooltipElement_instances = new WeakSet(), _TooltipElement_adjustedAnchorAlignment = function _TooltipElement_adjustedAnchorAlignment(anchorSide) {
296
- if (!this.control)
297
- return;
298
- const tooltipPosition = this.getBoundingClientRect();
299
- const targetPosition = this.control.getBoundingClientRect();
300
- const tooltipWidth = tooltipPosition.width;
301
- const tooltipCenter = tooltipPosition.left + tooltipWidth / 2;
302
- const targetCenter = targetPosition.x + targetPosition.width / 2;
303
- if (Math.abs(tooltipCenter - targetCenter) < 2 || anchorSide === 'outside-left' || anchorSide === 'outside-right') {
304
- return 'center';
305
- }
306
- else if (tooltipPosition.left === targetPosition.left) {
307
- return 'start';
308
- }
309
- else if (tooltipPosition.right === targetPosition.right) {
310
- return 'end';
311
- }
312
- else if (tooltipCenter < targetCenter) {
313
- if (tooltipPosition.left === 0)
314
- return 'start';
315
- return 'end';
285
+ _ToolTipElement_abortController = new WeakMap(), _ToolTipElement_align = new WeakMap(), _ToolTipElement_side = new WeakMap(), _ToolTipElement_allowUpdatePosition = new WeakMap(), _ToolTipElement_instances = new WeakSet(), _ToolTipElement_update = function _ToolTipElement_update() {
286
+ if (this.hidden) {
287
+ this.classList.remove(TOOLTIP_OPEN_CLASS, ...DIRECTION_CLASSES);
316
288
  }
317
289
  else {
318
- if (tooltipPosition.right === 0)
319
- return 'end';
320
- return 'start';
290
+ this.classList.add(TOOLTIP_OPEN_CLASS);
291
+ for (const tooltip of this.ownerDocument.querySelectorAll(this.tagName)) {
292
+ if (tooltip !== this)
293
+ tooltip.hidden = true;
294
+ }
295
+ __classPrivateFieldGet(this, _ToolTipElement_instances, "m", _ToolTipElement_updatePosition).call(this);
321
296
  }
322
- }, _TooltipElement_updatePosition = function _TooltipElement_updatePosition() {
297
+ }, _ToolTipElement_updatePosition = function _ToolTipElement_updatePosition() {
323
298
  if (!this.control)
324
299
  return;
325
- if (!__classPrivateFieldGet(this, _TooltipElement_allowUpdatePosition, "f") || this.hidden)
300
+ if (!__classPrivateFieldGet(this, _ToolTipElement_allowUpdatePosition, "f") || this.hidden)
326
301
  return;
327
302
  const TOOLTIP_OFFSET = 10;
328
303
  this.style.left = `0px`; // Ensures we have reliable tooltip width in `getAnchoredPosition`
329
- let position = getAnchoredPosition(this, this.control, {
330
- side: __classPrivateFieldGet(this, _TooltipElement_side, "f"),
331
- align: __classPrivateFieldGet(this, _TooltipElement_align, "f"),
304
+ const position = getAnchoredPosition(this, this.control, {
305
+ side: __classPrivateFieldGet(this, _ToolTipElement_side, "f"),
306
+ align: __classPrivateFieldGet(this, _ToolTipElement_align, "f"),
332
307
  anchorOffset: TOOLTIP_OFFSET
333
308
  });
334
- let anchorSide = position.anchorSide;
335
- // We need to set tooltip position in order to determine ideal align.
309
+ const anchorSide = position.anchorSide;
310
+ const align = position.anchorAlign;
336
311
  this.style.top = `${position.top}px`;
337
312
  this.style.left = `${position.left}px`;
338
313
  let direction = 's';
339
- const align = __classPrivateFieldGet(this, _TooltipElement_instances, "m", _TooltipElement_adjustedAnchorAlignment).call(this, anchorSide);
340
- if (!align)
341
- return;
342
- this.style.left = `0px`; // Reset tooltip position again to ensure accurate width in `getAnchoredPosition`
343
- position = getAnchoredPosition(this, this.control, { side: anchorSide, align, anchorOffset: TOOLTIP_OFFSET });
344
- anchorSide = position.anchorSide;
345
- this.style.top = `${position.top}px`;
346
- this.style.left = `${position.left}px`;
347
314
  if (anchorSide === 'outside-left') {
348
315
  direction = 'w';
349
316
  }
@@ -374,8 +341,8 @@ _TooltipElement_abortController = new WeakMap(), _TooltipElement_align = new Wea
374
341
  }
375
342
  this.classList.add(`tooltip-${direction}`);
376
343
  };
377
- TooltipElement.observedAttributes = ['data-type', 'data-direction', 'id', 'hidden'];
344
+ ToolTipElement.observedAttributes = ['data-type', 'data-direction', 'id', 'hidden'];
378
345
  if (!window.customElements.get('tool-tip')) {
379
- window.TooltipElement = TooltipElement;
380
- window.customElements.define('tool-tip', TooltipElement);
346
+ window.ToolTipElement = ToolTipElement;
347
+ window.customElements.define('tool-tip', ToolTipElement);
381
348
  }
@@ -2,7 +2,7 @@ import type {AnchorAlignment, AnchorSide} from '@primer/behaviors'
2
2
  import {getAnchoredPosition} from '@primer/behaviors'
3
3
 
4
4
  const TOOLTIP_OPEN_CLASS = 'tooltip-open'
5
- const TOOLTIP_ARROW_EDGE_OFFSET = 10
5
+ const TOOLTIP_ARROW_EDGE_OFFSET = 6
6
6
 
7
7
  type Direction = 'n' | 's' | 'e' | 'w' | 'ne' | 'se' | 'nw' | 'sw'
8
8
 
@@ -17,7 +17,7 @@ const DIRECTION_CLASSES = [
17
17
  'tooltip-sw'
18
18
  ]
19
19
 
20
- class TooltipElement extends HTMLElement {
20
+ class ToolTipElement extends HTMLElement {
21
21
  styles() {
22
22
  return `
23
23
  :host {
@@ -82,13 +82,13 @@ class TooltipElement extends HTMLElement {
82
82
  :host(.tooltip-s):before,
83
83
  :host(.tooltip-n):before {
84
84
  right: 50%;
85
+ margin-right: -${TOOLTIP_ARROW_EDGE_OFFSET}px;
85
86
  }
86
87
 
87
88
  :host(.tooltip-s):before,
88
89
  :host(.tooltip-se):before,
89
90
  :host(.tooltip-sw):before {
90
91
  bottom: 100%;
91
- margin-right: -${TOOLTIP_ARROW_EDGE_OFFSET}px;
92
92
  border-bottom-color: var(--color-neutral-emphasis-plus)
93
93
  }
94
94
 
@@ -102,7 +102,6 @@ class TooltipElement extends HTMLElement {
102
102
  :host(.tooltip-ne):before,
103
103
  :host(.tooltip-nw):before {
104
104
  top: 100%;
105
- margin-right: -${TOOLTIP_ARROW_EDGE_OFFSET}px;
106
105
  border-top-color: var(--color-neutral-emphasis-plus)
107
106
  }
108
107
 
@@ -176,8 +175,7 @@ class TooltipElement extends HTMLElement {
176
175
  return this.ownerDocument.getElementById(this.htmlFor)
177
176
  }
178
177
 
179
- constructor() {
180
- super()
178
+ connectedCallback() {
181
179
  const shadow = this.attachShadow({mode: 'open'})
182
180
  shadow.innerHTML = `
183
181
  <style>
@@ -185,9 +183,6 @@ class TooltipElement extends HTMLElement {
185
183
  </style>
186
184
  <slot></slot>
187
185
  `
188
- }
189
-
190
- connectedCallback() {
191
186
  this.hidden = true
192
187
  this.#allowUpdatePosition = true
193
188
 
@@ -209,6 +204,7 @@ class TooltipElement extends HTMLElement {
209
204
  this.control.addEventListener('focus', this, {signal})
210
205
  this.control.addEventListener('blur', this, {signal})
211
206
  this.ownerDocument.addEventListener('keydown', this, {signal})
207
+ this.#update()
212
208
  }
213
209
 
214
210
  disconnectedCallback() {
@@ -237,6 +233,18 @@ class TooltipElement extends HTMLElement {
237
233
 
238
234
  static observedAttributes = ['data-type', 'data-direction', 'id', 'hidden']
239
235
 
236
+ #update() {
237
+ if (this.hidden) {
238
+ this.classList.remove(TOOLTIP_OPEN_CLASS, ...DIRECTION_CLASSES)
239
+ } else {
240
+ this.classList.add(TOOLTIP_OPEN_CLASS)
241
+ for (const tooltip of this.ownerDocument.querySelectorAll<HTMLElement>(this.tagName)) {
242
+ if (tooltip !== this) tooltip.hidden = true
243
+ }
244
+ this.#updatePosition()
245
+ }
246
+ }
247
+
240
248
  attributeChangedCallback(name: string) {
241
249
  if (name === 'id' || name === 'data-type') {
242
250
  if (!this.id || !this.control) return
@@ -247,16 +255,8 @@ class TooltipElement extends HTMLElement {
247
255
  describedBy ? (describedBy = `${describedBy} ${this.id}`) : (describedBy = this.id)
248
256
  this.control.setAttribute('aria-describedby', describedBy)
249
257
  }
250
- } else if (name === 'hidden') {
251
- if (this.hidden) {
252
- this.classList.remove(TOOLTIP_OPEN_CLASS, ...DIRECTION_CLASSES)
253
- } else {
254
- this.classList.add(TOOLTIP_OPEN_CLASS)
255
- for (const tooltip of this.ownerDocument.querySelectorAll<HTMLElement>(this.tagName)) {
256
- if (tooltip !== this) tooltip.hidden = true
257
- }
258
- this.#updatePosition()
259
- }
258
+ } else if (this.isConnected && name === 'hidden') {
259
+ this.#update()
260
260
  } else if (name === 'data-direction') {
261
261
  this.classList.remove(...DIRECTION_CLASSES)
262
262
  const direction = this.direction
@@ -288,34 +288,6 @@ class TooltipElement extends HTMLElement {
288
288
  }
289
289
  }
290
290
 
291
- // `getAnchoredPosition` may calibrate `anchoredSide` but does not recalibrate `align`.
292
- // Therefore, we need to determine which `align` is best based on the initial `getAnchoredPosition` calcluation.
293
- // Related: https://github.com/primer/behaviors/issues/63
294
- #adjustedAnchorAlignment(anchorSide: AnchorSide): AnchorAlignment | undefined {
295
- if (!this.control) return
296
-
297
- const tooltipPosition = this.getBoundingClientRect()
298
- const targetPosition = this.control.getBoundingClientRect()
299
- const tooltipWidth = tooltipPosition.width
300
-
301
- const tooltipCenter = tooltipPosition.left + tooltipWidth / 2
302
- const targetCenter = targetPosition.x + targetPosition.width / 2
303
-
304
- if (Math.abs(tooltipCenter - targetCenter) < 2 || anchorSide === 'outside-left' || anchorSide === 'outside-right') {
305
- return 'center'
306
- } else if (tooltipPosition.left === targetPosition.left) {
307
- return 'start'
308
- } else if (tooltipPosition.right === targetPosition.right) {
309
- return 'end'
310
- } else if (tooltipCenter < targetCenter) {
311
- if (tooltipPosition.left === 0) return 'start'
312
- return 'end'
313
- } else {
314
- if (tooltipPosition.right === 0) return 'end'
315
- return 'start'
316
- }
317
- }
318
-
319
291
  #updatePosition() {
320
292
  if (!this.control) return
321
293
  if (!this.#allowUpdatePosition || this.hidden) return
@@ -323,27 +295,19 @@ class TooltipElement extends HTMLElement {
323
295
  const TOOLTIP_OFFSET = 10
324
296
 
325
297
  this.style.left = `0px` // Ensures we have reliable tooltip width in `getAnchoredPosition`
326
- let position = getAnchoredPosition(this, this.control, {
298
+
299
+ const position = getAnchoredPosition(this, this.control, {
327
300
  side: this.#side,
328
301
  align: this.#align,
329
302
  anchorOffset: TOOLTIP_OFFSET
330
303
  })
331
- let anchorSide = position.anchorSide
304
+ const anchorSide = position.anchorSide
305
+ const align = position.anchorAlign
332
306
 
333
- // We need to set tooltip position in order to determine ideal align.
334
307
  this.style.top = `${position.top}px`
335
308
  this.style.left = `${position.left}px`
336
- let direction: Direction = 's'
337
-
338
- const align = this.#adjustedAnchorAlignment(anchorSide)
339
- if (!align) return
340
-
341
- this.style.left = `0px` // Reset tooltip position again to ensure accurate width in `getAnchoredPosition`
342
- position = getAnchoredPosition(this, this.control, {side: anchorSide, align, anchorOffset: TOOLTIP_OFFSET})
343
- anchorSide = position.anchorSide
344
309
 
345
- this.style.top = `${position.top}px`
346
- this.style.left = `${position.left}px`
310
+ let direction: Direction = 's'
347
311
 
348
312
  if (anchorSide === 'outside-left') {
349
313
  direction = 'w'
@@ -372,12 +336,12 @@ class TooltipElement extends HTMLElement {
372
336
  }
373
337
 
374
338
  if (!window.customElements.get('tool-tip')) {
375
- window.TooltipElement = TooltipElement
376
- window.customElements.define('tool-tip', TooltipElement)
339
+ window.ToolTipElement = ToolTipElement
340
+ window.customElements.define('tool-tip', ToolTipElement)
377
341
  }
378
342
 
379
343
  declare global {
380
344
  interface Window {
381
- TooltipElement: typeof TooltipElement
345
+ ToolTipElement: typeof ToolTipElement
382
346
  }
383
347
  }
@@ -1,4 +1 @@
1
- <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
- <%= content %>
3
- <%= tooltip %>
4
- <% end %>
1
+ <%= render Primer::BaseComponent.new(**@system_arguments) do -%><%= content -%><%= tooltip -%><% end %>
@@ -5,4 +5,4 @@ import './time_ago_component';
5
5
  import './local_time';
6
6
  import './image_crop';
7
7
  import './dropdown';
8
- import './alpha/tooltip';
8
+ import './alpha/tool-tip-element';
@@ -5,4 +5,4 @@ import './time_ago_component';
5
5
  import './local_time';
6
6
  import './image_crop';
7
7
  import './dropdown';
8
- import './alpha/tooltip';
8
+ import './alpha/tool-tip-element';
@@ -5,4 +5,4 @@ import './time_ago_component'
5
5
  import './local_time'
6
6
  import './image_crop'
7
7
  import './dropdown'
8
- import './alpha/tooltip'
8
+ import './alpha/tool-tip-element'
@@ -5,7 +5,7 @@ module Primer
5
5
  module VERSION
6
6
  MAJOR = 0
7
7
  MINOR = 0
8
- PATCH = 71
8
+ PATCH = 72
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH].join(".")
11
11
  end
@@ -15,3 +15,6 @@ Primer/PrimerOcticon:
15
15
 
16
16
  Primer/DeprecatedArguments:
17
17
  Enabled: true
18
+
19
+ Primer/DeprecatedComponents:
20
+ Enabled: true
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+ require "json"
5
+ require "parser/current"
6
+
7
+ module RuboCop
8
+ module Cop
9
+ module Primer
10
+ # This cop ensures that components marked as "deprecated" in `static/statuses.json` are discouraged from use.
11
+ #
12
+ # bad
13
+ # Primer::BlankslateComponent.new(:foo)
14
+ #
15
+ # good
16
+ # Primer::Beta::Blankslate.new(:foo)
17
+ #
18
+ # bad
19
+ # Primer::Tooltip.new(:foo)
20
+ #
21
+ # good
22
+ # Primer::Alpha::Tooltip.new(:foo)
23
+ class DeprecatedComponents < BaseCop
24
+ # If there is no alternative to suggest, set the value to nil.
25
+ COMPONENT_TO_USE_INSTEAD = {
26
+ "Primer::BlankslateComponent" => "Primer::Beta::Blankslate",
27
+ "Primer::DropdownMenuComponent" => nil,
28
+ "Primer::Tooltip" => "Primer::Alpha::Tooltip",
29
+ "Primer::FlexComponent" => nil,
30
+ "Primer::FlexItemComponent" => nil
31
+ }.freeze
32
+
33
+ def on_send(node)
34
+ return unless node.source.include?("Primer::")
35
+
36
+ deprecated_components.each do |component|
37
+ pattern = NodePattern.new("(send #{pattern(component)} :new ...)")
38
+ add_offense(node, message: message(component)) if pattern.match(node)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ # Converts a string to acceptable rubocop-ast pattern syntax
45
+ def pattern(component)
46
+ Parser::CurrentRuby.parse(component)
47
+ .to_s
48
+ .gsub("nil", "nil?")
49
+ .delete("\n")
50
+ .gsub(" ", " ")
51
+ end
52
+
53
+ def message(component)
54
+ message = "#{component} has been deprecated and should not be used."
55
+ message += " Try #{COMPONENT_TO_USE_INSTEAD[component]} instead." if COMPONENT_TO_USE_INSTEAD.fetch(component).present?
56
+ message
57
+ end
58
+
59
+ def statuses_json
60
+ JSON.parse(
61
+ File.read(
62
+ File.join(File.dirname(__FILE__), "../../../../static/statuses.json")
63
+ )
64
+ ).freeze
65
+ end
66
+
67
+ def deprecated_components
68
+ @deprecated_components ||= statuses_json.select { |_, value| value == "deprecated" }.keys.tap do |deprecated_components|
69
+ deprecated_components.each do |deprecated|
70
+ unless COMPONENT_TO_USE_INSTEAD.key?(deprecated)
71
+ raise "Please provide a component that should be used in place of #{deprecated} in COMPONENT_TO_USE_INSTEAD. "\
72
+ "If there is no alternative, set the value to nil."
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end