@crowdstrike/glide-core 0.11.0 → 0.12.0

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 (39) hide show
  1. package/dist/checkbox-group.d.ts +3 -0
  2. package/dist/checkbox-group.js +43 -1
  3. package/dist/checkbox-group.styles.js +12 -0
  4. package/dist/checkbox-group.test.validity.js +69 -0
  5. package/dist/checkbox.d.ts +3 -1
  6. package/dist/checkbox.js +135 -1
  7. package/dist/checkbox.styles.js +12 -0
  8. package/dist/checkbox.test.validity.js +77 -1
  9. package/dist/dropdown.d.ts +3 -0
  10. package/dist/dropdown.js +195 -1
  11. package/dist/dropdown.styles.js +18 -6
  12. package/dist/dropdown.test.events.single.js +19 -0
  13. package/dist/dropdown.test.interactions.js +0 -18
  14. package/dist/dropdown.test.interactions.multiple.js +8 -10
  15. package/dist/dropdown.test.interactions.single.js +18 -0
  16. package/dist/dropdown.test.validity.js +172 -1
  17. package/dist/input.d.ts +4 -0
  18. package/dist/input.js +155 -1
  19. package/dist/input.styles.js +8 -0
  20. package/dist/input.test.validity.js +140 -62
  21. package/dist/menu.d.ts +2 -0
  22. package/dist/menu.js +1 -1
  23. package/dist/menu.test.basics.d.ts +1 -1
  24. package/dist/menu.test.basics.js +12 -27
  25. package/dist/menu.test.interactions.js +90 -0
  26. package/dist/radio-group.d.ts +3 -0
  27. package/dist/radio-group.js +45 -1
  28. package/dist/radio-group.styles.js +12 -0
  29. package/dist/radio-group.test.validity.js +82 -0
  30. package/dist/styles/variables.css +1 -1
  31. package/dist/tag.styles.js +1 -1
  32. package/dist/textarea.d.ts +3 -0
  33. package/dist/textarea.js +58 -2
  34. package/dist/textarea.styles.js +8 -0
  35. package/dist/textarea.test.events.js +0 -114
  36. package/dist/textarea.test.validity.js +64 -72
  37. package/dist/tooltip.d.ts +2 -1
  38. package/dist/tooltip.js +1 -1
  39. package/package.json +1 -1
@@ -104,117 +104,3 @@ it('does not dispatch an `invalid` event when `reportValidity` is called when re
104
104
  await aTimeout(0);
105
105
  expect(spy.callCount).to.equal(0);
106
106
  });
