• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

adobe / spectrum-web-components / 12192801342

06 Dec 2024 04:11AM UTC coverage: 98.146% (-0.06%) from 98.206%
12192801342

Pull #4973

github

web-flow
Merge 65e01d036 into 05d24ffc4
Pull Request #4973: chore: update css dependencies

5138 of 5410 branches covered (94.97%)

Branch coverage included in aggregate %.

17 of 17 new or added lines in 17 files covered. (100.0%)

26 existing lines in 2 files now uncovered.

32814 of 33259 relevant lines covered (98.66%)

392.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.21
/packages/tray/src/Tray.ts
1
/*
8✔
2
Copyright 2020 Adobe. All rights reserved.
8✔
3
This file is licensed to you under the Apache License, Version 2.0 (the "License");
8✔
4
you may not use this file except in compliance with the License. You may obtain a copy
8✔
5
of the License at http://www.apache.org/licenses/LICENSE-2.0
8✔
6

8✔
7
Unless required by applicable law or agreed to in writing, software distributed under
8✔
8
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
8✔
9
OF ANY KIND, either express or implied. See the License for the specific language
8✔
10
governing permissions and limitations under the License.
8✔
11
*/
8✔
12

8✔
13
import {
8✔
14
    CSSResultArray,
8✔
15
    html,
8✔
16
    PropertyValues,
8✔
17
    SpectrumElement,
8✔
18
    TemplateResult,
8✔
19
} from '@spectrum-web-components/base';
8✔
20
import {
8✔
21
    property,
8✔
22
    query,
8✔
23
} from '@spectrum-web-components/base/src/decorators.js';
8✔
24
import '@spectrum-web-components/underlay/sp-underlay.js';
8✔
25
import { firstFocusableIn } from '@spectrum-web-components/shared/src/first-focusable-in.js';
8✔
26
import { MatchMediaController } from '@spectrum-web-components/reactive-controllers/src/MatchMedia.js';
8✔
27

8✔
28
import modalStyles from '@spectrum-web-components/modal/src/modal.css.js';
8✔
29
import styles from './tray.css.js';
8✔
30

8✔
31
/**
8✔
32
 * @element sp-tray
8✔
33
 *
8✔
34
 * @slot - content to display within the Tray
8✔
35
 *
8✔
36
 * @fires close - Announces that the Tray has been closed.
8✔
37
 */
8✔
38
export class Tray extends SpectrumElement {
8✔
39
    public static override get styles(): CSSResultArray {
8✔
40
        return [modalStyles, styles];
8✔
41
    }
8✔
42

8✔
43
    @property({ type: Boolean, reflect: true })
8✔
44
    public open = false;
8✔
45

8✔
46
    protected prefersMotion = new MatchMediaController(
8✔
47
        this,
8✔
48
        '(prefers-reduced-motion: no-preference)'
8✔
49
    );
8✔
50

8✔
51
    private transitionPromise = Promise.resolve();
8✔
52

8✔
53
    private resolveTransitionPromise = () => {};
8✔
54

8✔
55
    @query('.tray')
8✔
56
    private tray!: HTMLDivElement;
8✔
57

8✔
58
    public override focus(): void {
8✔
59
        const firstFocusable = firstFocusableIn(this);
2✔
60
        if (firstFocusable) {
2✔
61
            firstFocusable.focus();
1✔
62
        } else if (this.children.length === 1) {
1✔
63
            this.tray.focus();
1✔
64
        } else {
1✔
65
            super.focus();
×
66
        }
×
67
    }
2✔
68

8✔
69
    private animating = false;
8✔
70

8✔
71
    public overlayWillCloseCallback(): boolean {
8✔
72
        if (!this.open) return this.animating;
×
73
        this.close();
×
74
        return true;
×
75
    }
×
76

8✔
77
    public close(): void {
8✔
UNCOV
78
        this.open = false;
×
UNCOV
79
        if (!this.prefersMotion.matches) {
×
80
            this.dispatchClosed();
×
81
        }
×
UNCOV
82
    }
×
83

8✔
84
    private dispatchClosed(): void {
8✔
UNCOV
85
        this.dispatchEvent(
×
UNCOV
86
            new Event('close', {
×
UNCOV
87
                bubbles: true,
×
UNCOV
88
            })
×
UNCOV
89
        );
×
UNCOV
90
    }
×
91

8✔
92
    protected handleUnderlayTransitionend(): void {
8✔
UNCOV
93
        if (!this.open) {
×
UNCOV
94
            this.resolveTransitionPromise();
×
UNCOV
95
            this.dispatchClosed();
×
UNCOV
96
        }
×
UNCOV
97
    }
×
98

8✔
99
    protected handleTrayTransitionend(): void {
8✔
UNCOV
100
        if (this.open) {
×
UNCOV
101
            this.resolveTransitionPromise();
×
UNCOV
102
        }
×
UNCOV
103
    }
×
104

8✔
105
    protected override update(changes: PropertyValues<this>): void {
8✔
106
        if (
13✔
107
            changes.has('open') &&
13✔
108
            changes.get('open') !== undefined &&
13✔
109
            this.prefersMotion.matches
5✔
110
        ) {
13✔
111
            this.animating = true;
5✔
112
            this.transitionPromise = new Promise((res) => {
5✔
113
                this.resolveTransitionPromise = () => {
5✔
UNCOV
114
                    this.animating = false;
×
UNCOV
115
                    res();
×
UNCOV
116
                };
×
117
            });
5✔
118
        }
5✔
119
        super.update(changes);
13✔
120
    }
13✔
121

8✔
122
    protected override render(): TemplateResult {
8✔
123
        return html`
13✔
124
            <sp-underlay
13✔
125
                ?open=${this.open}
13✔
126
                @close=${this.close}
13✔
127
                @transitionend=${this.handleUnderlayTransitionend}
13✔
128
            ></sp-underlay>
13✔
129
            <div
13✔
130
                class="tray modal"
13✔
131
                tabindex="-1"
13✔
132
                @transitionend=${this.handleTrayTransitionend}
13✔
133
            >
13✔
134
                <slot></slot>
13✔
135
            </div>
13✔
136
        `;
13✔
137
    }
13✔
138

8✔
139
    /**
8✔
140
     * Bind the open/close transition into the update complete lifecycle so
8✔
141
     * that the overlay system can wait for it to be "visibly ready" before
8✔
142
     * attempting to throw focus into the content contained herein. Not
8✔
143
     * waiting for this can cause small amounts of page scroll to happen
8✔
144
     * while opening the Tray when focusable content is included: e.g. Menu
8✔
145
     * elements whose selected Menu Item is not the first Menu Item.
8✔
146
     */
8✔
147
    protected override async getUpdateComplete(): Promise<boolean> {
8✔
148
        const complete = (await super.getUpdateComplete()) as boolean;
13✔
149
        await this.transitionPromise;
13✔
150
        return complete;
10✔
151
    }
13✔
152
}
8✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc