@crowdstrike/glide-core 0.29.2 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/accordion.js +240 -1
  2. package/dist/accordion.styles.js +13 -7
  3. package/dist/button-group.button.js +143 -1
  4. package/dist/button-group.button.styles.js +43 -15
  5. package/dist/button-group.js +249 -1
  6. package/dist/button-group.styles.js +10 -5
  7. package/dist/button.js +206 -1
  8. package/dist/button.styles.js +12 -7
  9. package/dist/checkbox-group.js +479 -14
  10. package/dist/checkbox-group.styles.js +5 -2
  11. package/dist/checkbox.js +519 -32
  12. package/dist/checkbox.styles.js +10 -5
  13. package/dist/drawer.js +168 -1
  14. package/dist/drawer.styles.js +5 -2
  15. package/dist/dropdown.js +2423 -123
  16. package/dist/dropdown.option.js +536 -1
  17. package/dist/dropdown.option.styles.js +5 -2
  18. package/dist/dropdown.styles.js +15 -8
  19. package/dist/form-controls-layout.js +102 -1
  20. package/dist/form-controls-layout.styles.js +5 -2
  21. package/dist/icon-button.js +139 -1
  22. package/dist/icon-button.styles.js +19 -7
  23. package/dist/icons/checked.js +28 -1
  24. package/dist/icons/chevron.js +21 -1
  25. package/dist/icons/magnifying-glass.js +23 -1
  26. package/dist/icons/pencil.js +21 -1
  27. package/dist/icons/severity-critical.js +20 -1
  28. package/dist/icons/severity-informational.js +20 -1
  29. package/dist/icons/severity-medium.js +20 -1
  30. package/dist/icons/x.js +21 -1
  31. package/dist/inline-alert.js +118 -1
  32. package/dist/inline-alert.styles.js +5 -2
  33. package/dist/input.d.ts +8 -2
  34. package/dist/input.js +505 -41
  35. package/dist/input.styles.js +25 -4
  36. package/dist/label.js +303 -1
  37. package/dist/label.styles.js +11 -5
  38. package/dist/library/assert-slot.js +136 -1
  39. package/dist/library/expect-unhandled-rejection.js +14 -1
  40. package/dist/library/expect-window-error.js +26 -1
  41. package/dist/library/final.js +18 -1
  42. package/dist/library/form-control.js +1 -1
  43. package/dist/library/localize.js +10 -1
  44. package/dist/library/mouse.js +35 -1
  45. package/dist/library/on-resize.js +24 -1
  46. package/dist/library/required.js +35 -1
  47. package/dist/library/shadow-root-mode.js +4 -1
  48. package/dist/library/unique-id.js +3 -1
  49. package/dist/link.js +92 -1
  50. package/dist/link.styles.js +10 -5
  51. package/dist/menu.d.ts +3 -2
  52. package/dist/menu.js +1259 -1
  53. package/dist/menu.styles.js +35 -19
  54. package/dist/modal.d.ts +4 -0
  55. package/dist/modal.icon-button.js +60 -1
  56. package/dist/modal.icon-button.styles.js +5 -2
  57. package/dist/modal.js +473 -1
  58. package/dist/modal.styles.js +71 -22
  59. package/dist/option.d.ts +74 -0
  60. package/dist/option.js +498 -0
  61. package/dist/option.styles.js +140 -0
  62. package/dist/{menu.options.d.ts → options.d.ts} +5 -6
  63. package/dist/options.js +130 -0
  64. package/dist/options.styles.js +21 -0
  65. package/dist/popover.js +620 -1
  66. package/dist/popover.styles.js +11 -5
  67. package/dist/radio-group.js +624 -17
  68. package/dist/radio-group.radio.js +211 -1
  69. package/dist/radio-group.radio.styles.js +9 -4
  70. package/dist/radio-group.styles.js +5 -2
  71. package/dist/slider.js +1040 -61
  72. package/dist/slider.styles.js +9 -4
  73. package/dist/spinner.js +60 -1
  74. package/dist/spinner.styles.js +5 -2
  75. package/dist/split-button.js +116 -1
  76. package/dist/split-button.primary-button.js +100 -1
  77. package/dist/split-button.primary-button.styles.js +13 -6
  78. package/dist/split-button.primary-link.js +102 -1
  79. package/dist/split-button.secondary-button.d.ts +2 -3
  80. package/dist/split-button.secondary-button.js +121 -1
  81. package/dist/split-button.secondary-button.styles.js +12 -7
  82. package/dist/split-button.styles.js +9 -4
  83. package/dist/styles/focus-outline.js +9 -3
  84. package/dist/styles/fonts.css +6 -1
  85. package/dist/styles/opacity-and-scale-animation.js +6 -3
  86. package/dist/styles/skeleton.js +6 -3
  87. package/dist/styles/variables.css +410 -1
  88. package/dist/styles/visually-hidden.js +6 -3
  89. package/dist/tab.group.js +386 -1
  90. package/dist/tab.group.styles.js +5 -2
  91. package/dist/tab.js +133 -1
  92. package/dist/tab.panel.js +93 -1
  93. package/dist/tab.panel.styles.js +11 -5
  94. package/dist/tab.styles.js +9 -4
  95. package/dist/tag.js +207 -1
  96. package/dist/tag.styles.js +10 -5
  97. package/dist/textarea.js +353 -19
  98. package/dist/textarea.styles.js +23 -4
  99. package/dist/toast.js +130 -1
  100. package/dist/toast.toasts.js +248 -25
  101. package/dist/toast.toasts.styles.js +9 -4
  102. package/dist/toggle.js +178 -1
  103. package/dist/toggle.styles.js +25 -5
  104. package/dist/tooltip.container.js +130 -1
  105. package/dist/tooltip.container.styles.js +5 -2
  106. package/dist/tooltip.js +484 -1
  107. package/dist/tooltip.styles.js +21 -5
  108. package/dist/translations/en.js +36 -1
  109. package/dist/translations/fr.js +37 -1
  110. package/dist/translations/ja.js +37 -1
  111. package/package.json +8 -12
  112. package/dist/menu.button.d.ts +0 -42
  113. package/dist/menu.button.js +0 -1
  114. package/dist/menu.button.styles.js +0 -32
  115. package/dist/menu.link.d.ts +0 -44
  116. package/dist/menu.link.js +0 -1
  117. package/dist/menu.link.styles.js +0 -35
  118. package/dist/menu.options.js +0 -1
  119. package/dist/menu.options.styles.d.ts +0 -2
  120. package/dist/menu.options.styles.js +0 -20
  121. /package/dist/{menu.button.styles.d.ts → option.styles.d.ts} +0 -0
  122. /package/dist/{menu.link.styles.d.ts → options.styles.d.ts} +0 -0
package/dist/popover.js CHANGED
@@ -1 +1,620 @@
1
- var __decorate=this&&this.__decorate||function(e,t,o,r){var i,l=arguments.length,a=l<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,o,r);else for(var s=e.length-1;s>=0;s--)(i=e[s])&&(a=(l<3?i(a):l>3?i(t,o,a):i(t,o))||a);return l>3&&a&&Object.defineProperty(t,o,a),a};import{html,LitElement}from"lit";import{arrow,autoUpdate,computePosition,flip,limitShift,offset,shift}from"@floating-ui/dom";import{choose}from"lit/directives/choose.js";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import packageJson from"../package.json"with{type:"json"};import styles from"./popover.styles.js";import assertSlot from"./library/assert-slot.js";import shadowRootMode from"./library/shadow-root-mode.js";import final from"./library/final.js";let Popover=class Popover extends LitElement{constructor(){super(...arguments),this.version=packageJson.version,this.effectivePlacement=this.placement??"bottom",this.#e=createRef(),this.#t=createRef(),this.#o=!1,this.#r=!1,this.#i=!1,this.#l=!1,this.#a=!1,this.#s=createRef(),this.#n=createRef(),this.#p=()=>{this.#r||this.#a||this.#o?setTimeout((()=>{this.#r=!1,this.#a=!1,this.#o=!1})):this.open=!1}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:shadowRootMode}}static{this.styles=styles}get disabled(){return this.#i}set disabled(e){this.#i=e,this.open&&!e?this.#f():this.#d()}get offset(){return this.#m??Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-base-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}set offset(e){this.#m=e}get open(){return this.#l}set open(e){const t=e!==this.#l;this.#l=e,e&&t&&!this.disabled?(this.#f(),this.dispatchEvent(new Event("toggle",{bubbles:!0,composed:!0}))):t&&(this.#d(),this.dispatchEvent(new Event("toggle",{bubbles:!0,composed:!0})))}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#p,{capture:!0})}firstUpdated(){this.#s.value&&(this.#s.value.popover="manual"),this.open&&!this.disabled&&this.#f(),this.#t.value?.addEventListener("mouseup",(()=>{this.#r=!0})),this.#n.value?.addEventListener("mouseup",(()=>{this.#a=!0})),this.#e.value?.addEventListener("mouseup",(()=>{this.#o=!0})),this.#n.value?.addEventListener("keydown",(e=>{"Enter"!==e.key&&" "!==e.key||(this.#a=!0)}))}render(){return html`<div class="component"><slot class="target-slot" data-test="target-slot" name="target" @click="${this.#h}" @keydown="${this.#c}" ${assertSlot([Element])} ${ref(this.#n)}></slot><div class="${classMap({popover:!0,[this.effectivePlacement]:!0})}" id="popover" data-test="popover" ${ref(this.#s)}><div class="${classMap({arrow:!0,[this.effectivePlacement]:!0})}" data-test="arrow" ${ref(this.#e)}>${choose(this.effectivePlacement,[["top",()=>icons.topArrow],["right",()=>icons.rightArrow],["bottom",()=>icons.bottomArrow],["left",()=>icons.leftArrow]])}</div><slot class="default-slot" ${assertSlot()} ${ref(this.#t)}></slot></div></div>`}#e;#u;#t;#o;#r;#i;#l;#a;#m;#s;#n;#p;#d(){this.#s.value?.hidePopover(),this.#v&&(this.#v.ariaExpanded="false"),this.#u?.()}#h(){this.open=!this.open}#c(e){"Escape"===e.key&&(e.preventDefault(),this.open=!1)}get#v(){return this.#n.value?.assignedElements().at(0)}#f(){this.disabled||(this.#u?.(),this.#n.value&&this.#s.value&&(this.#u=autoUpdate(this.#n.value,this.#s.value,(()=>{(async()=>{if(this.#n.value&&this.#s.value&&this.#e.value){const e=Number.parseFloat(window.getComputedStyle(this.#s.value).padding),{x:t,y:o,placement:r,middlewareData:i}=await computePosition(this.#n.value,this.#s.value,{placement:this.placement,middleware:[offset(this.offset-e-2),flip({fallbackStrategy:"initialPlacement"}),shift({limiter:limitShift({offset:30})}),arrow({element:this.#e.value})]});Object.assign(this.#s.value.style,{left:`${t}px`,top:`${o}px`}),Object.assign(this.#e.value.style,{left:i.arrow?.x?i.arrow.x-e+"px":null,top:i.arrow?.y?i.arrow.y-e+"px":null}),this.effectivePlacement=r,this.#s.value.showPopover(),this.#v&&(this.#v.ariaExpanded="true")}})()}))))}};__decorate([property({reflect:!0,type:Boolean})],Popover.prototype,"disabled",null),__decorate([property({reflect:!0,type:Number})],Popover.prototype,"offset",null),__decorate([property({reflect:!0,type:Boolean})],Popover.prototype,"open",null),__decorate([property()],Popover.prototype,"placement",void 0),__decorate([property({reflect:!0})],Popover.prototype,"version",void 0),__decorate([state()],Popover.prototype,"effectivePlacement",void 0),Popover=__decorate([customElement("glide-core-popover"),final],Popover);export default Popover;const icons={topArrow:html`<svg aria-hidden="true" viewBox="0 0 16 9" fill="none"><mask id="mask0_13064_691" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0"><path d="M16 6.99382e-07V9L0 9L3.93402e-07 0L16 6.99382e-07Z" fill="#D9D9D9"/></mask><g mask="url(#mask0_13064_691)"><g filter="url(#filter0_d_13064_691)"><path d="M8.76822 5.603C8.36842 6.13234 7.63157 6.13233 7.23178 5.60299L3 0L13 9.19407e-07L8.76822 5.603Z" fill="currentColor"/></g></g><defs><filter id="filter0_d_13064_691" x="2" y="0" width="0.75rem" height="0.625rem" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset dy="3"/><feGaussianBlur stdDeviation="0.5"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/><feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_13064_691"/><feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_13064_691" result="shape"/></filter></defs></svg>`,rightArrow:html`<svg aria-hidden="true" viewBox="0 0 9 16" fill="none"><mask id="mask0_13064_688" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0"><path d="M9 16H1.39876e-06L0 7.86805e-07L9 0L9 16Z" fill="#D9D9D9"/></mask><g mask="url(#mask0_13064_688)"><g filter="url(#filter0_d_13064_688)"><path d="M3.397 8.76822C2.86766 8.36843 2.86767 7.63157 3.39701 7.23178L9 3V13L3.397 8.76822Z" fill="currentColor"/></g></g><defs><filter id="filter0_d_13064_688" x="2" y="3" width="0.5rem" height="0.875rem" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset dy="3"/><feGaussianBlur stdDeviation="0.5"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/><feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_13064_688"/><feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_13064_688" result="shape"/></filter></defs></svg>`,bottomArrow:html`<svg aria-hidden="true" viewBox="0 0 16 9" fill="none"><mask id="mask0_13064_685" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0"><path d="M0 9L1.07324e-07 0L16 1.90798e-07V9H0Z" fill="#D9D9D9"/></mask><g mask="url(#mask0_13064_685)"><g filter="url(#filter0_dd_13064_685)"><path d="M7.23178 3.397C7.63157 2.86766 8.36843 2.86767 8.76822 3.39701L13 9L3 9L7.23178 3.397Z" fill="currentColor"/></g></g><defs><filter id="filter0_dd_13064_685" x="-5" y="-2" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset dy="3"/><feGaussianBlur stdDeviation="4"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/><feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_13064_685"/><feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset dy="-1"/><feGaussianBlur stdDeviation="1"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/><feBlend mode="normal" in2="effect1_dropShadow_13064_685" result="effect2_dropShadow_13064_685"/><feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_13064_685" result="shape"/></filter></defs></svg>`,leftArrow:html`<svg aria-hidden="true" viewBox="0 0 9 16" fill="none"><mask id="mask0_12969_88361" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0"><path d="M0 0H9V16H0V0Z" fill="#D9D9D9"/></mask><g mask="url(#mask0_12969_88361)"><g filter="url(#filter0_d_12969_88361)"><path d="M5.603 7.23178C6.13234 7.63157 6.13233 8.36843 5.60299 8.76822L0 13L4.82293e-07 3L5.603 7.23178Z" fill="currentColor"/></g></g><defs><filter id="filter0_d_12969_88361" x="-1" y="3" width="0.5rem" height="0.875rem" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset dy="3"/><feGaussianBlur stdDeviation="0.5"/><feComposite in2="hardAlpha" operator="out"/><feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/><feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_12969_88361"/><feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_12969_88361" result="shape"/></filter></defs></svg>`};
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { html, LitElement } from 'lit';
8
+ import { arrow, autoUpdate, computePosition, flip, limitShift, offset, shift, } from '@floating-ui/dom';
9
+ import { choose } from 'lit/directives/choose.js';
10
+ import { classMap } from 'lit/directives/class-map.js';
11
+ import { createRef, ref } from 'lit/directives/ref.js';
12
+ import { customElement, property, state } from 'lit/decorators.js';
13
+ import packageJson from '../package.json' with { type: 'json' };
14
+ import styles from './popover.styles.js';
15
+ import assertSlot from './library/assert-slot.js';
16
+ import shadowRootMode from './library/shadow-root-mode.js';
17
+ import final from './library/final.js';
18
+ /**
19
+ * @attr {boolean} [disabled=false]
20
+ * @attr {number} [offset=4]
21
+ * @attr {boolean} [open=false]
22
+ * @attr {'bottom'|'left'|'right'|'top'} [placement]
23
+ *
24
+ * @readonly
25
+ * @attr {string} [version]
26
+ *
27
+ * @slot {Element | string} - The content of the popover
28
+ * @slot {Element} [target] - The element to which the popover will anchor. Can be any focusable element.
29
+ *
30
+ * @fires {Event} toggle
31
+ */
32
+ let Popover = class Popover extends LitElement {
33
+ constructor() {
34
+ super(...arguments);
35
+ this.version = packageJson.version;
36
+ this.effectivePlacement = this.placement ?? 'bottom';
37
+ this.#arrowElementRef = createRef();
38
+ this.#defaultSlotElementRef = createRef();
39
+ this.#isArrowClick = false;
40
+ this.#isDefaultSlotClick = false;
41
+ this.#isDisabled = false;
42
+ this.#isOpen = false;
43
+ this.#isTargetSlotClick = false;
44
+ this.#popoverElementRef = createRef();
45
+ this.#targetSlotElementRef = createRef();
46
+ // An arrow function field instead of a method so `this` is closed over and
47
+ // set to the component instead of `document`.
48
+ this.#onDocumentClick = () => {
49
+ // Checking that the click's `event.target` is equal to
50
+ // `#defaultSlotElementRef.value` would be a lot simpler. But, when the target is
51
+ // inside of another web component, `event.target` will be that component instead.
52
+ // Same for `this.#isTargetSlotClick` and `this.#isArrowClick`.
53
+ if (this.#isDefaultSlotClick ||
54
+ this.#isTargetSlotClick ||
55
+ this.#isArrowClick) {
56
+ setTimeout(() => {
57
+ // This handler will be called twice for a single click if the element clicked was
58
+ // a `<label>`. Because clicking a `<label>` produces two "click" events.
59
+ //
60
+ // If we immediately set these variables to `false`, Popover will close when this
61
+ // handler is called the second time. So we wait a tick to ensure both "click"
62
+ // events have been dispatched.
63
+ this.#isDefaultSlotClick = false;
64
+ this.#isTargetSlotClick = false;
65
+ this.#isArrowClick = false;
66
+ });
67
+ return;
68
+ }
69
+ this.open = false;
70
+ };
71
+ }
72
+ static { this.shadowRootOptions = {
73
+ ...LitElement.shadowRootOptions,
74
+ mode: shadowRootMode,
75
+ }; }
76
+ static { this.styles = styles; }
77
+ /**
78
+ * @default false
79
+ */
80
+ get disabled() {
81
+ return this.#isDisabled;
82
+ }
83
+ set disabled(isDisabled) {
84
+ this.#isDisabled = isDisabled;
85
+ if (this.open && !isDisabled) {
86
+ this.#show();
87
+ }
88
+ else {
89
+ this.#hide();
90
+ }
91
+ }
92
+ /**
93
+ * @default 4
94
+ */
95
+ get offset() {
96
+ return (this.#offset ??
97
+ Number.parseFloat(window
98
+ .getComputedStyle(document.body)
99
+ .getPropertyValue('--glide-core-spacing-base-xxs')) *
100
+ Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize));
101
+ }
102
+ set offset(offset) {
103
+ this.#offset = offset;
104
+ }
105
+ /**
106
+ * @default false
107
+ */
108
+ get open() {
109
+ return this.#isOpen;
110
+ }
111
+ set open(isOpen) {
112
+ const hasChanged = isOpen !== this.#isOpen;
113
+ this.#isOpen = isOpen;
114
+ if (isOpen && hasChanged && !this.disabled) {
115
+ this.#show();
116
+ this.dispatchEvent(new Event('toggle', { bubbles: true, composed: true }));
117
+ }
118
+ else if (hasChanged) {
119
+ this.#hide();
120
+ this.dispatchEvent(new Event('toggle', { bubbles: true, composed: true }));
121
+ }
122
+ }
123
+ connectedCallback() {
124
+ super.connectedCallback();
125
+ // 1. The consumer has a click handler on a button.
126
+ // 2. The user clicks the button.
127
+ // 3. The button's click handler is called and it sets `this.open` to `true`.
128
+ // 4. The "click" event bubbles up and is handled by `#onDocumentClick`.
129
+ // 5. That handler sets `open` to `false` because the click came from outside
130
+ // Popover.
131
+ // 6. Popover is opened then closed in the same frame and so never opens.
132
+ //
133
+ // `capture` ensures `#onDocumentClick` is called before #3, so the button click
134
+ // handler setting `open` to `true` isn't overwritten by this handler setting
135
+ // `open` to `false`.
136
+ document.addEventListener('click', this.#onDocumentClick, {
137
+ capture: true,
138
+ });
139
+ }
140
+ firstUpdated() {
141
+ if (this.#popoverElementRef.value) {
142
+ // `popover` is used so the popover can break out of Modal or another container
143
+ // that has `overflow: hidden`. And elements with `popover` are positioned
144
+ // relative to the viewport. Thus Floating UI in addition to `popover`.
145
+ //
146
+ // Set here instead of in the template to escape Lit Analyzer, which isn't aware
147
+ // of `popover` and doesn't have a way to disable its "no-unknown-attribute" rule.
148
+ //
149
+ // "auto" means only one popover can be open at a time. Consumers, however, may
150
+ // have popovers in own components that need to be open while this one is open.
151
+ //
152
+ // "auto" also automatically opens the popover when its target is clicked. We want
153
+ // it to remain closed when clicked when there are no menu options.
154
+ this.#popoverElementRef.value.popover = 'manual';
155
+ }
156
+ if (this.open && !this.disabled) {
157
+ this.#show();
158
+ }
159
+ // Popover's "click" handler on `document` listens for clicks in the capture
160
+ // phase. There's a comment explaining why. `#isDefaultSlotclick` must be
161
+ // set before that handler is called so it has the information it needs
162
+ // to determine whether or not to close Popover. Same for `#isTargetSlotClick`
163
+ // and `#isArrowClick`.
164
+ this.#defaultSlotElementRef.value?.addEventListener('mouseup', () => {
165
+ this.#isDefaultSlotClick = true;
166
+ });
167
+ this.#targetSlotElementRef.value?.addEventListener('mouseup', () => {
168
+ this.#isTargetSlotClick = true;
169
+ });
170
+ this.#arrowElementRef.value?.addEventListener('mouseup', () => {
171
+ this.#isArrowClick = true;
172
+ });
173
+ this.#targetSlotElementRef.value?.addEventListener('keydown', (event) => {
174
+ if (event.key === 'Enter' || event.key === ' ') {
175
+ this.#isTargetSlotClick = true;
176
+ }
177
+ });
178
+ }
179
+ render() {
180
+ // Lit-a11y calls for "blur" and "focus" handlers but doesn't account for "focusin"
181
+ // and "focusout". It also calls for popovers to have an `aria-label`, but then
182
+ // VoiceOver, at least, won't read the popover's content. So an element with an
183
+ // `aria-label` is placed inside the popover.
184
+ return html `
185
+ <div class="component">
186
+ <slot
187
+ class="target-slot"
188
+ data-test="target-slot"
189
+ name="target"
190
+ @click=${this.#onTargetSlotClick}
191
+ @keydown=${this.#onTargetSlotKeydown}
192
+ ${assertSlot([Element])}
193
+ ${ref(this.#targetSlotElementRef)}
194
+ >
195
+ <!--
196
+ The element to which the popover will anchor. Can be any focusable element.
197
+ @type {Element}
198
+ -->
199
+ </slot>
200
+
201
+ <div
202
+ class=${classMap({
203
+ popover: true,
204
+ [this.effectivePlacement]: true,
205
+ })}
206
+ id="popover"
207
+ data-test="popover"
208
+ ${ref(this.#popoverElementRef)}
209
+ >
210
+ <div
211
+ class=${classMap({
212
+ arrow: true,
213
+ [this.effectivePlacement]: true,
214
+ })}
215
+ data-test="arrow"
216
+ ${ref(this.#arrowElementRef)}
217
+ >
218
+ ${choose(this.effectivePlacement, [
219
+ ['top', () => icons.topArrow],
220
+ ['right', () => icons.rightArrow],
221
+ ['bottom', () => icons.bottomArrow],
222
+ ['left', () => icons.leftArrow],
223
+ ])}
224
+ </div>
225
+
226
+ <slot
227
+ class="default-slot"
228
+ ${assertSlot()}
229
+ ${ref(this.#defaultSlotElementRef)}
230
+ >
231
+ <!--
232
+ The content of the popover
233
+ @type {Element | string}
234
+ -->
235
+ </slot>
236
+ </div>
237
+ </div>
238
+ `;
239
+ }
240
+ #arrowElementRef;
241
+ #cleanUpFloatingUi;
242
+ #defaultSlotElementRef;
243
+ #isArrowClick;
244
+ #isDefaultSlotClick;
245
+ #isDisabled;
246
+ #isOpen;
247
+ #isTargetSlotClick;
248
+ #offset;
249
+ #popoverElementRef;
250
+ #targetSlotElementRef;
251
+ // An arrow function field instead of a method so `this` is closed over and
252
+ // set to the component instead of `document`.
253
+ #onDocumentClick;
254
+ #hide() {
255
+ this.#popoverElementRef.value?.hidePopover();
256
+ if (this.#targetElement) {
257
+ this.#targetElement.ariaExpanded = 'false';
258
+ }
259
+ this.#cleanUpFloatingUi?.();
260
+ }
261
+ #onTargetSlotClick() {
262
+ this.open = !this.open;
263
+ }
264
+ #onTargetSlotKeydown(event) {
265
+ if (event.key === 'Escape') {
266
+ // Prevent Safari from leaving full screen.
267
+ event.preventDefault();
268
+ this.open = false;
269
+ }
270
+ }
271
+ get #targetElement() {
272
+ return this.#targetSlotElementRef.value?.assignedElements().at(0);
273
+ }
274
+ #show() {
275
+ if (!this.disabled) {
276
+ this.#cleanUpFloatingUi?.();
277
+ if (this.#targetSlotElementRef.value && this.#popoverElementRef.value) {
278
+ this.#cleanUpFloatingUi = autoUpdate(this.#targetSlotElementRef.value, this.#popoverElementRef.value, () => {
279
+ (async () => {
280
+ if (this.#targetSlotElementRef.value &&
281
+ this.#popoverElementRef.value &&
282
+ this.#arrowElementRef.value) {
283
+ // The Popover API doesn't allow overflow. And `.default-slot` has a
284
+ // shadow. So ".popover" has padding equal to the shadow, which prevents
285
+ // the shadow from getting cut off. But now we have to offset everything
286
+ // by that padding. Try removing the padding offset below. You'll see what
287
+ // I mean.
288
+ const paddingOffset = Number.parseFloat(window.getComputedStyle(this.#popoverElementRef.value)
289
+ .padding);
290
+ const { x, y, placement, middlewareData } = await computePosition(this.#targetSlotElementRef.value, this.#popoverElementRef.value, {
291
+ placement: this.placement,
292
+ middleware: [
293
+ // Every arrow icon is either 16 by 6 or 6 by 16 depending on which
294
+ // direction it faces. The "top" arrow, however, is necessarily 9 by
295
+ // 16 because its shadow extends past the arrow tip.
296
+ //
297
+ // So I either had to adjust the offset below and the height on `.arrow`
298
+ // just for the "top" arrow or make every arrow 16 by 9 (or 9 by 16)
299
+ // and apply a uniform offset. The latter turned out to be simpler.
300
+ //
301
+ // Thus the popover needs to be offset by -3 (6 - 9). I then add 1 to -3
302
+ // to give a little more room: to account for the effect on the eye of each
303
+ // arrow's shadow. So the offset is roughly 5 pixels, by default, but has
304
+ // the appearance of the 4, which is the desired outcome.
305
+ offset(this.offset - paddingOffset - 2),
306
+ flip({
307
+ fallbackStrategy: 'initialPlacement',
308
+ }),
309
+ shift({
310
+ limiter: limitShift({
311
+ // Shifting is limited so the arrow is never near the popover's rounded
312
+ // corners, which would leave a gap between the arrow and the part of
313
+ // the corner that's missing due to rounding. `30` is just a round number.
314
+ // `25` isn't enough.
315
+ offset: 30,
316
+ }),
317
+ }),
318
+ arrow({ element: this.#arrowElementRef.value }),
319
+ ],
320
+ });
321
+ Object.assign(this.#popoverElementRef.value.style, {
322
+ left: `${x}px`,
323
+ top: `${y}px`,
324
+ });
325
+ Object.assign(this.#arrowElementRef.value.style, {
326
+ left: middlewareData.arrow?.x
327
+ ? `${middlewareData.arrow.x - paddingOffset}px`
328
+ : null,
329
+ top: middlewareData.arrow?.y
330
+ ? `${middlewareData.arrow.y - paddingOffset}px`
331
+ : null,
332
+ });
333
+ this.effectivePlacement = placement;
334
+ this.#popoverElementRef.value.showPopover();
335
+ if (this.#targetElement) {
336
+ this.#targetElement.ariaExpanded = 'true';
337
+ }
338
+ }
339
+ })();
340
+ });
341
+ }
342
+ }
343
+ }
344
+ };
345
+ __decorate([
346
+ property({ reflect: true, type: Boolean })
347
+ ], Popover.prototype, "disabled", null);
348
+ __decorate([
349
+ property({ reflect: true, type: Number })
350
+ ], Popover.prototype, "offset", null);
351
+ __decorate([
352
+ property({ reflect: true, type: Boolean })
353
+ ], Popover.prototype, "open", null);
354
+ __decorate([
355
+ property()
356
+ ], Popover.prototype, "placement", void 0);
357
+ __decorate([
358
+ property({ reflect: true })
359
+ ], Popover.prototype, "version", void 0);
360
+ __decorate([
361
+ state()
362
+ ], Popover.prototype, "effectivePlacement", void 0);
363
+ Popover = __decorate([
364
+ customElement('glide-core-popover'),
365
+ final
366
+ ], Popover);
367
+ export default Popover;
368
+ const icons = {
369
+ topArrow: html `
370
+ <svg aria-hidden="true" viewBox="0 0 16 9" fill="none">
371
+ <mask
372
+ id="mask0_13064_691"
373
+ style="mask-type:alpha"
374
+ maskUnits="userSpaceOnUse"
375
+ x="0"
376
+ y="0"
377
+ >
378
+ <path
379
+ d="M16 6.99382e-07V9L0 9L3.93402e-07 0L16 6.99382e-07Z"
380
+ fill="#D9D9D9"
381
+ />
382
+ </mask>
383
+ <g mask="url(#mask0_13064_691)">
384
+ <g filter="url(#filter0_d_13064_691)">
385
+ <path
386
+ d="M8.76822 5.603C8.36842 6.13234 7.63157 6.13233 7.23178 5.60299L3 0L13 9.19407e-07L8.76822 5.603Z"
387
+ fill="currentColor"
388
+ />
389
+ </g>
390
+ </g>
391
+ <defs>
392
+ <filter
393
+ id="filter0_d_13064_691"
394
+ x="2"
395
+ y="0"
396
+ width="0.75rem"
397
+ height="0.625rem"
398
+ filterUnits="userSpaceOnUse"
399
+ color-interpolation-filters="sRGB"
400
+ >
401
+ <feFlood flood-opacity="0" result="BackgroundImageFix" />
402
+ <feColorMatrix
403
+ in="SourceAlpha"
404
+ type="matrix"
405
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
406
+ result="hardAlpha"
407
+ />
408
+ <feOffset dy="3" />
409
+ <feGaussianBlur stdDeviation="0.5" />
410
+ <feComposite in2="hardAlpha" operator="out" />
411
+ <feColorMatrix
412
+ type="matrix"
413
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"
414
+ />
415
+ <feBlend
416
+ mode="normal"
417
+ in2="BackgroundImageFix"
418
+ result="effect1_dropShadow_13064_691"
419
+ />
420
+ <feBlend
421
+ mode="normal"
422
+ in="SourceGraphic"
423
+ in2="effect1_dropShadow_13064_691"
424
+ result="shape"
425
+ />
426
+ </filter>
427
+ </defs>
428
+ </svg>
429
+ `,
430
+ rightArrow: html `
431
+ <svg aria-hidden="true" viewBox="0 0 9 16" fill="none">
432
+ <mask
433
+ id="mask0_13064_688"
434
+ style="mask-type:alpha"
435
+ maskUnits="userSpaceOnUse"
436
+ x="0"
437
+ y="0"
438
+ >
439
+ <path d="M9 16H1.39876e-06L0 7.86805e-07L9 0L9 16Z" fill="#D9D9D9" />
440
+ </mask>
441
+ <g mask="url(#mask0_13064_688)">
442
+ <g filter="url(#filter0_d_13064_688)">
443
+ <path
444
+ d="M3.397 8.76822C2.86766 8.36843 2.86767 7.63157 3.39701 7.23178L9 3V13L3.397 8.76822Z"
445
+ fill="currentColor"
446
+ />
447
+ </g>
448
+ </g>
449
+ <defs>
450
+ <filter
451
+ id="filter0_d_13064_688"
452
+ x="2"
453
+ y="3"
454
+ width="0.5rem"
455
+ height="0.875rem"
456
+ filterUnits="userSpaceOnUse"
457
+ color-interpolation-filters="sRGB"
458
+ >
459
+ <feFlood flood-opacity="0" result="BackgroundImageFix" />
460
+ <feColorMatrix
461
+ in="SourceAlpha"
462
+ type="matrix"
463
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
464
+ result="hardAlpha"
465
+ />
466
+ <feOffset dy="3" />
467
+ <feGaussianBlur stdDeviation="0.5" />
468
+ <feComposite in2="hardAlpha" operator="out" />
469
+ <feColorMatrix
470
+ type="matrix"
471
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"
472
+ />
473
+ <feBlend
474
+ mode="normal"
475
+ in2="BackgroundImageFix"
476
+ result="effect1_dropShadow_13064_688"
477
+ />
478
+ <feBlend
479
+ mode="normal"
480
+ in="SourceGraphic"
481
+ in2="effect1_dropShadow_13064_688"
482
+ result="shape"
483
+ />
484
+ </filter>
485
+ </defs>
486
+ </svg>
487
+ `,
488
+ bottomArrow: html `
489
+ <svg aria-hidden="true" viewBox="0 0 16 9" fill="none">
490
+ <mask
491
+ id="mask0_13064_685"
492
+ style="mask-type:alpha"
493
+ maskUnits="userSpaceOnUse"
494
+ x="0"
495
+ y="0"
496
+ >
497
+ <path d="M0 9L1.07324e-07 0L16 1.90798e-07V9H0Z" fill="#D9D9D9" />
498
+ </mask>
499
+ <g mask="url(#mask0_13064_685)">
500
+ <g filter="url(#filter0_dd_13064_685)">
501
+ <path
502
+ d="M7.23178 3.397C7.63157 2.86766 8.36843 2.86767 8.76822 3.39701L13 9L3 9L7.23178 3.397Z"
503
+ fill="currentColor"
504
+ />
505
+ </g>
506
+ </g>
507
+ <defs>
508
+ <filter
509
+ id="filter0_dd_13064_685"
510
+ x="-5"
511
+ y="-2"
512
+ filterUnits="userSpaceOnUse"
513
+ color-interpolation-filters="sRGB"
514
+ >
515
+ <feFlood flood-opacity="0" result="BackgroundImageFix" />
516
+ <feColorMatrix
517
+ in="SourceAlpha"
518
+ type="matrix"
519
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
520
+ result="hardAlpha"
521
+ />
522
+ <feOffset dy="3" />
523
+ <feGaussianBlur stdDeviation="4" />
524
+ <feComposite in2="hardAlpha" operator="out" />
525
+ <feColorMatrix
526
+ type="matrix"
527
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"
528
+ />
529
+ <feBlend
530
+ mode="normal"
531
+ in2="BackgroundImageFix"
532
+ result="effect1_dropShadow_13064_685"
533
+ />
534
+ <feColorMatrix
535
+ in="SourceAlpha"
536
+ type="matrix"
537
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
538
+ result="hardAlpha"
539
+ />
540
+ <feOffset dy="-1" />
541
+ <feGaussianBlur stdDeviation="1" />
542
+ <feComposite in2="hardAlpha" operator="out" />
543
+ <feColorMatrix
544
+ type="matrix"
545
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"
546
+ />
547
+ <feBlend
548
+ mode="normal"
549
+ in2="effect1_dropShadow_13064_685"
550
+ result="effect2_dropShadow_13064_685"
551
+ />
552
+ <feBlend
553
+ mode="normal"
554
+ in="SourceGraphic"
555
+ in2="effect2_dropShadow_13064_685"
556
+ result="shape"
557
+ />
558
+ </filter>
559
+ </defs>
560
+ </svg>
561
+ `,
562
+ leftArrow: html `
563
+ <svg aria-hidden="true" viewBox="0 0 9 16" fill="none">
564
+ <mask
565
+ id="mask0_12969_88361"
566
+ style="mask-type:alpha"
567
+ maskUnits="userSpaceOnUse"
568
+ x="0"
569
+ y="0"
570
+ >
571
+ <path d="M0 0H9V16H0V0Z" fill="#D9D9D9" />
572
+ </mask>
573
+ <g mask="url(#mask0_12969_88361)">
574
+ <g filter="url(#filter0_d_12969_88361)">
575
+ <path
576
+ d="M5.603 7.23178C6.13234 7.63157 6.13233 8.36843 5.60299 8.76822L0 13L4.82293e-07 3L5.603 7.23178Z"
577
+ fill="currentColor"
578
+ />
579
+ </g>
580
+ </g>
581
+ <defs>
582
+ <filter
583
+ id="filter0_d_12969_88361"
584
+ x="-1"
585
+ y="3"
586
+ width="0.5rem"
587
+ height="0.875rem"
588
+ filterUnits="userSpaceOnUse"
589
+ color-interpolation-filters="sRGB"
590
+ >
591
+ <feFlood flood-opacity="0" result="BackgroundImageFix" />
592
+ <feColorMatrix
593
+ in="SourceAlpha"
594
+ type="matrix"
595
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
596
+ result="hardAlpha"
597
+ />
598
+ <feOffset dy="3" />
599
+ <feGaussianBlur stdDeviation="0.5" />
600
+ <feComposite in2="hardAlpha" operator="out" />
601
+ <feColorMatrix
602
+ type="matrix"
603
+ values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"
604
+ />
605
+ <feBlend
606
+ mode="normal"
607
+ in2="BackgroundImageFix"
608
+ result="effect1_dropShadow_12969_88361"
609
+ />
610
+ <feBlend
611
+ mode="normal"
612
+ in="SourceGraphic"
613
+ in2="effect1_dropShadow_12969_88361"
614
+ result="shape"
615
+ />
616
+ </filter>
617
+ </defs>
618
+ </svg>
619
+ `,
620
+ };
@@ -1,7 +1,12 @@
1
- import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import opacityAndScaleAnimation from"./styles/opacity-and-scale-animation.js";export default[css`
2
- ${opacityAndScaleAnimation(".popover:popover-open")}
3
- ${focusOutline(".target:focus-visible")}
4
- `,css`
1
+ import { css } from 'lit';
2
+ import focusOutline from './styles/focus-outline.js';
3
+ import opacityAndScaleAnimation from './styles/opacity-and-scale-animation.js';
4
+ export default [
5
+ css `
6
+ ${opacityAndScaleAnimation('.popover:popover-open')}
7
+ ${focusOutline('.target:focus-visible')}
8
+ `,
9
+ css `
5
10
  :host {
6
11
  /* https://github.com/CrowdStrike/glide-core/pull/307/files#r1718545771 */
7
12
  display: inline-block;
@@ -116,4 +121,5 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
116
121
  min-inline-size: 5rem;
117
122
  padding: var(--glide-core-spacing-base-xs);
118
123
  }
119
- `];
124
+ `,
125
+ ];