107
- it('dispatches an `invalid` event after `requestSubmit` is called when `maxlength` exceeded', async () => {
108
- const form = document.createElement('form');
109
- const component = await fixture(html `<glide-core-textarea
110
- label="label"
111
- maxlength="3"
112
- ></glide-core-textarea>`, {
113
- parentNode: form,
114
- });
115
- setTimeout(async () => {
116
- component.focus();
117
- await sendKeys({ type: 'testing' });
118
- form.requestSubmit();
119
- });
120
- const event = await oneEvent(component, 'invalid');
121
- expect(event instanceof Event).to.be.true;
122
- });
123
- it('dispatches an `invalid` event after `checkValidity` is called when `maxlength` exceeded', async () => {
124
- const form = document.createElement('form');
125
- const component = await fixture(html `<glide-core-textarea
126
- label="label"
127
- maxlength="3"
128
- ></glide-core-textarea>`, {
129
- parentNode: form,
130
- });
131
- setTimeout(async () => {
132
- component.focus();
133
- await sendKeys({ type: 'testing' });
134
- component.checkValidity();
135
- });
136
- const event = await oneEvent(component, 'invalid');
137
- expect(event instanceof Event).to.be.true;
138
- });
139
- it('dispatches an `invalid` event after `reportValidity` is called when `maxlength` exceeded', async () => {
140
- const form = document.createElement('form');
141
- const component = await fixture(html `<glide-core-textarea
142
- label="label"
143
- maxlength="3"
144
- ></glide-core-textarea>`, {
145
- parentNode: form,
146
- });
147
- setTimeout(async () => {
148
- component.focus();
149
- await sendKeys({ type: 'testing' });
150
- component.reportValidity();
151
- });
152
- const event = await oneEvent(component, 'invalid');
153
- expect(event instanceof Event).to.be.true;
154
- });
155
- it('does not dispatch an `invalid` event after `checkValidity` is called when `maxlength` not exceeded', async () => {
156
- const form = document.createElement('form');
157
- const component = await fixture(html `<glide-core-textarea
158
- label="label"
159
- maxlength="3"
160
- ></glide-core-textarea>`, {
161
- parentNode: form,
162
- });
163
- const spy = sinon.spy();
164
- component.addEventListener('invalid', spy);
165
- component.focus();
166
- await sendKeys({ type: 'ab' });
167
- component.checkValidity();
168
- await aTimeout(0);
169
- expect(spy.callCount).to.equal(0);
170
- });
171
- it('does not dispatch an `invalid` event after `checkValidity` is called when `maxlength` exceeded and disabled', async () => {
172
- const form = document.createElement('form');
173
- const component = await fixture(html `<glide-core-textarea
174
- label="label"
175
- maxlength="3"
176
- disabled
177
- ></glide-core-textarea>`, {
178
- parentNode: form,
179
- });
180
- const spy = sinon.spy();
181
- component.addEventListener('invalid', spy);
182
- component.focus();
183
- await sendKeys({ type: 'test' });
184
- component.checkValidity();
185
- await aTimeout(0);
186
- expect(spy.callCount).to.equal(0);
187
- });
188
- it('does not dispatch an `invalid` event when `reportValidity` is called and `maxlength` is not exceeded,', async () => {
189
- const form = document.createElement('form');
190
- const component = await fixture(html `<glide-core-textarea
191
- label="label"
192
- maxlength="3"
193
- ></glide-core-textarea>`, {
194
- parentNode: form,
195
- });
196
- const spy = sinon.spy();
197
- component.addEventListener('invalid', spy);
198
- component.focus();
199
- await sendKeys({ type: 'ab' });
200
- component.reportValidity();
201
- await aTimeout(0);
202
- expect(spy.callCount).to.equal(0);
203
- });
204
- it('does not dispatch an `invalid` event when `reportValidity` is called `maxlength` exceeded and disabled,', async () => {
205
- const form = document.createElement('form');
206
- const component = await fixture(html `<glide-core-textarea
207
- label="label"
208
- maxlength="3"
209
- disabled
210
- ></glide-core-textarea>`, {
211
- parentNode: form,
212
- });
213
- const spy = sinon.spy();
214
- component.addEventListener('invalid', spy);
215
- component.focus();
216
- await sendKeys({ type: 'test' });
217
- component.reportValidity();
218
- await aTimeout(0);
219
- expect(spy.callCount).to.equal(0);
220
- });
@@ -42,46 +42,6 @@ it('is invalid if no value and required', async () => {
42
42
  ?.querySelector('textarea')
43
43
  ?.getAttribute('aria-invalid')).to.equal('true');
44
44
  });
