Compare commits

..

1 Commits

Author SHA1 Message Date
Cory LaViska
010f8402f6 update links to github 2025-06-02 07:42:26 -04:00
17 changed files with 28 additions and 633 deletions

View File

@@ -1,7 +1,7 @@
contact_links:
- name: Feature Requests
url: https://github.com/shoelace-style/shoelace/discussions/categories/ideas
url: https://github.com/shoelace-style/webawesome-alpha/discussions/categories/ideas
about: All requests for new features should go here.
- name: Help & Support
url: https://github.com/shoelace-style/shoelace/discussions/categories/help
url: https://github.com/shoelace-style/webawesome-alpha/discussions/categories/help-support
about: Please don't create issues for personal help requests. Instead, ask your question on the discussion forum.

View File

@@ -125,7 +125,7 @@ export default async function (eleventyConfig) {
eleventyConfig.addPlugin(currentLink());
// Add code examples for `<code class="example">` blocks
eleventyConfig.addPlugin(codeExamplesPlugin());
eleventyConfig.addPlugin(codeExamplesPlugin);
// Highlight code blocks with Prism
eleventyConfig.addPlugin(highlightCodePlugin());
@@ -136,10 +136,6 @@ export default async function (eleventyConfig) {
// Various text replacements
eleventyConfig.addPlugin(
replaceTextPlugin([
{
replace: /\[version\]/gs,
replaceWith: packageData.version,
},
// Replace [issue:1234] with a link to the issue on GitHub
{
replace: /\[pr:([0-9]+)\]/gs,

View File

@@ -137,7 +137,6 @@
</ul>
</li>
<li><a href="/docs/components/mutation-observer/">Mutation Observer</a></li>
<li><a href="/docs/components/popover/">Popover</a></li>
<li><a href="/docs/components/popup/">Popup</a></li>
<li><a href="/docs/components/progress-bar/">Progress Bar</a></li>
<li><a href="/docs/components/progress-ring/">Progress Ring</a></li>
@@ -175,7 +174,6 @@
<li><a href="/docs/components/tooltip/">Tooltip</a></li>
<li><a href="/docs/components/tree/">Tree</a></li>
<li><a href="/docs/components/tree-item/">Tree Item</a></li>
{# PLOP_NEW_COMPONENT_PLACEHOLDER #}
</ul>
</wa-details>

View File

@@ -1,19 +1,3 @@
import { allDefined } from '/dist/webawesome.js';
/**
* Determines how the page was loaded. Possible return values include "reload", "navigate", "back_forward", "prerender",
* and "unknown".
*/
function getNavigationType() {
if (performance.getEntriesByType) {
const navEntries = performance.getEntriesByType('navigation');
if (navEntries.length > 0) {
return navEntries[0].type;
}
}
return 'unknown';
}
// Smooth links
document.addEventListener('click', event => {
const link = event.target.closest('a');
@@ -47,26 +31,3 @@ function updateScrollClass() {
window.addEventListener('scroll', updateScrollClass);
window.addEventListener('turbo:render', updateScrollClass);
updateScrollClass();
// Restore scroll position after components are defined
allDefined().then(() => {
const navigationType = getNavigationType();
const key = `wa-scroll-y-[${location.pathname}]`;
const scrollY = sessionStorage.getItem(key);
// Only restore when reloading, otherwise clear it
if (navigationType === 'reload' && scrollY) {
window.scrollTo(0, scrollY);
} else {
sessionStorage.removeItem(key);
}
// After restoring, keep tabs on the page's scroll position for next reload
window.addEventListener(
'scroll',
() => {
sessionStorage.setItem(key, window.scrollY);
},
{ passive: true },
);
});

View File

@@ -1,143 +0,0 @@
---
title: Popover
layout: component
---
Popovers display interactive content when their anchor element is clicked. Unlike [tooltips](/docs/components/tooltip), popovers can contain links, buttons, and form controls. They appear without an overlay and will close when you click outside or press [[Escape]]. Only one popover can be open at a time.
```html {.example}
<wa-popover for="popover__overview">
<div style="display: flex; flex-direction: column; gap: 1rem;">
<p>This popover contains interactive content that users can engage with directly.</p>
<wa-button variant="primary" size="small">Take Action</wa-button>
</div>
</wa-popover>
<wa-button id="popover__overview">Show popover</wa-button>
```
## Examples
### Assigning an Anchor
Use `<wa-button>` or `<button>` elements as popover anchors. Connect the popover to its anchor by setting the `for` attribute to match the anchor's `id`.
```html {.example}
<wa-button id="popover__anchor-button">Show Popover</wa-button>
<wa-popover for="popover__anchor-button">
I'm anchored to a Web Awesome button.
</wa-popover>
<br><br>
<button id="popover__anchor-native-button">Show Popover</button>
<wa-popover for="popover__anchor-native-button">
I'm anchored to a native button.
</wa-popover>
```
:::warning
Make sure the anchor element exists in the DOM before the popover connects. If it doesn't exist, the popover won't attach and you'll see a console warning.
:::
### Opening and Closing
Popovers show when you click their anchor element. You can also control them programmatically by setting the `open` property to `true` or `false`.
Use `data-popover="close"` on any button inside a popover to close it automatically.
```html {.example}
<wa-popover for="popover__opening">
<p>The button below has <code>data-popover="close"</code> so clicking it will close the popover.</p>
<wa-button data-popover="close" variant="primary">Dismiss</wa-button>
</wa-popover>
<wa-button id="popover__opening">Show popover</wa-button>
```
### Placement
Use the `placement` attribute to set where the popover appears relative to its anchor. The popover will automatically reposition if there isn't enough space in the preferred location. The default placement is `top`.
```html {.example}
<div style="display: flex; gap: 1rem; align-items: center;">
<wa-button id="popover__top">Top</wa-button>
<wa-popover for="popover__top" placement="top">I'm on the top</wa-popover>
<wa-button id="popover__bottom">Bottom</wa-button>
<wa-popover for="popover__bottom" placement="bottom">I'm on the bottom</wa-popover>
<wa-button id="popover__left">Left</wa-button>
<wa-popover for="popover__left" placement="left">I'm on the left</wa-popover>
<wa-button id="popover__right">Right</wa-button>
<wa-popover for="popover__right" placement="right">I'm on the right</wa-popover>
</div>
```
### Distance
Use the `distance` attribute to control how far the popover appears from its anchor.
```html {.example}
<div style="display: flex; gap: 1rem; align-items: center;">
<wa-button id="popover__distance-near">Near</wa-button>
<wa-popover for="popover__distance-near" distance="0">I'm very close</wa-popover>
<wa-button id="popover__distance-far">Far</wa-button>
<wa-popover for="popover__distance-far" distance="30">I'm farther away</wa-popover>
</div>
```
### Arrow Size
Use the `--arrow-size` custom property to change the size of the popover's arrow. Set it to `0` to remove the arrow entirely.
```html {.example}
<div style="display: flex; gap: 1rem; align-items: center;">
<wa-button id="popover__big-arrow">Big arrow</wa-button>
<wa-popover for="popover__big-arrow" style="--arrow-size: 8px;">I have a big arrow</wa-popover>
<wa-button id="popover__no-arrow">No arrow</wa-button>
<wa-popover for="popover__no-arrow" style="--arrow-size: 0;">I don't have an arrow</wa-popover>
</div>
```
### Setting a Maximum Width
Use the `--max-width` custom property to control the maximum width of the popover.
```html {.example}
<wa-button id="popover__max-width">Toggle me</wa-button>
<wa-popover for="popover__max-width" style="--max-width: 160px;">
Popovers will usually grow to be much wider, but this one has a custom max width that forces text to wrap.
</wa-popover>
```
### Setting Focus
Use the [`autofocus`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus) global attribute to move focus to a specific form control when the popover opens.
```html {.example}
<wa-popover for="popover__autofocus">
<div style="display: flex; flex-direction: column; gap: 1rem;">
<wa-textarea
autofocus
placeholder="What's on your mind?"
size="small"
resize="none"
rows="3"
></wa-textarea>
<wa-button variant="primary" size="small" data-popover="close">
Submit
</wa-button>
</div>
</wa-popover>
<wa-button id="popover__autofocus">
<wa-icon name="comment" slot="prefix"></wa-icon>
Feedback
</wa-button>
```

View File

@@ -92,7 +92,7 @@ To contribute new translations or improvements to existing translations, please
Regional translations are welcome! For example, if a German translation (`de`) exists it's perfectly acceptable to submit a German (Switzerland) (`de-CH`) translation.
If you have any questions, please start a [discussion](https://github.com/shoelace-style/shoelace/discussions) or ask in the [community chat](https://discord.gg/mg8f26C).
If you have any questions, please start a [discussion](https://github.com/shoelace-style/webawesome-alpha/discussions) or ask in the [community chat](https://discord.gg/mg8f26C).
:::info
Web Awesome provides a localization mechanism for component internals. This is not designed to be used as localization tool for your entire application. You should use a more appropriate tool such as [i18next](https://www.i18next.com/) if you need to localize content in your app.

View File

@@ -14,7 +14,7 @@ Furthermore, accessibility doesnt stop at the component level. Using accessib
My commitment to Web Awesome users is this: Everything we develop will be built with accessibility in mind. We will test and improve every component to the best of our ability and knowledge. We will work around upstream issues, such as browser bugs and limitations, to the best of our ability and within reason.
Were fully aware that we may not get it right every time for every user, so we invite the community to participate in this ongoing effort by submitting [issues](https://github.com/shoelace-style/shoelace/issues?q=is%3Aissue+is%3Aopen+label%3Aa11y), [pull requests](https://github.com/shoelace-style/shoelace/pulls?q=is%3Aopen+is%3Apr+label%3Aa11y), and [discussions](https://github.com/shoelace-style/shoelace/discussions). Many accessibility improvements have already been made thanks to contributors submitting code, feedback, and suggestions.
Were fully aware that we may not get it right every time for every user, so we invite the community to participate in this ongoing effort by submitting [issues](https://github.com/shoelace-style/webawesome-alpha), pull requests, and [discussions](https://github.com/shoelace-style/webawesome-alpha/discussions). Many accessibility improvements have already been made thanks to contributors submitting code, feedback, and suggestions.
This is the path forward. Together, we will continue to make Web Awesome accessible to as many users as possible.

View File

@@ -31,7 +31,6 @@ During the alpha period, things might break! We take breaking changes very serio
- `<wa-tab-group no-scroll-controls>` => `<wa-tab-group without-scroll-controls>`
- `<wa-tag removable>` => `<wa-tag with-remove>`
- 🚨 BREAKING: removed the `size` attribute from `<wa-card>`; please set the size of child elements on the children directly
- Added a new free component: `<wa-popover>` (#2 of 14 per stretch goals)
- Added a `min-block-size` to `<wa-divider orientation="vertical">` to ensure the divider is visible regardless of container height [issue:675]
- Fixed a bug in `<wa-radio-group>` that caused radios to uncheck when assigning a numeric value [issue:924]
- Fixed `<wa-button-group>` so dividers properly show between buttons

View File

@@ -10,14 +10,14 @@ Please be respectful of other users and remember that Web Awesome is an open sou
## Discussion Forum
The [discussion forum](https://github.com/shoelace-style/shoelace/discussions) is open to anyone with a GitHub account. This is the best place to:
The [discussion forum](https://github.com/shoelace-style/webawesome-alpha/discussions) is open to anyone with a GitHub account. This is the best place to:
- Ask for help
- Share ideas and get feedback
- Show the community what you're working on
- Learn more about the project, its values, and its roadmap
<wa-button variant="brand" href="https://github.com/shoelace-style/shoelace/discussions" target="_blank" style="margin-block-end: var(--wa-flow-spacing);">
<wa-button variant="brand" href="https://github.com/shoelace-style/webawesome-alpha/discussions" target="_blank" style="margin-block-end: var(--wa-flow-spacing);">
<wa-icon name="github" family="brands" slot="prefix"></wa-icon>
Join the Discussion
</wa-button>
@@ -40,7 +40,7 @@ The [community chat](https://discord.gg/mg8f26C) is open to the public and power
Follow [@webawesomer](https://twitter.com/webawesomer) on Twitter for general updates and announcements about Web Awesome. This is a great place to say "hi" or to share something you're working on.
**Please avoid using Twitter for support questions.** The [discussion forum](https://github.com/shoelace-style/shoelace/discussions) is a much better place to share code snippets, screenshots, and other troubleshooting info. You'll have much better luck there, as more users will have a chance to help you.
**Please avoid using Twitter for support questions.** The [discussion forum](https://github.com/shoelace-style/webawesome-alpha/discussions) is a much better place to share code snippets, screenshots, and other troubleshooting info. You'll have much better luck there, as more users will have a chance to help you.
<wa-button variant="brand" href="https://twitter.com/webawesomer" target="_blank" style="margin-block-end: var(--wa-flow-spacing);">
<wa-icon name="twitter" family="brands" slot="prefix"></wa-icon>

View File

@@ -37,7 +37,7 @@ export default function (plop) {
},
{
type: 'add',
path: '../../src/components/{{ tagWithoutPrefix tag }}/{{ tagWithoutPrefix tag }}.css',
path: '../../src/components/{{ tagWithoutPrefix tag }}/{{ tagWithoutPrefix tag }}.styles.ts',
templateFile: 'templates/component/styles.hbs',
},
{
@@ -50,12 +50,6 @@ export default function (plop) {
path: '../../docs/docs/components/{{ tagWithoutPrefix tag }}.md',
templateFile: 'templates/component/docs.hbs',
},
{
type: 'modify',
path: '../../docs/_includes/sidebar.njk',
pattern: /\{# PLOP_NEW_COMPONENT_PLACEHOLDER #\}/,
template: `<li><a href="/docs/components/{{ tagWithoutPrefix tag }}">{{ tagToTitle tag }}</a></li>\n {# PLOP_NEW_COMPONENT_PLACEHOLDER #}`,
},
],
});
}

View File

@@ -1,8 +1,11 @@
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { html } from 'lit';
import { LocalizeController } from '../../utilities/localize.js';
import { watch } from '../../internal/watch.js';
import componentStyles from '../../styles/component.styles.js';
import styles from './test-element.styles.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import styles from './{{ tagWithoutPrefix tag }}.css';
import type { CSSResultGroup } from 'lit';
/**
* @summary Short summary of the component's intended use.
@@ -12,6 +15,8 @@ import styles from './{{ tagWithoutPrefix tag }}.css';
*
* @dependency wa-example
*
* @event wa-event-name - Emitted as an example.
*
* @slot - The default slot.
* @slot example - An example slot.
*
@@ -21,7 +26,9 @@ import styles from './{{ tagWithoutPrefix tag }}.css';
*/
@customElement("{{ tag }}")
export default class {{ properCase tag }} extends WebAwesomeElement {
static shadowStyle = styles;
static styles: CSSResultGroup = [componentStyles, styles];
private readonly localize = new LocalizeController(this);
/** An example attribute. */
@property() attr = 'example';

View File

@@ -1,3 +1,7 @@
:host {
display: block;
}
import { css } from 'lit';
export default css`
:host {
display: block;
}
`;

View File

@@ -1,3 +1,4 @@
import '../../../dist/webawesome.js';
import { expect, fixture, html } from '@open-wc/testing';
describe('<{{ tag }}>', () => {

View File

@@ -1,91 +0,0 @@
:host {
--arrow-size: 0.375rem;
--max-width: 25rem;
--show-duration: 100ms;
--hide-duration: 100ms;
/* Internal calculated properties */
--arrow-diagonal-size: calc((var(--arrow-size) * sin(45deg)));
display: contents;
/** Defaults for inherited CSS properties */
font-size: var(--wa-popover-font-size);
line-height: var(--wa-popover-line-height);
text-align: start;
white-space: normal;
}
/* The native dialog element */
.dialog {
display: none;
position: fixed;
inset: 0;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
border: none;
background: transparent;
overflow: visible;
pointer-events: none;
&:focus {
outline: none;
}
&[open] {
display: block;
}
}
/* The <wa-popup> element */
.popover {
--arrow-size: inherit;
--show-duration: inherit;
--hide-duration: inherit;
pointer-events: auto;
&::part(arrow) {
background-color: var(--wa-color-surface-default);
border-top: none;
border-left: none;
border-bottom: solid var(--wa-panel-border-width) var(--wa-color-surface-border);
border-right: solid var(--wa-panel-border-width) var(--wa-color-surface-border);
box-shadow: none;
}
}
.popover[placement^='top']::part(popup) {
transform-origin: bottom;
}
.popover[placement^='bottom']::part(popup) {
transform-origin: top;
}
.popover[placement^='left']::part(popup) {
transform-origin: right;
}
.popover[placement^='right']::part(popup) {
transform-origin: left;
}
/* Body */
.body {
display: flex;
flex-direction: column;
width: max-content;
max-width: var(--max-width);
padding: var(--wa-space);
background-color: var(--wa-color-surface-default);
border: var(--wa-panel-border-width) solid var(--wa-color-surface-border);
border-radius: var(--wa-panel-border-radius);
border-style: var(--wa-panel-border-style);
box-shadow: var(--wa-shadow-s);
color: var(--wa-color-text-normal);
user-select: none;
-webkit-user-select: none;
}

View File

@@ -1,9 +0,0 @@
import { expect, fixture, html } from '@open-wc/testing';
describe('<wa-popover>', () => {
it('should render a component', async () => {
const el = await fixture(html` <wa-popover></wa-popover> `);
expect(el).to.exist;
});
});

View File

@@ -1,310 +0,0 @@
import { html } from 'lit';
import { customElement, property, query, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { WaAfterHideEvent } from '../../events/after-hide.js';
import { WaAfterShowEvent } from '../../events/after-show.js';
import { WaHideEvent } from '../../events/hide.js';
import { WaShowEvent } from '../../events/show.js';
import { animateWithClass } from '../../internal/animate.js';
import { waitForEvent } from '../../internal/event.js';
import { uniqueId } from '../../internal/math.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import WaPopup from '../popup/popup.js';
import styles from './popover.css';
const openPopovers = new Set<WaPopover>();
/**
* @summary Popovers display contextual content and interactive elements in a floating panel.
* @documentation https://backers.webawesome.com/docs/components/popover
* @status stable
* @since 3.0
*
* @dependency wa-popup
*
* @slot - The popover's content. Interactive elements such as buttons and links are supported.
*
* @event wa-show - Emitted when the popover begins to show. Canceling this event will stop the popover from showing.
* @event wa-after-show - Emitted after the popover has shown and all animations are complete.
* @event wa-hide - Emitted when the popover begins to hide. Canceling this event will stop the popover from hiding.
* @event wa-after-hide - Emitted after the popover has hidden and all animations are complete.
*
* @csspart dialog - The native dialog element that contains the popover content.
* @csspart body - The popover's body where its content is rendered.
* @csspart popup - The internal `<wa-popup>` element that positions the popover.
* @csspart popup__popup - The popup's exported `popup` part. Use this to target the popover's popup container.
* @csspart popup__arrow - The popup's exported `arrow` part. Use this to target the popover's arrow.
*
* @cssproperty [--arrow-size=0.375rem] - The size of the tiny arrow that points to the popover (set to zero to remove).
* @cssproperty [--max-width=25rem] - The maximum width of the popover's body content.
* @cssproperty [--show-duration=100ms] - The speed of the show animation.
* @cssproperty [--hide-duration=100ms] - The speed of the hide animation.
*/
@customElement('wa-popover')
export default class WaPopover extends WebAwesomeElement {
static shadowStyle = styles;
static dependencies = { 'wa-popup': WaPopup };
@query('dialog') dialog: HTMLDialogElement;
@query('.body') body: HTMLElement;
@query('wa-popup') popup: WaPopup;
@state() anchor: null | Element = null;
/**
* The preferred placement of the popover. Note that the actual placement may vary as needed to keep the popover
* inside of the viewport.
*/
@property() placement:
| 'top'
| 'top-start'
| 'top-end'
| 'right'
| 'right-start'
| 'right-end'
| 'bottom'
| 'bottom-start'
| 'bottom-end'
| 'left'
| 'left-start'
| 'left-end' = 'top';
/** Shows or hides the popover. */
@property({ type: Boolean, reflect: true }) open = false;
/** The distance in pixels from which to offset the popover away from its target. */
@property({ type: Number }) distance = 8;
/** The distance in pixels from which to offset the popover along its target. */
@property({ type: Number }) skidding = 0;
/** The ID of the popover's anchor element. This must be an interactive/focusable element such as a button. */
@property() for: string | null = null;
private eventController = new AbortController();
connectedCallback() {
super.connectedCallback();
// If the user doesn't give us an id, generate one.
if (!this.id) {
this.id = uniqueId('wa-popover-');
}
}
disconnectedCallback() {
super.disconnectedCallback();
// Cleanup events in case the popover is removed while open
document.removeEventListener('keydown', this.handleDocumentKeyDown);
this.eventController.abort();
}
firstUpdated() {
// If the popover is visible on init, update its position
if (this.open) {
this.dialog.show();
this.popup.active = true;
this.popup.reposition();
}
}
private handleAnchorClick = () => {
// Clicks on the anchor should toggle the popover
this.open = !this.open;
};
private handleBodyClick = (event: PointerEvent) => {
const target = event.target as HTMLElement;
const button = target.closest('[data-popover="close"]');
// Watch for [data-popover="close"] clicks
if (button) {
event.stopPropagation();
this.open = false;
}
};
private handleDocumentKeyDown = (event: KeyboardEvent) => {
// Hide the popover when escape is pressed
if (event.key === 'Escape') {
event.preventDefault();
this.open = false;
if (this.anchor && typeof (this.anchor as any).focus === 'function') {
(this.anchor as any).focus();
}
}
};
private handleDocumentClick = (event: PointerEvent) => {
const target = event.target as HTMLElement;
// Ignore clicks on the anchor so it will be closed by the anchor's click handler
if (this.anchor && event.composedPath().includes(this.anchor)) {
return;
}
// Detect when clicks occur outside the popover
if (target.closest('wa-popover') !== this) {
this.open = false;
}
};
@watch('open', { waitUntilFirstUpdate: true })
async handleOpenChange() {
if (this.open) {
// Show
const waShowEvent = new WaShowEvent();
this.dispatchEvent(waShowEvent);
if (waShowEvent.defaultPrevented) {
this.open = false;
return;
}
// Close other popovers that are open
openPopovers.forEach(popover => (popover.open = false));
document.addEventListener('keydown', this.handleDocumentKeyDown, { signal: this.eventController.signal });
document.addEventListener('click', this.handleDocumentClick, { signal: this.eventController.signal });
// Show the dialog non-modally
this.dialog.show();
this.popup.active = true;
openPopovers.add(this);
// Autofocus the first element with the autofocus attribute
requestAnimationFrame(() => {
const elementToFocus = this.querySelector<HTMLElement>('[autofocus]');
if (elementToFocus && typeof elementToFocus.focus === 'function') {
elementToFocus.focus();
} else {
// Fall back to setting focus on the dialog
this.dialog.focus();
}
});
await animateWithClass(this.popup.popup, 'show-with-scale');
this.popup.reposition();
this.dispatchEvent(new WaAfterShowEvent());
} else {
// Hide
const waHideEvent = new WaHideEvent();
this.dispatchEvent(waHideEvent);
if (waHideEvent.defaultPrevented) {
this.open = true;
return;
}
document.removeEventListener('keydown', this.handleDocumentKeyDown);
document.removeEventListener('click', this.handleDocumentClick);
openPopovers.delete(this);
await animateWithClass(this.popup.popup, 'hide-with-scale');
this.popup.active = false;
this.dialog.close();
this.dispatchEvent(new WaAfterHideEvent());
}
}
@watch('for')
handleForChange() {
const rootNode = this.getRootNode() as Document | ShadowRoot | null;
if (!rootNode) {
return;
}
const newAnchor = this.for ? rootNode.querySelector(`#${this.for}`) : null;
const oldAnchor = this.anchor;
if (newAnchor === oldAnchor) {
return;
}
const { signal } = this.eventController;
if (newAnchor) {
newAnchor.addEventListener('click', this.handleAnchorClick, { signal });
}
if (oldAnchor) {
oldAnchor.removeEventListener('click', this.handleAnchorClick);
}
this.anchor = newAnchor;
if (this.for && !newAnchor) {
console.warn(
`A popover was assigned to an element with an ID of "${this.for}" but the element could not be found.`,
this,
);
}
}
@watch(['distance', 'placement', 'skidding'])
async handleOptionsChange() {
if (this.hasUpdated) {
await this.updateComplete;
this.popup.reposition();
}
}
/** Shows the popover. */
async show() {
if (this.open) {
return undefined;
}
this.open = true;
return waitForEvent(this, 'wa-after-show');
}
/** Hides the popover. */
async hide() {
if (!this.open) {
return undefined;
}
this.open = false;
return waitForEvent(this, 'wa-after-hide');
}
render() {
return html`
<dialog part="dialog" class="dialog">
<wa-popup
part="popup"
exportparts="
popup:popup__popup,
arrow:popup__arrow
"
class=${classMap({
popover: true,
'popover-open': this.open,
})}
placement=${this.placement}
distance=${this.distance}
skidding=${this.skidding}
flip
shift
arrow
.anchor=${this.anchor}
>
<div part="body" class="body" @click=${this.handleBodyClick}>
<slot></slot>
</div>
</wa-popup>
</dialog>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'wa-popover': WaPopover;
}
}

View File

@@ -48,19 +48,7 @@
height: calc(var(--arrow-size-diagonal) * 2);
rotate: 45deg;
background: var(--arrow-color);
z-index: 3;
}
:host([data-current-placement~='left']) .arrow {
rotate: -45deg;
}
:host([data-current-placement~='right']) .arrow {
rotate: 135deg;
}
:host([data-current-placement~='bottom']) .arrow {
rotate: 225deg;
z-index: -1;
}
/* Hover bridge */