@crowdstrike/glide-core 0.5.1 → 0.6.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.
- package/README.md +11 -1
- package/dist/accordion.js +1 -1
- package/dist/accordion.styles.js +5 -4
- package/dist/accordion.test.basics.js +109 -0
- package/dist/accordion.test.events.js +39 -0
- package/dist/button-group.button.js +1 -1
- package/dist/button-group.button.styles.js +6 -5
- package/dist/button-group.button.test.basics.js +169 -0
- package/dist/button-group.button.test.events.js +73 -0
- package/dist/button-group.js +1 -1
- package/dist/button-group.styles.js +3 -3
- package/dist/button-group.test.basics.js +268 -0
- package/dist/button-group.test.events.js +291 -0
- package/dist/button.d.ts +3 -2
- package/dist/button.js +1 -1
- package/dist/button.styles.js +5 -5
- package/dist/button.test.basics.js +202 -0
- package/dist/button.test.events.js +25 -0
- package/dist/button.test.form.js +49 -0
- package/dist/checkbox-group.js +1 -1
- package/dist/checkbox-group.styles.js +2 -2
- package/dist/checkbox-group.test.basics.js +119 -0
- package/dist/checkbox-group.test.events.js +110 -0
- package/dist/checkbox-group.test.focus.js +45 -0
- package/dist/checkbox-group.test.form.js +130 -0
- package/dist/checkbox-group.test.validity.js +75 -0
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.styles.js +7 -4
- package/dist/checkbox.test.basics.js +89 -0
- package/dist/checkbox.test.events.js +87 -0
- package/dist/checkbox.test.focus.js +38 -0
- package/dist/checkbox.test.form.js +115 -0
- package/dist/checkbox.test.states.js +62 -0
- package/dist/checkbox.test.validity.js +51 -0
- package/dist/drawer.d.ts +2 -2
- package/dist/drawer.js +1 -15
- package/dist/drawer.styles.js +14 -4
- package/dist/drawer.test.accessibility.js +22 -0
- package/dist/drawer.test.basics.js +43 -0
- package/dist/drawer.test.closing.js +37 -0
- package/dist/drawer.test.events.js +52 -0
- package/dist/drawer.test.floating-components.d.ts +1 -0
- package/dist/drawer.test.floating-components.js +51 -0
- package/dist/drawer.test.methods.js +34 -0
- package/dist/dropdown.d.ts +4 -2
- package/dist/dropdown.js +1 -1
- package/dist/dropdown.option.d.ts +0 -2
- package/dist/dropdown.option.js +1 -1
- package/dist/dropdown.option.styles.js +2 -2
- package/dist/dropdown.option.test.basics.js +59 -0
- package/dist/dropdown.option.test.basics.multiple.js +26 -0
- package/dist/dropdown.option.test.basics.single.js +20 -0
- package/dist/dropdown.option.test.events.js +27 -0
- package/dist/dropdown.option.test.focus.js +11 -0
- package/dist/dropdown.option.test.interactions.multiple.js +82 -0
- package/dist/dropdown.option.test.interactions.single.js +22 -0
- package/dist/dropdown.styles.js +26 -6
- package/dist/dropdown.test.basics.filterable.js +84 -0
- package/dist/dropdown.test.basics.js +233 -0
- package/dist/dropdown.test.basics.multiple.js +270 -0
- package/dist/dropdown.test.basics.single.js +79 -0
- package/dist/dropdown.test.events.js +268 -0
- package/dist/dropdown.test.events.multiple.js +130 -0
- package/dist/dropdown.test.focus.d.ts +1 -0
- package/dist/dropdown.test.focus.filterable.js +154 -0
- package/dist/dropdown.test.focus.js +28 -0
- package/dist/dropdown.test.focus.multiple.js +181 -0
- package/dist/dropdown.test.focus.single.js +53 -0
- package/dist/dropdown.test.form.js +140 -0
- package/dist/dropdown.test.form.multiple.js +149 -0
- package/dist/dropdown.test.form.single.js +128 -0
- package/dist/dropdown.test.interactions.filterable.js +449 -0
- package/dist/dropdown.test.interactions.js +446 -0
- package/dist/dropdown.test.interactions.multiple.js +908 -0
- package/dist/dropdown.test.interactions.single.js +466 -0
- package/dist/dropdown.test.validity.js +46 -0
- package/dist/icon-button.d.ts +3 -2
- package/dist/icon-button.js +1 -1
- package/dist/icon-button.styles.js +12 -12
- package/dist/icon-button.test.basics.js +110 -0
- package/dist/icons/checked.js +1 -1
- package/dist/icons/magnifying-glass.js +1 -1
- package/dist/input.js +1 -1
- package/dist/input.styles.js +4 -3
- package/dist/input.test.basics.js +169 -0
- package/dist/input.test.events.js +97 -0
- package/dist/input.test.focus.js +54 -0
- package/dist/input.test.form.js +56 -0
- package/dist/input.test.validity.js +50 -0
- package/dist/label.js +1 -1
- package/dist/label.styles.js +13 -15
- package/dist/label.test.basics.js +129 -0
- package/dist/library/expect-argument-error.js +1 -1
- package/dist/library/localize.d.ts +17 -0
- package/dist/library/localize.js +1 -0
- package/dist/library/ow.js +1 -1
- package/dist/library/ow.test.js +55 -0
- package/dist/library/set-containing-block.d.ts +15 -0
- package/dist/library/set-containing-block.js +1 -0
- package/dist/menu.button.d.ts +1 -2
- package/dist/menu.button.js +1 -1
- package/dist/menu.button.styles.js +3 -3
- package/dist/menu.button.test.basics.js +42 -0
- package/dist/menu.d.ts +7 -2
- package/dist/menu.js +1 -1
- package/dist/menu.link.d.ts +1 -2
- package/dist/menu.link.js +1 -1
- package/dist/menu.link.styles.js +3 -3
- package/dist/menu.link.test.basics.js +46 -0
- package/dist/menu.options.d.ts +22 -0
- package/dist/menu.options.js +1 -0
- package/dist/menu.options.styles.d.ts +2 -0
- package/dist/menu.options.styles.js +33 -0
- package/dist/menu.options.test.basics.d.ts +2 -0
- package/dist/menu.options.test.basics.js +43 -0
- package/dist/menu.stories.d.ts +1 -0
- package/dist/menu.styles.js +7 -31
- package/dist/menu.test.basics.d.ts +1 -0
- package/dist/menu.test.basics.js +183 -0
- package/dist/menu.test.focus.d.ts +0 -1
- package/dist/menu.test.focus.js +84 -0
- package/dist/menu.test.interactions.d.ts +1 -1
- package/dist/menu.test.interactions.js +664 -0
- package/dist/modal.icon-button.js +1 -1
- package/dist/modal.icon-button.styles.js +2 -2
- package/dist/modal.icon-button.test.basics.js +45 -0
- package/dist/modal.js +1 -15
- package/dist/modal.styles.js +4 -7
- package/dist/modal.tertiary-icon.d.ts +1 -0
- package/dist/modal.tertiary-icon.js +1 -1
- package/dist/modal.tertiary-icon.test.basics.js +59 -0
- package/dist/modal.test.accessibility.js +48 -0
- package/dist/modal.test.basics.js +203 -0
- package/dist/modal.test.close.js +38 -0
- package/dist/modal.test.events.js +110 -0
- package/dist/modal.test.floating-components.d.ts +1 -0
- package/dist/modal.test.floating-components.js +62 -0
- package/dist/modal.test.lock-scroll.js +76 -0
- package/dist/modal.test.methods.js +23 -0
- package/dist/modal.test.scrollbars.js +19 -0
- package/dist/radio-group.js +1 -1
- package/dist/radio-group.styles.js +20 -24
- package/dist/radio-group.test.basics.js +323 -0
- package/dist/radio-group.test.events.js +277 -0
- package/dist/radio-group.test.focus.js +75 -0
- package/dist/radio-group.test.form.js +104 -0
- package/dist/radio-group.test.validity.js +228 -0
- package/dist/radio.js +1 -1
- package/dist/radio.styles.js +14 -31
- package/dist/split-button.d.ts +27 -0
- package/dist/split-button.js +1 -0
- package/dist/split-button.stories.d.ts +17 -0
- package/dist/split-button.styles.d.ts +2 -0
- package/dist/split-button.styles.js +102 -0
- package/dist/split-button.test.basics.d.ts +1 -0
- package/dist/split-button.test.basics.js +99 -0
- package/dist/split-container.d.ts +31 -0
- package/dist/split-container.js +1 -0
- package/dist/split-container.styles.d.ts +2 -0
- package/dist/split-container.styles.js +134 -0
- package/dist/split-container.test.basics.d.ts +3 -0
- package/dist/split-container.test.basics.js +440 -0
- package/dist/split-container.test.interactions.d.ts +1 -0
- package/dist/split-container.test.interactions.js +20 -0
- package/dist/split-link.d.ts +25 -0
- package/dist/split-link.js +1 -0
- package/dist/split-link.test.basics.d.ts +1 -0
- package/dist/split-link.test.basics.js +92 -0
- package/dist/split-link.test.interactions.d.ts +1 -0
- package/dist/split-link.test.interactions.js +19 -0
- package/dist/status-indicator.js +1 -1
- package/dist/status-indicator.styles.js +2 -2
- package/dist/status-indicator.test.basics.js +102 -0
- package/dist/styles/focus-outline.js +1 -4
- package/dist/styles/variables.css +1 -1
- package/dist/styles/visually-hidden.js +1 -11
- package/dist/tab.group.js +1 -1
- package/dist/tab.group.styles.js +2 -2
- package/dist/tab.group.test.basics.js +185 -0
- package/dist/tab.js +1 -1
- package/dist/tab.panel.js +1 -1
- package/dist/tab.panel.styles.js +3 -3
- package/dist/tab.styles.js +80 -55
- package/dist/tab.test.basics.js +71 -0
- package/dist/tag.js +1 -1
- package/dist/tag.styles.js +4 -3
- package/dist/tag.test.basics.js +118 -0
- package/dist/tag.test.events.js +16 -0
- package/dist/tag.test.focus.js +11 -0
- package/dist/tag.test.translations.d.ts +1 -0
- package/dist/tag.test.translations.js +25 -0
- package/dist/textarea.js +2 -2
- package/dist/textarea.styles.js +5 -4
- package/dist/textarea.test.basics.js +140 -0
- package/dist/textarea.test.events.js +204 -0
- package/dist/textarea.test.form.js +70 -0
- package/dist/textarea.test.validity.js +83 -0
- package/dist/toasts.js +1 -1
- package/dist/toasts.styles.js +2 -2
- package/dist/toasts.test.basics.js +94 -0
- package/dist/toasts.toast.js +1 -1
- package/dist/toasts.toast.styles.js +5 -2
- package/dist/toasts.toast.test.basics.js +139 -0
- package/dist/toggle.js +1 -1
- package/dist/toggle.styles.js +3 -3
- package/dist/toggle.test.basics.js +68 -0
- package/dist/toggle.test.events.js +29 -0
- package/dist/toggle.test.focus.js +9 -0
- package/dist/toggle.test.states.js +43 -0
- package/dist/tooltip.d.ts +2 -0
- package/dist/tooltip.js +1 -1
- package/dist/tooltip.styles.js +5 -3
- package/dist/tooltip.test.basics.js +64 -0
- package/dist/tooltip.test.interactions.js +78 -0
- package/dist/translations/en.d.ts +3 -0
- package/dist/translations/en.js +1 -0
- package/dist/translations/fr.d.ts +3 -0
- package/dist/translations/fr.js +1 -0
- package/dist/translations/ja.d.ts +3 -0
- package/dist/translations/ja.js +1 -0
- package/dist/tree.d.ts +1 -0
- package/dist/tree.item.d.ts +3 -1
- package/dist/tree.item.icon-button.js +1 -1
- package/dist/tree.item.icon-button.styles.js +2 -2
- package/dist/tree.item.icon-button.test.basics.js +13 -0
- package/dist/tree.item.js +1 -1
- package/dist/tree.item.menu.d.ts +2 -0
- package/dist/tree.item.menu.js +1 -1
- package/dist/tree.item.menu.styles.js +2 -2
- package/dist/tree.item.menu.test.basics.js +33 -0
- package/dist/tree.item.styles.js +23 -8
- package/dist/tree.item.test.basics.js +102 -0
- package/dist/tree.js +1 -1
- package/dist/tree.stories.d.ts +1 -0
- package/dist/tree.styles.js +2 -2
- package/dist/tree.test.aria.js +86 -0
- package/dist/tree.test.basics.js +123 -0
- package/dist/tree.test.events.js +19 -0
- package/dist/tree.test.focus.js +261 -0
- package/package.json +25 -18
- /package/dist/{dropdown.option.test.focus.multiple.d.ts → dropdown.option.test.focus.d.ts} +0 -0
- /package/dist/{dropdown.option.test.focus.single.d.ts → dropdown.test.events.multiple.d.ts} +0 -0
package/dist/label.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
var __decorate=this&&this.__decorate||function(t,e,o,l){var i,r=arguments.length,s=r<3?e:null===l?l=Object.getOwnPropertyDescriptor(e,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,o,l);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(s=(r<3?i(s):r>3?i(e,o,s):i(e,o))||s);return r>3&&s&&Object.defineProperty(e,o,s),s};import"./tooltip.js";import{LitElement,html}from"lit";import{LocalizeController}from"./library/localize.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{owSlot}from"./library/ow.js";import styles from"./label.styles.js";import{svg}from"lit";const infoCircleIcon=svg`<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"><path d="M12 16L12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="8" r="1" fill="currentColor">`;let GlideCoreLabel=class GlideCoreLabel extends LitElement{constructor(){super(...arguments),this.disabled=!1,this.error=!1,this.hide=!1,this.orientation="horizontal",this.required=!1,this.hasDescriptionSlot=!1,this.hasSummarySlot=!1,this.hasTooltipSlot=!1,this.#t=createRef(),this.#e=createRef(),this.#o=createRef(),this.#l=new LocalizeController(this),this.#i=createRef(),this.#r=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#e.value),owSlot(this.#t.value)}render(){return html`<div class="${classMap({component:!0,horizontal:"horizontal"===this.orientation,vertical:"vertical"===this.orientation,"hidden-label":this.hide})}"><div class="${classMap({"tooltip-and-label":!0,hidden:this.hide})}" part="tooltip-and-label-container"><div class="tooltip-and-label"><glide-core-tooltip class="${classMap({tooltip:!0,vertical:"vertical"===this.orientation,visible:this.hasTooltipSlot})}" placement="${"vertical"===this.orientation?"right":"bottom"}"><span class="tooltip-target" slot="target" tabindex="0"><svg aria-label="${this.#l.term("moreInformation")}" width="16" height="16" viewBox="0 0 24 24" fill="none">${infoCircleIcon}</svg></span><slot class="${classMap({tooltip:!0,visible:this.hasTooltipSlot})}" name="tooltip" @slotchange="${this.#s}" ${ref(this.#r)}></slot></glide-core-tooltip><div class="${classMap({label:!0,disabled:this.disabled})}" data-test="label"><slot @slotchange="${this.#a}" ${ref(this.#e)}></slot>${this.required?html`<span aria-hidden="true" class="required-symbol">*</span>`:""}</div></div></div><div class="control-and-summary"><slot class="${classMap({control:!0,error:this.error,disabled:this.disabled,vertical:"vertical"===this.orientation,summaryless:!this.hasSummarySlot,"hidden-label":this.hide})}" name="control" @slotchange="${this.#n}" ${ref(this.#t)}></slot><slot class="${classMap({summary:!0,error:this.error})}" name="summary" @slotchange="${this.#c}" ${ref(this.#i)}></slot></div><slot class="${classMap({description:!0,visible:this.hasDescriptionSlot,error:this.error,tooltip:this.hasTooltipSlot})}" id="description" name="description" @slotchange="${this.#d}" ${ref(this.#o)}></slot></div>`}#t;#e;#o;#l;#i;#r;#n(){owSlot(this.#t.value)}#a(){owSlot(this.#e.value)}#d(){const t=this.#o.value?.assignedNodes({flatten:!0});this.hasDescriptionSlot=Boolean(t&&t.length>0)}#c(){const t=this.#i.value?.assignedNodes({flatten:!0});this.hasSummarySlot=Boolean(t&&t.length>0)}#s(){const t=this.#r.value?.assignedNodes({flatten:!0});this.hasTooltipSlot=Boolean(t&&t.length>0)}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"disabled",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"error",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"hide",void 0),__decorate([property({reflect:!0})],GlideCoreLabel.prototype,"orientation",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreLabel.prototype,"required",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasDescriptionSlot",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasSummarySlot",void 0),__decorate([state()],GlideCoreLabel.prototype,"hasTooltipSlot",void 0),GlideCoreLabel=__decorate([customElement("glide-core-label")],GlideCoreLabel);export default GlideCoreLabel;
|
package/dist/label.styles.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
"
|
1
|
+
import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
|
2
2
|
.component {
|
3
3
|
&.horizontal {
|
4
4
|
column-gap: var(--glide-core-spacing-sm);
|
@@ -29,7 +29,7 @@
|
|
29
29
|
display: flex;
|
30
30
|
|
31
31
|
&.hidden {
|
32
|
-
${
|
32
|
+
${visuallyHidden};
|
33
33
|
}
|
34
34
|
}
|
35
35
|
|
@@ -52,23 +52,21 @@
|
|
52
52
|
.tooltip-target {
|
53
53
|
background-color: transparent;
|
54
54
|
border: none;
|
55
|
-
|
56
|
-
/* TODO
|
57
|
-
We want the focus outline to wrap neatly around the trigger. Tooltip should
|
58
|
-
probably wrap its default slot in a SPAN with "tabindex=0" and include the
|
59
|
-
below styles so every consumer doesn't have to.
|
60
|
-
*/
|
61
|
-
border-radius: 50%;
|
55
|
+
border-radius: 0.0625rem;
|
62
56
|
color: var(--glide-core-text-body-1);
|
63
57
|
|
64
58
|
/*
|
65
|
-
Any "display" that's not inline-level will do. We don't want the button to
|
66
|
-
acquire a line box, which will make it taller than its content and thus
|
67
|
-
make it difficult to center vertically with the label.
|
68
|
-
*/
|
59
|
+
Any "display" that's not inline-level will do. We don't want the button to
|
60
|
+
acquire a line box, which will make it taller than its content and thus
|
61
|
+
make it difficult to center vertically with the label.
|
62
|
+
*/
|
63
|
+
|
69
64
|
display: flex;
|
70
|
-
outline-offset: 1px;
|
71
65
|
padding: 0;
|
66
|
+
|
67
|
+
&:focus-visible {
|
68
|
+
${focusOutline};
|
69
|
+
}
|
72
70
|
}
|
73
71
|
|
74
72
|
.label {
|
@@ -151,4 +149,4 @@ make it difficult to center vertically with the label.
|
|
151
149
|
display: block;
|
152
150
|
}
|
153
151
|
}
|
154
|
-
`];
|
152
|
+
`];
|
@@ -0,0 +1,129 @@
|
|
1
|
+
import { ArgumentError } from 'ow';
|
2
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
3
|
+
import GlideCoreLabel from './label.js';
|
4
|
+
import sinon from 'sinon';
|
5
|
+
GlideCoreLabel.shadowRootOptions.mode = 'open';
|
6
|
+
it('registers', async () => {
|
7
|
+
expect(window.customElements.get('glide-core-label')).to.equal(GlideCoreLabel);
|
8
|
+
});
|
9
|
+
it('has defaults', async () => {
|
10
|
+
const component = await fixture(html `<glide-core-label>
|
11
|
+
<label for="input">Label</label>
|
12
|
+
<input id="input" slot="control" />
|
13
|
+
</glide-core-label>`);
|
14
|
+
expect(component.getAttribute('error')).to.equal(null);
|
15
|
+
expect(component.error).to.equal(false);
|
16
|
+
expect(component.getAttribute('hide')).to.equal(null);
|
17
|
+
expect(component.hide).to.equal(false);
|
18
|
+
expect(component.getAttribute('orientation')).to.equal('horizontal');
|
19
|
+
expect(component.orientation).to.equal('horizontal');
|
20
|
+
expect(component.hasAttribute('required')).to.be.false;
|
21
|
+
expect(component.required).to.be.false;
|
22
|
+
});
|
23
|
+
it('is accessible', async () => {
|
24
|
+
const component = await fixture(html `<glide-core-label>
|
25
|
+
<label for="input">Label</label>
|
26
|
+
<input id="input" slot="control" />
|
27
|
+
<div slot="tooltip">Tooltip</div>
|
28
|
+
<div slot="description">Description</div>
|
29
|
+
</glide-core-label>`);
|
30
|
+
await expect(component).to.be.accessible();
|
31
|
+
});
|
32
|
+
it('can have a label', async () => {
|
33
|
+
const component = await fixture(html `<glide-core-label>
|
34
|
+
<label for="input">Label</label>
|
35
|
+
<input id="input" slot="control" />
|
36
|
+
</glide-core-label>`);
|
37
|
+
const assignedElements = component.shadowRoot
|
38
|
+
?.querySelector('slot:not([name])')
|
39
|
+
?.assignedElements();
|
40
|
+
expect(assignedElements?.at(0)?.textContent).to.equal('Label');
|
41
|
+
});
|
42
|
+
it('can have a description', async () => {
|
43
|
+
const component = await fixture(html `<glide-core-label>
|
44
|
+
<label for="input">Label</label>
|
45
|
+
<input id="input" slot="control" />
|
46
|
+
<div slot="description">Description</div>
|
47
|
+
</glide-core-label>`);
|
48
|
+
const assignedElements = component.shadowRoot
|
49
|
+
?.querySelector('slot[name="description"]')
|
50
|
+
?.assignedElements();
|
51
|
+
expect(assignedElements?.at(0)?.textContent).to.equal('Description');
|
52
|
+
});
|
53
|
+
it('can have a tooltip', async () => {
|
54
|
+
const component = await fixture(html `<glide-core-label>
|
55
|
+
<label for="input">Label</label>
|
56
|
+
<input id="input" slot="control" />
|
57
|
+
<div slot="tooltip">Tooltip</div>
|
58
|
+
</glide-core-label>`);
|
59
|
+
const assignedElements = component.shadowRoot
|
60
|
+
?.querySelector('slot[name="tooltip"]')
|
61
|
+
?.assignedElements();
|
62
|
+
expect(assignedElements?.at(0)?.textContent).to.equal('Tooltip');
|
63
|
+
});
|
64
|
+
it('can be required', async () => {
|
65
|
+
const component = await fixture(html `<glide-core-label required>
|
66
|
+
<label for="input">Label</label>
|
67
|
+
<input id="input" slot="control" />
|
68
|
+
</glide-core-label>`);
|
69
|
+
expect(component.hasAttribute('required')).to.be.true;
|
70
|
+
expect(component.required).to.equal(true);
|
71
|
+
const label = component.shadowRoot?.querySelector('[data-test="label"]');
|
72
|
+
expect(label?.textContent?.includes('*')).to.be.true;
|
73
|
+
});
|
74
|
+
it('can have an `error`', async () => {
|
75
|
+
const component = await fixture(html `<glide-core-label ?error=${true}>
|
76
|
+
<label for="input">Label</label>
|
77
|
+
<input id="input" slot="control" />
|
78
|
+
</glide-core-label>`);
|
79
|
+
expect(component.hasAttribute('error')).to.be.true;
|
80
|
+
expect(component.error).to.equal(true);
|
81
|
+
});
|
82
|
+
it('places the tooltip on the bottom when horizontal', async () => {
|
83
|
+
const component = await fixture(html `<glide-core-label>
|
84
|
+
<label for="input">Label</label>
|
85
|
+
<input id="input" slot="control" />
|
86
|
+
<div slot="tooltip">Tooltip</div>
|
87
|
+
</glide-core-label>`);
|
88
|
+
expect(component.shadowRoot
|
89
|
+
?.querySelector('glide-core-tooltip')
|
90
|
+
?.getAttribute('placement')).to.equal('bottom');
|
91
|
+
});
|
92
|
+
it('places the tooltip on the right when vertical', async () => {
|
93
|
+
const component = await fixture(html `<glide-core-label orientation="vertical">
|
94
|
+
<label for="input">Label</label>
|
95
|
+
<input id="input" slot="control" />
|
96
|
+
<div slot="tooltip">Tooltip</div>
|
97
|
+
</glide-core-label>`);
|
98
|
+
expect(component.shadowRoot
|
99
|
+
?.querySelector('glide-core-tooltip')
|
100
|
+
?.getAttribute('placement')).to.equal('right');
|
101
|
+
});
|
102
|
+
it('throws if it does not have a default slot', async () => {
|
103
|
+
const spy = sinon.spy();
|
104
|
+
try {
|
105
|
+
await fixture(html `<glide-core-label orientation="vertical"
|
106
|
+
><input slot="control"
|
107
|
+
/></glide-core-label>`);
|
108
|
+
}
|
109
|
+
catch (error) {
|
110
|
+
if (error instanceof ArgumentError) {
|
111
|
+
spy();
|
112
|
+
}
|
113
|
+
}
|
114
|
+
expect(spy.called).to.be.true;
|
115
|
+
});
|
116
|
+
it('throws if it does not have a "control" slot', async () => {
|
117
|
+
const spy = sinon.spy();
|
118
|
+
try {
|
119
|
+
await fixture(html `<glide-core-label orientation="vertical">
|
120
|
+
<label>Label</label>
|
121
|
+
</glide-core-label>`);
|
122
|
+
}
|
123
|
+
catch (error) {
|
124
|
+
if (error instanceof ArgumentError) {
|
125
|
+
spy();
|
126
|
+
}
|
127
|
+
}
|
128
|
+
expect(spy.called).to.be.true;
|
129
|
+
});
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
import{ArgumentError}from"ow";import{expect}from"@open-wc/testing";import sinon from"sinon";export default async function(o){const r=window.onerror;window.onerror=null;const n=sinon.spy();try{await o.call(context)}catch(o){o instanceof ArgumentError&&n()}expect(n.called).to.be.true,window.onerror=r}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { LocalizeController as DefaultLocalizationController } from '@shoelace-style/localize';
|
2
|
+
import type { Translation as DefaultTranslation } from '@shoelace-style/localize';
|
3
|
+
export declare class LocalizeController extends DefaultLocalizationController<Translation> {
|
4
|
+
}
|
5
|
+
export interface Translation extends DefaultTranslation {
|
6
|
+
$code: string;
|
7
|
+
$name: string;
|
8
|
+
$dir: 'ltr' | 'rtl';
|
9
|
+
close: string;
|
10
|
+
dismiss: string;
|
11
|
+
open: string;
|
12
|
+
selectAll: string;
|
13
|
+
clearEntry: string;
|
14
|
+
moreInformation: string;
|
15
|
+
notifications: string;
|
16
|
+
removeTag: (name: string) => string;
|
17
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
import{LocalizeController as DefaultLocalizationController,registerTranslation}from"@shoelace-style/localize";import en from"../translations/en.js";import fr from"../translations/fr.js";import ja from"../translations/ja.js";export class LocalizeController extends DefaultLocalizationController{static{registerTranslation(en,ja,fr)}}
|
package/dist/library/ow.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
import ow,{}from"ow";const isDevelopment=window.location.host.startsWith("localhost")||window.location.host.startsWith("127.0.0.1");export function owSlot(e){isDevelopment&&(ow(e,ow.object.is((e=>e instanceof HTMLSlotElement))),ow(e.assignedNodes().length,ow.number.is((e=>e>0)).message(e.name?`Expected a "${e.name}" slot.`:"Expected a default slot.")))}export function owSlotType(e,o=[]){if(isDevelopment&&(ow(e,ow.object.is((e=>e instanceof HTMLSlotElement))),0!==e.assignedNodes().length&&o.length>0)){const t=e.assignedNodes({flatten:!0}).filter((e=>!!(e instanceof Text&&o.includes(Text))||!(e instanceof Text)));ow(t.length,ow.number.is((e=>e>0)).message(`Expected a slotted node that extends ${o.map((({name:e})=>e)).join(" or ")}.`));for(const e of t){const t=`Expected slotted node to extend ${o.map((({name:e})=>e)).join(" or ")}. Extends ${e.constructor.name} instead.`,n=o.some((o=>e instanceof o));ow(n,ow.boolean.true.message(t))}}}const shim=new Proxy((()=>{}),{get:()=>shim,apply:()=>shim}),owOrShim=isDevelopment?ow:shim;export default owOrShim;
|
@@ -0,0 +1,55 @@
|
|
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
|
+
/* eslint-disable @crowdstrike/glide-core-eslint-plugin/prefer-closed-shadow-root */
|
8
|
+
/* This is a test file that doesn't contain one of our components, so we don't need to enforce this rule. */
|
9
|
+
import { LitElement } from 'lit';
|
10
|
+
import { assert, expect, fixture, html } from '@open-wc/testing';
|
11
|
+
import { customElement } from 'lit/decorators.js';
|
12
|
+
import { owSlot, owSlotType } from './ow.js';
|
13
|
+
let GlideCoreSlot = class GlideCoreSlot extends LitElement {
|
14
|
+
render() {
|
15
|
+
return html `<slot></slot>`;
|
16
|
+
}
|
17
|
+
};
|
18
|
+
GlideCoreSlot = __decorate([
|
19
|
+
customElement('glide-core-slot')
|
20
|
+
], GlideCoreSlot);
|
21
|
+
export default GlideCoreSlot;
|
22
|
+
it('throws when a slot lacks a node', async () => {
|
23
|
+
const component = await fixture(html `<glide-core-slot></glide-core-slot>`);
|
24
|
+
const slot = component.shadowRoot?.querySelector('slot');
|
25
|
+
assert(slot !== null);
|
26
|
+
expect(() => owSlot(slot)).to.throw();
|
27
|
+
});
|
28
|
+
it('throws when a slot lacks a specific node', async () => {
|
29
|
+
const component = await fixture(html `<glide-core-slot>
|
30
|
+
<span>Span</span>
|
31
|
+
</glide-core-slot>`);
|
32
|
+
const slot = component.shadowRoot?.querySelector('slot');
|
33
|
+
assert(slot !== null);
|
34
|
+
expect(() => owSlotType(slot, [HTMLButtonElement])).to.throw();
|
35
|
+
});
|
36
|
+
it('does not throw when a slot has a node', async () => {
|
37
|
+
const component = await fixture(html `<glide-core-slot>
|
38
|
+
<span>Span</span>
|
39
|
+
</glide-core-slot>`);
|
40
|
+
const slot = component.shadowRoot?.querySelector('slot');
|
41
|
+
assert(slot !== null);
|
42
|
+
expect(() => owSlot(slot)).to.not.throw();
|
43
|
+
});
|
44
|
+
it('does not throw when a slot has a specific node', async () => {
|
45
|
+
const component = await fixture(html `<glide-core-slot> Text </glide-core-slot>`);
|
46
|
+
const slot = component.shadowRoot?.querySelector('slot');
|
47
|
+
assert(slot !== null);
|
48
|
+
expect(() => owSlotType(slot, [Text])).to.not.throw();
|
49
|
+
});
|
50
|
+
it('does not throw when a slot has no nodes', async () => {
|
51
|
+
const component = await fixture(html `<glide-core-slot></glide-core-slot>`);
|
52
|
+
const slot = component.shadowRoot?.querySelector('slot');
|
53
|
+
assert(slot !== null);
|
54
|
+
expect(() => owSlotType(slot, [HTMLButtonElement])).to.not.throw();
|
55
|
+
});
|
@@ -0,0 +1,15 @@
|
|
1
|
+
interface Arguments {
|
2
|
+
elements: Element[];
|
3
|
+
containingBlock: Element;
|
4
|
+
}
|
5
|
+
/**
|
6
|
+
* Sets the containing block for all child elements that might contain
|
7
|
+
* floating-ui components (i.e. tooltips, popovers, or menus),
|
8
|
+
* for cases where the containing block element is inside a closed shadow DOM,
|
9
|
+
* and therefore wouldn't be able to be detected by floating-ui's getOffsetParent calculations.
|
10
|
+
* Necessary when the containing block has something like a backdrop-filter
|
11
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
|
12
|
+
* https://github.com/floating-ui/floating-ui/issues/2955
|
13
|
+
*/
|
14
|
+
export declare function setContainingBlock({ elements, containingBlock }: Arguments): void;
|
15
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
import GlideCoreMenu from"../menu.js";import GlideCoreTooltip from"../tooltip.js";import GlideCoreTree from"../tree.js";export function setContainingBlock({elements:o,containingBlock:e}){const i=o.filter((o=>o instanceof GlideCoreTooltip||o instanceof GlideCoreMenu||o instanceof GlideCoreTree));for(const o of i)o.setContainingBlock(e)}
|
package/dist/menu.button.d.ts
CHANGED
@@ -15,7 +15,6 @@ export default class GlideCoreMenuButton extends LitElement {
|
|
15
15
|
static styles: import("lit").CSSResult[];
|
16
16
|
label?: string;
|
17
17
|
privateActive: boolean;
|
18
|
-
|
19
|
-
focus(): void;
|
18
|
+
connectedCallback(): void;
|
20
19
|
render(): import("lit").TemplateResult<1>;
|
21
20
|
}
|
package/dist/menu.button.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
var __decorate=this&&this.__decorate||function(t,e,o,r){var i,n=arguments.length,s=n<3?e:null===r?r=Object.getOwnPropertyDescriptor(e,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(t,e,o,r);else for(var l=t.length-1;l>=0;l--)(i=t[l])&&(s=(n<3?i(s):n>3?i(e,o,s):i(e,o))||s);return n>3&&s&&Object.defineProperty(e,o,s),s};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{customElement,property}from"lit/decorators.js";import styles from"./menu.button.styles.js";let GlideCoreMenuButton=class GlideCoreMenuButton extends LitElement{constructor(){super(...arguments),this.privateActive=!1,this.#t=window.crypto.randomUUID()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}connectedCallback(){super.connectedCallback(),this.id=this.#t,this.role="menuitem",this.tabIndex=-1}render(){return html`<button class="${classMap({component:!0,active:this.privateActive})}" data-test="component" type="button"><slot name="icon"></slot>${this.label}</button>`}#t};__decorate([property({reflect:!0})],GlideCoreMenuButton.prototype,"label",void 0),__decorate([property({type:Boolean})],GlideCoreMenuButton.prototype,"privateActive",void 0),GlideCoreMenuButton=__decorate([customElement("glide-core-menu-button")],GlideCoreMenuButton);export default GlideCoreMenuButton;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
import{css}from"lit";export default[css`
|
2
2
|
.component {
|
3
3
|
align-items: center;
|
4
4
|
background-color: transparent;
|
@@ -13,8 +13,8 @@
|
|
13
13
|
padding-inline: var(--padding-inline);
|
14
14
|
user-select: none;
|
15
15
|
|
16
|
-
&.
|
16
|
+
&.active {
|
17
17
|
background-color: var(--glide-core-surface-hover);
|
18
18
|
}
|
19
19
|
}
|
20
|
-
`];
|
20
|
+
`];
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
2
|
+
import GlideCoreMenuButton from './menu.button.js';
|
3
|
+
GlideCoreMenuButton.shadowRootOptions.mode = 'open';
|
4
|
+
it('registers', async () => {
|
5
|
+
expect(window.customElements.get('glide-core-menu-button')).to.equal(GlideCoreMenuButton);
|
6
|
+
});
|
7
|
+
it('has defaults', async () => {
|
8
|
+
// Required attributes are supplied and not asserted below. The idea is that
|
9
|
+
// this test shouldn't fail to typecheck if these templates are eventually
|
10
|
+
// typechecked, which means supplying required attributes up front.
|
11
|
+
const component = await fixture(html `<glide-core-menu-button label="Label"></glide-core-menu-button>`);
|
12
|
+
// Not reflected. So no attribute assertions are necessary.
|
13
|
+
expect(component.privateActive).to.equal(false);
|
14
|
+
});
|
15
|
+
it('can have a label', async () => {
|
16
|
+
const button = await fixture(html `<glide-core-menu-button label="Label"></glide-core-menu-button>`);
|
17
|
+
expect(button.shadowRoot?.textContent?.trim()).to.equal('Label');
|
18
|
+
});
|
19
|
+
it('can have an icon', async () => {
|
20
|
+
const component = await fixture(html `<glide-core-menu-button label="Label">
|
21
|
+
<svg
|
22
|
+
slot="icon"
|
23
|
+
width="16"
|
24
|
+
height="16"
|
25
|
+
fill="none"
|
26
|
+
viewBox="0 0 24 24"
|
27
|
+
stroke-width="1.5"
|
28
|
+
stroke="currentColor"
|
29
|
+
>
|
30
|
+
<path
|
31
|
+
stroke-linecap="round"
|
32
|
+
stroke-linejoin="round"
|
33
|
+
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"
|
34
|
+
/>
|
35
|
+
</svg>
|
36
|
+
</glide-core-menu-button>`);
|
37
|
+
const icon = component?.shadowRoot
|
38
|
+
?.querySelector('slot[name="icon"]')
|
39
|
+
?.assignedElements()
|
40
|
+
.at(0);
|
41
|
+
expect(icon instanceof Element).to.be.true;
|
42
|
+
});
|
package/dist/menu.d.ts
CHANGED
@@ -8,7 +8,7 @@ declare global {
|
|
8
8
|
/**
|
9
9
|
* @description A basic menu.
|
10
10
|
*
|
11
|
-
* @slot -
|
11
|
+
* @slot - <glide-core-menu-options>.
|
12
12
|
* @slot target - A focusable element against which Menu will be positioned. Opens and closes Menu when interacted with.
|
13
13
|
*/
|
14
14
|
export default class GlideCoreMenu extends LitElement {
|
@@ -18,10 +18,15 @@ export default class GlideCoreMenu extends LitElement {
|
|
18
18
|
get open(): boolean;
|
19
19
|
set open(isOpen: boolean);
|
20
20
|
placement: Placement;
|
21
|
-
|
21
|
+
containingBlock?: Element;
|
22
|
+
get size(): 'small' | 'large';
|
23
|
+
set size(size: 'small' | 'large');
|
22
24
|
connectedCallback(): void;
|
25
|
+
createRenderRoot(): ShadowRoot;
|
23
26
|
disconnectedCallback(): void;
|
24
27
|
firstUpdated(): void;
|
25
28
|
focus(): void;
|
26
29
|
render(): import("lit").TemplateResult<1>;
|
30
|
+
setContainingBlock(containingBlock: Element): void;
|
31
|
+
private isTargetDisabled;
|
27
32
|
}
|
package/dist/menu.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
var __decorate=this&&this.__decorate||function(t,e,i,o){var n,s=arguments.length,l=s<3?e:null===o?o=Object.getOwnPropertyDescriptor(e,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(t,e,i,o);else for(var a=t.length-1;a>=0;a--)(n=t[a])&&(l=(s<3?n(l):s>3?n(e,i,l):n(e,i))||l);return s>3&&l&&Object.defineProperty(e,i,l),l};import{LitElement,html}from"lit";import{autoUpdate,computePosition,flip,offset,platform}from"@floating-ui/dom";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{offsetParent}from"composed-offset-position";import{owSlot,owSlotType}from"./library/ow.js";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import GlideCoreMenuOptions from"./menu.options.js";import styles from"./menu.styles.js";let GlideCoreMenu=class GlideCoreMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.isTargetDisabled=!1,this.#t=createRef(),this.#e=createRef(),this.#i=!1,this.#o=!1,this.#n="large",this.#s=createRef(),this.#l=t=>{t.target&&this.contains(t.target)||(this.open=!1,this.#a&&(this.#a.ariaActivedescendant=""))}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get open(){return this.#o}set open(t){this.#o=t,t&&!this.isTargetDisabled&&this.#a?(this.#r(),this.#a.ariaActivedescendant=this.#c?.id??""):this.#a&&(this.#p?.(),this.#a.ariaActivedescendant=""),this.#h&&(this.#h.ariaExpanded=t&&!this.isTargetDisabled?"true":"false")}get size(){return this.#n}set size(t){this.#n=t,this.#a&&(this.#a.privateSize=t)}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#l,{capture:!0})}createRenderRoot(){return this.#d=super.createRenderRoot(),this.#d}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.#l,{capture:!0})}firstUpdated(){owSlot(this.#e.value),owSlot(this.#s.value),owSlotType(this.#e.value,[GlideCoreMenuOptions]);const t=this.#m?.at(0);this.open&&t&&this.#a&&(this.#r(),t.privateActive=!0,this.#a.ariaActivedescendant=t.id)}focus(){this.#h&&"focus"in this.#h&&this.#h?.focus()}render(){return html`<div class="component" @focusout="${this.#f}" ${ref(this.#t)}><slot class="target-slot" name="target" @click="${this.#u}" @keydown="${this.#E}" @slotchange="${this.#g}" ${ref(this.#s)}></slot><slot class="${classMap({"default-slot":!0,visible:this.open&&!this.isTargetDisabled})}" @click="${this.#v}" @focusin="${this.#S}" @keydown="${this.#E}" @mouseover="${this.#y}" @slotchange="${this.#C}" ${ref(this.#e)}></slot></div>`}setContainingBlock(t){this.containingBlock=t}#p;#t;#e;#i;#o;#d;#n;#s;get#c(){return this.#m?.find((({privateActive:t})=>t))}get#a(){const t=this.#e.value?.assignedElements().at(0);return t||null}#l;#C(){owSlot(this.#e.value),owSlotType(this.#e.value,[GlideCoreMenuOptions]);const t=this.#m?.at(0);t&&(t.privateActive=!0),this.#a&&(this.#a.privateSize=this.size)}#v(){this.open=!1,this.#a&&(this.#a.ariaActivedescendant="")}#S(t){(t.target instanceof GlideCoreMenuButton||t.target instanceof GlideCoreMenuLink)&&this.#c&&this.#a&&(this.#c.privateActive=!1,t.target.privateActive=!0,this.#a.ariaActivedescendant=t.target.id)}#y(t){if(t.target instanceof GlideCoreMenuLink||t.target instanceof GlideCoreMenuButton){if(this.#m)for(const e of this.#m)e.privateActive=e===t.target;this.#a&&(this.#a.ariaActivedescendant=t.target.id)}}#f(t){const e=t.relatedTarget instanceof HTMLElement&&this.#d?.contains(t.relatedTarget),i=t.relatedTarget instanceof HTMLElement&&this.contains(t.relatedTarget);e||i||(this.open=!1)}#E(t){if([" ","Enter","Escape"].includes(t.key)&&this.open&&this.#a)return this.open=!1,this.#a.ariaActivedescendant="",this.focus(),void(this.#i=!0);if([" ","ArrowUp","ArrowDown"].includes(t.key)&&!this.open&&this.#c&&this.#a)return t.preventDefault(),this.open=!0,void(this.#a.ariaActivedescendant=this.#c.id);if(this.open&&this.#c&&this.#m){const e=this.#m.indexOf(this.#c);if("ArrowUp"===t.key&&!t.metaKey){t.preventDefault();const i=this.#m?.at(e-1);return void(i&&0!==e&&this.#a&&(this.#c.privateActive=!1,this.#a.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowDown"===t.key&&!t.metaKey&&this.#a){t.preventDefault();const i=this.#m?.at(e+1);return void(i&&(this.#c.privateActive=!1,this.#a.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowUp"===t.key&&t.metaKey||"Home"===t.key||"PageUp"===t.key){t.preventDefault();const e=this.#m?.at(0);return void(e&&this.#a&&(this.#c.privateActive=!1,this.#a.ariaActivedescendant=e.id,e.privateActive=!0))}if("ArrowDown"===t.key&&t.metaKey||"End"===t.key||"PageDown"===t.key){t.preventDefault();const e=this.#m?.at(-1);return void(e&&this.#a&&(this.#c.privateActive=!1,this.#a.ariaActivedescendant=e.id,e.privateActive=!0))}}}#g(){owSlot(this.#s.value);const t=this.#h&&"disabled"in this.#h&&this.#h.disabled,e=this.#h&&"true"===this.#h.ariaDisabled;this.isTargetDisabled=Boolean(t)||Boolean(e),this.#h&&this.#a&&(this.#h.ariaHasPopup="true",this.#h.ariaExpanded=this.open&&!this.isTargetDisabled?"true":"false",this.#h.id=window.crypto.randomUUID(),this.#h.setAttribute("aria-controls",this.#a.id),this.#a.ariaLabelledby=this.#h.id)}#u(){this.isTargetDisabled||this.#i?this.#i=!1:(this.#h instanceof HTMLElement&&(this.#h.ariaExpanded=this.open?"true":"false"),this.open=!this.open,this.open&&this.#c&&this.#a?this.#a.ariaActivedescendant=this.#c.id:!this.open&&this.#a&&(this.#a.ariaActivedescendant="",this.focus()))}get#m(){const t=this.#e.value?.assignedElements()?.at(0)?.children;if(t)return[...t].filter((t=>t instanceof GlideCoreMenuLink||t instanceof GlideCoreMenuButton))}#r(){this.#h&&this.#e.value&&(this.#p=autoUpdate(this.#h,this.#e.value,(()=>{(async()=>{if(this.#h&&this.#e.value){const{x:t,y:e,placement:i}=await computePosition(this.#h,this.#e.value,{platform:{...platform,getOffsetParent:t=>this.containingBlock??platform.getOffsetParent(t,offsetParent)},placement:this.placement,middleware:[offset({mainAxis:16*Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))}),flip()]});this.#e.value.dataset.placement=i,Object.assign(this.#e.value.style,{left:`${t}px`,top:`${e}px`})}})()})))}get#h(){return this.#s.value?.assignedElements().at(0)}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreMenu.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"placement",void 0),__decorate([state()],GlideCoreMenu.prototype,"containingBlock",void 0),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"size",null),__decorate([state()],GlideCoreMenu.prototype,"isTargetDisabled",void 0),GlideCoreMenu=__decorate([customElement("glide-core-menu")],GlideCoreMenu);export default GlideCoreMenu;
|
package/dist/menu.link.d.ts
CHANGED
package/dist/menu.link.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,o,i){var r,n=arguments.length,l=n<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,o,i);else for(var s=e.length-1;s>=0;s--)(r=e[s])&&(l=(n<3?r(l):n>3?r(t,o,l):r(t,o))||l);return n>3&&l&&Object.defineProperty(t,o,l),l};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{customElement,property}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import styles from"./menu.link.styles.js";let GlideCoreMenuLink=class GlideCoreMenuLink extends LitElement{constructor(){super(...arguments),this.privateActive=!1,this.#e=window.crypto.randomUUID()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}connectedCallback(){super.connectedCallback(),this.id=this.#e,this.role="menuitem",this.tabIndex=-1}render(){return html`<a class="${classMap({component:!0,active:this.privateActive})}" data-test="component" href="${ifDefined(this.url)}"><slot name="icon"></slot>${this.label}</a>`}#e};__decorate([property({reflect:!0})],GlideCoreMenuLink.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreMenuLink.prototype,"url",void 0),__decorate([property({type:Boolean})],GlideCoreMenuLink.prototype,"privateActive",void 0),GlideCoreMenuLink=__decorate([customElement("glide-core-menu-link")],GlideCoreMenuLink);export default GlideCoreMenuLink;
|
package/dist/menu.link.styles.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
import{css}from"lit";export default[css`
|
2
2
|
.component {
|
3
3
|
align-items: center;
|
4
4
|
background-color: transparent;
|
@@ -15,8 +15,8 @@
|
|
15
15
|
text-decoration: none;
|
16
16
|
user-select: none;
|
17
17
|
|
18
|
-
&.
|
18
|
+
&.active {
|
19
19
|
background-color: var(--glide-core-surface-hover);
|
20
20
|
}
|
21
21
|
}
|
22
|
-
`];
|
22
|
+
`];
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
2
|
+
import GlideCoreMenuLink from './menu.link.js';
|
3
|
+
GlideCoreMenuLink.shadowRootOptions.mode = 'open';
|
4
|
+
it('registers', async () => {
|
5
|
+
expect(window.customElements.get('glide-core-menu-link')).to.equal(GlideCoreMenuLink);
|
6
|
+
});
|
7
|
+
it('has defaults', async () => {
|
8
|
+
// Required attributes are supplied and not asserted below. The idea is that
|
9
|
+
// this test shouldn't fail to typecheck if these templates are eventually
|
10
|
+
// typechecked, which means supplying required attributes up front.
|
11
|
+
const component = await fixture(html `<glide-core-menu-link label="Label" url="/"></glide-core-menu-link>`);
|
12
|
+
// Not reflected. So no attribute assertions are necessary.
|
13
|
+
expect(component.privateActive).to.be.false;
|
14
|
+
});
|
15
|
+
it('can have a label', async () => {
|
16
|
+
const component = await fixture(html `<glide-core-menu-link label="Label" url="/"></glide-core-menu-link>`);
|
17
|
+
expect(component.shadowRoot?.textContent?.trim()).to.equal('Label');
|
18
|
+
});
|
19
|
+
it('can have a URL', async () => {
|
20
|
+
const component = await fixture(html `<glide-core-menu-link label="Label" url="/"></glide-core-menu-link>`);
|
21
|
+
expect(component.url).to.equal('/');
|
22
|
+
});
|
23
|
+
it('can have an icon', async () => {
|
24
|
+
const component = await fixture(html `<glide-core-menu-link label="Label">
|
25
|
+
<svg
|
26
|
+
slot="icon"
|
27
|
+
width="16"
|
28
|
+
height="16"
|
29
|
+
fill="none"
|
30
|
+
viewBox="0 0 24 24"
|
31
|
+
stroke-width="1.5"
|
32
|
+
stroke="currentColor"
|
33
|
+
>
|
34
|
+
<path
|
35
|
+
stroke-linecap="round"
|
36
|
+
stroke-linejoin="round"
|
37
|
+
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"
|
38
|
+
/>
|
39
|
+
</svg>
|
40
|
+
</glide-core-menu-link>`);
|
41
|
+
const icon = component?.shadowRoot
|
42
|
+
?.querySelector('slot[name="icon"]')
|
43
|
+
?.assignedElements()
|
44
|
+
.at(0);
|
45
|
+
expect(icon instanceof Element).to.be.true;
|
46
|
+
});
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { LitElement } from 'lit';
|
2
|
+
declare global {
|
3
|
+
interface HTMLElementTagNameMap {
|
4
|
+
'glide-core-menu-options': GlideCoreMenuOptions;
|
5
|
+
}
|
6
|
+
}
|
7
|
+
/**
|
8
|
+
* @description An options container for use within a <glide-core-menu>.
|
9
|
+
*
|
10
|
+
* @slot - One or more of <glide-core-menu-link> or <glide-core-menu-button>.
|
11
|
+
*/
|
12
|
+
export default class GlideCoreMenuOptions extends LitElement {
|
13
|
+
#private;
|
14
|
+
static shadowRootOptions: ShadowRootInit;
|
15
|
+
static styles: import("lit").CSSResult[];
|
16
|
+
ariaActivedescendant: string;
|
17
|
+
ariaLabelledby: string;
|
18
|
+
privateSize: 'small' | 'large';
|
19
|
+
connectedCallback(): void;
|
20
|
+
firstUpdated(): void;
|
21
|
+
render(): import("lit").TemplateResult<1>;
|
22
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,o,i){var l,r=arguments.length,n=r<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,o,i);else for(var s=e.length-1;s>=0;s--)(l=e[s])&&(n=(r<3?l(n):r>3?l(t,o,n):l(t,o))||n);return r>3&&n&&Object.defineProperty(t,o,n),n};import{LitElement,html}from"lit";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{owSlot,owSlotType}from"./library/ow.js";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import styles from"./menu.options.styles.js";let GlideCoreMenuOptions=class GlideCoreMenuOptions extends LitElement{constructor(){super(...arguments),this.ariaActivedescendant="",this.ariaLabelledby="",this.privateSize="large",this.#e=createRef(),this.#t=window.crypto.randomUUID()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}connectedCallback(){super.connectedCallback(),this.id=this.#t,this.role="menu",this.tabIndex=-1}firstUpdated(){owSlot(this.#e.value),owSlotType(this.#e.value,[GlideCoreMenuButton,GlideCoreMenuLink,Text])}render(){return html`<div class="${classMap({component:!0,large:"large"===this.privateSize,small:"small"===this.privateSize})}" role="none"><slot @slotchange="${this.#o}" ${ref(this.#e)}></slot></div>`}#e;#t;#o(){owSlot(this.#e.value),owSlotType(this.#e.value,[GlideCoreMenuButton,GlideCoreMenuLink,Text])}};__decorate([property({attribute:"aria-activedescendant",reflect:!0})],GlideCoreMenuOptions.prototype,"ariaActivedescendant",void 0),__decorate([property({attribute:"aria-labelledby",reflect:!0})],GlideCoreMenuOptions.prototype,"ariaLabelledby",void 0),__decorate([state()],GlideCoreMenuOptions.prototype,"privateSize",void 0),GlideCoreMenuOptions=__decorate([customElement("glide-core-menu-options")],GlideCoreMenuOptions);export default GlideCoreMenuOptions;
|