45
- it('is valid when empty and does not exceed `maxlength`', async () => {
46
- const component = await fixture(html `<glide-core-textarea maxlength="3"></glide-core-textarea>`);
47
- expect(component.validity?.valid).to.be.true;
48
- expect(component.validity?.valueMissing).to.be.false;
49
- expect(component.validity?.tooLong).to.be.false;
50
- expect(component.checkValidity()).to.be.true;
51
- expect(component.reportValidity()).to.be.true;
52
- await elementUpdated(component);
53
- expect(component.shadowRoot
54
- ?.querySelector('textarea')
55
- ?.getAttribute('aria-invalid')).to.equal('false');
56
- });
57
- it('is valid when filled in and does not exceed `maxlength`', async () => {
58
- const component = await fixture(html `<glide-core-textarea maxlength="3"></glide-core-textarea>`);
59
- component.focus();
60
- await sendKeys({ type: 'abc' });
61
- expect(component.validity?.valid).to.be.true;
62
- expect(component.validity?.valueMissing).to.be.false;
63
- expect(component.validity?.tooLong).to.be.false;
64
- expect(component.checkValidity()).to.be.true;
65
- expect(component.reportValidity()).to.be.true;
66
- await elementUpdated(component);
67
- expect(component.shadowRoot
68
- ?.querySelector('textarea')
69
- ?.getAttribute('aria-invalid')).to.equal('false');
70
- });
71
- it('is invalid when filled in and exceeds `maxlength`', async () => {
72
- const component = await fixture(html `<glide-core-textarea maxlength="3"></glide-core-textarea>`);
73
- component.focus();
74
- await sendKeys({ type: 'value' });
75
- expect(component.validity?.valid).to.be.false;
76
- expect(component.validity?.valueMissing).to.be.false;
77
- expect(component.validity?.tooLong).to.be.true;
78
- expect(component.checkValidity()).to.be.false;
79
- expect(component.reportValidity()).to.be.false;
80
- await elementUpdated(component);
81
- expect(component.shadowRoot
82
- ?.querySelector('textarea')
83
- ?.getAttribute('aria-invalid')).to.equal('true');
84
- });
85
45
  it('is valid if no value but required and disabled', async () => {
86
46
  const component = await fixture(html `<glide-core-textarea required disabled></glide-core-textarea>`);
87
47
  expect(component.validity?.valid).to.be.true;
@@ -166,38 +126,6 @@ it('is valid when `value` is empty and `required` is set to `false` programmatic
166
126
  ?.querySelector('textarea')
167
127
  ?.getAttribute('aria-invalid')).to.equal('false');
168
128
  });
