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

mozilla / blurts-server / #13028

pending completion
#13028

push

circleci

web-flow
Merge pull request #2951 from mozilla/MNTOR-1475-Custom-email-select-width

MNTOR-1475: Wait for custom email select width to be available

282 of 1601 branches covered (17.61%)

Branch coverage included in aggregate %.

4 of 4 new or added lines in 1 file covered. (100.0%)

959 of 4323 relevant lines covered (22.18%)

1.85 hits per line

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

0.0
/src/client/js/components/custom-select.js
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4

5
const html = `
×
6
<style>
7
  :host{
8
    contain: style paint;
9
    position: relative;
10
    display: inline-block;
11
    width: min(100%, var(--option-w) + 20px);
12
    color: var(--purple-70);
13
  }
14

15
  :host([hidden]) {
16
    display: none 
17
  }
18

19
  select{
20
    appearance: none;
21
    background: none;
22
    border: none;
23
    outline: none;
24
    width: 100%;
25
    margin: 0;
26
    padding: 0 20px 0 0;
27
    overflow: hidden;
28
    text-overflow: ellipsis;
29
    font: inherit;
30
    color: inherit;
31
 }
32

33
  select.hidden{
34
    position: absolute;
35
    visibility: hidden;
36
    width: auto;
37
    padding: 0;
38
    pointer-events: none;
39
 }
40

41
  svg {
42
    position: absolute;
43
    top: 0;
44
    right: 0;
45
    width: 16px;
46
    height: 100%;
47
    color: inherit;
48
    pointer-events: none;
49
  }
50
</style>
51

52
<select></select>
53
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor">
54
  <path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/>
55
</svg>
56
`
57

58
customElements.define('custom-select', class extends HTMLElement {
×
59
  constructor () {
60
    super()
×
61
    this.attachShadow({ mode: 'open' })
×
62
    this.shadowRoot.innerHTML = html
×
63
    this.select = this.shadowRoot.querySelector('select')
×
64
    this.options = this.querySelectorAll('option')
×
65

66
    // move <option> elements into <select> (<slot> not permitted as <select> child)
67
    this.select.append(...this.options)
×
68
    this.setAttribute('value', this.select.value)
×
69
    this.setAttribute('selected-index', this.select.selectedIndex)
×
70
  }
71

72
  get value () {
73
    return this.getAttribute('value')
×
74
  }
75

76
  get selectedIndex () {
77
    return this.getAttribute('selected-index')
×
78
  }
79

80
  connectedCallback () {
81
    this.matchOptionWidth()
×
82
    this.select.addEventListener('change', this)
×
83
  }
84

85
  handleEvent (e) {
86
    switch (e.type) {
×
87
      case 'change':
88
        this.matchOptionWidth()
×
89
        this.setAttribute('value', e.target.value)
×
90
        this.setAttribute('selected-index', e.target.selectedIndex)
×
91
        this.dispatchEvent(new Event('change'))
×
92
        break
×
93
    }
94
  }
95

96
  matchOptionWidth () {
97
    // update <select> width based on selected <option> (override fixed width based on largest <option>)
98
    const temp = document.createElement('select')
×
99
    const selectedOption = this.options[this.select.selectedIndex]
×
100

101
    temp.className = 'hidden'
×
102
    temp.append(selectedOption.cloneNode(true))
×
103
    this.shadowRoot.append(temp)
×
104

105
    // let’s wait for the next tick to make sure that the dimensions of temp are available
106
    window.requestAnimationFrame(() => {
×
107
      temp.w = Math.ceil(temp.getBoundingClientRect().width) + 5 // adds 5px safety for font load delay or other quirks
×
108
      this.style.setProperty('--option-w', `${temp.w}px`)
×
109
      temp.remove()
×
110
    })
111
  }
112

113
  disconnectedCallback () {
114
    this.select.removeEventListener('change', this)
×
115
  }
116
})
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