@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/tab.panel.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
var
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,i,o){var s,r=arguments.length,a=r<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,i,o);else for(var l=e.length-1;l>=0;l--)(s=e[l])&&(a=(r<3?s(a):r>3?s(t,i,a):s(t,i))||a);return r>3&&a&&Object.defineProperty(t,i,a),a};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{customElement,property}from"lit/decorators.js";import{nanoid}from"nanoid";import styles from"./tab.panel.styles.js";let GlideCoreTabPanel=class GlideCoreTabPanel extends LitElement{constructor(){super(...arguments),this.name="",this.isActive=!0,this.#e=nanoid()}static{this.instanceCount=0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){this.setAttribute("role","tabpanel"),this.id=this.#e}render(){return html`<div class="${classMap({component:!0,hidden:!this.isActive})}"><slot></slot></div>`}updated(e){super.updated(e),e.has("isActive")&&this.setAttribute("aria-hidden",this.isActive?"false":"true")}#e};__decorate([property({reflect:!0})],GlideCoreTabPanel.prototype,"name",void 0),__decorate([property({type:Boolean})],GlideCoreTabPanel.prototype,"isActive",void 0),GlideCoreTabPanel=__decorate([customElement("glide-core-tab-panel")],GlideCoreTabPanel);export default GlideCoreTabPanel;
|
package/dist/tab.panel.styles.js
CHANGED
@@ -1,6 +1,16 @@
|
|
1
|
-
import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
|
1
|
+
import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
|
2
|
+
:host(:focus-visible) {
|
3
|
+
outline: none;
|
4
|
+
}
|
5
|
+
|
6
|
+
/* stylelint-disable-next-line csstools/use-nesting */
|
7
|
+
:host(:focus-visible) .component {
|
8
|
+
${focusOutline};
|
9
|
+
}
|
10
|
+
|
2
11
|
.component {
|
3
12
|
font-family: var(--glide-core-font-sans);
|
13
|
+
outline: none;
|
4
14
|
}
|
5
15
|
|
6
16
|
.hidden {
|
package/dist/tab.styles.js
CHANGED
@@ -12,16 +12,20 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
12
12
|
.component {
|
13
13
|
align-items: center;
|
14
14
|
cursor: pointer;
|
15
|
-
display: inline-flex;
|
16
15
|
font-family: var(--glide-core-heading-xxs-font-family);
|
17
16
|
font-size: var(--glide-core-heading-xxxs-font-size);
|
18
17
|
font-style: var(--glide-core-heading-xxs-font-style);
|
18
|
+
font-weight: var(--glide-core-body-sm-font-weight);
|
19
19
|
gap: 0.4375rem;
|
20
20
|
justify-content: center;
|
21
21
|
line-height: 1.1875rem;
|
22
22
|
padding-block: var(--glide-core-spacing-xs);
|
23
23
|
padding-inline: var(--glide-core-spacing-md);
|
24
24
|
|
25
|
+
&.active {
|
26
|
+
border-block-end: 2px solid var(--glide-core-border-focus);
|
27
|
+
}
|
28
|
+
|
25
29
|
&:hover {
|
26
30
|
color: var(--glide-core-text-primary);
|
27
31
|
}
|
@@ -35,74 +39,9 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
|
|
35
39
|
& .container {
|
36
40
|
border-radius: 0.0625rem;
|
37
41
|
display: flex;
|
42
|
+
flex-shrink: 0;
|
38
43
|
gap: var(--glide-core-spacing-xs);
|
39
|
-
|
40
|
-
|
41
|
-
/* Primary */
|
42
|
-
|
43
|
-
&.primary {
|
44
|
-
border: 1px solid transparent;
|
45
|
-
border-block-end-width: 0;
|
46
|
-
border-end-end-radius: 0;
|
47
|
-
border-end-start-radius: 0;
|
48
|
-
border-start-end-radius: var(--glide-core-spacing-sm);
|
49
|
-
border-start-start-radius: var(--glide-core-spacing-sm);
|
50
|
-
font-weight: var(--glide-core-heading-xxs-font-weight);
|
51
|
-
|
52
|
-
&.active,
|
53
|
-
&:hover:not(.disabled) {
|
54
|
-
background-color: var(--glide-core-surface-base);
|
55
|
-
border: 1px solid var(--glide-core-border-primary);
|
56
|
-
|
57
|
-
/* hide the outer tab-group bottom border */
|
58
|
-
border-block-end: 1px solid var(--glide-core-surface-base);
|
59
|
-
margin-block-end: -1px;
|
60
|
-
}
|
61
|
-
|
62
|
-
& .active.default-slot {
|
63
|
-
background-color: red;
|
64
|
-
}
|
65
|
-
}
|
66
|
-
|
67
|
-
/* Secondary */
|
68
|
-
|
69
|
-
&.secondary {
|
70
|
-
border-color: transparent;
|
71
|
-
border-style: solid;
|
72
|
-
border-width: 1px;
|
73
|
-
font-weight: var(--glide-core-body-sm-font-weight);
|
74
|
-
|
75
|
-
&.active {
|
76
|
-
border-block-end: 2px solid var(--glide-core-border-focus);
|
77
|
-
}
|
78
|
-
}
|
79
|
-
|
80
|
-
/* Vertical */
|
81
|
-
|
82
|
-
&.vertical {
|
83
|
-
flex-direction: column;
|
84
|
-
font-weight: var(--glide-core-body-sm-font-weight);
|
85
|
-
padding-inline: var(--glide-core-spacing-xxs);
|
86
|
-
|
87
|
-
& .default-slot {
|
88
|
-
transform: rotate(180deg);
|
89
|
-
writing-mode: vertical-lr;
|
90
|
-
}
|
91
|
-
|
92
|
-
&.active {
|
93
|
-
border-inline-start: 2px solid var(--glide-core-border-focus);
|
94
|
-
}
|
95
|
-
|
96
|
-
&.active,
|
97
|
-
&.disabled {
|
98
|
-
background-color: var(--glide-core-surface-base);
|
99
|
-
}
|
100
|
-
|
101
|
-
& .container {
|
102
|
-
display: flex;
|
103
|
-
flex-direction: column;
|
104
|
-
gap: var(--glide-core-spacing-xs);
|
105
|
-
}
|
44
|
+
white-space: nowrap;
|
106
45
|
}
|
107
46
|
}
|
108
47
|
`];
|
package/dist/tab.test.basics.js
CHANGED
@@ -12,29 +12,9 @@ it('renders correct markup and sets correct attributes for the default case', as
|
|
12
12
|
await expect(element).to.not.be.accessible();
|
13
13
|
expect(element.active).to.equal(false, 'active defaults to false');
|
14
14
|
expect(element.disabled).to.equal(false, 'disabled defaults to false');
|
15
|
-
expect(element.variant).to.equal('primary');
|
16
15
|
expect(element.getAttribute('aria-disabled')).to.equal(null, 'does not set aria-disabled');
|
17
16
|
expect([...element.shadowRoot.firstElementChild.classList]).to.deep.equal([
|
18
17
|
'component',
|
19
|
-
'primary',
|
20
|
-
]);
|
21
|
-
});
|
22
|
-
it('renders a secondary variant', async () => {
|
23
|
-
const element = await fixture(html `
|
24
|
-
<glide-core-tab variant="secondary">Tab</glide-core-tab>
|
25
|
-
`);
|
26
|
-
expect([...element.shadowRoot.firstElementChild.classList]).to.deep.equal([
|
27
|
-
'component',
|
28
|
-
'secondary',
|
29
|
-
]);
|
30
|
-
});
|
31
|
-
it('renders a vertical variant', async () => {
|
32
|
-
const element = await fixture(html `
|
33
|
-
<glide-core-tab variant="vertical">Tab</glide-core-tab>
|
34
|
-
`);
|
35
|
-
expect([...element.shadowRoot.firstElementChild.classList]).to.deep.equal([
|
36
|
-
'component',
|
37
|
-
'vertical',
|
38
18
|
]);
|
39
19
|
});
|
40
20
|
it('sets the panel attribute', async () => {
|
package/dist/tabs.stories.d.ts
CHANGED
@@ -5,5 +5,4 @@ import type { Meta, StoryObj } from '@storybook/web-components';
|
|
5
5
|
declare const meta: Meta;
|
6
6
|
export default meta;
|
7
7
|
export declare const Primary: StoryObj;
|
8
|
-
export declare const
|
9
|
-
export declare const Vertical: StoryObj;
|
8
|
+
export declare const Overflow: StoryObj;
|
package/dist/tag.test.basics.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
1
2
|
import { ArgumentError } from 'ow';
|
2
3
|
import { aTimeout, expect, fixture, html } from '@open-wc/testing';
|
3
4
|
import GlideCoreTag from './tag.js';
|
@@ -78,7 +79,7 @@ it('throws an error when the default slot is empty', async () => {
|
|
78
79
|
spy();
|
79
80
|
}
|
80
81
|
}
|
81
|
-
expect(spy.
|
82
|
+
expect(spy.callCount).to.equal(1);
|
82
83
|
});
|
83
84
|
it('does not throw an error when the default slot is non-empty', async () => {
|
84
85
|
const spy = sinon.spy();
|
@@ -90,7 +91,7 @@ it('does not throw an error when the default slot is non-empty', async () => {
|
|
90
91
|
spy();
|
91
92
|
}
|
92
93
|
}
|
93
|
-
expect(spy.
|
94
|
+
expect(spy.callCount).to.equal(0);
|
94
95
|
});
|
95
96
|
it('toggles the "activate" and "deactivate" clases when the button is clicked', async () => {
|
96
97
|
const element = await fixture(html `<glide-core-tag removable-label="test-aria-label"
|
package/dist/textarea.d.ts
CHANGED
package/dist/textarea.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
var __decorate=this&&this.__decorate||function(e,t,i,a){var r,o=arguments.length,l=o<3?t:null===a?a=Object.getOwnPropertyDescriptor(t,i):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,a);else for(var s=e.length-1;s>=0;s--)(r=e[s])&&(l=(o<3?r(l):o>3?r(t,i,l):r(t,i))||l);return o>3&&l&&Object.defineProperty(t,i,l),l};import"./label.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,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import
|
2
|
-
</textarea></div><div class="meta"
|
1
|
+
var __decorate=this&&this.__decorate||function(e,t,i,a){var r,o=arguments.length,l=o<3?t:null===a?a=Object.getOwnPropertyDescriptor(t,i):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,a);else for(var s=e.length-1;s>=0;s--)(r=e[s])&&(l=(o<3?r(l):o>3?r(t,i,l):r(t,i))||l);return o>3&&l&&Object.defineProperty(t,i,l),l};import"./label.js";import{LitElement,html,nothing}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{ifDefined}from"lit/directives/if-defined.js";import ow from"./library/ow.js";import styles from"./textarea.styles.js";let GlideCoreTextarea=class GlideCoreTextarea extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed",delegatesFocus:!0}}static{this.styles=styles}blur(){this.#e.value?.blur()}checkValidity(){this.isCheckingValidity=!0;const e=this.#t.checkValidity();return this.isCheckingValidity=!1,e}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#i)}get form(){return this.#t.form}get validity(){return!this.required||this.value||this.disabled?this.#a?this.#t.setValidity({tooLong:!0}," ",this.#e.value):this.#t.setValidity({}):this.#t.setValidity({valueMissing:!0}," ",this.#e.value),this.#t.validity}get willValidate(){return this.#t.willValidate}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#i)}formResetCallback(){this.value=this.getAttribute("value")??""}render(){return html`<glide-core-private-label split="${ifDefined(this.privateSplit??void 0)}" orientation="${this.orientation}" ?disabled="${this.disabled}" ?error="${this.#r||this.#a}" ?hide="${this.hideLabel}" ?required="${this.required}"><slot name="tooltip" slot="tooltip"></slot><label class="label" for="textarea">${this.label}</label><div class="textarea-container" slot="control"><textarea aria-describedby="meta" aria-invalid="${this.#r||this.#a}" class="${classMap({error:this.#r||this.#a})}" id="textarea" name="${ifDefined(this.name)}" placeholder="${ifDefined(this.placeholder)}" rows="${this.rows}" autocapitalize="${ifDefined(this.autocapitalize)}" spellcheck="${this.spellcheck}" .value="${this.value}" ?required="${this.required}" ?readonly="${this.readonly}" ?disabled="${this.disabled}" ${ref(this.#e)} @input="${this.#o}" @change="${this.#l}" @blur="${this.#s}">
|
2
|
+
</textarea></div><div class="meta" id="meta" slot="description"><slot class="description" name="description"></slot>${this.maxlength?html`<div class="${classMap({"character-count":!0,error:this.#a})}" data-test="character-count-container"><span aria-hidden="true" data-test="character-count-text">${this.#d.term("displayedCharacterCount",this.#n,this.maxlength)} </span><span class="hidden" data-test="character-count-announcement">${this.#d.term("announcedCharacterCount",this.#n,this.maxlength)}</span></div>`:nothing}</div></glide-core-private-label>`}reportValidity(){this.isReportValidityOrSubmit=!0;const e=this.#t.reportValidity();return this.requestUpdate(),e}constructor(){super(),this.value="",this.label="",this.hideLabel=!1,this.orientation="horizontal",this.placeholder="",this.rows=2,this.required=!1,this.readonly=!1,this.disabled=!1,this.spellcheck=!1,this.autocapitalize="on",this.isBlurring=!1,this.isCheckingValidity=!1,this.isReportValidityOrSubmit=!1,this.#d=new LocalizeController(this),this.#e=createRef(),this.#i=({formData:e})=>{this.name&&this.value&&!this.disabled&&e.append(this.name,this.value)},this.#t=this.attachInternals(),this.addEventListener("invalid",(e=>{if(e?.preventDefault(),this.isCheckingValidity||this.isBlurring)return;this.isReportValidityOrSubmit=!0;this.form?.querySelector(":invalid")===this&&this.focus()}))}#t;#d;#e;#i;get#r(){return!this.disabled&&!this.readonly&&!this.validity.valid&&this.isReportValidityOrSubmit}get#n(){return this.value.length}get#a(){return Boolean(!this.disabled&&!this.readonly&&this.maxlength&&this.#n>this.maxlength)}#s(){this.isBlurring=!0,this.reportValidity(),this.isBlurring=!1}#l(e){ow(this.#e.value,ow.object.instanceOf(HTMLTextAreaElement)),this.value=this.#e.value.value,this.dispatchEvent(new Event(e.type,e))}#o(){ow(this.#e.value,ow.object.instanceOf(HTMLTextAreaElement)),this.value=this.#e.value.value}};__decorate([property()],GlideCoreTextarea.prototype,"value",void 0),__decorate([property()],GlideCoreTextarea.prototype,"label",void 0),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreTextarea.prototype,"hideLabel",void 0),__decorate([property({reflect:!0})],GlideCoreTextarea.prototype,"orientation",void 0),__decorate([property()],GlideCoreTextarea.prototype,"placeholder",void 0),__decorate([property({reflect:!0,type:Number})],GlideCoreTextarea.prototype,"rows",void 0),__decorate([property({type:Boolean})],GlideCoreTextarea.prototype,"required",void 0),__decorate([property({type:Boolean})],GlideCoreTextarea.prototype,"readonly",void 0),__decorate([property({type:Boolean})],GlideCoreTextarea.prototype,"disabled",void 0),__decorate([property({type:Number,converter:e=>e&&Number.parseInt(e,10)})],GlideCoreTextarea.prototype,"maxlength",void 0),__decorate([property({reflect:!0})],GlideCoreTextarea.prototype,"name",void 0),__decorate([property({type:Boolean})],GlideCoreTextarea.prototype,"spellcheck",void 0),__decorate([property()],GlideCoreTextarea.prototype,"autocapitalize",void 0),__decorate([property()],GlideCoreTextarea.prototype,"privateSplit",void 0),__decorate([state()],GlideCoreTextarea.prototype,"isBlurring",void 0),__decorate([state()],GlideCoreTextarea.prototype,"isCheckingValidity",void 0),__decorate([state()],GlideCoreTextarea.prototype,"isReportValidityOrSubmit",void 0),GlideCoreTextarea=__decorate([customElement("glide-core-textarea")],GlideCoreTextarea);export default GlideCoreTextarea;
|
@@ -2,12 +2,11 @@ import type { Meta, StoryObj } from '@storybook/web-components';
|
|
2
2
|
declare const meta: Meta;
|
3
3
|
export default meta;
|
4
4
|
export declare const Default: StoryObj;
|
5
|
-
export declare const
|
6
|
-
export declare const
|
5
|
+
export declare const WithError: StoryObj;
|
6
|
+
export declare const Description: StoryObj;
|
7
7
|
export declare const Readonly: StoryObj;
|
8
8
|
export declare const Disabled: StoryObj;
|
9
9
|
export declare const Placeholder: StoryObj;
|
10
10
|
export declare const MaxLength: StoryObj;
|
11
|
-
export declare const
|
12
|
-
export declare const WithError: StoryObj;
|
11
|
+
export declare const MaxLengthAndDescription: StoryObj;
|
13
12
|
export declare const Tooltip: StoryObj;
|
package/dist/textarea.styles.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import{css}from"lit";export default css`
|
2
|
-
glide-core-label::part(tooltips-and-label) {
|
1
|
+
import{css,unsafeCSS}from"lit";import visuallyHidden from"./styles/visually-hidden.js";const fieldSizingContent=unsafeCSS("\n field-sizing: content;\n");export default css`
|
2
|
+
glide-core-private-label::part(tooltips-and-label) {
|
3
3
|
align-items: flex-start;
|
4
4
|
margin-block-start: var(--glide-core-spacing-sm);
|
5
5
|
}
|
@@ -8,6 +8,10 @@ import{css}from"lit";export default css`
|
|
8
8
|
display: flex;
|
9
9
|
}
|
10
10
|
|
11
|
+
.description {
|
12
|
+
display: block;
|
13
|
+
}
|
14
|
+
|
11
15
|
textarea {
|
12
16
|
appearance: none;
|
13
17
|
background-color: var(--glide-core-surface-base-lighter);
|
@@ -20,11 +24,14 @@ import{css}from"lit";export default css`
|
|
20
24
|
font-family: var(--glide-core-body-xs-font-family);
|
21
25
|
font-size: var(--glide-core-body-sm-font-size);
|
22
26
|
font-weight: var(--glide-core-body-xs-font-weight);
|
23
|
-
|
27
|
+
max-block-size: 5lh;
|
28
|
+
min-block-size: 3lh;
|
24
29
|
padding: var(--glide-core-spacing-xs) var(--glide-core-spacing-sm);
|
25
30
|
resize: vertical;
|
26
31
|
transition: border-color 200ms ease-in-out;
|
27
32
|
|
33
|
+
${fieldSizingContent};
|
34
|
+
|
28
35
|
&:hover {
|
29
36
|
border-color: var(--glide-core-border-base);
|
30
37
|
}
|
@@ -66,5 +73,9 @@ import{css}from"lit";export default css`
|
|
66
73
|
&.error {
|
67
74
|
font-weight: var(--glide-core-font-weight-bold);
|
68
75
|
}
|
76
|
+
|
77
|
+
.hidden {
|
78
|
+
${visuallyHidden};
|
79
|
+
}
|
69
80
|
}
|
70
81
|
`;
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
2
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
2
3
|
import { sendKeys } from '@web/test-runner-commands';
|
3
4
|
import GlideCoreTextarea from './textarea.js';
|
4
5
|
GlideCoreTextarea.shadowRootOptions.mode = 'open';
|
@@ -6,13 +7,17 @@ it('registers', async () => {
|
|
6
7
|
expect(window.customElements.get('glide-core-textarea')).to.equal(GlideCoreTextarea);
|
7
8
|
});
|
8
9
|
it('is accessible', async () => {
|
9
|
-
const
|
10
|
-
|
10
|
+
const element = await fixture(html `<glide-core-textarea
|
11
|
+
value="value"
|
12
|
+
label="label"
|
13
|
+
></glide-core-textarea>`);
|
11
14
|
await expect(element).to.be.accessible();
|
12
15
|
});
|
13
16
|
it('renders a textarea with two rows and value when attribute `value` is set ', async () => {
|
14
|
-
const
|
15
|
-
|
17
|
+
const element = await fixture(html `<glide-core-textarea
|
18
|
+
value="value"
|
19
|
+
label="label"
|
20
|
+
></glide-core-textarea>`);
|
16
21
|
const textarea = element.shadowRoot.querySelector('textarea');
|
17
22
|
expect(element);
|
18
23
|
expect(element).to.have.attribute('rows', '2');
|
@@ -20,119 +25,151 @@ it('renders a textarea with two rows and value when attribute `value` is set ',
|
|
20
25
|
expect(textarea).to.have.attribute('rows', '2');
|
21
26
|
});
|
22
27
|
it('renders the `rows` attribute on the textarea when set', async () => {
|
23
|
-
const
|
24
|
-
|
28
|
+
const element = await fixture(html `<glide-core-textarea
|
29
|
+
value="value"
|
30
|
+
label="label"
|
31
|
+
rows="5"
|
32
|
+
></glide-core-textarea>`);
|
25
33
|
const textarea = element.shadowRoot.querySelector('textarea');
|
26
34
|
expect(textarea).to.have.attribute('rows', '5');
|
27
35
|
});
|
28
36
|
it('renders a label when attribute `label` is set', async () => {
|
29
|
-
const
|
30
|
-
|
37
|
+
const element = await fixture(html `<glide-core-textarea
|
38
|
+
value="value"
|
39
|
+
label="label"
|
40
|
+
></glide-core-textarea>`);
|
31
41
|
const label = element.shadowRoot.querySelector('label');
|
32
42
|
expect(label).to.exist;
|
33
43
|
expect(label?.textContent?.trim()).to.be.equal('label');
|
34
44
|
});
|
35
45
|
it('renders the textarea as readonly when attribute `readonly` is set', async () => {
|
36
|
-
const
|
37
|
-
|
46
|
+
const element = await fixture(html `<glide-core-textarea
|
47
|
+
value="value"
|
48
|
+
label="label"
|
49
|
+
readonly
|
50
|
+
></glide-core-textarea>`);
|
38
51
|
const textarea = element.shadowRoot.querySelector('textarea');
|
39
52
|
expect(textarea).to.have.attribute('readonly');
|
40
53
|
});
|
41
54
|
it('renders the textarea as disabled when attribute `disabled` is set', async () => {
|
42
|
-
const
|
43
|
-
|
55
|
+
const element = await fixture(html `<glide-core-textarea
|
56
|
+
value="value"
|
57
|
+
label="label"
|
58
|
+
disabled
|
59
|
+
></glide-core-textarea>`);
|
44
60
|
const textarea = element.shadowRoot.querySelector('textarea');
|
45
61
|
expect(textarea).to.have.attribute('disabled');
|
46
62
|
});
|
47
63
|
it('renders the textarea with a placeholder when attribute `placeholder` is set', async () => {
|
48
|
-
const
|
49
|
-
|
64
|
+
const element = await fixture(html `<glide-core-textarea
|
65
|
+
value=""
|
66
|
+
label="label"
|
67
|
+
placeholder="placeholder"
|
68
|
+
></glide-core-textarea>`);
|
50
69
|
const textarea = element.shadowRoot.querySelector('textarea');
|
51
70
|
expect(textarea).to.have.attribute('placeholder', 'placeholder');
|
52
71
|
});
|
53
72
|
it('renders `required` on textarea when set', async () => {
|
54
|
-
const
|
55
|
-
|
73
|
+
const element = await fixture(html `<glide-core-textarea
|
74
|
+
value="value"
|
75
|
+
label="label"
|
76
|
+
required
|
77
|
+
></glide-core-textarea>`);
|
56
78
|
const textarea = element.shadowRoot.querySelector('textarea');
|
57
79
|
expect(textarea).to.have.attribute('required');
|
58
80
|
});
|
59
81
|
it('renders a `name` attribute on the textarea when set', async () => {
|
60
|
-
const
|
61
|
-
|
82
|
+
const element = await fixture(html `<glide-core-textarea
|
83
|
+
value="value"
|
84
|
+
label="label"
|
85
|
+
name="test-name"
|
86
|
+
></glide-core-textarea>`);
|
62
87
|
const textarea = element.shadowRoot.querySelector('textarea');
|
63
88
|
expect(textarea).to.have.attribute('name', 'test-name');
|
64
89
|
});
|
65
90
|
it('supports a "tooltip" slot', async () => {
|
66
|
-
const
|
91
|
+
const element = await fixture(html `
|
67
92
|
<glide-core-textarea value="value" label="label" required>
|
68
93
|
<div slot="tooltip">Tooltip</div>
|
69
94
|
</glide-core-textarea>
|
70
|
-
|
71
|
-
const element = await fixture(template);
|
95
|
+
`);
|
72
96
|
const assignedElements = element.shadowRoot
|
73
97
|
?.querySelector('slot[name="tooltip"]')
|
74
98
|
?.assignedElements();
|
75
99
|
expect(assignedElements?.at(0)?.textContent).to.equal('Tooltip');
|
76
100
|
});
|
77
101
|
it('renders a slot with description', async () => {
|
78
|
-
const
|
79
|
-
|
102
|
+
const element = await fixture(html `<glide-core-textarea value="value" label="label"
|
103
|
+
><span slot="description" data-test-content
|
104
|
+
>Description</span
|
105
|
+
></glide-core-textarea
|
106
|
+
>`);
|
80
107
|
expect(element).to.exist;
|
81
108
|
const contentRendered = element.querySelector('[data-test-content]');
|
82
109
|
expect(contentRendered).to.exist;
|
83
110
|
expect(contentRendered?.textContent).to.be.equal('Description');
|
84
111
|
});
|
112
|
+
it('displays visually hidden character count text for screenreaders', async () => {
|
113
|
+
const element = await fixture(html `<glide-core-textarea
|
114
|
+
label="label"
|
115
|
+
maxlength="10"
|
116
|
+
></glide-core-textarea>`);
|
117
|
+
const maxCharacterCountAnnouncement = element.shadowRoot?.querySelector('[data-test="character-count-announcement"]');
|
118
|
+
expect(maxCharacterCountAnnouncement?.textContent?.trim()).to.equal('Character count 0 of 10');
|
119
|
+
});
|
85
120
|
it('renders a character count when attribute `maxlength` is set greater than zero', async () => {
|
86
|
-
const
|
87
|
-
|
88
|
-
|
121
|
+
const element = await fixture(html `<glide-core-textarea value="value" label="label" maxlength="10"
|
122
|
+
><span slot="description">Description</span></glide-core-textarea
|
123
|
+
>`);
|
124
|
+
const container = element.shadowRoot.querySelector('[data-test="character-count-text"]');
|
89
125
|
expect(container?.textContent?.trim()).to.be.equal('5/10');
|
90
126
|
});
|
91
127
|
it('does not render a character count when attribute `maxlength` is set less than than zero', async () => {
|
92
|
-
const
|
93
|
-
|
94
|
-
|
95
|
-
|
128
|
+
const element = await fixture(html `<glide-core-textarea value="value" label="label" maxlength="0"
|
129
|
+
><span slot="description">Description</span></glide-core-textarea
|
130
|
+
>`);
|
131
|
+
const container = element.shadowRoot?.querySelector('[data-test="character-count-container"]');
|
132
|
+
expect(container).to.be.null;
|
96
133
|
});
|
97
134
|
it('focuses the textarea when the label is clicked', async () => {
|
98
|
-
const
|
99
|
-
|
135
|
+
const element = await fixture(html `<glide-core-textarea
|
136
|
+
value="value"
|
137
|
+
label="label"
|
138
|
+
></glide-core-textarea>`);
|
100
139
|
const label = element.shadowRoot.querySelector('label');
|
101
140
|
label?.click();
|
102
141
|
expect(element).to.have.focus;
|
103
142
|
await expect(element.shadowRoot?.activeElement?.tagName.toLocaleLowerCase()).to.be.equal('textarea');
|
104
143
|
});
|
105
144
|
it('has tabbable textarea', async () => {
|
106
|
-
const
|
107
|
-
|
145
|
+
const element = await fixture(html `<glide-core-textarea
|
146
|
+
value="value"
|
147
|
+
label="label"
|
148
|
+
></glide-core-textarea>`);
|
108
149
|
await sendKeys({ press: 'Tab' });
|
109
150
|
expect(element).to.have.focus;
|
110
151
|
await expect(element.shadowRoot?.activeElement?.tagName.toLocaleLowerCase()).to.be.equal('textarea');
|
111
152
|
});
|
112
153
|
it('renders text when typed into text area', async () => {
|
113
|
-
const
|
114
|
-
const element = await fixture(template);
|
154
|
+
const element = await fixture(html `<glide-core-textarea value="" label="label"></glide-core-textarea>`);
|
115
155
|
const textarea = element.shadowRoot.querySelector('textarea');
|
116
156
|
element.focus();
|
117
157
|
await sendKeys({ type: 'test text' });
|
118
158
|
expect(textarea?.value).to.equal('test text');
|
119
159
|
});
|
120
160
|
it('returns the content of the textarea when getting the `value` property', async () => {
|
121
|
-
const
|
122
|
-
const element = await fixture(template);
|
161
|
+
const element = await fixture(html `<glide-core-textarea value="" label="label"></glide-core-textarea>`);
|
123
162
|
element.focus();
|
124
163
|
await sendKeys({ type: 'test text' });
|
125
164
|
expect(element.value).to.equal('test text');
|
126
165
|
});
|
127
|
-
it('focuses the textarea when `focus` is called', async () => {
|
128
|
-
const
|
129
|
-
const element = await fixture(template);
|
166
|
+
it('focuses the textarea when `focus()` is called', async () => {
|
167
|
+
const element = await fixture(html `<glide-core-textarea value="" label="label"></glide-core-textarea>`);
|
130
168
|
element.focus();
|
131
169
|
await expect(element.shadowRoot?.activeElement?.tagName.toLocaleLowerCase()).to.be.equal('textarea');
|
132
170
|
});
|
133
171
|
it('blurs the textarea when `blur` is called', async () => {
|
134
|
-
const
|
135
|
-
const element = await fixture(template);
|
172
|
+
const element = await fixture(html `<glide-core-textarea value="" label="label"></glide-core-textarea>`);
|
136
173
|
element.focus();
|
137
174
|
await expect(element.shadowRoot?.activeElement?.tagName.toLocaleLowerCase()).to.be.equal('textarea');
|
138
175
|
element.blur();
|