169
- it('is valid when filled in, disabled, and value exceeds `maxlength`', async () => {
170
- const component = await fixture(html `<glide-core-textarea
171
- value="value"
172
- disabled
173
- maxlength="3"
174
- ></glide-core-textarea>`);
175
- expect(component.validity?.valid).to.be.true;
176
- expect(component.validity?.valueMissing).to.be.false;
177
- expect(component.validity?.tooLong).to.be.false;
178
- expect(component.checkValidity()).to.be.true;
179
- expect(component.reportValidity()).to.be.true;
180
- await elementUpdated(component);
181
- expect(component.shadowRoot
182
- ?.querySelector('textarea')
183
- ?.getAttribute('aria-invalid')).to.equal('false');
184
- });
185
- it('is valid when filled in, readonly, and value exceeds `maxlength`', async () => {
186
- const component = await fixture(html `<glide-core-textarea
187
- value="value"
188
- readonly
189
- maxlength="3"
190
- ></glide-core-textarea>`);
191
- expect(component.validity?.valid).to.be.true;
192
- expect(component.validity?.valueMissing).to.be.false;
193
- expect(component.validity?.tooLong).to.be.false;
194
- expect(component.checkValidity()).to.be.true;
195
- expect(component.reportValidity()).to.be.true;
196
- await elementUpdated(component);
197
- expect(component.shadowRoot
198
- ?.querySelector('textarea')
199
- ?.getAttribute('aria-invalid')).to.equal('false');
200
- });
201
129
  it('blurs the textarea and reports validity if `blur` is called', async () => {
202
130
  const component = await fixture(html `<glide-core-textarea required></glide-core-textarea>`);
203
131
  component.focus();
@@ -210,3 +138,67 @@ it('blurs the textarea and reports validity if `blur` is called', async () => {
210
138
  expect(component.shadowRoot?.querySelector('glide-core-private-label')?.error)
211
139
  .to.be.true;
212
140
  });
141
+ it('sets the validity message with `setCustomValidity()`', async () => {
142
+ const component = await fixture(html `<glide-core-textarea label="Label"></glide-core-textarea>`);
143
+ component.setCustomValidity('validity message');
144
+ expect(component.validity?.valid).to.be.false;
145
+ expect(component.validity?.customError).to.be.true;
146
+ expect(component.checkValidity()).to.be.false;
147
+ await elementUpdated(component);
148
+ // Like native, the validity message shouldn't display until `reportValidity()` is called.
149
+ expect(component.shadowRoot?.querySelector('[data-test="validity-message"]')
150
+ ?.textContent).to.be.undefined;
151
+ expect(component.reportValidity()).to.be.false;
152
+ await elementUpdated(component);
153
+ expect(component.shadowRoot
154
+ ?.querySelector('textarea')
155
+ ?.getAttribute('aria-invalid')).to.equal('true');
156
+ expect(component.shadowRoot?.querySelector('[data-test="validity-message"]')
157
+ ?.textContent).to.equal('validity message');
158
+ });
159
+ it('removes a validity message with an empty argument to `setCustomValidity()`', async () => {
160
+ const component = await fixture(html `<glide-core-textarea label="Label"></glide-core-textarea>`);
161
+ component.setCustomValidity('validity message');
162
+ component.reportValidity();
163
+ await elementUpdated(component);
164
+ component.setCustomValidity('');
165
+ await elementUpdated(component);
166
+ expect(component.shadowRoot?.querySelector('[data-test="validity-message"]')
167
+ ?.textContent).to.be.undefined;
168
+ });
169
+ it('is invalid when `setValidity()` is called', async () => {
170
+ const component = await fixture(html `<glide-core-textarea label="Label"></glide-core-textarea>`);
171
+ component.setValidity({ customError: true }, 'validity message');
172
+ expect(component.validity.valid).to.be.false;
173
+ await elementUpdated(component);
174
+ // Like native, the validity message shouldn't display until `reportValidity()` is called.
175
+ expect(component.shadowRoot?.querySelector('[data-test="validity-message"]')
176
+ ?.textContent).to.be.undefined;
177
+ expect(component.validity?.customError).to.be.true;
178
+ component.reportValidity();
179
+ await elementUpdated(component);
180
+ expect(component.shadowRoot
181
+ ?.querySelector('textarea')
182
+ ?.getAttribute('aria-invalid')).to.equal('true');
183
+ expect(component.shadowRoot?.querySelector('[data-test="validity-message"]')
184
+ ?.textContent).to.equal('validity message');
185
+ });
186
+ it('is valid when `setValidity()` is called', async () => {
187
+ const component = await fixture(html `<glide-core-textarea label="Label"></glide-core-textarea>`);
188
+ component.setValidity({ customError: true }, 'validity message');
189
+ component.setValidity({});
190
+ await elementUpdated(component);
191
+ expect(component.validity.valid).to.be.true;
192
+ expect(component.validity.customError).to.be.false;
193
+ expect(component.reportValidity()).to.be.true;
194
+ await elementUpdated(component);
195
+ expect(component.shadowRoot?.querySelector('[data-test="validity-message"]')
196
+ ?.textContent).to.be.undefined;
197
+ });
198
+ it('retains existing validity state when `setCustomValidity()` is called', async () => {
199
+ const component = await fixture(html `<glide-core-textarea label="Label" required></glide-core-textarea>`);
200
+ component.setCustomValidity('validity message');
201
+ expect(component.validity?.valid).to.be.false;
202
+ expect(component.validity?.customError).to.be.true;
203
+ expect(component.validity?.valueMissing).to.be.true;
204
+ });
package/dist/tooltip.d.ts CHANGED
@@ -14,7 +14,8 @@ export default class GlideCoreTooltip extends LitElement {
14
14
  static styles: import("lit").CSSResult[];
15
15
  get disabled(): boolean;
16
16
  set disabled(isDisabled: boolean);
17
- offset: number;
17
+ get offset(): number;
18
+ set offset(offset: number);
18
19
  get open(): boolean;
19
20
  set open(isOpen: boolean);
20
21
  placement?: 'bottom' | 'left' | 'right' | 'top';
package/dist/tooltip.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,o,l){var i,s=arguments.length,a=s<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,o,l);else for(var r=e.length-1;r>=0;r--)(i=e[r])&&(a=(s<3?i(a):s>3?i(t,o,a):i(t,o))||a);return s>3&&a&&Object.defineProperty(t,o,a),a};import{LitElement,html}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{ifDefined}from"lit/directives/if-defined.js";import{map}from"lit/directives/map.js";import ow,{owSlot}from"./library/ow.js";import styles from"./tooltip.styles.js";let GlideCoreTooltip=class GlideCoreTooltip extends LitElement{constructor(){super(...arguments),this.offset=4,this.shortcut=[],this.effectivePlacement=this.placement??"bottom",this.#e=createRef(),this.#t=createRef(),this.#o=!1,this.#l=!1,this.#i=createRef(),this.#s=createRef(),this.#a=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}get disabled(){return this.#o}set disabled(e){this.#o=e,this.open&&!e?this.#r():this.#n()}get open(){return this.#l}set open(e){this.#l=e,e&&!this.disabled?this.#r():this.#n()}disconnectedCallback(){super.disconnectedCallback(),clearTimeout(this.#f),clearTimeout(this.#h)}firstUpdated(){owSlot(this.#t.value),owSlot(this.#s.value),ow(this.#a.value,ow.object.instanceOf(HTMLElement)),this.#a.value.popover="manual",this.open&&!this.disabled&&this.#r()}render(){return html`<div class="component" data-test="component" @mouseover="${this.#c}" @mouseout="${this.#p}"><div aria-labelledby="${ifDefined(this.disabled?void 0:"tooltip")}" class="target" data-test="target" slot="target" @focusin="${this.#d}" @focusout="${this.#m}" @keydown="${this.#u}" ${ref(this.#i)}><slot @slotchange="${this.#v}" ${ref(this.#s)} name="target"></slot></div><div class="${classMap({tooltip:!0,[this.effectivePlacement]:!0})}" id="tooltip" data-test="tooltip" data-open-delay="300" data-close-delay="200" role="${ifDefined(this.disabled?void 0:"tooltip")}" ${ref(this.#a)}><div class="${classMap({arrow:!0,[this.effectivePlacement]:!0})}" data-test="arrow" ${ref(this.#e)}>${choose(this.effectivePlacement,[["top",()=>html`<svg viewBox="0 0 10 6" fill="none"><path d="M4.23178 5.07814C4.63157 5.55789 5.36843 5.55789 5.76822 5.07813L10 -7.9486e-08L-2.62268e-07 3.57628e-07L4.23178 5.07814Z" fill="currentColor"/></svg>`],["right",()=>html`<svg viewBox="0 0 6 10" fill="none"><path d="M0.921865 4.23178C0.442111 4.63157 0.442112 5.36843 0.921866 5.76822L6 10L6 -2.62268e-07L0.921865 4.23178Z" fill="currentColor"/></svg>`],["bottom",()=>html`<svg viewBox="0 0 10 6" fill="none"><path d="M4.23178 0.921865C4.63157 0.442111 5.36843 0.442112 5.76822 0.921866L10 6L-2.62268e-07 6L4.23178 0.921865Z" fill="currentColor"/></svg>`],["left",()=>html`<svg viewBox="0 0 6 10" fill="none"><path d="M5.07814 4.23178C5.55789 4.63157 5.55789 5.36843 5.07813 5.76822L-4.37114e-07 10L0 -2.62268e-07L5.07814 4.23178Z" fill="currentColor"/></svg>`]])}</div><span aria-label="${ifDefined(this.disabled?void 0:"Tooltip: ")}"></span><div class="${classMap({content:!0,reversed:"left"===this.effectivePlacement})}"><slot class="default-slot" @slotchange="${this.#g}" ${ref(this.#t)}></slot><kbd class="${classMap({shortcut:!0,reversed:"left"===this.effectivePlacement,visible:this.shortcut.length>0})}" data-test="shortcut">${1===this.shortcut.length?this.shortcut.at(0):map(this.shortcut,((e,t)=>html`<kbd>${e}</kbd> ${t===this.shortcut.length-1?"":" + "}`))}</kbd></div></div></div>`}#e;#R;#f;#t;#o;#l;#h;#i;#s;#a;#E(){clearTimeout(this.#f)}#n(){this.#a.value?.hidePopover(),this.#R&&this.#R()}#g(){owSlot(this.#t.value)}#d(){this.open=!0}#m(){this.open=!1}#u(e){"Escape"===e.key&&(this.open=!1)}#p(){this.#w(),clearTimeout(this.#h)}#c(){ow(this.#a.value,ow.object.instanceOf(HTMLElement)),this.#E(),this.#h=setTimeout((()=>{this.open=!0}),Number(this.#a.value.dataset.openDelay))}#v(){owSlot(this.#s.value)}#w(){ow(this.#a.value,ow.object.instanceOf(HTMLElement)),this.#f=setTimeout((()=>{this.open=!1}),Number(this.#a.value.dataset.closeDelay))}#r(){this.disabled||(this.#R?.(),this.#i.value&&this.#a.value&&(this.#R=autoUpdate(this.#i.value,this.#a.value,(()=>{(async()=>{if(this.#i.value&&this.#a.value&&this.#e.value){const{x:e,y:t,placement:o,middlewareData:l}=await computePosition(this.#i.value,this.#a.value,{placement:this.placement,middleware:[offset(this.offset),flip({fallbackStrategy:"initialPlacement"}),shift({limiter:limitShift({offset:20})}),arrow({element:this.#e.value})]});Object.assign(this.#a.value.style,{left:`${e}px`,top:`${t}px`}),Object.assign(this.#e.value.style,{left:l.arrow?.x?`${l.arrow.x}px`:null,top:l.arrow?.y?`${l.arrow.y}px`:null}),this.effectivePlacement=o,this.#a.value.showPopover()}})()}))))}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreTooltip.prototype,"disabled",null),__decorate([property({reflect:!0,type:Number})],GlideCoreTooltip.prototype,"offset",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreTooltip.prototype,"open",null),__decorate([property()],GlideCoreTooltip.prototype,"placement",void 0),__decorate([property({reflect:!0,type:Array})],GlideCoreTooltip.prototype,"shortcut",void 0),__decorate([state()],GlideCoreTooltip.prototype,"effectivePlacement",void 0),GlideCoreTooltip=__decorate([customElement("glide-core-tooltip")],GlideCoreTooltip);export default GlideCoreTooltip;
1
+ var __decorate=this&&this.__decorate||function(e,t,o,l){var i,s=arguments.length,a=s<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,o,l);else for(var r=e.length-1;r>=0;r--)(i=e[r])&&(a=(s<3?i(a):s>3?i(t,o,a):i(t,o))||a);return s>3&&a&&Object.defineProperty(t,o,a),a};import{LitElement,html}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{ifDefined}from"lit/directives/if-defined.js";import{map}from"lit/directives/map.js";import ow,{owSlot}from"./library/ow.js";import styles from"./tooltip.styles.js";let GlideCoreTooltip=class GlideCoreTooltip extends LitElement{constructor(){super(...arguments),this.shortcut=[],this.effectivePlacement=this.placement??"bottom",this.#e=createRef(),this.#t=createRef(),this.#o=!1,this.#l=!1,this.#i=createRef(),this.#s=createRef(),this.#a=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}get disabled(){return this.#o}set disabled(e){this.#o=e,this.open&&!e?this.#r():this.#n()}get offset(){return this.#f??Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}set offset(e){this.#f=e}get open(){return this.#l}set open(e){this.#l=e,e&&!this.disabled?this.#r():this.#n()}disconnectedCallback(){super.disconnectedCallback(),clearTimeout(this.#p),clearTimeout(this.#c)}firstUpdated(){owSlot(this.#t.value),owSlot(this.#s.value),ow(this.#a.value,ow.object.instanceOf(HTMLElement)),this.#a.value.popover="manual",this.open&&!this.disabled&&this.#r()}render(){return html`<div class="component" data-test="component" @mouseover="${this.#h}" @mouseout="${this.#d}"><div aria-labelledby="${ifDefined(this.disabled?void 0:"tooltip")}" class="target" data-test="target" slot="target" @focusin="${this.#m}" @focusout="${this.#u}" @keydown="${this.#v}" ${ref(this.#i)}><slot @slotchange="${this.#g}" ${ref(this.#s)} name="target"></slot></div><div class="${classMap({tooltip:!0,[this.effectivePlacement]:!0})}" id="tooltip" data-test="tooltip" data-open-delay="300" data-close-delay="200" role="${ifDefined(this.disabled?void 0:"tooltip")}" ${ref(this.#a)}><div class="${classMap({arrow:!0,[this.effectivePlacement]:!0})}" data-test="arrow" ${ref(this.#e)}>${choose(this.effectivePlacement,[["top",()=>html`<svg viewBox="0 0 10 6" fill="none"><path d="M4.23178 5.07814C4.63157 5.55789 5.36843 5.55789 5.76822 5.07813L10 -7.9486e-08L-2.62268e-07 3.57628e-07L4.23178 5.07814Z" fill="currentColor"/></svg>`],["right",()=>html`<svg viewBox="0 0 6 10" fill="none"><path d="M0.921865 4.23178C0.442111 4.63157 0.442112 5.36843 0.921866 5.76822L6 10L6 -2.62268e-07L0.921865 4.23178Z" fill="currentColor"/></svg>`],["bottom",()=>html`<svg viewBox="0 0 10 6" fill="none"><path d="M4.23178 0.921865C4.63157 0.442111 5.36843 0.442112 5.76822 0.921866L10 6L-2.62268e-07 6L4.23178 0.921865Z" fill="currentColor"/></svg>`],["left",()=>html`<svg viewBox="0 0 6 10" fill="none"><path d="M5.07814 4.23178C5.55789 4.63157 5.55789 5.36843 5.07813 5.76822L-4.37114e-07 10L0 -2.62268e-07L5.07814 4.23178Z" fill="currentColor"/></svg>`]])}</div><span aria-label="${ifDefined(this.disabled?void 0:"Tooltip: ")}"></span><div class="${classMap({content:!0,reversed:"left"===this.effectivePlacement})}"><slot class="default-slot" @slotchange="${this.#R}" ${ref(this.#t)}></slot><kbd class="${classMap({shortcut:!0,reversed:"left"===this.effectivePlacement,visible:this.shortcut.length>0})}" data-test="shortcut">${1===this.shortcut.length?this.shortcut.at(0):map(this.shortcut,((e,t)=>html`<kbd>${e}</kbd> ${t===this.shortcut.length-1?"":" + "}`))}</kbd></div></div></div>`}#e;#w;#p;#t;#o;#l;#f;#c;#i;#s;#a;#E(){clearTimeout(this.#p)}#n(){this.#a.value?.hidePopover(),this.#w&&this.#w()}#R(){owSlot(this.#t.value)}#m(){this.open=!0}#u(){this.open=!1}#v(e){"Escape"===e.key&&(this.open=!1)}#d(){this.#y(),clearTimeout(this.#c)}#h(){ow(this.#a.value,ow.object.instanceOf(HTMLElement)),this.#E(),this.#c=setTimeout((()=>{this.open=!0}),Number(this.#a.value.dataset.openDelay))}#g(){owSlot(this.#s.value)}#y(){ow(this.#a.value,ow.object.instanceOf(HTMLElement)),this.#p=setTimeout((()=>{this.open=!1}),Number(this.#a.value.dataset.closeDelay))}#r(){this.disabled||(this.#w?.(),this.#i.value&&this.#a.value&&(this.#w=autoUpdate(this.#i.value,this.#a.value,(()=>{(async()=>{if(this.#i.value&&this.#a.value&&this.#e.value){const{x:e,y:t,placement:o,middlewareData:l}=await computePosition(this.#i.value,this.#a.value,{placement:this.placement,middleware:[offset(this.offset),flip({fallbackStrategy:"initialPlacement"}),shift({limiter:limitShift({offset:20})}),arrow({element:this.#e.value})]});Object.assign(this.#a.value.style,{left:`${e}px`,top:`${t}px`}),Object.assign(this.#e.value.style,{left:l.arrow?.x?`${l.arrow.x}px`:null,top:l.arrow?.y?`${l.arrow.y}px`:null}),this.effectivePlacement=o,this.#a.value.showPopover()}})()}))))}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreTooltip.prototype,"disabled",null),__decorate([property({reflect:!0,type:Number})],GlideCoreTooltip.prototype,"offset",null),__decorate([property({reflect:!0,type:Boolean})],GlideCoreTooltip.prototype,"open",null),__decorate([property()],GlideCoreTooltip.prototype,"placement",void 0),__decorate([property({reflect:!0,type:Array})],GlideCoreTooltip.prototype,"shortcut",void 0),__decorate([state()],GlideCoreTooltip.prototype,"effectivePlacement",void 0),GlideCoreTooltip=__decorate([customElement("glide-core-tooltip")],GlideCoreTooltip);export default GlideCoreTooltip;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdstrike/glide-core",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "CrowdStrike's Glide Design System components package for providing web components",
5
5
  "author": "CrowdStrike UX Team",
6
6
  "license": "Apache-2.0",