devex: Create btrix-popover
component (#2632)
Add and documents new `btrix-popover` component.
This commit is contained in:
parent
7e3e8a594f
commit
9f17264aa9
@ -30,6 +30,7 @@ import("./numbered-list");
|
||||
import("./overflow-dropdown");
|
||||
import("./overflow-scroll");
|
||||
import("./pagination");
|
||||
import("./popover");
|
||||
import("./pw-strength-alert");
|
||||
import("./relative-duration");
|
||||
import("./search-combobox");
|
||||
|
70
frontend/src/components/ui/popover.ts
Normal file
70
frontend/src/components/ui/popover.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import { localized } from "@lit/localize";
|
||||
import SlTooltip from "@shoelace-style/shoelace/dist/components/tooltip/tooltip.component.js";
|
||||
import slTooltipStyles from "@shoelace-style/shoelace/dist/components/tooltip/tooltip.styles.js";
|
||||
import { css } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
/**
|
||||
* Popovers are used to reveal supplementary information, like additional context or details.
|
||||
* They're hidden until an anchor is activated, e.g. on hover.
|
||||
*
|
||||
* Popovers should be used to convey information in full sentences or complex HTML.
|
||||
* To display titles, labels, and expand truncated text on hover, use `<sl-tooltip>`.
|
||||
*
|
||||
* @attr {String} content
|
||||
* @attr {String} placement
|
||||
* @attr {String} trigger
|
||||
* @attr {Boolean} open
|
||||
*/
|
||||
@customElement("btrix-popover")
|
||||
@localized()
|
||||
export class Popover extends SlTooltip {
|
||||
@property({ type: Boolean, reflect: true })
|
||||
hoist = true;
|
||||
|
||||
@property({ type: String, reflect: true })
|
||||
placement: SlTooltip["placement"] = "bottom";
|
||||
|
||||
static styles = [
|
||||
slTooltipStyles,
|
||||
css`
|
||||
:host {
|
||||
--btrix-border: 1px solid var(--sl-panel-border-color);
|
||||
--sl-tooltip-background-color: var(--sl-color-neutral-0);
|
||||
--sl-tooltip-color: var(--sl-color-neutral-700);
|
||||
--sl-tooltip-font-size: var(--sl-font-size-x-small);
|
||||
--sl-tooltip-padding: var(--sl-spacing-small);
|
||||
--sl-tooltip-line-height: var(--sl-line-height-dense);
|
||||
}
|
||||
|
||||
::part(body) {
|
||||
border: var(--btrix-border);
|
||||
box-shadow: var(--sl-shadow-medium);
|
||||
}
|
||||
|
||||
::part(arrow) {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
[placement^="bottom"]::part(arrow),
|
||||
[placement^="left"]::part(arrow) {
|
||||
border-top: var(--btrix-border);
|
||||
}
|
||||
|
||||
[placement^="bottom"]::part(arrow),
|
||||
[placement^="right"]::part(arrow) {
|
||||
border-left: var(--btrix-border);
|
||||
}
|
||||
|
||||
[placement^="top"]::part(arrow),
|
||||
[placement^="right"]::part(arrow) {
|
||||
border-bottom: var(--btrix-border);
|
||||
}
|
||||
|
||||
[placement^="top"]::part(arrow),
|
||||
[placement^="left"]::part(arrow) {
|
||||
border-right: var(--btrix-border);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
74
frontend/src/stories/components/Popover.stories.ts
Normal file
74
frontend/src/stories/components/Popover.stories.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import type { Meta, StoryObj } from "@storybook/web-components";
|
||||
import { html } from "lit";
|
||||
|
||||
import { renderComponent, type RenderProps } from "./Popover";
|
||||
|
||||
const meta = {
|
||||
title: "Components/Popover",
|
||||
component: "btrix-popover",
|
||||
tags: ["autodocs"],
|
||||
decorators: (story) =>
|
||||
html` <div class="px-20 py-10 text-center">${story()}</div>`,
|
||||
render: renderComponent,
|
||||
argTypes: {
|
||||
anchor: { table: { disable: true } },
|
||||
slottedContent: { table: { disable: true } },
|
||||
},
|
||||
args: {
|
||||
content: "Popover content",
|
||||
anchor: html`<btrix-badge>Hover me</btrix-badge>`,
|
||||
},
|
||||
} satisfies Meta<RenderProps>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<RenderProps>;
|
||||
|
||||
export const Basic: Story = {
|
||||
args: {},
|
||||
};
|
||||
|
||||
export const Open: Story = {
|
||||
args: {
|
||||
open: true,
|
||||
anchor: html`<btrix-badge>Always open</btrix-badge>`,
|
||||
},
|
||||
};
|
||||
|
||||
export const TopPlacement: Story = {
|
||||
args: {
|
||||
open: true,
|
||||
placement: "top",
|
||||
anchor: html`<btrix-badge>Popover displays below</btrix-badge>`,
|
||||
},
|
||||
};
|
||||
|
||||
export const LeftPlacement: Story = {
|
||||
args: {
|
||||
open: true,
|
||||
placement: "left",
|
||||
anchor: html`<btrix-badge>Popover displays left</btrix-badge>`,
|
||||
},
|
||||
};
|
||||
|
||||
export const RightPlacement: Story = {
|
||||
args: {
|
||||
open: true,
|
||||
placement: "right",
|
||||
anchor: html`<btrix-badge>Popover displays right</btrix-badge>`,
|
||||
},
|
||||
};
|
||||
|
||||
export const HTMLContent: Story = {
|
||||
args: {
|
||||
open: true,
|
||||
anchor: html`<btrix-badge>HTML Content</btrix-badge>`,
|
||||
slottedContent: html`
|
||||
<header class="font-medium leading-none">Popover Title</header>
|
||||
<hr class="my-2" />
|
||||
<p>
|
||||
This popover has HTML content for displaying informative text or
|
||||
additional details when the anchor is activated.
|
||||
</p>
|
||||
`,
|
||||
},
|
||||
};
|
33
frontend/src/stories/components/Popover.ts
Normal file
33
frontend/src/stories/components/Popover.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { html, nothing, type TemplateResult } from "lit";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import type { Popover } from "@/components/ui/popover";
|
||||
|
||||
import "@/components/ui/popover";
|
||||
|
||||
export type RenderProps = Popover & {
|
||||
anchor: TemplateResult;
|
||||
slottedContent: TemplateResult;
|
||||
};
|
||||
|
||||
export const renderComponent = ({
|
||||
content,
|
||||
placement,
|
||||
open,
|
||||
anchor,
|
||||
slottedContent,
|
||||
}: Partial<RenderProps>) => {
|
||||
return html`
|
||||
<btrix-popover
|
||||
content=${ifDefined(content)}
|
||||
placement=${ifDefined(placement)}
|
||||
trigger=${open ? "manual" : "hover"}
|
||||
?open=${open}
|
||||
>
|
||||
${anchor}
|
||||
${slottedContent
|
||||
? html`<div slot="content">${slottedContent}</div>`
|
||||
: nothing}
|
||||
</btrix-popover>
|
||||
`;
|
||||
};
|
@ -258,6 +258,7 @@
|
||||
}
|
||||
|
||||
/* Style tooltip with white background */
|
||||
/* TODO Replace instances with `<btrix-popover>` */
|
||||
sl-tooltip.invert-tooltip {
|
||||
--sl-tooltip-arrow-size: 0;
|
||||
--sl-tooltip-background-color: var(--sl-color-neutral-50);
|
||||
|
Loading…
Reference in New Issue
Block a user