@xaroth.nl/design 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +62 -0
- package/dist/all.css +2536 -0
- package/dist/astro.d.ts +41 -0
- package/dist/astro.js +41 -0
- package/dist/bem.d.ts +12 -0
- package/dist/bem.js +19 -0
- package/dist/components/alert/alert.astro +46 -0
- package/dist/components/alert/alert.css +68 -0
- package/dist/components/alert/alert.d.ts +11 -0
- package/dist/components/alert/alert.js +6 -0
- package/dist/components/alert/index.d.ts +14 -0
- package/dist/components/alert/index.js +27 -0
- package/dist/components/avatar/avatar.astro +23 -0
- package/dist/components/avatar/avatar.css +35 -0
- package/dist/components/avatar/avatar.d.ts +5 -0
- package/dist/components/avatar/avatar.js +7 -0
- package/dist/components/avatar/index.d.ts +32 -0
- package/dist/components/avatar/index.js +24 -0
- package/dist/components/badge/badge.astro +11 -0
- package/dist/components/badge/badge.css +46 -0
- package/dist/components/badge/badge.d.ts +5 -0
- package/dist/components/badge/badge.js +6 -0
- package/dist/components/badge/index.d.ts +6 -0
- package/dist/components/badge/index.js +3 -0
- package/dist/components/breadcrumbs/breadcrumbs.astro +27 -0
- package/dist/components/breadcrumbs/breadcrumbs.css +33 -0
- package/dist/components/breadcrumbs/breadcrumbs.d.ts +9 -0
- package/dist/components/breadcrumbs/breadcrumbs.js +11 -0
- package/dist/components/breadcrumbs/index.d.ts +37 -0
- package/dist/components/breadcrumbs/index.js +16 -0
- package/dist/components/button/button.astro +36 -0
- package/dist/components/button/button.css +117 -0
- package/dist/components/button/button.d.ts +18 -0
- package/dist/components/button/button.js +23 -0
- package/dist/components/button/index.d.ts +59 -0
- package/dist/components/button/index.js +26 -0
- package/dist/components/card/card.astro +98 -0
- package/dist/components/card/card.css +91 -0
- package/dist/components/card/card.d.ts +19 -0
- package/dist/components/card/card.js +7 -0
- package/dist/components/card/index.d.ts +11 -0
- package/dist/components/card/index.js +7 -0
- package/dist/components/description-list/description-list.astro +39 -0
- package/dist/components/description-list/description-list.css +72 -0
- package/dist/components/description-list/description-list.d.ts +7 -0
- package/dist/components/description-list/description-list.js +6 -0
- package/dist/components/description-list/index.d.ts +12 -0
- package/dist/components/description-list/index.js +5 -0
- package/dist/components/divider/divider.astro +27 -0
- package/dist/components/divider/divider.css +40 -0
- package/dist/components/divider/divider.d.ts +5 -0
- package/dist/components/divider/divider.js +11 -0
- package/dist/components/divider/index.d.ts +22 -0
- package/dist/components/divider/index.js +11 -0
- package/dist/components/empty-state/empty-state.astro +47 -0
- package/dist/components/empty-state/empty-state.css +38 -0
- package/dist/components/empty-state/empty-state.d.ts +12 -0
- package/dist/components/empty-state/empty-state.js +7 -0
- package/dist/components/empty-state/index.d.ts +5 -0
- package/dist/components/empty-state/index.js +3 -0
- package/dist/components/field/checkbox-group.astro +58 -0
- package/dist/components/field/checkbox.astro +17 -0
- package/dist/components/field/field.astro +51 -0
- package/dist/components/field/field.css +336 -0
- package/dist/components/field/field.d.ts +47 -0
- package/dist/components/field/field.js +51 -0
- package/dist/components/field/index.d.ts +53 -0
- package/dist/components/field/index.js +54 -0
- package/dist/components/field/input.astro +27 -0
- package/dist/components/field/radio-group.astro +58 -0
- package/dist/components/field/radio.astro +17 -0
- package/dist/components/field/select.astro +13 -0
- package/dist/components/field/switch.astro +17 -0
- package/dist/components/field/textarea.astro +24 -0
- package/dist/components/filters/filter-layout.astro +72 -0
- package/dist/components/filters/filter-panel.astro +13 -0
- package/dist/components/filters/filters.css +230 -0
- package/dist/components/filters/filters.d.ts +20 -0
- package/dist/components/filters/filters.js +24 -0
- package/dist/components/filters/index.d.ts +27 -0
- package/dist/components/filters/index.js +25 -0
- package/dist/components/footer/footer.astro +70 -0
- package/dist/components/footer/footer.css +128 -0
- package/dist/components/footer/footer.d.ts +16 -0
- package/dist/components/footer/footer.js +7 -0
- package/dist/components/footer/index.d.ts +35 -0
- package/dist/components/footer/index.js +18 -0
- package/dist/components/header/header.astro +89 -0
- package/dist/components/header/header.css +163 -0
- package/dist/components/header/header.d.ts +18 -0
- package/dist/components/header/header.js +9 -0
- package/dist/components/header/index.d.ts +39 -0
- package/dist/components/header/index.js +25 -0
- package/dist/components/icon/icon.astro +21 -0
- package/dist/components/icon/icon.css +15 -0
- package/dist/components/icon/icon.d.ts +5 -0
- package/dist/components/icon/icon.js +6 -0
- package/dist/components/icon/index.d.ts +57 -0
- package/dist/components/icon/index.js +72 -0
- package/dist/components/layout/container.astro +15 -0
- package/dist/components/layout/grid.astro +14 -0
- package/dist/components/layout/index.d.ts +33 -0
- package/dist/components/layout/index.js +13 -0
- package/dist/components/layout/layout.css +262 -0
- package/dist/components/layout/layout.d.ts +24 -0
- package/dist/components/layout/layout.js +17 -0
- package/dist/components/layout/section-head.astro +42 -0
- package/dist/components/layout/section.astro +15 -0
- package/dist/components/page-head/index.d.ts +18 -0
- package/dist/components/page-head/index.js +14 -0
- package/dist/components/page-head/page-head.astro +60 -0
- package/dist/components/page-head/page-head.css +79 -0
- package/dist/components/page-head/page-head.d.ts +18 -0
- package/dist/components/page-head/page-head.js +8 -0
- package/dist/components/pagination/index.d.ts +73 -0
- package/dist/components/pagination/index.js +87 -0
- package/dist/components/pagination/pagination.astro +81 -0
- package/dist/components/pagination/pagination.css +70 -0
- package/dist/components/pagination/pagination.d.ts +8 -0
- package/dist/components/pagination/pagination.js +19 -0
- package/dist/components/panel/index.d.ts +11 -0
- package/dist/components/panel/index.js +3 -0
- package/dist/components/panel/panel.astro +15 -0
- package/dist/components/panel/panel.css +48 -0
- package/dist/components/panel/panel.d.ts +7 -0
- package/dist/components/panel/panel.js +6 -0
- package/dist/components/progress/index.d.ts +37 -0
- package/dist/components/progress/index.js +44 -0
- package/dist/components/progress/progress.astro +18 -0
- package/dist/components/progress/progress.css +115 -0
- package/dist/components/progress/progress.d.ts +5 -0
- package/dist/components/progress/progress.js +7 -0
- package/dist/components/prose/code-block.astro +26 -0
- package/dist/components/prose/index.d.ts +14 -0
- package/dist/components/prose/index.js +67 -0
- package/dist/components/prose/prose.astro +14 -0
- package/dist/components/prose/prose.css +156 -0
- package/dist/components/prose/prose.d.ts +12 -0
- package/dist/components/prose/prose.js +11 -0
- package/dist/components/stat/index.d.ts +15 -0
- package/dist/components/stat/index.js +5 -0
- package/dist/components/stat/stat-group.astro +11 -0
- package/dist/components/stat/stat.astro +43 -0
- package/dist/components/stat/stat.css +51 -0
- package/dist/components/stat/stat.d.ts +15 -0
- package/dist/components/stat/stat.js +10 -0
- package/dist/components/table/index.d.ts +38 -0
- package/dist/components/table/index.js +18 -0
- package/dist/components/table/table.astro +111 -0
- package/dist/components/table/table.css +78 -0
- package/dist/components/table/table.d.ts +11 -0
- package/dist/components/table/table.js +10 -0
- package/dist/components/tabs/index.d.ts +21 -0
- package/dist/components/tabs/index.js +13 -0
- package/dist/components/tabs/tabs.astro +30 -0
- package/dist/components/tabs/tabs.css +59 -0
- package/dist/components/tabs/tabs.d.ts +9 -0
- package/dist/components/tabs/tabs.js +6 -0
- package/dist/components/tag/index.d.ts +19 -0
- package/dist/components/tag/index.js +7 -0
- package/dist/components/tag/tag.astro +17 -0
- package/dist/components/tag/tag.css +30 -0
- package/dist/components/tag/tag.d.ts +9 -0
- package/dist/components/tag/tag.js +12 -0
- package/dist/components/timeline/index.d.ts +22 -0
- package/dist/components/timeline/index.js +5 -0
- package/dist/components/timeline/timeline.astro +40 -0
- package/dist/components/timeline/timeline.css +92 -0
- package/dist/components/timeline/timeline.d.ts +9 -0
- package/dist/components/timeline/timeline.js +7 -0
- package/dist/components/tooltip/index.d.ts +15 -0
- package/dist/components/tooltip/index.js +41 -0
- package/dist/components/tooltip/tooltip.astro +25 -0
- package/dist/components/tooltip/tooltip.css +84 -0
- package/dist/components/tooltip/tooltip.d.ts +12 -0
- package/dist/components/tooltip/tooltip.js +34 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.js +6 -0
- package/dist/env.d.ts +2 -0
- package/dist/html.d.ts +37 -0
- package/dist/html.js +126 -0
- package/dist/parts.d.ts +27 -0
- package/dist/parts.js +28 -0
- package/dist/react.d.ts +27 -0
- package/dist/react.js +28 -0
- package/dist/scss/_chamfer.scss +37 -0
- package/dist/scss/_layers.scss +2 -0
- package/dist/scss/_theme.scss +15 -0
- package/dist/themes/eve-online.css +1945 -0
- package/dist/themes/xaroth.css +1974 -0
- package/dist/themes.css +3919 -0
- package/package.json +80 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import './table.scss';
|
|
2
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
import { type TableColumn, type TableLabel, type TableOptions, type TableRow } from './index.ts';
|
|
4
|
+
export type TableProps = Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'aria-label' | 'aria-labelledby'> & Omit<TableOptions, 'className'> & TableLabel & {
|
|
5
|
+
columns: TableColumn[];
|
|
6
|
+
rows: TableRow<ReactNode>[];
|
|
7
|
+
caption?: ReactNode;
|
|
8
|
+
/** Header stays in view while the wrapper scrolls; the wrapper caps its height (--x-table-max-height). */
|
|
9
|
+
stickyHeader?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare function Table({ columns, rows, caption, density, striped, hover, stickyHeader, label, className, ...rest }: TableProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import './table.css';
|
|
3
|
+
import { tableCellClass, tableClass, tableWrapClass, } from "./index.js";
|
|
4
|
+
export function Table({ columns, rows, caption, density, striped, hover, stickyHeader, label, className, ...rest }) {
|
|
5
|
+
return (_jsx("div", { ...rest,
|
|
6
|
+
// oxlint-disable-next-line jsx-a11y/prefer-tag-over-role
|
|
7
|
+
role: "region",
|
|
8
|
+
// oxlint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
9
|
+
tabIndex: 0, "aria-label": label, className: tableWrapClass({ stickyHeader, className }), children: _jsxs("table", { className: tableClass({ density, striped, hover }), children: [caption != null && caption !== '' && _jsx("caption", { className: "x-table__caption", children: caption }), _jsx("thead", { children: _jsx("tr", { children: columns.map((column) => (_jsx("th", { className: tableCellClass(column, 'head'), scope: "col", style: column.width ? { width: column.width } : undefined, children: column.label }, column.key))) }) }), _jsx("tbody", { children: rows.map((row, i) => (_jsx("tr", { children: columns.map((column) => (_jsx("td", { className: tableCellClass(column, 'body'), children: row[column.key] }, column.key))) }, i))) })] }) }));
|
|
10
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type TabItem = {
|
|
2
|
+
label: string;
|
|
3
|
+
href: string;
|
|
4
|
+
current?: boolean;
|
|
5
|
+
/** Shown after the label, for example the number of rows behind the tab. */
|
|
6
|
+
count?: number | string;
|
|
7
|
+
};
|
|
8
|
+
export type TabsOptions = {
|
|
9
|
+
className?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const tabsClass: ({ className }?: TabsOptions) => string;
|
|
12
|
+
export declare const tabsClasses: {
|
|
13
|
+
readonly list: string;
|
|
14
|
+
readonly item: string;
|
|
15
|
+
readonly link: string;
|
|
16
|
+
readonly count: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const tabLinkAttrs: ({ href, current }: TabItem) => {
|
|
19
|
+
'aria-current'?: "page" | undefined;
|
|
20
|
+
href: string;
|
|
21
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
const tabs = bem('x-tabs');
|
|
3
|
+
export const tabsClass = ({ className } = {}) => tabs({}, className);
|
|
4
|
+
export const tabsClasses = {
|
|
5
|
+
list: tabs.el('list'),
|
|
6
|
+
item: tabs.el('item'),
|
|
7
|
+
link: tabs.el('link'),
|
|
8
|
+
count: tabs.el('count'),
|
|
9
|
+
};
|
|
10
|
+
export const tabLinkAttrs = ({ href, current }) => ({
|
|
11
|
+
href,
|
|
12
|
+
...(current && { 'aria-current': 'page' }),
|
|
13
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './tabs.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { tabLinkAttrs, tabsClass, tabsClasses as c, type TabItem } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<'nav'>, 'class'> & {
|
|
7
|
+
class?: string
|
|
8
|
+
items: TabItem[]
|
|
9
|
+
/** Accessible name of the nav, for example "Tool sections". */
|
|
10
|
+
label: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const { class: className, items, label, slot: _slot, ...rest } = Astro.props
|
|
14
|
+
const attrs = { ...rest, 'aria-label': label }
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
<nav {...attrs} class={tabsClass({ className })}>
|
|
18
|
+
<ul class={c.list}>
|
|
19
|
+
{
|
|
20
|
+
items.map((item) => (
|
|
21
|
+
<li class={c.item}>
|
|
22
|
+
<a class={c.link} {...tabLinkAttrs(item)}>
|
|
23
|
+
{item.label}
|
|
24
|
+
{item.count !== undefined && <span class={c.count}>{item.count}</span>}
|
|
25
|
+
</a>
|
|
26
|
+
</li>
|
|
27
|
+
))
|
|
28
|
+
}
|
|
29
|
+
</ul>
|
|
30
|
+
</nav>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-tabs {
|
|
4
|
+
--x-tabs-fade: var(--x-color-bg);
|
|
5
|
+
min-width: 0;
|
|
6
|
+
}
|
|
7
|
+
.x-tabs__list {
|
|
8
|
+
display: flex;
|
|
9
|
+
padding: 0;
|
|
10
|
+
margin: 0;
|
|
11
|
+
overflow-x: auto;
|
|
12
|
+
list-style: none;
|
|
13
|
+
border-bottom: 1px solid var(--x-color-line);
|
|
14
|
+
scrollbar-width: none;
|
|
15
|
+
scroll-padding-inline: var(--x-space-6);
|
|
16
|
+
}
|
|
17
|
+
@media (width < 1024px) {
|
|
18
|
+
.x-tabs__list::after {
|
|
19
|
+
content: "";
|
|
20
|
+
position: sticky;
|
|
21
|
+
right: 0;
|
|
22
|
+
flex: none;
|
|
23
|
+
width: var(--x-space-6);
|
|
24
|
+
pointer-events: none;
|
|
25
|
+
background: linear-gradient(to right, transparent, var(--x-tabs-fade) 85%);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
.x-tabs__item {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex: none;
|
|
31
|
+
}
|
|
32
|
+
.x-tabs__link {
|
|
33
|
+
position: relative;
|
|
34
|
+
display: flex;
|
|
35
|
+
gap: var(--x-space-2);
|
|
36
|
+
align-items: center;
|
|
37
|
+
min-height: var(--x-control-md);
|
|
38
|
+
color: var(--x-color-text-muted);
|
|
39
|
+
text-decoration: none;
|
|
40
|
+
white-space: nowrap;
|
|
41
|
+
transition: color var(--x-duration) var(--x-ease);
|
|
42
|
+
}
|
|
43
|
+
.x-tabs__link:focus-visible {
|
|
44
|
+
outline-offset: calc(-1 * var(--x-focus-width));
|
|
45
|
+
}
|
|
46
|
+
.x-tabs__count {
|
|
47
|
+
display: inline-grid;
|
|
48
|
+
place-items: center;
|
|
49
|
+
min-width: 1.5rem;
|
|
50
|
+
padding: 0 var(--x-space-1);
|
|
51
|
+
font-family: var(--x-font-mono);
|
|
52
|
+
font-size: var(--x-fs-label);
|
|
53
|
+
font-weight: 400;
|
|
54
|
+
line-height: 1.5;
|
|
55
|
+
letter-spacing: normal;
|
|
56
|
+
color: var(--x-color-text-muted);
|
|
57
|
+
border: 1px solid var(--x-color-line-strong);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import './tabs.scss';
|
|
2
|
+
import type { HTMLAttributes } from 'react';
|
|
3
|
+
import { type TabItem } from './index.ts';
|
|
4
|
+
export type TabsProps = Omit<HTMLAttributes<HTMLElement>, 'children'> & {
|
|
5
|
+
items: TabItem[];
|
|
6
|
+
/** Accessible name of the nav, for example "Tool sections". */
|
|
7
|
+
label: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function Tabs({ className, items, label, ...rest }: TabsProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import './tabs.css';
|
|
3
|
+
import { tabLinkAttrs, tabsClass, tabsClasses as c } from "./index.js";
|
|
4
|
+
export function Tabs({ className, items, label, ...rest }) {
|
|
5
|
+
return (_jsx("nav", { ...rest, "aria-label": label, className: tabsClass({ className }), children: _jsx("ul", { className: c.list, children: items.map((item) => (_jsx("li", { className: c.item, children: _jsxs("a", { className: c.link, ...tabLinkAttrs(item), children: [item.label, item.count !== undefined && _jsx("span", { className: c.count, children: item.count })] }) }, item.href))) }) }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type TagOptions = {
|
|
2
|
+
active?: boolean;
|
|
3
|
+
className?: string;
|
|
4
|
+
};
|
|
5
|
+
export type TagStateInput = {
|
|
6
|
+
href?: string;
|
|
7
|
+
active?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare const tagClass: ({ active, className }?: TagOptions) => string;
|
|
10
|
+
export declare const tagState: ({ href, active }: TagStateInput) => {
|
|
11
|
+
tag: "a";
|
|
12
|
+
attrs: {
|
|
13
|
+
'aria-current'?: "true" | undefined;
|
|
14
|
+
href: string;
|
|
15
|
+
};
|
|
16
|
+
} | {
|
|
17
|
+
tag: "span";
|
|
18
|
+
attrs: {};
|
|
19
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
const tag = bem('x-tag');
|
|
3
|
+
export const tagClass = ({ active, className } = {}) => tag({ active }, className);
|
|
4
|
+
// An active link tag is the current filter, so assistive tech hears it too; a span tag is only a label.
|
|
5
|
+
export const tagState = ({ href, active }) => href !== undefined
|
|
6
|
+
? { tag: 'a', attrs: { href, ...(active && { 'aria-current': 'true' }) } }
|
|
7
|
+
: { tag: 'span', attrs: {} };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './tag.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { tagClass, tagState, type TagOptions } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Common = Omit<TagOptions, 'className'> & { class?: string }
|
|
7
|
+
|
|
8
|
+
type Props =
|
|
9
|
+
| (Common & Omit<HTMLAttributes<'span'>, 'class'> & { href?: undefined })
|
|
10
|
+
| (Common & Omit<HTMLAttributes<'a'>, 'class'> & { href: string })
|
|
11
|
+
|
|
12
|
+
const { active, href, class: className, slot: _slot, ...rest } = Astro.props
|
|
13
|
+
const { tag: El, attrs: state } = tagState({ href, active })
|
|
14
|
+
const attrs = { ...rest, ...state }
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
<El {...attrs} class={tagClass({ active, className })}><slot /></El>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-tag {
|
|
4
|
+
display: inline-flex;
|
|
5
|
+
flex: none;
|
|
6
|
+
align-items: center;
|
|
7
|
+
min-height: 26px;
|
|
8
|
+
padding: 0 var(--x-space-2);
|
|
9
|
+
font-family: var(--x-font-mono);
|
|
10
|
+
font-size: var(--x-fs-label);
|
|
11
|
+
line-height: 1.5;
|
|
12
|
+
letter-spacing: normal;
|
|
13
|
+
text-transform: none;
|
|
14
|
+
color: var(--x-color-text-muted);
|
|
15
|
+
text-decoration: none;
|
|
16
|
+
white-space: nowrap;
|
|
17
|
+
background: var(--x-color-surface-2);
|
|
18
|
+
border: 1px solid var(--x-color-line-strong);
|
|
19
|
+
transition: color var(--x-duration) var(--x-ease), background var(--x-duration) var(--x-ease), border-color var(--x-duration) var(--x-ease);
|
|
20
|
+
}
|
|
21
|
+
.x-tag:where(a):hover {
|
|
22
|
+
color: var(--x-color-accent);
|
|
23
|
+
border-color: var(--x-color-accent-edge);
|
|
24
|
+
}
|
|
25
|
+
.x-tag--active, .x-tag--active:where(a):hover {
|
|
26
|
+
color: var(--x-color-on-accent);
|
|
27
|
+
background: var(--x-color-accent);
|
|
28
|
+
border-color: var(--x-color-accent);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import './tag.scss';
|
|
2
|
+
import type { AnchorHTMLAttributes, HTMLAttributes } from 'react';
|
|
3
|
+
import { type TagOptions } from './index.ts';
|
|
4
|
+
export type TagProps = (Omit<TagOptions, 'className'> & HTMLAttributes<HTMLSpanElement> & {
|
|
5
|
+
href?: undefined;
|
|
6
|
+
}) | (Omit<TagOptions, 'className'> & AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
7
|
+
href: string;
|
|
8
|
+
});
|
|
9
|
+
export declare function Tag(props: TagProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import './tag.css';
|
|
3
|
+
import { tagClass, tagState } from "./index.js";
|
|
4
|
+
export function Tag(props) {
|
|
5
|
+
const { active, className, children, href, ...rest } = props;
|
|
6
|
+
const classes = tagClass({ active, className });
|
|
7
|
+
const { tag, attrs } = tagState({ href, active });
|
|
8
|
+
if (tag === 'a') {
|
|
9
|
+
return (_jsx("a", { ...rest, ...attrs, className: classes, children: children }));
|
|
10
|
+
}
|
|
11
|
+
return (_jsx("span", { ...rest, className: classes, children: children }));
|
|
12
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type TimelineWhen = {
|
|
2
|
+
date: string;
|
|
3
|
+
label?: string;
|
|
4
|
+
} | {
|
|
5
|
+
date?: undefined;
|
|
6
|
+
label: string;
|
|
7
|
+
};
|
|
8
|
+
export type TimelineEntry<T = string> = TimelineWhen & {
|
|
9
|
+
title: T;
|
|
10
|
+
text?: T;
|
|
11
|
+
current?: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type TimelineHeadingLevel = 2 | 3 | 4 | 5 | 6;
|
|
14
|
+
export type TimelineOptions = {
|
|
15
|
+
className?: string;
|
|
16
|
+
};
|
|
17
|
+
export declare const timelineClass: ({ className }?: TimelineOptions) => string;
|
|
18
|
+
export declare const timelineItemClass: ({ current }?: {
|
|
19
|
+
current?: boolean;
|
|
20
|
+
}) => string;
|
|
21
|
+
export declare const timelineHeading: (level?: TimelineHeadingLevel) => "h2" | "h3" | "h4" | "h5" | "h6";
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
const timeline = bem('x-timeline');
|
|
3
|
+
export const timelineClass = ({ className } = {}) => timeline({}, className);
|
|
4
|
+
export const timelineItemClass = ({ current } = {}) => timeline.el('item', { current });
|
|
5
|
+
export const timelineHeading = (level = 3) => `h${level}`;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './timeline.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import {
|
|
5
|
+
timelineClass,
|
|
6
|
+
timelineHeading,
|
|
7
|
+
timelineItemClass,
|
|
8
|
+
type TimelineEntry,
|
|
9
|
+
type TimelineHeadingLevel,
|
|
10
|
+
} from './index.js'
|
|
11
|
+
|
|
12
|
+
type Props = Omit<HTMLAttributes<'ol'>, 'class'> & {
|
|
13
|
+
class?: string
|
|
14
|
+
items: TimelineEntry[]
|
|
15
|
+
headingLevel?: TimelineHeadingLevel
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const { items, headingLevel, class: className, slot: _slot, ...rest } = Astro.props
|
|
19
|
+
const Heading = timelineHeading(headingLevel)
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<ol {...rest} class={timelineClass({ className })}>
|
|
23
|
+
{
|
|
24
|
+
items.map(({ date, label, title, text, current }) => (
|
|
25
|
+
<li class={timelineItemClass({ current })}>
|
|
26
|
+
{date ? (
|
|
27
|
+
<time class="x-timeline__date" datetime={date}>
|
|
28
|
+
{label ?? date}
|
|
29
|
+
</time>
|
|
30
|
+
) : (
|
|
31
|
+
<span class="x-timeline__date">{label}</span>
|
|
32
|
+
)}
|
|
33
|
+
<div class="x-timeline__body">
|
|
34
|
+
<Heading class="x-timeline__title">{title}</Heading>
|
|
35
|
+
{text && <p class="x-timeline__text">{text}</p>}
|
|
36
|
+
</div>
|
|
37
|
+
</li>
|
|
38
|
+
))
|
|
39
|
+
}
|
|
40
|
+
</ol>
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-timeline {
|
|
4
|
+
--x-timeline-gap: var(--x-space-5);
|
|
5
|
+
--x-timeline-rail: 24px;
|
|
6
|
+
--x-timeline-node: 9px;
|
|
7
|
+
--x-timeline-date-fs: 1rem;
|
|
8
|
+
--x-timeline-date-lh: 1.3;
|
|
9
|
+
--x-timeline-mid: calc(var(--x-timeline-date-fs) * var(--x-timeline-date-lh) / 2);
|
|
10
|
+
--x-timeline-spine: var(--x-color-line-strong);
|
|
11
|
+
display: grid;
|
|
12
|
+
grid-template-columns: [rail-start] var(--x-timeline-rail) [rail-end date-start body-start] minmax(0, 1fr) [date-end body-end];
|
|
13
|
+
column-gap: var(--x-timeline-column-gap, var(--x-space-4));
|
|
14
|
+
row-gap: var(--x-timeline-gap);
|
|
15
|
+
padding: 0;
|
|
16
|
+
list-style: none;
|
|
17
|
+
}
|
|
18
|
+
@media (min-width: 640px) {
|
|
19
|
+
.x-timeline {
|
|
20
|
+
grid-template-columns: var(--x-timeline-columns, [rail-start] var(--x-timeline-rail) [rail-end date-start] max-content [date-end body-start] minmax(0, 1fr) [body-end]);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
.x-timeline__item {
|
|
24
|
+
display: grid;
|
|
25
|
+
grid-template-columns: subgrid;
|
|
26
|
+
grid-column: 1/-1;
|
|
27
|
+
row-gap: var(--x-space-1);
|
|
28
|
+
}
|
|
29
|
+
.x-timeline__item::before {
|
|
30
|
+
content: "";
|
|
31
|
+
grid-row: 1/span 2;
|
|
32
|
+
grid-column: rail;
|
|
33
|
+
justify-self: center;
|
|
34
|
+
width: 1px;
|
|
35
|
+
margin-bottom: calc(-1 * var(--x-timeline-gap));
|
|
36
|
+
background: var(--x-timeline-spine);
|
|
37
|
+
}
|
|
38
|
+
@media (min-width: 640px) {
|
|
39
|
+
.x-timeline__item::before {
|
|
40
|
+
grid-row: 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
.x-timeline__item:first-child::before {
|
|
44
|
+
margin-top: var(--x-timeline-mid);
|
|
45
|
+
}
|
|
46
|
+
.x-timeline__item:last-child::before {
|
|
47
|
+
align-self: start;
|
|
48
|
+
height: var(--x-timeline-mid);
|
|
49
|
+
margin-bottom: 0;
|
|
50
|
+
}
|
|
51
|
+
.x-timeline__item:only-child::before {
|
|
52
|
+
display: none;
|
|
53
|
+
}
|
|
54
|
+
.x-timeline__item::after {
|
|
55
|
+
content: "";
|
|
56
|
+
grid-row: 1;
|
|
57
|
+
grid-column: rail;
|
|
58
|
+
align-self: start;
|
|
59
|
+
justify-self: center;
|
|
60
|
+
width: var(--x-timeline-node);
|
|
61
|
+
height: var(--x-timeline-node);
|
|
62
|
+
margin-top: calc(var(--x-timeline-mid) - var(--x-timeline-node) / 2);
|
|
63
|
+
background: var(--x-color-bg);
|
|
64
|
+
border: 1px solid var(--x-color-accent);
|
|
65
|
+
transform: rotate(45deg);
|
|
66
|
+
}
|
|
67
|
+
.x-timeline__date {
|
|
68
|
+
grid-row: 1;
|
|
69
|
+
grid-column: date;
|
|
70
|
+
font-size: var(--x-timeline-date-fs);
|
|
71
|
+
font-variant-numeric: lining-nums tabular-nums;
|
|
72
|
+
line-height: var(--x-timeline-date-lh);
|
|
73
|
+
white-space: nowrap;
|
|
74
|
+
}
|
|
75
|
+
.x-timeline__body {
|
|
76
|
+
grid-row: 2;
|
|
77
|
+
grid-column: body;
|
|
78
|
+
}
|
|
79
|
+
@media (min-width: 640px) {
|
|
80
|
+
.x-timeline__body {
|
|
81
|
+
grid-row: 1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
.x-timeline__title {
|
|
85
|
+
font-size: 1.125rem;
|
|
86
|
+
line-height: 1.3;
|
|
87
|
+
}
|
|
88
|
+
.x-timeline__text {
|
|
89
|
+
margin-top: var(--x-space-1);
|
|
90
|
+
color: var(--x-color-text-muted);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import './timeline.scss';
|
|
2
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
import { type TimelineEntry, type TimelineHeadingLevel } from './index.ts';
|
|
4
|
+
export type TimelineProps = Omit<HTMLAttributes<HTMLOListElement>, 'children'> & {
|
|
5
|
+
items: TimelineEntry<ReactNode>[];
|
|
6
|
+
/** Heading level of each entry title. */
|
|
7
|
+
headingLevel?: TimelineHeadingLevel;
|
|
8
|
+
};
|
|
9
|
+
export declare function Timeline({ items, headingLevel, className, ...rest }: TimelineProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import './timeline.css';
|
|
3
|
+
import { timelineClass, timelineHeading, timelineItemClass, } from "./index.js";
|
|
4
|
+
export function Timeline({ items, headingLevel, className, ...rest }) {
|
|
5
|
+
const Heading = timelineHeading(headingLevel);
|
|
6
|
+
return (_jsx("ol", { ...rest, className: timelineClass({ className }), children: items.map(({ date, label, title, text, current }, i) => (_jsxs("li", { className: timelineItemClass({ current }), children: [date ? (_jsx("time", { className: "x-timeline__date", dateTime: date, children: label ?? date })) : (_jsx("span", { className: "x-timeline__date", children: label })), _jsxs("div", { className: "x-timeline__body", children: [_jsx(Heading, { className: "x-timeline__title", children: title }), text != null && text !== '' && _jsx("p", { className: "x-timeline__text", children: text })] })] }, i))) }));
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type TooltipPlacement = 'top' | 'bottom';
|
|
2
|
+
export type TooltipOptions = {
|
|
3
|
+
placement?: TooltipPlacement;
|
|
4
|
+
/** Always shown, for docs and previews. */
|
|
5
|
+
open?: boolean;
|
|
6
|
+
className?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const tooltipClass: ({ placement, open, dismissed, className, }?: TooltipOptions & {
|
|
9
|
+
dismissed?: boolean;
|
|
10
|
+
}) => string;
|
|
11
|
+
export declare const tooltipId: (id: string) => string;
|
|
12
|
+
export declare const describedBy: (existing: string | undefined, id: string) => string;
|
|
13
|
+
export declare const describeTrigger: (html: string, id: string) => string;
|
|
14
|
+
export declare const tooltipDismissedClass = "x-tooltip--dismissed";
|
|
15
|
+
export declare const tooltipEscapeScript = "(()=>{if(window.__xTooltip)return;window.__xTooltip=1;const c='x-tooltip--dismissed';const clear=(e)=>{const t=e.target instanceof Element&&e.target.closest('.'+c);if(t)t.classList.remove(c)};document.addEventListener('keydown',(e)=>{if(e.key!=='Escape')return;document.querySelectorAll('.x-tooltip:not(.'+c+')').forEach((t)=>{if(!t.matches(':hover,:has(:focus-visible)'))return;t.classList.add(c);t.addEventListener('pointerleave',()=>t.classList.remove(c),{once:true})})});document.addEventListener('focusin',clear);document.addEventListener('focusout',clear)})()";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
import { findTag, getAttr, mergeTokens, replaceTag } from "../../html.js";
|
|
3
|
+
const tooltip = bem('x-tooltip', { defaults: { placement: 'top' } });
|
|
4
|
+
export const tooltipClass = ({ placement = 'top', open, dismissed, className, } = {}) => tooltip({ placement, open, dismissed }, className);
|
|
5
|
+
export const tooltipId = (id) => `${id}-tip`;
|
|
6
|
+
// Keeps any description the trigger already has and adds the tooltip after it.
|
|
7
|
+
export const describedBy = (existing, id) => mergeTokens(existing, tooltipId(id));
|
|
8
|
+
const focusableTags = new Set(['button', 'select', 'textarea', 'summary', 'iframe']);
|
|
9
|
+
const wrapperTags = new Set(['astro-island', 'astro-slot', 'astro-static-slot']);
|
|
10
|
+
const isFocusable = (tag) => {
|
|
11
|
+
const tabindex = getAttr(tag, 'tabindex');
|
|
12
|
+
if (tabindex !== undefined) {
|
|
13
|
+
return tabindex !== '-1';
|
|
14
|
+
}
|
|
15
|
+
if (focusableTags.has(tag.name)) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
if (tag.name === 'a' || tag.name === 'area') {
|
|
19
|
+
return getAttr(tag, 'href') !== undefined;
|
|
20
|
+
}
|
|
21
|
+
if (tag.name === 'input') {
|
|
22
|
+
return getAttr(tag, 'type') !== 'hidden';
|
|
23
|
+
}
|
|
24
|
+
const editable = getAttr(tag, 'contenteditable');
|
|
25
|
+
return editable !== undefined && editable !== 'false';
|
|
26
|
+
};
|
|
27
|
+
// The trigger is the first focusable element; without one, the first element that is not a framework wrapper.
|
|
28
|
+
export const describeTrigger = (html, id) => {
|
|
29
|
+
const trigger = findTag(html, isFocusable) ?? findTag(html, (tag) => !wrapperTags.has(tag.name));
|
|
30
|
+
if (!trigger) {
|
|
31
|
+
return html;
|
|
32
|
+
}
|
|
33
|
+
const existing = getAttr(trigger, 'aria-describedby');
|
|
34
|
+
return replaceTag(html, trigger, {
|
|
35
|
+
'aria-describedby': describedBy(typeof existing === 'string' ? existing : undefined, id),
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
export const tooltipDismissedClass = 'x-tooltip--dismissed';
|
|
39
|
+
// Escape hides the shown tooltip (WCAG 1.4.13) until the pointer leaves it or focus moves in or out of it.
|
|
40
|
+
// Guarded so copies on one page register once.
|
|
41
|
+
export const tooltipEscapeScript = `(()=>{if(window.__xTooltip)return;window.__xTooltip=1;const c='${tooltipDismissedClass}';const clear=(e)=>{const t=e.target instanceof Element&&e.target.closest('.'+c);if(t)t.classList.remove(c)};document.addEventListener('keydown',(e)=>{if(e.key!=='Escape')return;document.querySelectorAll('.x-tooltip:not(.'+c+')').forEach((t)=>{if(!t.matches(':hover,:has(:focus-visible)'))return;t.classList.add(c);t.addEventListener('pointerleave',()=>t.classList.remove(c),{once:true})})});document.addEventListener('focusin',clear);document.addEventListener('focusout',clear)})()`;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './tooltip.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { firstOnPage } from '../../html.js'
|
|
5
|
+
import { describeTrigger, tooltipClass, tooltipEscapeScript, tooltipId, type TooltipOptions } from './index.js'
|
|
6
|
+
|
|
7
|
+
type Props = Omit<HTMLAttributes<'span'>, 'class' | 'id'> &
|
|
8
|
+
Omit<TooltipOptions, 'className'> & {
|
|
9
|
+
class?: string
|
|
10
|
+
/** Base for the tooltip id that the trigger's aria-describedby points at. Unique per page. */
|
|
11
|
+
id: string
|
|
12
|
+
/** Short hint. Never the only place for information needed to use the page. */
|
|
13
|
+
text: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { id, text, placement, open, class: className, slot: _slot, ...rest } = Astro.props
|
|
17
|
+
const trigger = describeTrigger(await Astro.slots.render('default'), id)
|
|
18
|
+
const withScript = firstOnPage(Astro.request, 'x-tooltip')
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
<span {...{ ...rest, class: tooltipClass({ placement, open, className }) }}>
|
|
22
|
+
<Fragment set:html={trigger} />
|
|
23
|
+
<span class="x-tooltip__bubble" role="tooltip" id={tooltipId(id)}>{text}</span>
|
|
24
|
+
</span>
|
|
25
|
+
{withScript && <script is:inline set:html={tooltipEscapeScript} />}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-tooltip {
|
|
4
|
+
--x-tooltip-gap: 10px;
|
|
5
|
+
--x-tooltip-arrow: 6px;
|
|
6
|
+
--x-tooltip-bg: var(--x-color-surface-3);
|
|
7
|
+
--x-tooltip-edge: transparent;
|
|
8
|
+
position: relative;
|
|
9
|
+
display: inline-block;
|
|
10
|
+
}
|
|
11
|
+
.x-tooltip__bubble {
|
|
12
|
+
position: absolute;
|
|
13
|
+
bottom: calc(100% + var(--x-tooltip-gap));
|
|
14
|
+
left: var(--x-tooltip-left, 50%);
|
|
15
|
+
z-index: 20;
|
|
16
|
+
width: max-content;
|
|
17
|
+
max-width: min(var(--x-tooltip-max, 16rem), 100vw - 2 * var(--x-gutter));
|
|
18
|
+
padding: var(--x-space-2) var(--x-space-3);
|
|
19
|
+
font-family: var(--x-tooltip-font, var(--x-font-ui));
|
|
20
|
+
font-size: var(--x-fs-small);
|
|
21
|
+
font-weight: 400;
|
|
22
|
+
line-height: 1.45;
|
|
23
|
+
letter-spacing: normal;
|
|
24
|
+
text-align: start;
|
|
25
|
+
text-transform: none;
|
|
26
|
+
white-space: normal;
|
|
27
|
+
color: var(--x-color-text);
|
|
28
|
+
background: var(--x-tooltip-bg);
|
|
29
|
+
border: 1px solid var(--x-tooltip-edge);
|
|
30
|
+
border-radius: var(--x-radius);
|
|
31
|
+
visibility: hidden;
|
|
32
|
+
opacity: 0;
|
|
33
|
+
translate: var(--x-tooltip-shift, -50%) 4px;
|
|
34
|
+
transition: opacity var(--x-duration) var(--x-ease), translate var(--x-duration) var(--x-ease), visibility 0s linear var(--x-duration);
|
|
35
|
+
}
|
|
36
|
+
.x-tooltip__bubble::before {
|
|
37
|
+
content: "";
|
|
38
|
+
position: absolute;
|
|
39
|
+
inset: 100% 0 auto;
|
|
40
|
+
height: calc(var(--x-tooltip-gap) + 2px);
|
|
41
|
+
}
|
|
42
|
+
.x-tooltip__bubble::after {
|
|
43
|
+
content: "";
|
|
44
|
+
position: absolute;
|
|
45
|
+
top: calc(100% - var(--x-tooltip-arrow) + 1px);
|
|
46
|
+
left: var(--x-tooltip-arrow-left, 50%);
|
|
47
|
+
width: calc(var(--x-tooltip-arrow) * 2);
|
|
48
|
+
height: calc(var(--x-tooltip-arrow) * 2);
|
|
49
|
+
margin-left: calc(var(--x-tooltip-arrow) * -1);
|
|
50
|
+
background: var(--x-tooltip-bg);
|
|
51
|
+
border: solid var(--x-tooltip-edge);
|
|
52
|
+
border-width: 0 1px 1px 0;
|
|
53
|
+
rotate: 45deg;
|
|
54
|
+
clip-path: polygon(100% 0, 100% 100%, 0 100%);
|
|
55
|
+
}
|
|
56
|
+
.x-tooltip:hover .x-tooltip__bubble, .x-tooltip:has(:focus-visible) .x-tooltip__bubble, .x-tooltip--open .x-tooltip__bubble {
|
|
57
|
+
visibility: visible;
|
|
58
|
+
opacity: 1;
|
|
59
|
+
translate: var(--x-tooltip-shift, -50%) 0;
|
|
60
|
+
transition-delay: 0s;
|
|
61
|
+
}
|
|
62
|
+
.x-tooltip.x-tooltip--dismissed .x-tooltip__bubble {
|
|
63
|
+
visibility: hidden;
|
|
64
|
+
opacity: 0;
|
|
65
|
+
}
|
|
66
|
+
.x-tooltip--bottom .x-tooltip__bubble {
|
|
67
|
+
top: calc(100% + var(--x-tooltip-gap));
|
|
68
|
+
bottom: auto;
|
|
69
|
+
}
|
|
70
|
+
.x-tooltip--bottom .x-tooltip__bubble::before {
|
|
71
|
+
inset: auto 0 100%;
|
|
72
|
+
}
|
|
73
|
+
.x-tooltip--bottom .x-tooltip__bubble::after {
|
|
74
|
+
top: auto;
|
|
75
|
+
bottom: calc(100% - var(--x-tooltip-arrow) + 1px);
|
|
76
|
+
border-width: 1px 0 0 1px;
|
|
77
|
+
clip-path: polygon(0 0, 100% 0, 0 100%);
|
|
78
|
+
}
|
|
79
|
+
@media (prefers-reduced-motion: reduce) {
|
|
80
|
+
.x-tooltip .x-tooltip__bubble {
|
|
81
|
+
transition: none;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import './tooltip.scss';
|
|
2
|
+
import { type HTMLAttributes, type ReactNode } from 'react';
|
|
3
|
+
import { type TooltipOptions } from './index.ts';
|
|
4
|
+
export type TooltipProps = Omit<TooltipOptions, 'className'> & Omit<HTMLAttributes<HTMLSpanElement>, 'id'> & {
|
|
5
|
+
/** Base for the tooltip id that the trigger's aria-describedby points at. Unique per page. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** Short hint. Never the only place for information needed to use the page. */
|
|
8
|
+
text: string;
|
|
9
|
+
/** The trigger: one focusable element. */
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
};
|
|
12
|
+
export declare function Tooltip({ id, text, placement, open, className, children, onPointerLeave, onFocus, onBlur, ...rest }: TooltipProps): import("react").JSX.Element;
|