Skip to content

Commit

Permalink
fix: iterate
Browse files Browse the repository at this point in the history
  • Loading branch information
luwes committed Mar 5, 2023
1 parent d6afd7b commit 0cefbee
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 8 deletions.
88 changes: 88 additions & 0 deletions extended.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<!doctype html>

<title>selectmenu polyfill</title>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', sans-serif;
line-height: 1.4;
max-width: 800px;
margin: 20px auto;
padding: 0 10px;
word-wrap: break-word;
color: #363636;
color: var(--text-main);
background: #fff;
background: var(--background-body);
text-rendering: optimizeLegibility;
}
</style>

<script type="module" src="src/selectmenu.js"></script>

<h1>SelectMenu Polyfill</h1>

<style>
.my-custom-select [slot='button'] {
display: flex;
align-items: center;
gap: 1rem;
}
.my-custom-select button {
border: none;
margin: 0;
padding: 0;
width: 2rem;
height: 2rem;
border-radius: 50%;
display: grid;
place-content: center;
}
.my-custom-select button::before {
content: '\25BC';
}
.my-custom-select [popup] {
padding: 0;
}
.my-custom-select .section {
padding: 1rem 0 0;
background: radial-gradient(ellipse 60% 50px at center top, #000a 0%, transparent 130%);
}
.my-custom-select h3 {
margin: 0 0 1rem 0;
text-align: center;
color: white;
}
.my-custom-select option {
text-align: center;
padding: 0.5rem;
}
</style>
<selectmenu class="my-custom-select">
<div slot="button">
<span class="label">Choose a plant</span>
<span behavior="selected-value" slot="selected-value"></span>
<button behavior="button"></button>
</div>
<div slot="listbox">
<div popup behavior="listbox">
<div class="section">
<h3>Flowers</h3>
<option>Rose</option>
<option>Lily</option>
<option>Orchid</option>
<option>Tulip</option>
</div>
<div class="section">
<h3>Trees</h3>
<option>Weeping willow</option>
<option>Dragon tree</option>
<option>Giant sequoia</option>
</div>
</div>
</div>
</selectmenu>

<br>
<br>

<a href="..">Back</a>
82 changes: 82 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,92 @@
<!doctype html>

<title>selectmenu polyfill</title>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', sans-serif;
line-height: 1.4;
max-width: 800px;
margin: 20px auto;
padding: 0 10px;
word-wrap: break-word;
color: #363636;
color: var(--text-main);
background: #fff;
background: var(--background-body);
text-rendering: optimizeLegibility;
}
</style>

<script type="module" src="src/selectmenu.js"></script>

<h1>SelectMenu Polyfill</h1>


<h3>Default behavior</h3>

<selectmenu>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</selectmenu>


<h3>Styling parts of the control</h3>

<style>
.my-select-menu::part(button) {
color: white;
background-color: #f00;
padding: 5px;
border-radius: 5px;
}

.my-select-menu::part(listbox) {
padding: 10px;
margin-top: 5px;
border: 1px solid red;
border-radius: 5px;
}
</style>
<selectmenu class="my-select-menu">
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</selectmenu>


<h3>Use your own markup</h3>

<style>
.my-custom-select [slot='button'] {
display: flex;
align-content: center;
}
.my-custom-select button {
padding: 5px;
border: none;
background: #f06;
border-radius: 5px 0 0 5px;
color: white;
font-weight: bold;
}
.my-custom-select .label {
padding: 5px;
border: 1px solid #f06;
border-radius: 0 5px 5px 0;
}
</style>
<selectmenu class="my-custom-select">
<div slot="button">
<button behavior="button">Open</button>
<span class="label">Choose an option</span>
</div>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
</selectmenu>

<br>
<br>

<a href="extended.html">Extended</a>
34 changes: 26 additions & 8 deletions src/selectmenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,43 +105,61 @@ class SelectMenuPolyfill {
selectmenu.addEventListener('click', this.#handleClick);
document.addEventListener('click', this.#handleBlur);

this.#defaultSlot.addEventListener('slotchange', this.#handleSlot);
this.#defaultSlot.addEventListener('slotchange', this.#handleDefaultSlot);
this.#listboxSlot.addEventListener('slotchange', this.#handleListboxSlot);
}

#select() {
const selected = this.#options
.find(el => el.hasAttribute('selected')) ?? this.#options[0];

this.#selectOption(selected);
}

#selectOption(option) {
this.#selectedValue.textContent = option.value;
}

#handleSlot = () => {
this.#options = this.#defaultSlot.assignedElements();
#handleDefaultSlot = () => {
this.#options = [...this.#selectmenu.querySelectorAll('option')];
this.#select();
}

const selected = this.#options.find(el => el.hasAttribute('selected')) ?? this.#options[0];
#handleListboxSlot = () => {
this.#options = [...this.#selectmenu.querySelectorAll('option')];
this.#select();
}

this.#selectOption(selected);
get #buttonSlot() {
return this.#selectmenu.shadowRoot.querySelector('slot[name=button]');
}

get #listboxSlot() {
return this.#selectmenu.shadowRoot.querySelector('slot[name=listbox]');
}

get #defaultSlot() {
return this.#selectmenu.shadowRoot.querySelector('slot:not([name])');
}

get #selectedValue() {
let selectedValue = this.#selectmenu.querySelector(':scope > [behavior=selected-value]');
let selectedValue = this.#selectmenu.querySelector('[behavior=selected-value]');
if (!selectedValue) {
selectedValue = this.#selectmenu.shadowRoot.querySelector('[behavior=selected-value]');
}
return selectedValue;
}

get #button() {
let button = this.#selectmenu.querySelector(':scope > [behavior=button]');
let button = this.#selectmenu.querySelector('[behavior=button]');
if (!button) {
button = this.#selectmenu.shadowRoot.querySelector('[behavior=button]');
}
return button;
}

get #listbox() {
let listbox = this.#selectmenu.querySelector(':scope > [behavior=listbox]');
let listbox = this.#selectmenu.querySelector('[behavior=listbox]');
if (!listbox) {
listbox = this.#selectmenu.shadowRoot.querySelector('[behavior=listbox]');
}
Expand Down

1 comment on commit 0cefbee

@vercel
Copy link

@vercel vercel bot commented on 0cefbee Mar 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

selectmenu-polyfill – ./

selectmenu-polyfill-git-main-luwes.vercel.app
selectmenu-polyfill-luwes.vercel.app
selectmenu-polyfill.vercel.app

Please sign in to comment.