mirror of
https://github.com/hunvreus/basecoat.git
synced 2026-11-11 04:38:18 +00:00
Fixing more issues with popovers
This commit is contained in:
@@ -8,21 +8,19 @@
|
||||
</a>
|
||||
</header>
|
||||
<div class="p-4">
|
||||
<div class="flex flex-col gap-4">
|
||||
{% set footer %}
|
||||
<button class="btn-outline" @click="open = false">Cancel</button>
|
||||
<button class="btn-primary" @click="open = false">Continue</button>
|
||||
{% endset %}
|
||||
{{ dialog(
|
||||
id="alert-dialog-demo",
|
||||
title="Are you absolutely sure?",
|
||||
description="This action cannot be undone. This will permanently delete your account and remove your data from our servers.",
|
||||
trigger="Open dialog",
|
||||
trigger_attrs={"class": "btn-outline"},
|
||||
footer=footer,
|
||||
close_button=false,
|
||||
close_on_overlay_click=false
|
||||
) }}
|
||||
</div>
|
||||
{% set footer %}
|
||||
<button class="btn-outline" @click="open = false">Cancel</button>
|
||||
<button class="btn-primary" @click="open = false">Continue</button>
|
||||
{% endset %}
|
||||
{{ dialog(
|
||||
id="alert-dialog-demo",
|
||||
title="Are you absolutely sure?",
|
||||
description="This action cannot be undone. This will permanently delete your account and remove your data from our servers.",
|
||||
trigger="Open dialog",
|
||||
trigger_attrs={"class": "btn-outline"},
|
||||
footer=footer,
|
||||
close_button=false,
|
||||
close_on_overlay_click=false
|
||||
) }}
|
||||
</div>
|
||||
</section>
|
||||
@@ -16,7 +16,7 @@
|
||||
popover_attrs={"class": "min-w-56"}
|
||||
) %}
|
||||
<div role="group" aria-labelledby="account-options">
|
||||
<div role="presentation" id="account-options">My Account</div>
|
||||
<div role="heading" id="account-options">My Account</div>
|
||||
<div role="menuitem">
|
||||
Profile
|
||||
<span class="text-muted-foreground ml-auto text-xs tracking-widest">⇧⌘P</span>
|
||||
@@ -37,7 +37,7 @@
|
||||
<hr role="separator">
|
||||
<div role="menuitem">GitHub</div>
|
||||
<div role="menuitem">Support</div>
|
||||
<div role="menuitem" disabled>API</div>
|
||||
<div role="menuitem" aria-disabled="true">API</div>
|
||||
<hr role="separator">
|
||||
<div role="menuitem">
|
||||
Logout
|
||||
@@ -52,7 +52,7 @@
|
||||
popover_attrs={"class": "min-w-56"}
|
||||
) %}
|
||||
<div role="group" aria-labelledby="account-options">
|
||||
<div role="presentation" id="account-options">Account Options</div>
|
||||
<div role="heading" id="account-options">Account Options</div>
|
||||
<div role="menuitem">
|
||||
{% lucide "user" %}
|
||||
Profile
|
||||
@@ -71,7 +71,7 @@
|
||||
</div>
|
||||
<hr role="separator">
|
||||
<div role="group" aria-labelledby="appearance-options">
|
||||
<div role="presentation" id="appearance-options">Appearance</div>
|
||||
<div role="heading" id="appearance-options">Appearance</div>
|
||||
<div
|
||||
role="menuitemcheckbox"
|
||||
aria-checked="true"
|
||||
@@ -92,7 +92,7 @@
|
||||
role="menuitemcheckbox"
|
||||
aria-checked="false"
|
||||
class="group"
|
||||
disabled
|
||||
aria-disabled="true"
|
||||
x-data="{ checked: false }"
|
||||
@click="checked = !checked"
|
||||
:aria-checked="checked"
|
||||
|
||||
+15
-18
@@ -1015,11 +1015,6 @@
|
||||
.filter {
|
||||
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
||||
}
|
||||
.transition {
|
||||
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter;
|
||||
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
||||
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
||||
}
|
||||
.transition-all {
|
||||
transition-property: all;
|
||||
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
||||
@@ -2558,28 +2553,30 @@
|
||||
& svg {
|
||||
color: var(--color-muted-foreground);
|
||||
}
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
&:not([aria-disabled='true']) {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
background-color: var(--color-accent);
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
color: var(--color-accent-foreground);
|
||||
}
|
||||
}
|
||||
&:focus-visible {
|
||||
background-color: var(--color-accent);
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
&:focus-visible {
|
||||
color: var(--color-accent-foreground);
|
||||
}
|
||||
}
|
||||
&:focus-visible {
|
||||
background-color: var(--color-accent);
|
||||
}
|
||||
&:focus-visible {
|
||||
color: var(--color-accent-foreground);
|
||||
}
|
||||
&.active {
|
||||
background-color: var(--color-accent);
|
||||
color: var(--color-accent-foreground);
|
||||
}
|
||||
}
|
||||
[role='menu'] [role="presentation"] {
|
||||
[role='menu'] [role='heading'] {
|
||||
display: flex;
|
||||
padding-inline: calc(var(--spacing) * 2);
|
||||
padding-block: calc(var(--spacing) * 1.5);
|
||||
@@ -3171,7 +3168,7 @@
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
[role='listbox'] [role="presentation"] {
|
||||
[role='listbox'] [role='heading'] {
|
||||
display: flex;
|
||||
padding-inline: calc(var(--spacing) * 2);
|
||||
padding-block: calc(var(--spacing) * 1.5);
|
||||
|
||||
@@ -213,7 +213,7 @@ toc:
|
||||
<div class="max-h-64 overflow-y-auto scrollbar">
|
||||
{% for group in options_timezones %}
|
||||
<div role="group" aria-labelledby="demo-combobox-timezones-group-{{ loop.index0 }}">
|
||||
<div role="presentation" id="demo-combobox-timezones-group-{{ loop.index0 }}">{{ group.label }}</div>
|
||||
<div role="heading" id="demo-combobox-timezones-group-{{ loop.index0 }}">{{ group.label }}</div>
|
||||
{% for timezone in group.timezones %}
|
||||
<div role="option" data-value="{{ timezone.value}}">
|
||||
{{ timezone.label }}
|
||||
|
||||
@@ -38,7 +38,7 @@ toc:
|
||||
popover_attrs={"class": "min-w-56"}
|
||||
) %}
|
||||
<div role="group" aria-labelledby="account-options">
|
||||
<div role="presentation" id="account-options">My Account</div>
|
||||
<div role="heading" id="account-options">My Account</div>
|
||||
<div role="menuitem">
|
||||
Profile
|
||||
<span class="text-muted-foreground ml-auto text-xs tracking-widest">⇧⌘P</span>
|
||||
@@ -63,7 +63,7 @@ toc:
|
||||
<div role="menuitem">
|
||||
Support
|
||||
</div>
|
||||
<div role="menuitem" disabled>
|
||||
<div role="menuitem" aria-disabled="true">
|
||||
API
|
||||
</div>
|
||||
<hr role="separator">
|
||||
@@ -183,7 +183,7 @@ toc:
|
||||
popover_attrs={"class": "min-w-56"}
|
||||
) %}
|
||||
<div role="group" aria-labelledby="account-options">
|
||||
<div role="presentation" id="account-options">My Account</div>
|
||||
<div role="heading" id="account-options">My Account</div>
|
||||
<div role="menuitem">
|
||||
Profile
|
||||
<span class="text-muted-foreground ml-auto text-xs tracking-widest">⇧⌘P</span>
|
||||
@@ -230,7 +230,7 @@ toc:
|
||||
popover_attrs={"class": "min-w-56"}
|
||||
) %}
|
||||
<div role="group" aria-labelledby="account-options">
|
||||
<div role="presentation" id="account-options">Account Options</div>
|
||||
<div role="heading" id="account-options">Account Options</div>
|
||||
<div role="menuitem">
|
||||
{% lucide "user" %}
|
||||
Profile
|
||||
@@ -249,7 +249,7 @@ toc:
|
||||
</div>
|
||||
<hr role="separator">
|
||||
<div role="group" aria-labelledby="appearance-options">
|
||||
<div role="presentation" id="appearance-options">Appearance</div>
|
||||
<div role="heading" id="appearance-options">Appearance</div>
|
||||
<div
|
||||
role="menuitemcheckbox"
|
||||
aria-checked="true"
|
||||
|
||||
@@ -76,7 +76,7 @@ toc:
|
||||
menu=menu
|
||||
) }}
|
||||
<main>
|
||||
<button type="button" onclick="window.dispatchEvent(new CustomEvent('basecoat:sidebar'))">Toggle sidebar</button>
|
||||
<button type="button" onclick="document.dispatchEvent(new CustomEvent('basecoat:sidebar'))">Toggle sidebar</button>
|
||||
<h1>Content</h1>
|
||||
</main>
|
||||
{% endset %}
|
||||
@@ -86,9 +86,9 @@ toc:
|
||||
<p>Any element on the page can toggle, open or close the sidebar by dispatching the <code>basecoat:sidebar</code>. By default, the event will toggle the sidebar, but can be used to open or close if you add an <code>action</code> to the detail:</p>
|
||||
</section>
|
||||
|
||||
{% set code_trigger %}<button type="button" onclick="window.dispatchEvent(new CustomEvent('basecoat:sidebar'));">Toggle sidebar</button>
|
||||
<button type="button" onclick="window.dispatchEvent(new CustomEvent('basecoat:sidebar', { detail: { action: 'open' } }));">Open sidebar</button>
|
||||
<button type="button" onclick="window.dispatchEvent(new CustomEvent('basecoat:sidebar', { detail: { action: 'close' } }));">Close sidebar</button>{% endset %}
|
||||
{% set code_trigger %}<button type="button" onclick="document.dispatchEvent(new CustomEvent('basecoat:sidebar'));">Toggle sidebar</button>
|
||||
<button type="button" onclick="document.dispatchEvent(new CustomEvent('basecoat:sidebar', { detail: { action: 'open' } }));">Open sidebar</button>
|
||||
<button type="button" onclick="document.dispatchEvent(new CustomEvent('basecoat:sidebar', { detail: { action: 'close' } }));">Close sidebar</button>{% endset %}
|
||||
{{ code_block(code_trigger | prettyHtml, "html") }}
|
||||
|
||||
<h4 id="usage-html-js-3"><a href="#usage-html-js-3">HTML structure</a></h4>
|
||||
@@ -155,8 +155,8 @@ toc:
|
||||
</dd>
|
||||
<dt><code class="highlight language-html"><main></code></dt>
|
||||
<dd>A wrapper for the content of the page.</dd>
|
||||
<dt><code class="highlight language-html"><button type="button" onclick="window.dispatchEvent(new CustomEvent('sidebar:toggle'))"></code></dt>
|
||||
<dd>A button to toggle the sidebar. If you want to use multiple sidebars you will need to add unique ids to the sidebars (i.e. <code><aside class="sidebar" id="{SIDEBAR_ID}"></code>) and refer to them in the event <code>detail</code> (i.e. <code>window.dispatchEvent(new CustomEvent('sidebar:toggle', { detail: { id: '{SIDEBAR_ID}' } }));</code>).</dd>
|
||||
<dt><code class="highlight language-html"><button type="button" onclick="document.dispatchEvent(new CustomEvent('sidebar:toggle'))"></code></dt>
|
||||
<dd>A button to toggle the sidebar. If you want to use multiple sidebars you will need to add unique ids to the sidebars (i.e. <code><aside class="sidebar" id="{SIDEBAR_ID}"></code>) and refer to them in the event <code>detail</code> (i.e. <code>document.dispatchEvent(new CustomEvent('sidebar:toggle', { detail: { id: '{SIDEBAR_ID}' } }));</code>).</dd>
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ toc:
|
||||
|
||||
{% set code_client_side %}<button
|
||||
class="btn-outline"
|
||||
onclick="window.dispatchEvent(new CustomEvent('basecoat:toast', {
|
||||
onclick="document.dispatchEvent(new CustomEvent('basecoat:toast', {
|
||||
detail: {
|
||||
config: {
|
||||
category: 'success',
|
||||
|
||||
@@ -92,7 +92,7 @@ toc:
|
||||
<li class="step mt-8">
|
||||
<h3 class="mb-4 scroll-m-20 font-semibold tracking-tight" id="install-npm-js"><a href="#install-npm-js">(Optional) Add JavaScript files</a></h3>
|
||||
<div class="prose">
|
||||
<p>Some components <a href="#install-js">need some JavaScript/a> (e.g. the <a href="/components/tabs">Tabs</a> component). There are two ways to get it into your project:</p>
|
||||
<p>Some components <a href="#install-js">need some JavaScript</a> (e.g. the <a href="/components/tabs">Tabs</a> component). There are two ways to get it into your project:</p>
|
||||
|
||||
<h4 class="mt-6 font-semibold">Using a build tool (Vite, Webpack…)</h4>
|
||||
<p>If your project is ESM-aware you can directly import the scripts. To include all components:</p>
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "basecoat",
|
||||
"version": "0.2.2",
|
||||
"version": "0.2.3",
|
||||
"description": "shadcn/ui for the rest of us",
|
||||
"author": "hunvreus",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "basecoat-cli",
|
||||
"version": "0.2.2",
|
||||
"version": "0.2.3",
|
||||
"description": "Add Basecoat components to your project",
|
||||
"author": "hunvreus",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "basecoat-css",
|
||||
"version": "0.2.2",
|
||||
"version": "0.2.3",
|
||||
"description": "Tailwind CSS for Basecoat components",
|
||||
"author": {
|
||||
"name": "hunvreus",
|
||||
|
||||
@@ -514,12 +514,16 @@
|
||||
[role='menuitemcheckbox'],
|
||||
[role='menuitemradio'] {
|
||||
@apply aria-hidden:hidden [&_svg]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none [&_svg]:shrink-0 [&_svg]:size-4 aria-disabled:opacity-50 aria-disabled:pointer-events-none disabled:opacity-50 disabled:pointer-events-none w-full truncate;
|
||||
@apply focus-visible:bg-accent focus-visible:text-accent-foreground hover:bg-accent hover:text-accent-foreground;
|
||||
|
||||
&:not([aria-disabled='true']) {
|
||||
@apply focus-visible:bg-accent focus-visible:text-accent-foreground hover:bg-accent hover:text-accent-foreground;
|
||||
}
|
||||
|
||||
&.active {
|
||||
@apply bg-accent text-accent-foreground;
|
||||
}
|
||||
}
|
||||
[role='menu'] [role="presentation"] {
|
||||
[role='menu'] [role='heading'] {
|
||||
@apply flex px-2 py-1.5 text-sm font-medium;
|
||||
}
|
||||
[role='separator'] {
|
||||
@@ -734,7 +738,7 @@
|
||||
@apply bg-[image:var(--check-icon)] bg-no-repeat bg-position-[center_right_0.5rem] bg-size-[0.875rem];
|
||||
}
|
||||
}
|
||||
[role='listbox'] [role="presentation"] {
|
||||
[role='listbox'] [role='heading'] {
|
||||
@apply flex text-muted-foreground px-2 py-1.5 text-xs;
|
||||
}
|
||||
[role='listbox'] [role='group']:not(:has([role='option']:not([aria-hidden='true']))) {
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
>
|
||||
<div role="presentation" id="{{ group_label_id }}">{{ item.label }}</div>
|
||||
<div role="heading" id="{{ group_label_id }}">{{ item.label }}</div>
|
||||
{{ render_dropdown_items(item.items, item_id) if item.items }}
|
||||
</div>
|
||||
{% elif item.type == "separator" %}
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
>
|
||||
<div role="presentation" id="{{ group_label_id }}">{{ item.label }}</div>
|
||||
<div role="heading" id="{{ group_label_id }}">{{ item.label }}</div>
|
||||
{{ render_select_items(item.items, selected, item_id) if item.items }}
|
||||
</div>
|
||||
{% elif item.type == "separator" %}
|
||||
|
||||
+31
-18
@@ -16,19 +16,30 @@
|
||||
let menuItems = [];
|
||||
let activeIndex = -1;
|
||||
|
||||
const closeMenu = () => {
|
||||
const closePopover = (focusOnTrigger = true) => {
|
||||
if (trigger.getAttribute('aria-expanded') === 'false') return;
|
||||
trigger.setAttribute('aria-expanded', 'false');
|
||||
trigger.removeAttribute('aria-activedescendant');
|
||||
popover.setAttribute('aria-hidden', 'true');
|
||||
trigger.focus();
|
||||
|
||||
if (focusOnTrigger) {
|
||||
trigger.focus();
|
||||
}
|
||||
|
||||
setActiveItem(-1);
|
||||
};
|
||||
|
||||
const openMenu = () => {
|
||||
const openPopover = () => {
|
||||
document.dispatchEvent(new CustomEvent('basecoat:popover', {
|
||||
detail: { source: dropdownMenuComponent }
|
||||
}));
|
||||
|
||||
trigger.setAttribute('aria-expanded', 'true');
|
||||
popover.setAttribute('aria-hidden', 'false');
|
||||
menuItems = Array.from(menu.querySelectorAll('[role^="menuitem"]:not([disabled])'));
|
||||
menuItems = Array.from(menu.querySelectorAll('[role^="menuitem"]')).filter(item =>
|
||||
!item.hasAttribute('disabled') &&
|
||||
item.getAttribute('aria-disabled') !== 'true'
|
||||
);
|
||||
if (menuItems.length > 0) {
|
||||
setActiveItem(0);
|
||||
}
|
||||
@@ -51,9 +62,9 @@
|
||||
trigger.addEventListener('click', () => {
|
||||
const isExpanded = trigger.getAttribute('aria-expanded') === 'true';
|
||||
if (isExpanded) {
|
||||
closeMenu();
|
||||
closePopover();
|
||||
} else {
|
||||
openMenu();
|
||||
openPopover();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -61,14 +72,14 @@
|
||||
const isExpanded = trigger.getAttribute('aria-expanded') === 'true';
|
||||
|
||||
if (event.key === 'Escape') {
|
||||
if (isExpanded) closeMenu();
|
||||
if (isExpanded) closePopover();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isExpanded) {
|
||||
if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(event.key)) {
|
||||
event.preventDefault();
|
||||
openMenu();
|
||||
openPopover();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -80,15 +91,11 @@
|
||||
switch (event.key) {
|
||||
case 'ArrowDown':
|
||||
event.preventDefault();
|
||||
if (activeIndex < menuItems.length - 1) {
|
||||
nextIndex = activeIndex + 1;
|
||||
}
|
||||
break;
|
||||
nextIndex = Math.min(activeIndex + 1, menuItems.length - 1);
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
event.preventDefault();
|
||||
if (activeIndex > 0) {
|
||||
nextIndex = activeIndex - 1;
|
||||
}
|
||||
nextIndex = Math.max(activeIndex - 1, 0);
|
||||
break;
|
||||
case 'Home':
|
||||
event.preventDefault();
|
||||
@@ -102,7 +109,7 @@
|
||||
case ' ':
|
||||
event.preventDefault();
|
||||
menuItems[activeIndex]?.click();
|
||||
closeMenu();
|
||||
closePopover();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -113,13 +120,19 @@
|
||||
|
||||
menu.addEventListener('click', (event) => {
|
||||
if (event.target.closest('[role^="menuitem"]')) {
|
||||
closeMenu();
|
||||
closePopover();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('click', (event) => {
|
||||
if (!dropdownMenuComponent.contains(event.target)) {
|
||||
closeMenu();
|
||||
closePopover();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('basecoat:popover', (event) => {
|
||||
if (event.detail.source !== dropdownMenuComponent) {
|
||||
closePopover(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+14
-2
@@ -11,14 +11,20 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const closePopover = () => {
|
||||
const closePopover = (focusOnTrigger = true) => {
|
||||
if (trigger.getAttribute('aria-expanded') === 'false') return;
|
||||
trigger.setAttribute('aria-expanded', 'false');
|
||||
content.setAttribute('aria-hidden', 'true');
|
||||
trigger.focus();
|
||||
if (focusOnTrigger) {
|
||||
trigger.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const openPopover = () => {
|
||||
document.dispatchEvent(new CustomEvent('basecoat:popover', {
|
||||
detail: { source: popoverComponent }
|
||||
}));
|
||||
|
||||
const elementToFocus = content.querySelector('[autofocus]');
|
||||
if (elementToFocus) {
|
||||
content.addEventListener('transitionend', () => {
|
||||
@@ -51,6 +57,12 @@
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('basecoat:popover', (event) => {
|
||||
if (event.detail.source !== popoverComponent) {
|
||||
closePopover(false);
|
||||
}
|
||||
});
|
||||
|
||||
popoverComponent.dataset.popoverInitialized = true;
|
||||
};
|
||||
|
||||
|
||||
+40
-27
@@ -148,7 +148,7 @@
|
||||
if (currentVisibleIndex > 0) {
|
||||
nextVisibleIndex = currentVisibleIndex - 1;
|
||||
} else if (currentVisibleIndex === -1) {
|
||||
nextVisibleIndex = 0; // Start from top if nothing is active
|
||||
nextVisibleIndex = 0;
|
||||
}
|
||||
break;
|
||||
case 'Home':
|
||||
@@ -180,37 +180,44 @@
|
||||
filter.addEventListener('keydown', handleKeyNavigation);
|
||||
}
|
||||
|
||||
const openPopover = () => {
|
||||
document.dispatchEvent(new CustomEvent('basecoat:popover', {
|
||||
detail: { source: selectComponent }
|
||||
}));
|
||||
|
||||
if (filter) {
|
||||
if (hasTransition()) {
|
||||
popover.addEventListener('transitionend', () => {
|
||||
filter.focus();
|
||||
}, { once: true });
|
||||
} else {
|
||||
filter.focus();
|
||||
}
|
||||
}
|
||||
|
||||
popover.setAttribute('aria-hidden', 'false');
|
||||
trigger.setAttribute('aria-expanded', 'true');
|
||||
|
||||
const selectedOption = listbox.querySelector('[role="option"][aria-selected="true"]');
|
||||
if (selectedOption) {
|
||||
if (activeIndex > -1) {
|
||||
options[activeIndex]?.classList.remove('active');
|
||||
}
|
||||
activeIndex = options.indexOf(selectedOption);
|
||||
selectedOption.classList.add('active');
|
||||
if (selectedOption.id) {
|
||||
trigger.setAttribute('aria-activedescendant', selectedOption.id);
|
||||
}
|
||||
selectedOption.scrollIntoView({ block: 'nearest' });
|
||||
}
|
||||
};
|
||||
|
||||
trigger.addEventListener('click', () => {
|
||||
const isExpanded = trigger.getAttribute('aria-expanded') === 'true';
|
||||
|
||||
if (isExpanded) {
|
||||
closePopover();
|
||||
} else {
|
||||
if (filter) {
|
||||
if (hasTransition()) {
|
||||
popover.addEventListener('transitionend', () => {
|
||||
filter.focus();
|
||||
}, { once: true });
|
||||
} else {
|
||||
filter.focus();
|
||||
}
|
||||
}
|
||||
|
||||
popover.setAttribute('aria-hidden', 'false');
|
||||
trigger.setAttribute('aria-expanded', 'true');
|
||||
|
||||
const selectedOption = listbox.querySelector('[role="option"][aria-selected="true"]');
|
||||
if (selectedOption) {
|
||||
if (activeIndex > -1) {
|
||||
options[activeIndex]?.classList.remove('active');
|
||||
}
|
||||
activeIndex = options.indexOf(selectedOption);
|
||||
selectedOption.classList.add('active');
|
||||
if (selectedOption.id) {
|
||||
trigger.setAttribute('aria-activedescendant', selectedOption.id);
|
||||
}
|
||||
selectedOption.scrollIntoView({ block: 'nearest' });
|
||||
}
|
||||
openPopover();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -227,6 +234,12 @@
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('basecoat:popover', (event) => {
|
||||
if (event.detail.source !== selectComponent) {
|
||||
closePopover(false);
|
||||
}
|
||||
});
|
||||
|
||||
popover.setAttribute('aria-hidden', 'true');
|
||||
selectComponent.dataset.selectInitialized = true;
|
||||
};
|
||||
|
||||
+1
-1
@@ -166,7 +166,7 @@
|
||||
const initialToaster = document.getElementById('toaster');
|
||||
if (initialToaster) initToaster(initialToaster);
|
||||
|
||||
window.addEventListener('basecoat:toast', (event) => {
|
||||
document.addEventListener('basecoat:toast', (event) => {
|
||||
if (!toaster) {
|
||||
console.error('Cannot create toast: toaster container not found on page.');
|
||||
return;
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
>
|
||||
<div role="presentation" id="{{ group_label_id }}">{{ item.label }}</div>
|
||||
<div role="heading" id="{{ group_label_id }}">{{ item.label }}</div>
|
||||
{{ render_dropdown_items(item.items, item_id) if item.items }}
|
||||
</div>
|
||||
{% elif item.type == "separator" %}
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
>
|
||||
<div role="presentation" id="{{ group_label_id }}">{{ item.label }}</div>
|
||||
<div role="heading" id="{{ group_label_id }}">{{ item.label }}</div>
|
||||
{{ render_select_items(item.items, selected, item_id) if item.items }}
|
||||
</div>
|
||||
{% elif item.type == "separator" %}
|
||||
|
||||
Reference in New Issue
Block a user