@crowdstrike/glide-core 0.7.0 → 0.9.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 +44 -5
- package/dist/accordion.test.basics.js +1 -0
- package/dist/accordion.test.events.js +1 -0
- package/dist/button-group.button.d.ts +14 -15
- package/dist/button-group.button.js +1 -1
- package/dist/button-group.button.styles.js +75 -52
- package/dist/button-group.button.test.basics.d.ts +1 -1
- package/dist/button-group.button.test.basics.js +84 -147
- package/dist/button-group.button.test.events.js +9 -67
- package/dist/button-group.button.test.focus.js +13 -0
- package/dist/button-group.button.test.interactions.d.ts +1 -0
- package/dist/button-group.button.test.interactions.js +42 -0
- package/dist/button-group.d.ts +7 -10
- package/dist/button-group.js +1 -1
- package/dist/button-group.stories.d.ts +1 -5
- package/dist/button-group.styles.js +18 -6
- package/dist/button-group.test.basics.js +114 -234
- package/dist/button-group.test.events.js +211 -263
- package/dist/button-group.test.focus.d.ts +1 -0
- package/dist/button-group.test.focus.js +39 -0
- package/dist/button-group.test.interactions.d.ts +1 -0
- package/dist/button-group.test.interactions.js +91 -0
- package/dist/button.test.basics.js +2 -1
- package/dist/button.test.events.js +1 -0
- package/dist/button.test.form.js +1 -0
- package/dist/checkbox-group.js +1 -1
- package/dist/checkbox-group.styles.js +1 -1
- package/dist/checkbox-group.test.basics.js +2 -1
- package/dist/checkbox-group.test.events.js +5 -4
- package/dist/checkbox-group.test.focus.js +5 -3
- package/dist/checkbox-group.test.form.js +1 -0
- package/dist/checkbox-group.test.validity.js +1 -0
- package/dist/checkbox.d.ts +7 -1
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.styles.js +11 -3
- package/dist/checkbox.test.basics.js +1 -0
- package/dist/checkbox.test.events.js +5 -4
- package/dist/checkbox.test.focus.js +2 -2
- package/dist/checkbox.test.form.js +1 -0
- package/dist/{checkbox.test.states.js → checkbox.test.interactions.js} +25 -1
- package/dist/checkbox.test.validity.js +1 -0
- package/dist/drawer.js +1 -1
- package/dist/drawer.test.basics.js +1 -0
- package/dist/drawer.test.closing.js +1 -0
- package/dist/drawer.test.events.js +1 -0
- package/dist/drawer.test.methods.js +1 -0
- package/dist/dropdown.d.ts +6 -4
- package/dist/dropdown.js +1 -1
- package/dist/dropdown.option.d.ts +7 -2
- package/dist/dropdown.option.js +1 -1
- package/dist/dropdown.option.styles.js +13 -0
- package/dist/dropdown.option.test.basics.js +7 -3
- package/dist/dropdown.option.test.basics.multiple.js +1 -0
- package/dist/dropdown.option.test.basics.single.js +1 -0
- package/dist/dropdown.option.test.events.js +2 -1
- package/dist/dropdown.option.test.focus.js +1 -1
- package/dist/dropdown.option.test.interactions.multiple.js +2 -54
- package/dist/dropdown.option.test.interactions.single.js +52 -9
- package/dist/dropdown.styles.js +20 -19
- package/dist/dropdown.test.basics.filterable.js +1 -0
- package/dist/dropdown.test.basics.js +144 -2
- package/dist/dropdown.test.basics.multiple.js +6 -3
- package/dist/dropdown.test.basics.single.js +1 -1
- package/dist/dropdown.test.events.filterable.js +74 -0
- package/dist/dropdown.test.events.js +50 -160
- package/dist/dropdown.test.events.multiple.js +268 -10
- package/dist/dropdown.test.events.single.js +202 -4
- package/dist/dropdown.test.focus.filterable.js +9 -5
- package/dist/dropdown.test.focus.js +2 -1
- package/dist/dropdown.test.focus.multiple.js +1 -2
- package/dist/dropdown.test.focus.single.js +1 -1
- package/dist/dropdown.test.form.js +1 -0
- package/dist/dropdown.test.form.multiple.js +1 -0
- package/dist/dropdown.test.form.single.js +1 -0
- package/dist/dropdown.test.interactions.filterable.js +69 -11
- package/dist/dropdown.test.interactions.js +95 -5
- package/dist/dropdown.test.interactions.multiple.js +203 -6
- package/dist/dropdown.test.interactions.single.js +69 -6
- package/dist/dropdown.test.validity.js +1 -0
- package/dist/form-controls-layout.test.basics.js +2 -1
- package/dist/icon-button.test.basics.js +2 -1
- package/dist/icons/checked.d.ts +1 -1
- package/dist/icons/checked.js +1 -1
- package/dist/icons/magnifying-glass.js +1 -1
- package/dist/input.d.ts +0 -6
- package/dist/input.js +1 -1
- package/dist/input.styles.js +7 -2
- package/dist/input.test.basics.js +20 -5
- package/dist/input.test.events.js +5 -4
- package/dist/input.test.focus.js +5 -4
- package/dist/input.test.form.js +1 -0
- package/dist/input.test.translations.d.ts +1 -0
- package/dist/input.test.translations.js +38 -0
- package/dist/input.test.validity.js +134 -4
- package/dist/label.d.ts +1 -1
- package/dist/label.js +1 -1
- package/dist/label.styles.js +29 -20
- package/dist/label.test.basics.js +27 -24
- package/dist/library/expect-argument-error.js +1 -1
- package/dist/library/localize.d.ts +5 -1
- package/dist/library/ow.test.d.ts +2 -1
- package/dist/library/ow.test.js +8 -3
- package/dist/menu.button.test.basics.js +1 -0
- package/dist/menu.d.ts +3 -5
- package/dist/menu.js +1 -1
- package/dist/menu.link.test.basics.js +1 -0
- package/dist/menu.options.test.basics.js +3 -2
- package/dist/menu.styles.js +1 -15
- package/dist/menu.test.basics.d.ts +1 -2
- package/dist/menu.test.basics.js +23 -6
- package/dist/menu.test.events.d.ts +1 -0
- package/dist/menu.test.events.js +2 -1
- package/dist/menu.test.focus.d.ts +1 -0
- package/dist/menu.test.focus.js +14 -6
- package/dist/menu.test.interactions.js +213 -56
- package/dist/modal.icon-button.test.basics.js +2 -1
- package/dist/modal.js +1 -1
- package/dist/modal.styles.js +18 -13
- package/dist/modal.tertiary-icon.d.ts +0 -1
- package/dist/modal.tertiary-icon.js +1 -1
- package/dist/modal.tertiary-icon.test.basics.js +2 -1
- package/dist/modal.test.accessibility.js +1 -0
- package/dist/modal.test.basics.js +2 -1
- package/dist/modal.test.close.js +1 -0
- package/dist/modal.test.events.js +11 -10
- package/dist/modal.test.lock-scroll.js +1 -0
- package/dist/modal.test.methods.js +1 -0
- package/dist/modal.test.scrollbars.js +1 -0
- package/dist/radio-group.js +1 -1
- package/dist/radio-group.styles.js +1 -1
- package/dist/radio-group.test.basics.js +1 -0
- package/dist/radio-group.test.events.js +1 -0
- package/dist/radio-group.test.focus.js +4 -3
- package/dist/radio-group.test.form.js +1 -0
- package/dist/radio-group.test.validity.js +1 -0
- package/dist/radio.d.ts +1 -0
- package/dist/radio.js +1 -1
- package/dist/radio.styles.js +33 -0
- package/dist/split-button.test.basics.js +1 -0
- package/dist/split-container.test.basics.js +5 -0
- package/dist/split-link.test.basics.js +1 -0
- package/dist/split-link.test.interactions.js +2 -1
- package/dist/styles/variables.css +1 -1
- package/dist/tab.d.ts +1 -3
- package/dist/tab.group.d.ts +3 -5
- package/dist/tab.group.js +1 -1
- package/dist/tab.group.styles.js +27 -13
- package/dist/tab.group.test.basics.js +8 -57
- package/dist/tab.group.test.interactions.d.ts +3 -0
- package/dist/tab.group.test.interactions.js +454 -0
- package/dist/tab.js +1 -1
- package/dist/tab.panel.d.ts +1 -0
- package/dist/tab.panel.js +1 -1
- package/dist/tab.panel.styles.js +11 -1
- package/dist/tab.styles.js +7 -68
- package/dist/tab.test.basics.js +0 -20
- package/dist/tabs.stories.d.ts +1 -2
- package/dist/tag.test.basics.js +3 -2
- package/dist/textarea.d.ts +0 -1
- package/dist/textarea.js +2 -2
- package/dist/textarea.stories.d.ts +3 -4
- package/dist/textarea.styles.js +14 -3
- package/dist/textarea.test.basics.js +81 -44
- package/dist/textarea.test.events.js +57 -41
- package/dist/textarea.test.form.js +1 -0
- package/dist/textarea.test.translations.d.ts +1 -0
- package/dist/textarea.test.translations.js +34 -0
- package/dist/textarea.test.validity.js +105 -20
- package/dist/toasts.js +1 -1
- package/dist/toasts.styles.js +8 -1
- package/dist/toasts.test.basics.js +20 -0
- package/dist/toggle.js +1 -1
- package/dist/toggle.test.basics.js +1 -0
- package/dist/toggle.test.events.js +1 -0
- package/dist/toggle.test.focus.js +1 -1
- package/dist/toggle.test.interactions.d.ts +1 -0
- package/dist/{toggle.test.states.js → toggle.test.interactions.js} +1 -0
- package/dist/tooltip.d.ts +7 -5
- package/dist/tooltip.js +1 -1
- package/dist/tooltip.styles.js +90 -25
- package/dist/tooltip.test.basics.js +39 -3
- package/dist/tooltip.test.interactions.js +137 -34
- package/dist/translations/en.js +1 -1
- package/dist/translations/fr.js +1 -1
- package/dist/translations/ja.js +1 -1
- package/dist/tree.d.ts +0 -1
- package/dist/tree.item.d.ts +2 -3
- package/dist/tree.item.js +1 -1
- package/dist/tree.item.menu.d.ts +0 -1
- package/dist/tree.item.menu.js +1 -1
- package/dist/tree.item.test.basics.js +1 -0
- package/dist/tree.js +1 -1
- package/dist/tree.test.basics.js +2 -1
- package/dist/tree.test.events.js +1 -1
- package/package.json +40 -29
- package/dist/drawer.test.floating-components.d.ts +0 -1
- package/dist/drawer.test.floating-components.js +0 -51
- package/dist/library/set-containing-block.d.ts +0 -15
- package/dist/library/set-containing-block.js +0 -1
- package/dist/modal.test.floating-components.js +0 -62
- /package/dist/{checkbox.test.states.d.ts → button-group.button.test.focus.d.ts} +0 -0
- /package/dist/{modal.test.floating-components.d.ts → checkbox.test.interactions.d.ts} +0 -0
- /package/dist/{toggle.test.states.d.ts → dropdown.test.events.filterable.d.ts} +0 -0
package/dist/tooltip.styles.js
CHANGED
@@ -1,7 +1,26 @@
|
|
1
1
|
import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
|
2
|
+
@keyframes tooltip {
|
3
|
+
from {
|
4
|
+
opacity: 0;
|
5
|
+
transform: scale(0.95);
|
6
|
+
}
|
7
|
+
|
8
|
+
to {
|
9
|
+
opacity: 1;
|
10
|
+
transform: scale(1);
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
:host {
|
15
|
+
display: inline-block;
|
16
|
+
}
|
17
|
+
|
2
18
|
.component {
|
3
19
|
/* https://github.com/CrowdStrike/glide-core/pull/119#issuecomment-2113314591 */
|
4
20
|
display: flex;
|
21
|
+
|
22
|
+
/* https://css-tricks.com/flexbox-truncated-text/#aa-the-solution-is-min-width-0-on-the-flex-child */
|
23
|
+
min-inline-size: 0;
|
5
24
|
position: relative;
|
6
25
|
}
|
7
26
|
|
@@ -9,10 +28,13 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
9
28
|
background-color: transparent;
|
10
29
|
border-width: 0;
|
11
30
|
|
12
|
-
/*
|
31
|
+
/*
|
32
|
+
Additional whitespace from line height and the tooltip won't be vertically
|
33
|
+
centered against its target.
|
34
|
+
*/
|
13
35
|
display: flex;
|
14
36
|
|
15
|
-
/* Allows the consumer to style the target
|
37
|
+
/* Allows the consumer to style the target with an ellipsis when its text is truncated. */
|
16
38
|
inline-size: 100%;
|
17
39
|
padding: 0;
|
18
40
|
position: relative;
|
@@ -31,22 +53,11 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
31
53
|
}
|
32
54
|
|
33
55
|
.tooltip {
|
34
|
-
background-color:
|
35
|
-
border
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
font-style: var(--glide-core-body-md-font-style);
|
40
|
-
font-weight: var(--glide-core-body-md-font-weight);
|
41
|
-
inline-size: max-content;
|
42
|
-
inset-block-start: 50%;
|
43
|
-
inset-block-start: 0;
|
44
|
-
inset-inline-start: 0;
|
45
|
-
max-inline-size: 11.25rem;
|
46
|
-
overflow-wrap: break-word;
|
47
|
-
padding: var(--glide-core-spacing-xs) var(--glide-core-spacing-sm);
|
48
|
-
position: fixed;
|
49
|
-
z-index: 1;
|
56
|
+
background-color: transparent;
|
57
|
+
border: none;
|
58
|
+
inset: unset;
|
59
|
+
padding: 0;
|
60
|
+
position: absolute;
|
50
61
|
|
51
62
|
::slotted(kbd) {
|
52
63
|
color: var(--glide-core-text-header-2);
|
@@ -56,16 +67,70 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
56
67
|
white-space: nowrap;
|
57
68
|
}
|
58
69
|
|
59
|
-
|
60
|
-
|
70
|
+
&:popover-open {
|
71
|
+
animation: tooltip 250ms cubic-bezier(0.25, 0, 0.3, 1);
|
72
|
+
display: flex;
|
73
|
+
|
74
|
+
/*
|
75
|
+
Elements with a "popover" attribute don't allow overflow. So the arrow can't
|
76
|
+
be positioned with "position: absolute". Relative positioning is used instead.
|
77
|
+
Flex is used to get the arrow on the correct side of the tooltip. Floating UI
|
78
|
+
handles the rest.
|
79
|
+
|
80
|
+
A simple "transform" could replace Floating UI for the arrow if not for a Chrome
|
81
|
+
bug with "popover" when "scale()" is animated on the popover or a container within
|
82
|
+
it. With "transform" on the arrow, the arrow is initially offset by a couple pixels
|
83
|
+
before landing in the correct position when the animation finishes. It only happens
|
84
|
+
when the tooltip is left or right of its target.
|
85
|
+
*/
|
86
|
+
|
87
|
+
&.top {
|
88
|
+
flex-direction: column-reverse;
|
89
|
+
}
|
90
|
+
|
91
|
+
&.right {
|
92
|
+
flex-direction: row-reverse;
|
93
|
+
}
|
94
|
+
|
95
|
+
&.bottom {
|
96
|
+
flex-direction: column;
|
97
|
+
}
|
61
98
|
}
|
62
99
|
}
|
63
100
|
|
64
101
|
.arrow {
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
102
|
+
--arrow-height: 0.375rem;
|
103
|
+
--arrow-width: 0.625rem;
|
104
|
+
|
105
|
+
display: flex;
|
106
|
+
position: relative;
|
107
|
+
|
108
|
+
&.top,
|
109
|
+
&.bottom {
|
110
|
+
block-size: var(--arrow-height);
|
111
|
+
inline-size: var(--arrow-width);
|
112
|
+
}
|
113
|
+
|
114
|
+
&.right,
|
115
|
+
&.left {
|
116
|
+
block-size: var(--arrow-width);
|
117
|
+
inline-size: var(--arrow-height);
|
118
|
+
order: 2;
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
.default-slot {
|
123
|
+
background-color: var(--glide-core-surface-base-dark);
|
124
|
+
border-radius: var(--glide-core-spacing-xs);
|
125
|
+
color: var(--glide-core-text-selected);
|
126
|
+
display: block;
|
127
|
+
font-family: var(--glide-core-body-md-font-family);
|
128
|
+
font-style: var(--glide-core-body-md-font-style);
|
129
|
+
font-weight: var(--glide-core-body-md-font-weight);
|
130
|
+
inline-size: max-content;
|
131
|
+
inset-block-start: 50%;
|
132
|
+
max-inline-size: 11.25rem;
|
133
|
+
overflow-wrap: break-word;
|
134
|
+
padding: var(--glide-core-spacing-xs) var(--glide-core-spacing-sm);
|
70
135
|
}
|
71
136
|
`];
|
@@ -1,6 +1,7 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
1
2
|
import './tooltip.js';
|
2
3
|
import { ArgumentError } from 'ow';
|
3
|
-
import { expect, fixture, html } from '@open-wc/testing';
|
4
|
+
import { aTimeout, expect, fixture, html } from '@open-wc/testing';
|
4
5
|
import GlideCoreTooltip from './tooltip.js';
|
5
6
|
import sinon from 'sinon';
|
6
7
|
GlideCoreTooltip.shadowRootOptions.mode = 'open';
|
@@ -17,6 +18,31 @@ it('is accessible', async () => {
|
|
17
18
|
ignoredRules: ['aria-tooltip-name'],
|
18
19
|
});
|
19
20
|
});
|
21
|
+
it('has defaults', async () => {
|
22
|
+
const component = await fixture(html `<glide-core-tooltip>
|
23
|
+
Tooltip
|
24
|
+
<span slot="target" tabindex="0">Target</span>
|
25
|
+
</glide-core-tooltip>`);
|
26
|
+
const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
27
|
+
// Wait for Floating UI.
|
28
|
+
await aTimeout(0);
|
29
|
+
expect(component.offset).to.equal(4);
|
30
|
+
expect(component.open).to.be.false;
|
31
|
+
expect(component.placement).to.be.be.undefined;
|
32
|
+
expect(component.disabled).to.be.false;
|
33
|
+
expect(component.hasAttribute('disabled')).to.be.false;
|
34
|
+
expect(tooltip?.checkVisibility()).to.be.false;
|
35
|
+
});
|
36
|
+
it('can be open', async () => {
|
37
|
+
const component = await fixture(html `<glide-core-tooltip aria-label="Label" open>
|
38
|
+
Tooltip
|
39
|
+
<span slot="target" tabindex="0">Target</span>
|
40
|
+
</glide-core-tooltip>`);
|
41
|
+
const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
42
|
+
// Wait for Floating UI.
|
43
|
+
await aTimeout(0);
|
44
|
+
expect(tooltip?.checkVisibility()).to.be.true;
|
45
|
+
});
|
20
46
|
it('can have a tooltip', async () => {
|
21
47
|
const component = await fixture(html `<glide-core-tooltip aria-label="Label">
|
22
48
|
Tooltip
|
@@ -38,6 +64,16 @@ it('can have a target', async () => {
|
|
38
64
|
?.assignedElements();
|
39
65
|
expect(assignedElements?.at(0)?.textContent).to.equal('Target');
|
40
66
|
});
|
67
|
+
it('does not open when disabled', async () => {
|
68
|
+
const component = await fixture(html `<glide-core-tooltip aria-label="Label" open disabled>
|
69
|
+
Tooltip
|
70
|
+
<span slot="target" tabindex="0">Target</span>
|
71
|
+
</glide-core-tooltip>`);
|
72
|
+
const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
73
|
+
// Wait for Floating UI.
|
74
|
+
await aTimeout(0);
|
75
|
+
expect(tooltip?.checkVisibility()).to.be.false;
|
76
|
+
});
|
41
77
|
it('throws if it does not have a default slot', async () => {
|
42
78
|
const spy = sinon.spy();
|
43
79
|
try {
|
@@ -48,7 +84,7 @@ it('throws if it does not have a default slot', async () => {
|
|
48
84
|
spy();
|
49
85
|
}
|
50
86
|
}
|
51
|
-
expect(spy.
|
87
|
+
expect(spy.callCount).to.equal(1);
|
52
88
|
});
|
53
89
|
it('throws if it does not have a "target" slot', async () => {
|
54
90
|
const spy = sinon.spy();
|
@@ -60,5 +96,5 @@ it('throws if it does not have a "target" slot', async () => {
|
|
60
96
|
spy();
|
61
97
|
}
|
62
98
|
}
|
63
|
-
expect(spy.
|
99
|
+
expect(spy.callCount).to.equal(1);
|
64
100
|
});
|
@@ -1,19 +1,68 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
1
2
|
import './tooltip.js';
|
2
|
-
import {
|
3
|
+
import { aTimeout, assert, expect, fixture, html } from '@open-wc/testing';
|
3
4
|
import { sendKeys } from '@web/test-runner-commands';
|
4
5
|
import GlideCoreTooltip from './tooltip.js';
|
5
|
-
import sinon from 'sinon';
|
6
6
|
GlideCoreTooltip.shadowRootOptions.mode = 'open';
|
7
|
+
it('is open when opened programmatically', async () => {
|
8
|
+
const component = await fixture(html `<glide-core-tooltip aria-label="Label">
|
9
|
+
Tooltip
|
10
|
+
<span slot="target" tabindex="0">Target</span>
|
11
|
+
</glide-core-tooltip>`);
|
12
|
+
component.open = true;
|
13
|
+
// Wait for Floating UI.
|
14
|
+
await aTimeout(0);
|
15
|
+
const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
16
|
+
expect(tooltip?.checkVisibility()).to.be.true;
|
17
|
+
});
|
18
|
+
it('is open when `open` and enabled programmatically', async () => {
|
19
|
+
const component = await fixture(html `<glide-core-tooltip aria-label="Label" open disabled>
|
20
|
+
Tooltip
|
21
|
+
<span slot="target" tabindex="0">Target</span>
|
22
|
+
</glide-core-tooltip>`);
|
23
|
+
component.disabled = false;
|
24
|
+
// Wait for Floating UI.
|
25
|
+
await aTimeout(0);
|
26
|
+
const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
27
|
+
expect(tooltip?.checkVisibility()).to.be.true;
|
28
|
+
});
|
29
|
+
it('is not open when `open` and disabled programmatically', async () => {
|
30
|
+
const component = await fixture(html `<glide-core-tooltip aria-label="Label" open>
|
31
|
+
Tooltip
|
32
|
+
<span slot="target" tabindex="0">Target</span>
|
33
|
+
</glide-core-tooltip>`);
|
34
|
+
// Wait for Floating UI.
|
35
|
+
await aTimeout(0);
|
36
|
+
component.disabled = true;
|
37
|
+
// Wait for Floating UI.
|
38
|
+
await aTimeout(0);
|
39
|
+
const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
40
|
+
expect(tooltip?.checkVisibility()).to.be.false;
|
41
|
+
});
|
42
|
+
it('is not open when opened programmatically and disabled', async () => {
|
43
|
+
const component = await fixture(html `<glide-core-tooltip aria-label="Label" disabled>
|
44
|
+
Tooltip
|
45
|
+
<span slot="target" tabindex="0">Target</span>
|
46
|
+
</glide-core-tooltip>`);
|
47
|
+
component.open = true;
|
48
|
+
// Wait for Floating UI.
|
49
|
+
await aTimeout(0);
|
50
|
+
const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
51
|
+
expect(tooltip?.checkVisibility()).to.be.false;
|
52
|
+
});
|
7
53
|
it('is visible on "focusin"', async () => {
|
8
54
|
const component = await fixture(html `<glide-core-tooltip>
|
9
55
|
Tooltip
|
10
56
|
<span slot="target" tabindex="0">Target</span>
|
11
57
|
</glide-core-tooltip>`);
|
12
58
|
component.shadowRoot
|
13
|
-
?.querySelector('[
|
59
|
+
?.querySelector('[data-test="target"]')
|
14
60
|
?.dispatchEvent(new FocusEvent('focusin'));
|
15
|
-
|
16
|
-
|
61
|
+
// Wait for Floating UI.
|
62
|
+
await aTimeout(0);
|
63
|
+
expect(component.shadowRoot
|
64
|
+
?.querySelector('[data-test="tooltip"]')
|
65
|
+
?.checkVisibility()).to.be.true;
|
17
66
|
});
|
18
67
|
it('is hidden on "focusin" when disabled', async () => {
|
19
68
|
const component = await fixture(html `<glide-core-tooltip disabled>
|
@@ -21,25 +70,27 @@ it('is hidden on "focusin" when disabled', async () => {
|
|
21
70
|
<span slot="target" tabindex="0">Target</span>
|
22
71
|
</glide-core-tooltip>`);
|
23
72
|
component.shadowRoot
|
24
|
-
?.querySelector('[
|
73
|
+
?.querySelector('[data-test="target"]')
|
25
74
|
?.dispatchEvent(new FocusEvent('focusin'));
|
26
|
-
|
27
|
-
|
75
|
+
// Wait for Floating UI.
|
76
|
+
await aTimeout(0);
|
77
|
+
expect(component.shadowRoot
|
78
|
+
?.querySelector('[data-test="tooltip"]')
|
79
|
+
?.checkVisibility()).to.be.false;
|
28
80
|
});
|
29
81
|
it('is hidden on "blur"', async () => {
|
30
82
|
const component = await fixture(html `<glide-core-tooltip>
|
31
83
|
Tooltip
|
32
84
|
<span slot="target" tabindex="0">Target</span>
|
33
85
|
</glide-core-tooltip>`);
|
34
|
-
component.shadowRoot
|
35
|
-
|
36
|
-
|
37
|
-
await
|
38
|
-
|
39
|
-
|
40
|
-
?.
|
41
|
-
|
42
|
-
expect(component.shadowRoot?.querySelector('[role="tooltip"]')?.checkVisibility()).to.be.false;
|
86
|
+
const target = component.shadowRoot?.querySelector('[data-test="target"]');
|
87
|
+
target?.dispatchEvent(new FocusEvent('focusin'));
|
88
|
+
// Wait for Floating UI.
|
89
|
+
await aTimeout(0);
|
90
|
+
target?.dispatchEvent(new FocusEvent('focusout'));
|
91
|
+
expect(component.shadowRoot
|
92
|
+
?.querySelector('[data-test="tooltip"]')
|
93
|
+
?.checkVisibility()).to.be.false;
|
43
94
|
});
|
44
95
|
it('is hidden on Escape', async () => {
|
45
96
|
const component = await fixture(html `<glide-core-tooltip>
|
@@ -47,54 +98,106 @@ it('is hidden on Escape', async () => {
|
|
47
98
|
<span slot="target" tabindex="0">Target</span>
|
48
99
|
</glide-core-tooltip>`);
|
49
100
|
component.shadowRoot
|
50
|
-
?.querySelector('[
|
101
|
+
?.querySelector('[data-test="target"]')
|
51
102
|
?.dispatchEvent(new FocusEvent('focusin'));
|
52
|
-
|
53
|
-
|
54
|
-
// clear why `component.focus()` doesn't focus the span when using
|
55
|
-
// Playwright.
|
103
|
+
// Wait for Floating UI.
|
104
|
+
await aTimeout(0);
|
56
105
|
component.querySelector('span')?.focus();
|
57
106
|
await sendKeys({ press: 'Escape' });
|
58
|
-
|
59
|
-
|
107
|
+
expect(component.shadowRoot
|
108
|
+
?.querySelector('[data-test="tooltip"]')
|
109
|
+
?.checkVisibility()).to.be.false;
|
60
110
|
});
|
61
111
|
it('is visible on "mouseover"', async () => {
|
62
112
|
const component = await fixture(html `<glide-core-tooltip>
|
63
113
|
Tooltip
|
64
114
|
<span slot="target" tabindex="0">Target</span>
|
65
115
|
</glide-core-tooltip>`);
|
116
|
+
const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
117
|
+
assert(tooltip);
|
118
|
+
tooltip.dataset.openDelay = '0';
|
66
119
|
component.shadowRoot
|
67
120
|
?.querySelector('.component')
|
68
121
|
?.dispatchEvent(new MouseEvent('mouseover'));
|
69
|
-
|
70
|
-
|
122
|
+
// Wait for Floating UI and the open delay.
|
123
|
+
await aTimeout(0);
|
124
|
+
expect(tooltip.checkVisibility()).to.be.true;
|
71
125
|
});
|
72
126
|
it('is hidden on "mouseover" when disabled', async () => {
|
73
127
|
const component = await fixture(html `<glide-core-tooltip disabled>
|
74
128
|
Tooltip
|
75
129
|
<span slot="target" tabindex="0">Target</span>
|
76
130
|
</glide-core-tooltip>`);
|
131
|
+
const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
132
|
+
assert(tooltip);
|
133
|
+
tooltip.dataset.openDelay = '0';
|
77
134
|
component.shadowRoot
|
78
135
|
?.querySelector('.component')
|
79
136
|
?.dispatchEvent(new MouseEvent('mouseover'));
|
80
|
-
|
81
|
-
|
137
|
+
// Wait for Floating UI.
|
138
|
+
await aTimeout(0);
|
139
|
+
expect(tooltip.checkVisibility()).to.be.false;
|
82
140
|
});
|
83
141
|
it('is hidden on "mouseout"', async () => {
|
84
|
-
const clock = sinon.useFakeTimers();
|
85
142
|
const component = await fixture(html `<glide-core-tooltip>
|
86
143
|
Tooltip
|
87
144
|
<span slot="target" tabindex="0">Target</span>
|
88
145
|
</glide-core-tooltip>`);
|
146
|
+
const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
147
|
+
assert(tooltip);
|
148
|
+
tooltip.dataset.openDelay = '0';
|
149
|
+
component.shadowRoot
|
150
|
+
?.querySelector('.component')
|
151
|
+
?.dispatchEvent(new MouseEvent('mouseover'));
|
152
|
+
// Wait for Floating UI and the open delay.
|
153
|
+
await aTimeout(0);
|
154
|
+
tooltip.dataset.closeDelay = '0';
|
155
|
+
component.shadowRoot
|
156
|
+
?.querySelector('.component')
|
157
|
+
?.dispatchEvent(new MouseEvent('mouseout'));
|
158
|
+
// Wait for the close delay.
|
159
|
+
await aTimeout(0);
|
160
|
+
expect(tooltip.checkVisibility()).to.be.false;
|
161
|
+
});
|
162
|
+
it('remains hidden if "mouseout" fires before the "mouseover" delay', async () => {
|
163
|
+
const component = await fixture(html `<glide-core-tooltip>
|
164
|
+
Tooltip
|
165
|
+
<span slot="target" tabindex="0">Target</span>
|
166
|
+
</glide-core-tooltip>`);
|
167
|
+
const tooltip = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
168
|
+
assert(tooltip);
|
169
|
+
tooltip.dataset.openDelay = '1';
|
170
|
+
tooltip.dataset.closeDelay = '0';
|
89
171
|
component.shadowRoot
|
90
172
|
?.querySelector('.component')
|
91
173
|
?.dispatchEvent(new MouseEvent('mouseover'));
|
92
|
-
|
174
|
+
expect(tooltip?.checkVisibility()).to.be.false;
|
93
175
|
component.shadowRoot
|
94
176
|
?.querySelector('.component')
|
95
177
|
?.dispatchEvent(new MouseEvent('mouseout'));
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
178
|
+
await aTimeout(1);
|
179
|
+
expect(tooltip.checkVisibility()).to.be.false;
|
180
|
+
});
|
181
|
+
// This would be better served by a visual regression test. It exists only
|
182
|
+
// to meet our coverage threshold, so the `middlewareData.arrow.y` branch
|
183
|
+
// is hit.
|
184
|
+
it('positions the tooltip when `placement="right"`', async () => {
|
185
|
+
const component = await fixture(html `<glide-core-tooltip
|
186
|
+
placement="right"
|
187
|
+
style="align-items: center; display: flex; height: 100vh; justify-content:center; width: 100vw;"
|
188
|
+
>
|
189
|
+
Tooltip
|
190
|
+
<span slot="target" tabindex="0">Target</span>
|
191
|
+
</glide-core-tooltip>`);
|
192
|
+
component.shadowRoot
|
193
|
+
?.querySelector('[data-test="target"]')
|
194
|
+
?.dispatchEvent(new FocusEvent('focusin'));
|
195
|
+
// Wait for Floating UI.
|
196
|
+
await aTimeout(0);
|
197
|
+
const tooltipContainer = component.shadowRoot?.querySelector('[data-test="tooltip"]');
|
198
|
+
const arrow = component.shadowRoot?.querySelector('[data-test="arrow"]');
|
199
|
+
expect(tooltipContainer?.style.left).to.not.be.empty.string;
|
200
|
+
expect(tooltipContainer?.style.top).to.not.be.empty.string;
|
201
|
+
expect(arrow?.style.left).to.be.empty.string;
|
202
|
+
expect(arrow?.style.top).to.not.be.empty.string;
|
100
203
|
});
|
package/dist/translations/en.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
const translation={$code:"en",$name:"English",$dir:"ltr",close:"Close",dismiss:"Dismiss",open:"Open",selectAll:"Select all",
|
1
|
+
const translation={$code:"en",$name:"English",$dir:"ltr",close:"Close",dismiss:"Dismiss",open:"Open",selectAll:"Select all",moreInformation:"More information",nextTab:"Next tab",notifications:"Notifications",previousTab:"Previous tab",announcedCharacterCount:(e,t)=>`Character count ${e} of ${t}`,displayedCharacterCount:(e,t)=>`${e}/${t}`,clearEntry:e=>`Clear ${e} entry`,removeTag:e=>`Remove tag: ${e}`};export default translation;
|
package/dist/translations/fr.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
const translation={$code:"fr",$name:"French",$dir:"ltr",close:"Fermer",dismiss:"Congédier",open:"Ouvrir",selectAll:"Tout sélectionner",
|
1
|
+
const translation={$code:"fr",$name:"French",$dir:"ltr",close:"Fermer",dismiss:"Congédier",open:"Ouvrir",selectAll:"Tout sélectionner",moreInformation:"Plus d’informations",notifications:"Notifications",nextTab:"Next tab",previousTab:"Previous tab",announcedCharacterCount:(e,r)=>`Character count ${e} of ${r}`,displayedCharacterCount:(e,r)=>`${e}/${r}`,clearEntry:e=>`Clear ${e} entry`,removeTag:e=>`Supprimer la balise : ${e}`};export default translation;
|
package/dist/translations/ja.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
const translation={$code:"ja",$name:"Japanese",$dir:"ltr",close:"閉じる",dismiss:"無視",open:"オープン",selectAll:"すべて選択",
|
1
|
+
const translation={$code:"ja",$name:"Japanese",$dir:"ltr",close:"閉じる",dismiss:"無視",open:"オープン",selectAll:"すべて選択",moreInformation:"詳細情報",notifications:"通知",nextTab:"Next tab",previousTab:"Previous tab",announcedCharacterCount:(a,e)=>`Character count ${a} of ${e}`,displayedCharacterCount:(a,e)=>`${a}/${e}`,clearEntry:a=>`Clear ${a} entry`,removeTag:a=>`タグを削除: ${a}`};export default translation;
|
package/dist/tree.d.ts
CHANGED
package/dist/tree.item.d.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import './tree.item.menu.js';
|
2
2
|
import { LitElement } from 'lit';
|
3
|
-
import GlideCoreMenu from './menu.js';
|
3
|
+
import type GlideCoreMenu from './menu.js';
|
4
4
|
declare global {
|
5
5
|
interface HTMLElementTagNameMap {
|
6
6
|
'glide-core-tree-item': GlideCoreTreeItem;
|
@@ -29,7 +29,7 @@ export default class GlideCoreTreeItem extends LitElement {
|
|
29
29
|
slotElements: GlideCoreTreeItem[];
|
30
30
|
suffixSlotAssignedElements: HTMLElement[];
|
31
31
|
firstUpdated(): void;
|
32
|
-
focus(): void;
|
32
|
+
focus(options?: FocusOptions): void;
|
33
33
|
get hasChildTreeItems(): boolean;
|
34
34
|
get hasExpandIcon(): boolean;
|
35
35
|
render(): import("lit").TemplateResult<1>;
|
@@ -39,7 +39,6 @@ export default class GlideCoreTreeItem extends LitElement {
|
|
39
39
|
* Returns the selected item
|
40
40
|
*/
|
41
41
|
selectItem(item: GlideCoreTreeItem): GlideCoreTreeItem | undefined;
|
42
|
-
setContainingBlock(containingBlock: Element): void;
|
43
42
|
toggleExpand(): void;
|
44
43
|
private childTreeItems;
|
45
44
|
}
|
package/dist/tree.item.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(e,t,i,o){var s
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,i,o){var r,s=arguments.length,l=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var d=e.length-1;d>=0;d--)(r=e[d])&&(l=(s<3?r(l):s>3?r(t,i,l):r(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import"./tree.item.menu.js";import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,queryAssignedElements,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{when}from"lit/directives/when.js";import styles from"./tree.item.styles.js";let GlideCoreTreeItem=class GlideCoreTreeItem extends LitElement{constructor(){super(...arguments),this.expanded=!1,this.label="",this.level=1,this.selected=!1,this.removeIndentation=!1,this.nonCollapsible=!1,this.childTreeItems=[],this.#e=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}firstUpdated(){this.#t()}focus(e){this.#e.value?.focus(e)}get hasChildTreeItems(){return this.childTreeItems.length>0}get hasExpandIcon(){return this.hasChildTreeItems&&!this.nonCollapsible}render(){return html`<div class="${classMap({component:!0,expanded:this.expanded,selected:this.selected})}" role="treeitem" aria-label="${this.label}" aria-selected="${ifDefined(this.#i)}" aria-expanded="${ifDefined(this.#o)}"><div class="${classMap({"label-container":!0})}" tabindex="-1" ${ref(this.#e)}><div style="flex-shrink: 0; width:${this.#r};"></div>${when(!this.removeIndentation||this.hasExpandIcon,(()=>html`<div class="expand-icon-container">${when(this.hasExpandIcon,(()=>html`<div><svg aria-hidden="true" class="${classMap({"expand-icon":!0,"expand-icon-expanded":this.expanded})}" width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M9 18L15 12L9 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>`))}</div>`))}<slot name="prefix"></slot><div class="label">${this.label}</div><div class="icon-container"><slot name="menu"></slot><slot name="suffix"></slot></div></div><div class="child-items" role="group"><slot></slot></div></div>`}selectItem(e){let t;for(const i of this.slotElements)if(e===i)i.setAttribute("selected","true"),t=i;else{i.removeAttribute("selected");const o=i.selectItem(e);o&&(t=o)}return t}toggleExpand(){this.expanded=!this.expanded}#e;get#o(){return this.hasChildTreeItems?this.expanded?"true":"false":void 0}get#i(){return this.hasChildTreeItems?void 0:this.selected?"true":"false"}get#r(){return 20*(this.level-1)+"px"}#t(){const e=[];for(const t of this.slotElements)t.level=this.level+1,e.push(t);this.childTreeItems=e}};__decorate([property({type:Boolean})],GlideCoreTreeItem.prototype,"expanded",void 0),__decorate([property({reflect:!0})],GlideCoreTreeItem.prototype,"label",void 0),__decorate([property({type:Number})],GlideCoreTreeItem.prototype,"level",void 0),__decorate([property({type:Boolean})],GlideCoreTreeItem.prototype,"selected",void 0),__decorate([property({type:Boolean,attribute:"remove-indentation"})],GlideCoreTreeItem.prototype,"removeIndentation",void 0),__decorate([property({type:Boolean,attribute:"non-collapsible"})],GlideCoreTreeItem.prototype,"nonCollapsible",void 0),__decorate([queryAssignedElements({slot:"menu"})],GlideCoreTreeItem.prototype,"menuSlotAssignedElements",void 0),__decorate([queryAssignedElements({slot:"prefix"})],GlideCoreTreeItem.prototype,"prefixSlotAssignedElements",void 0),__decorate([queryAssignedElements()],GlideCoreTreeItem.prototype,"slotElements",void 0),__decorate([queryAssignedElements({slot:"suffix"})],GlideCoreTreeItem.prototype,"suffixSlotAssignedElements",void 0),__decorate([state()],GlideCoreTreeItem.prototype,"childTreeItems",void 0),GlideCoreTreeItem=__decorate([customElement("glide-core-tree-item")],GlideCoreTreeItem);export default GlideCoreTreeItem;
|
package/dist/tree.item.menu.d.ts
CHANGED
package/dist/tree.item.menu.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(e,t,o,
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,o,r){var l,n=arguments.length,i=n<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,o,r);else for(var s=e.length-1;s>=0;s--)(l=e[s])&&(i=(n<3?l(i):n>3?l(t,o,i):l(t,o))||i);return n>3&&i&&Object.defineProperty(t,o,i),i};import"./icon-button.js";import"./menu.js";import"./menu.options.js";import{LitElement,html}from"lit";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}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"./tree.item.menu.styles.js";let GlideCoreTreeItemMenu=class GlideCoreTreeItemMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.#e=createRef(),this.#t=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#e.value),owSlotType(this.#e.value,[GlideCoreMenuButton,GlideCoreMenuLink])}render(){return html`<glide-core-menu class="component" placement="${this.placement}" ${ref(this.#t)}><glide-core-menu-options><slot @slotchange="${this.#o}" ${ref(this.#e)}></slot></glide-core-menu-options><glide-core-icon-button slot="target" variant="tertiary"><svg width="4" height="14" viewBox="0 0 4 18" fill="none" stroke="currentColor" stroke-width="2"><path d="M2 15C2.55228 15 3 15.4477 3 16C3 16.5523 2.55228 17 2 17C1.44772 17 1 16.5523 1 16C1 15.4477 1.44772 15 2 15Z"/><path d="M2 8C2.55228 8 3 8.44772 3 9C3 9.55228 2.55228 10 2 10C1.44772 10 1 9.55228 1 9C1 8.44772 1.44772 8 2 8Z"/><path d="M2 1C2.55228 1 3 1.44772 3 2C3 2.55228 2.55228 3 2 3C1.44772 3 1 2.55228 1 2C1 1.44772 1.44772 1 2 1Z"/></svg></glide-core-icon-button></glide-core-menu>`}#e;#t;#o(){owSlot(this.#e.value),owSlotType(this.#e.value,[GlideCoreMenuButton,GlideCoreMenuLink])}};__decorate([property({reflect:!0})],GlideCoreTreeItemMenu.prototype,"placement",void 0),GlideCoreTreeItemMenu=__decorate([customElement("glide-core-tree-item-menu")],GlideCoreTreeItemMenu);export default GlideCoreTreeItemMenu;
|
package/dist/tree.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(e,t,o,s){var l,r=arguments.length,i=r<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,o):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,o,s);else for(var n=e.length-1;n>=0;n--)(l=e[n])&&(i=(r<3?l(i):r>3?l(t,o,i):l(t,o))||i);return r>3&&i&&Object.defineProperty(t,o,i),i};import{LitElement,html}from"lit";import{createRef,ref}from"lit/directives/ref.js";import{customElement,queryAssignedElements,state}from"lit/decorators.js";import{owSlot,owSlotType}from"./library/ow.js";import GlideCoreTreeItem from"./tree.item.js";import styles from"./tree.styles.js";let GlideCoreTree=class GlideCoreTree extends LitElement{static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("focusin",this.#e),this.removeEventListener("focusout",this.#t)}firstUpdated(){owSlot(this.#o.value),owSlotType(this.#o.value,[GlideCoreTreeItem])}render(){return html`<div class="component" role="tree" tabindex="${this.privateTabIndex}" @click="${this.#s}" @keydown="${this.#l}"><slot @slotchange="${this.#r}" ${ref(this.#o)}></slot></div>`}selectItem(e){for(const t of this.slotElements){e===t?(t.setAttribute("selected","true"),this.selectedItem=t):t.removeAttribute("selected");const o=t.selectItem(e);o&&(this.selectedItem=o)}this.dispatchEvent(new CustomEvent("item-selected",{bubbles:!0,detail:e}))}
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,o,s){var l,r=arguments.length,i=r<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,o):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,o,s);else for(var n=e.length-1;n>=0;n--)(l=e[n])&&(i=(r<3?l(i):r>3?l(t,o,i):l(t,o))||i);return r>3&&i&&Object.defineProperty(t,o,i),i};import{LitElement,html}from"lit";import{createRef,ref}from"lit/directives/ref.js";import{customElement,queryAssignedElements,state}from"lit/decorators.js";import{owSlot,owSlotType}from"./library/ow.js";import GlideCoreTreeItem from"./tree.item.js";import styles from"./tree.styles.js";let GlideCoreTree=class GlideCoreTree extends LitElement{static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("focusin",this.#e),this.removeEventListener("focusout",this.#t)}firstUpdated(){owSlot(this.#o.value),owSlotType(this.#o.value,[GlideCoreTreeItem])}render(){return html`<div class="component" role="tree" tabindex="${this.privateTabIndex}" @click="${this.#s}" @keydown="${this.#l}"><slot @slotchange="${this.#r}" ${ref(this.#o)}></slot></div>`}selectItem(e){for(const t of this.slotElements){e===t?(t.setAttribute("selected","true"),this.selectedItem=t):t.removeAttribute("selected");const o=t.selectItem(e);o&&(this.selectedItem=o)}this.dispatchEvent(new CustomEvent("item-selected",{bubbles:!0,detail:e}))}constructor(){super(),this.privateTabIndex=0,this.#o=createRef(),this.addEventListener("focusin",this.#e),this.addEventListener("focusout",this.#t)}#o;#i(e){e?.focus(),this.focusedItem=e}#n(){return[...this.querySelectorAll("glide-core-tree-item")]}#d(){const e=this.#n(),t=new Set;return e.filter((e=>{const o=e.parentElement?.closest("glide-core-tree-item");return!o||o.expanded&&!t.has(o)||t.add(e),!t.has(e)}))}#s(e){const t=e.target;if(t.closest("glide-core-tree-item-icon-button")??t.closest("glide-core-tree-item-menu"))return;const o=t.closest("glide-core-tree-item");o&&(o.hasChildTreeItems&&!o.nonCollapsible?o.toggleExpand():this.selectItem(o))}#e(e){let t;e.target===this?t=this.selectedItem??this.slotElements[0]:e.target instanceof GlideCoreTreeItem&&(t=e.target,this.privateTabIndex=-1),this.#i(t)}#t(e){const t=e.relatedTarget;t&&this.contains(t)||(this.privateTabIndex=0,this.focusedItem=void 0)}#l(e){if(!["ArrowRight","ArrowLeft","ArrowDown","ArrowUp","Home","End","Enter"].includes(e.key))return;const t=this.#d(),{focusedItem:o}=this,s=t.findIndex((e=>e.matches(":focus")));if("ArrowRight"===e.key&&o?.hasChildTreeItems&&(o.expanded?this.#i(o.slotElements[0]):o.toggleExpand()),"ArrowLeft"===e.key)if(o?.expanded&&!o.nonCollapsible)o.toggleExpand();else{const e=o?.parentElement?.closest("glide-core-tree-item");this.#i(e)}"ArrowDown"===e.key&&-1!==s&&s<t.length-1&&this.#i(t[s+1]),"ArrowUp"===e.key&&s>0&&this.#i(t[s-1]),"Home"===e.key&&this.#i(t[0]),"End"===e.key&&this.#i(t.at(-1)),"Enter"===e.key&&o&&(o.hasChildTreeItems&&!o.nonCollapsible?o.toggleExpand():this.selectItem(o))}#r(){owSlot(this.#o.value),owSlotType(this.#o.value,[GlideCoreTreeItem])}};__decorate([state()],GlideCoreTree.prototype,"selectedItem",void 0),__decorate([state()],GlideCoreTree.prototype,"focusedItem",void 0),__decorate([state()],GlideCoreTree.prototype,"privateTabIndex",void 0),__decorate([queryAssignedElements()],GlideCoreTree.prototype,"slotElements",void 0),GlideCoreTree=__decorate([customElement("glide-core-tree")],GlideCoreTree);export default GlideCoreTree;
|
package/dist/tree.test.basics.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
1
2
|
import './tree.item.icon-button.js';
|
2
3
|
import './tree.item.js';
|
3
4
|
import './tree.js';
|
@@ -116,7 +117,7 @@ it('throws if it does not have a default slot', async () => {
|
|
116
117
|
spy();
|
117
118
|
}
|
118
119
|
}
|
119
|
-
expect(spy.
|
120
|
+
expect(spy.callCount).to.equal(1);
|
120
121
|
});
|
121
122
|
it('throws if the default slot is the incorrect type', async () => {
|
122
123
|
await expectArgumentError(() => {
|
package/dist/tree.test.events.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
1
2
|
import './tree.item.menu.js';
|
2
3
|
import './tree.js';
|
3
4
|
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
|
4
|
-
import GlideCoreTree from './tree.js';
|
5
5
|
import GlideCoreTreeItem from './tree.item.js';
|
6
6
|
it('dispatches an "item-selected" event when an item is clicked', async () => {
|
7
7
|
const component = await fixture(html `
|