@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,87 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
const pagination = bem('x-pagination');
|
|
3
|
+
export const paginationClass = ({ align = 'center', className } = {}) => pagination({ align }, className);
|
|
4
|
+
export const paginationClasses = {
|
|
5
|
+
list: pagination.el('list'),
|
|
6
|
+
item: pagination.el('item'),
|
|
7
|
+
// Page links, gaps and First/Last give way to the summary on narrow screens.
|
|
8
|
+
itemPage: pagination.el('item', { page: true }),
|
|
9
|
+
itemEnd: pagination.el('item', { end: true }),
|
|
10
|
+
itemSummary: pagination.el('item', { summary: true }),
|
|
11
|
+
summary: pagination.el('summary'),
|
|
12
|
+
link: pagination.el('link'),
|
|
13
|
+
edge: pagination.el('link', { edge: true }),
|
|
14
|
+
disabled: pagination.el('link', { edge: true, disabled: true }),
|
|
15
|
+
gap: pagination.el('gap'),
|
|
16
|
+
};
|
|
17
|
+
export const paginationHref = (href, page, firstHref) => page === 1 && firstHref !== undefined
|
|
18
|
+
? firstHref
|
|
19
|
+
: typeof href === 'function'
|
|
20
|
+
? href(page)
|
|
21
|
+
: href.replaceAll('{page}', String(page));
|
|
22
|
+
// Whole pages, at least 1, and a page inside 1..pages.
|
|
23
|
+
export const paginationClamp = (page, pages) => {
|
|
24
|
+
const total = Math.max(1, Math.floor(pages) || 1);
|
|
25
|
+
return { page: Math.min(total, Math.max(1, Math.floor(page) || 1)), pages: total };
|
|
26
|
+
};
|
|
27
|
+
// Keeps the window a fixed width near the ends, so page 1 and 2 of 8 both read 1 2 3 … 8.
|
|
28
|
+
// A gap that would hide a single page shows that page instead.
|
|
29
|
+
export const paginationPages = (requested, total, siblings = 1) => {
|
|
30
|
+
const { page, pages } = paginationClamp(requested, total);
|
|
31
|
+
const width = 2 * siblings + 1;
|
|
32
|
+
const start = Math.max(1, Math.min(page - siblings, pages - width + 1));
|
|
33
|
+
const end = Math.min(pages, start + width - 1);
|
|
34
|
+
const shown = new Set([1, pages]);
|
|
35
|
+
for (let p = start; p <= end; p++) {
|
|
36
|
+
shown.add(p);
|
|
37
|
+
}
|
|
38
|
+
const sorted = [...shown].filter((p) => p >= 1 && p <= pages).sort((a, b) => a - b);
|
|
39
|
+
const out = [];
|
|
40
|
+
sorted.forEach((p, i) => {
|
|
41
|
+
const prev = sorted[i - 1];
|
|
42
|
+
if (prev !== undefined && p - prev === 2) {
|
|
43
|
+
out.push(prev + 1);
|
|
44
|
+
}
|
|
45
|
+
else if (prev !== undefined && p - prev > 2) {
|
|
46
|
+
out.push('gap');
|
|
47
|
+
}
|
|
48
|
+
out.push(p);
|
|
49
|
+
});
|
|
50
|
+
return out;
|
|
51
|
+
};
|
|
52
|
+
export const paginationEntries = ({ href, firstHref, siblings, ends, prevLabel = 'Prev', nextLabel = 'Next', firstLabel = 'First', lastLabel = 'Last', summaryLabel = 'Page {page} of {pages}', ...input }) => {
|
|
53
|
+
const { page, pages } = paginationClamp(input.page, input.pages);
|
|
54
|
+
const to = (p) => paginationHref(href, p, firstHref);
|
|
55
|
+
const atStart = page <= 1;
|
|
56
|
+
const atEnd = page >= pages;
|
|
57
|
+
const entries = [];
|
|
58
|
+
if (ends) {
|
|
59
|
+
entries.push({ kind: 'edge', key: 'first', label: firstLabel, href: atStart ? undefined : to(1) });
|
|
60
|
+
}
|
|
61
|
+
entries.push({ kind: 'edge', key: 'prev', label: prevLabel, href: atStart ? undefined : to(page - 1), rel: 'prev' });
|
|
62
|
+
entries.push({
|
|
63
|
+
kind: 'summary',
|
|
64
|
+
key: 'summary',
|
|
65
|
+
text: `${page} / ${pages}`,
|
|
66
|
+
label: summaryLabel.replaceAll('{page}', String(page)).replaceAll('{pages}', String(pages)),
|
|
67
|
+
});
|
|
68
|
+
paginationPages(page, pages, siblings).forEach((p, i) => entries.push(p === 'gap'
|
|
69
|
+
? { kind: 'gap', key: `gap-${i}` }
|
|
70
|
+
: { kind: 'page', key: String(p), label: String(p), href: to(p), current: p === page }));
|
|
71
|
+
entries.push({ kind: 'edge', key: 'next', label: nextLabel, href: atEnd ? undefined : to(page + 1), rel: 'next' });
|
|
72
|
+
if (ends) {
|
|
73
|
+
entries.push({ kind: 'edge', key: 'last', label: lastLabel, href: atEnd ? undefined : to(pages) });
|
|
74
|
+
}
|
|
75
|
+
return entries;
|
|
76
|
+
};
|
|
77
|
+
export const paginationItemClass = (entry) => entry.kind === 'summary'
|
|
78
|
+
? paginationClasses.itemSummary
|
|
79
|
+
: entry.kind === 'edge'
|
|
80
|
+
? entry.key === 'prev' || entry.key === 'next'
|
|
81
|
+
? paginationClasses.item
|
|
82
|
+
: paginationClasses.itemEnd
|
|
83
|
+
: paginationClasses.itemPage;
|
|
84
|
+
export const paginationPageAttrs = (entry) => ({
|
|
85
|
+
href: entry.href,
|
|
86
|
+
'aria-current': entry.current ? 'page' : undefined,
|
|
87
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './pagination.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import {
|
|
5
|
+
paginationClass,
|
|
6
|
+
paginationClasses as c,
|
|
7
|
+
paginationEntries,
|
|
8
|
+
paginationItemClass,
|
|
9
|
+
paginationPageAttrs,
|
|
10
|
+
type PaginationInput,
|
|
11
|
+
type PaginationOptions,
|
|
12
|
+
} from './index.js'
|
|
13
|
+
|
|
14
|
+
type Props = Omit<HTMLAttributes<'nav'>, 'class'> &
|
|
15
|
+
Omit<PaginationOptions, 'className'> &
|
|
16
|
+
PaginationInput & {
|
|
17
|
+
class?: string
|
|
18
|
+
/** Accessible name of the nav. */
|
|
19
|
+
label?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
align,
|
|
24
|
+
class: className,
|
|
25
|
+
page,
|
|
26
|
+
pages,
|
|
27
|
+
href,
|
|
28
|
+
firstHref,
|
|
29
|
+
siblings,
|
|
30
|
+
ends,
|
|
31
|
+
prevLabel,
|
|
32
|
+
nextLabel,
|
|
33
|
+
firstLabel,
|
|
34
|
+
lastLabel,
|
|
35
|
+
summaryLabel,
|
|
36
|
+
label = 'Pagination',
|
|
37
|
+
...rest
|
|
38
|
+
} = Astro.props
|
|
39
|
+
const entries = paginationEntries({
|
|
40
|
+
page,
|
|
41
|
+
pages,
|
|
42
|
+
href,
|
|
43
|
+
firstHref,
|
|
44
|
+
siblings,
|
|
45
|
+
ends,
|
|
46
|
+
prevLabel,
|
|
47
|
+
nextLabel,
|
|
48
|
+
firstLabel,
|
|
49
|
+
lastLabel,
|
|
50
|
+
summaryLabel,
|
|
51
|
+
})
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
<nav class={paginationClass({ align, className })} aria-label={label} {...rest}>
|
|
55
|
+
<ul class={c.list}>
|
|
56
|
+
{
|
|
57
|
+
entries.map((entry) => (
|
|
58
|
+
<li class={paginationItemClass(entry)}>
|
|
59
|
+
{entry.kind === 'summary' ? (
|
|
60
|
+
<span class={c.summary}>
|
|
61
|
+
<span aria-hidden="true">{entry.text}</span>
|
|
62
|
+
<span class="x-visually-hidden">{entry.label}</span>
|
|
63
|
+
</span>
|
|
64
|
+
) : entry.kind === 'page' ? (
|
|
65
|
+
<a class={c.link} {...paginationPageAttrs(entry)}>
|
|
66
|
+
{entry.label}
|
|
67
|
+
</a>
|
|
68
|
+
) : entry.kind === 'gap' ? (
|
|
69
|
+
<span class={c.gap}>…</span>
|
|
70
|
+
) : entry.href === undefined ? (
|
|
71
|
+
<span class={c.disabled}>{entry.label}</span>
|
|
72
|
+
) : (
|
|
73
|
+
<a class={c.edge} href={entry.href} rel={entry.rel}>
|
|
74
|
+
{entry.label}
|
|
75
|
+
</a>
|
|
76
|
+
)}
|
|
77
|
+
</li>
|
|
78
|
+
))
|
|
79
|
+
}
|
|
80
|
+
</ul>
|
|
81
|
+
</nav>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-pagination__list {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-wrap: wrap;
|
|
6
|
+
gap: var(--x-space-2);
|
|
7
|
+
align-items: center;
|
|
8
|
+
padding: 0;
|
|
9
|
+
margin: 0;
|
|
10
|
+
list-style: none;
|
|
11
|
+
}
|
|
12
|
+
.x-pagination--center .x-pagination__list {
|
|
13
|
+
justify-content: center;
|
|
14
|
+
}
|
|
15
|
+
.x-pagination__item {
|
|
16
|
+
display: flex;
|
|
17
|
+
}
|
|
18
|
+
.x-pagination__item--summary {
|
|
19
|
+
display: none;
|
|
20
|
+
}
|
|
21
|
+
@media (width < 480px) {
|
|
22
|
+
.x-pagination__list {
|
|
23
|
+
flex-wrap: nowrap;
|
|
24
|
+
}
|
|
25
|
+
.x-pagination__item--page, .x-pagination__item--end {
|
|
26
|
+
display: none;
|
|
27
|
+
}
|
|
28
|
+
.x-pagination__item--summary {
|
|
29
|
+
display: flex;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
.x-pagination__link, .x-pagination__gap, .x-pagination__summary {
|
|
33
|
+
display: grid;
|
|
34
|
+
place-items: center;
|
|
35
|
+
min-width: var(--x-control-md);
|
|
36
|
+
height: var(--x-control-md);
|
|
37
|
+
padding: 0 var(--x-space-3);
|
|
38
|
+
font-size: var(--x-fs-small);
|
|
39
|
+
line-height: 1;
|
|
40
|
+
color: var(--x-color-text-muted);
|
|
41
|
+
text-decoration: none;
|
|
42
|
+
white-space: nowrap;
|
|
43
|
+
border: 1px solid var(--x-color-line-strong);
|
|
44
|
+
transition: color var(--x-duration) var(--x-ease), border-color var(--x-duration) var(--x-ease);
|
|
45
|
+
}
|
|
46
|
+
.x-pagination__link:where(a):hover {
|
|
47
|
+
color: var(--x-color-accent);
|
|
48
|
+
border-color: var(--x-color-accent-edge);
|
|
49
|
+
}
|
|
50
|
+
.x-pagination__link[aria-current=page], .x-pagination__link[aria-current=page]:hover {
|
|
51
|
+
color: var(--x-color-on-accent);
|
|
52
|
+
background: var(--x-color-accent);
|
|
53
|
+
border-color: var(--x-color-accent);
|
|
54
|
+
}
|
|
55
|
+
.x-pagination__link--edge {
|
|
56
|
+
padding: 0 var(--x-space-4);
|
|
57
|
+
font-size: var(--x-fs-label);
|
|
58
|
+
text-transform: uppercase;
|
|
59
|
+
}
|
|
60
|
+
.x-pagination__link--disabled {
|
|
61
|
+
color: var(--x-color-text-faint);
|
|
62
|
+
}
|
|
63
|
+
.x-pagination__gap, .x-pagination__summary {
|
|
64
|
+
border-color: transparent;
|
|
65
|
+
}
|
|
66
|
+
.x-pagination__summary {
|
|
67
|
+
font-variant-numeric: tabular-nums;
|
|
68
|
+
color: var(--x-color-text);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import './pagination.scss';
|
|
2
|
+
import type { HTMLAttributes } from 'react';
|
|
3
|
+
import { type PaginationInput, type PaginationOptions } from './index.ts';
|
|
4
|
+
export type PaginationProps = Omit<HTMLAttributes<HTMLElement>, 'children'> & Omit<PaginationOptions, 'className'> & PaginationInput & {
|
|
5
|
+
/** Accessible name of the nav. */
|
|
6
|
+
label?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function Pagination({ align, className, page, pages, href, firstHref, siblings, ends, prevLabel, nextLabel, firstLabel, lastLabel, summaryLabel, label, ...rest }: PaginationProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import './pagination.css';
|
|
3
|
+
import { paginationClass, paginationClasses as c, paginationEntries, paginationItemClass, paginationPageAttrs, } from "./index.js";
|
|
4
|
+
export function Pagination({ align, className, page, pages, href, firstHref, siblings, ends, prevLabel, nextLabel, firstLabel, lastLabel, summaryLabel, label = 'Pagination', ...rest }) {
|
|
5
|
+
const entries = paginationEntries({
|
|
6
|
+
page,
|
|
7
|
+
pages,
|
|
8
|
+
href,
|
|
9
|
+
firstHref,
|
|
10
|
+
siblings,
|
|
11
|
+
ends,
|
|
12
|
+
prevLabel,
|
|
13
|
+
nextLabel,
|
|
14
|
+
firstLabel,
|
|
15
|
+
lastLabel,
|
|
16
|
+
summaryLabel,
|
|
17
|
+
});
|
|
18
|
+
return (_jsx("nav", { className: paginationClass({ align, className }), "aria-label": label, ...rest, children: _jsx("ul", { className: c.list, children: entries.map((entry) => (_jsx("li", { className: paginationItemClass(entry), children: entry.kind === 'summary' ? (_jsxs("span", { className: c.summary, children: [_jsx("span", { "aria-hidden": "true", children: entry.text }), _jsx("span", { className: "x-visually-hidden", children: entry.label })] })) : entry.kind === 'page' ? (_jsx("a", { className: c.link, ...paginationPageAttrs(entry), children: entry.label })) : entry.kind === 'gap' ? (_jsx("span", { className: c.gap, children: "\u2026" })) : entry.href === undefined ? (_jsx("span", { className: c.disabled, children: entry.label })) : (_jsx("a", { className: c.edge, href: entry.href, rel: entry.rel, children: entry.label })) }, entry.key))) }) }));
|
|
19
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type PanelVariant = 'plain' | 'raised' | 'accent' | 'callout';
|
|
2
|
+
export type PanelPadding = 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
3
|
+
export type PanelElement = 'div' | 'section' | 'article' | 'aside' | 'li' | 'form' | 'header' | 'footer';
|
|
4
|
+
export type PanelOptions = {
|
|
5
|
+
variant?: PanelVariant;
|
|
6
|
+
/** Corner ornament: brackets on eve-online, a gold top line on xaroth. */
|
|
7
|
+
marks?: boolean;
|
|
8
|
+
padding?: PanelPadding;
|
|
9
|
+
className?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const panelClass: ({ variant, marks, padding, className }?: PanelOptions) => string;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
const panel = bem('x-panel', { defaults: { variant: 'plain', pad: 'md' }, prefixed: ['pad'] });
|
|
3
|
+
export const panelClass = ({ variant = 'plain', marks, padding = 'md', className } = {}) => panel({ variant, pad: padding, marks }, className);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './panel.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { panelClass, type PanelElement, type PanelOptions } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<'div'>, 'class'> &
|
|
7
|
+
Omit<PanelOptions, 'className'> & {
|
|
8
|
+
class?: string
|
|
9
|
+
as?: PanelElement
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const { variant, marks, padding, as: El = 'div', class: className, slot: _slot, ...rest } = Astro.props
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<El {...rest} class={panelClass({ variant, marks, padding, className })}><slot /></El>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-panel {
|
|
4
|
+
--x-panel-pad: var(--x-space-4);
|
|
5
|
+
position: relative;
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
min-width: 0;
|
|
8
|
+
padding: var(--x-panel-pad);
|
|
9
|
+
color: var(--x-color-text);
|
|
10
|
+
}
|
|
11
|
+
@media (min-width: 640px) {
|
|
12
|
+
.x-panel {
|
|
13
|
+
--x-panel-pad: var(--x-space-5);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
.x-panel--pad-none {
|
|
17
|
+
--x-panel-pad: 0;
|
|
18
|
+
}
|
|
19
|
+
@media (min-width: 640px) {
|
|
20
|
+
.x-panel--pad-none {
|
|
21
|
+
--x-panel-pad: 0;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
.x-panel--pad-sm {
|
|
25
|
+
--x-panel-pad: var(--x-space-3);
|
|
26
|
+
}
|
|
27
|
+
@media (min-width: 640px) {
|
|
28
|
+
.x-panel--pad-sm {
|
|
29
|
+
--x-panel-pad: var(--x-space-4);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
.x-panel--pad-lg {
|
|
33
|
+
--x-panel-pad: var(--x-space-5);
|
|
34
|
+
}
|
|
35
|
+
@media (min-width: 640px) {
|
|
36
|
+
.x-panel--pad-lg {
|
|
37
|
+
--x-panel-pad: var(--x-space-6);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
.x-panel--pad-xl {
|
|
41
|
+
--x-panel-pad: var(--x-space-6) var(--x-space-5);
|
|
42
|
+
}
|
|
43
|
+
@media (min-width: 640px) {
|
|
44
|
+
.x-panel--pad-xl {
|
|
45
|
+
--x-panel-pad: var(--x-space-7);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import './panel.scss';
|
|
2
|
+
import type { HTMLAttributes } from 'react';
|
|
3
|
+
import { type PanelElement, type PanelOptions } from './index.ts';
|
|
4
|
+
export type PanelProps = Omit<PanelOptions, 'className'> & HTMLAttributes<HTMLElement> & {
|
|
5
|
+
as?: PanelElement;
|
|
6
|
+
};
|
|
7
|
+
export declare function Panel({ variant, marks, padding, as: El, className, ...rest }: PanelProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import './panel.css';
|
|
3
|
+
import { panelClass } from "./index.js";
|
|
4
|
+
export function Panel({ variant, marks, padding, as: El = 'div', className, ...rest }) {
|
|
5
|
+
return (_jsx(El, { ...rest, className: panelClass({ variant, marks, padding, className }) }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type ProgressTone = 'default' | 'info' | 'success' | 'warning' | 'danger';
|
|
2
|
+
export type ProgressSize = 'sm' | 'md';
|
|
3
|
+
export type ProgressName = {
|
|
4
|
+
label: string;
|
|
5
|
+
} | {
|
|
6
|
+
label?: string;
|
|
7
|
+
'aria-labelledby': string;
|
|
8
|
+
};
|
|
9
|
+
export type ProgressOptions = {
|
|
10
|
+
/** 0..max. Leave undefined for an indeterminate (busy) bar. */
|
|
11
|
+
value?: number;
|
|
12
|
+
max?: number;
|
|
13
|
+
tone?: ProgressTone;
|
|
14
|
+
/** Makes the fill a gradient from this tone (left) to `tone` (right), spanning the whole track. */
|
|
15
|
+
startTone?: ProgressTone;
|
|
16
|
+
size?: ProgressSize;
|
|
17
|
+
/** Shows the percentage next to the bar. */
|
|
18
|
+
showValue?: boolean;
|
|
19
|
+
className?: string;
|
|
20
|
+
};
|
|
21
|
+
export declare const progressProperty = "--x-progress";
|
|
22
|
+
export declare const progressClass: ({ value, max, tone, startTone, size, className, }?: Omit<ProgressOptions, "showValue">) => string;
|
|
23
|
+
export declare const progressState: ({ value, max, label, showValue, }: Pick<ProgressOptions, "value" | "max" | "showValue"> & {
|
|
24
|
+
label?: string;
|
|
25
|
+
}) => {
|
|
26
|
+
width: string | undefined;
|
|
27
|
+
text: string | undefined;
|
|
28
|
+
attrs: {
|
|
29
|
+
'aria-valuetext'?: string | undefined;
|
|
30
|
+
'aria-valuenow'?: number | undefined;
|
|
31
|
+
'aria-valuemin': number;
|
|
32
|
+
'aria-valuemax': number;
|
|
33
|
+
'aria-label'?: string | undefined;
|
|
34
|
+
role: "progressbar";
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export declare const progressStyle: (width: string | undefined) => string | undefined;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
export const progressProperty = '--x-progress';
|
|
3
|
+
const resolve = (value, max = 100) => {
|
|
4
|
+
const top = max > 0 ? max : 100;
|
|
5
|
+
if (value === undefined || Number.isNaN(value)) {
|
|
6
|
+
return { top, now: undefined, ratio: undefined };
|
|
7
|
+
}
|
|
8
|
+
const now = Math.min(Math.max(value, 0), top);
|
|
9
|
+
return { top, now, ratio: now / top };
|
|
10
|
+
};
|
|
11
|
+
const progress = bem('x-progress', { defaults: { tone: 'default', size: 'md' }, prefixed: ['from'] });
|
|
12
|
+
export const progressClass = ({ value, max, tone = 'default', startTone, size = 'md', className, } = {}) => {
|
|
13
|
+
const { ratio } = resolve(value, max);
|
|
14
|
+
return progress({
|
|
15
|
+
size,
|
|
16
|
+
indeterminate: ratio === undefined,
|
|
17
|
+
empty: ratio === 0,
|
|
18
|
+
done: ratio === 1,
|
|
19
|
+
tone,
|
|
20
|
+
gradient: Boolean(startTone),
|
|
21
|
+
from: startTone,
|
|
22
|
+
}, className);
|
|
23
|
+
};
|
|
24
|
+
// Attributes for the progressbar root, plus the visible text. Unset keys are left out so they never erase a user
|
|
25
|
+
// attribute.
|
|
26
|
+
export const progressState = ({ value, max, label, showValue, }) => {
|
|
27
|
+
const { top, now, ratio } = resolve(value, max);
|
|
28
|
+
const text = ratio === undefined ? undefined : `${Math.round(ratio * 100)}%`;
|
|
29
|
+
const width = ratio === undefined ? undefined : `${Math.round(ratio * 10000) / 100}%`;
|
|
30
|
+
return {
|
|
31
|
+
width,
|
|
32
|
+
text: showValue ? text : undefined,
|
|
33
|
+
attrs: {
|
|
34
|
+
role: 'progressbar',
|
|
35
|
+
...(label !== undefined && { 'aria-label': label }),
|
|
36
|
+
'aria-valuemin': 0,
|
|
37
|
+
'aria-valuemax': top,
|
|
38
|
+
...(now !== undefined && { 'aria-valuenow': now }),
|
|
39
|
+
...(showValue && text !== undefined && { 'aria-valuetext': text }),
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
// A string so Astro emits the same attribute React serializes from a style object.
|
|
44
|
+
export const progressStyle = (width) => width === undefined ? undefined : `${progressProperty}:${width}`;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './progress.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { progressClass, progressState, progressStyle, type ProgressName, type ProgressOptions } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<'div'>, 'class' | 'style' | 'role'> &
|
|
7
|
+
Omit<ProgressOptions, 'className'> &
|
|
8
|
+
ProgressName & { class?: string }
|
|
9
|
+
|
|
10
|
+
const { value, max, tone, startTone, size, showValue, label, class: className, slot: _slot, ...rest } = Astro.props
|
|
11
|
+
const { width, text, attrs: state } = progressState({ value, max, label, showValue })
|
|
12
|
+
const attrs = { ...rest, ...state, style: progressStyle(width) }
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<div {...attrs} class={progressClass({ value, max, tone, startTone, size, className })}>
|
|
16
|
+
<span class="x-progress__track"><span class="x-progress__fill"></span></span>
|
|
17
|
+
{text !== undefined && <span class="x-progress__value">{text}</span>}
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-progress {
|
|
4
|
+
--x-progress-tone: var(--x-progress-default, var(--x-color-accent));
|
|
5
|
+
--x-progress-height: var(--x-progress-md, 8px);
|
|
6
|
+
--x-progress-end: var(--x-progress-tone);
|
|
7
|
+
display: flex;
|
|
8
|
+
gap: var(--x-space-3);
|
|
9
|
+
align-items: center;
|
|
10
|
+
min-width: 9rem;
|
|
11
|
+
}
|
|
12
|
+
.x-progress--sm {
|
|
13
|
+
--x-progress-height: var(--x-progress-sm, 4px);
|
|
14
|
+
gap: var(--x-space-2);
|
|
15
|
+
}
|
|
16
|
+
.x-progress--done {
|
|
17
|
+
--x-progress-tone: var(--x-color-success);
|
|
18
|
+
}
|
|
19
|
+
.x-progress--info {
|
|
20
|
+
--x-progress-tone: var(--x-color-info);
|
|
21
|
+
}
|
|
22
|
+
.x-progress--success {
|
|
23
|
+
--x-progress-tone: var(--x-color-success);
|
|
24
|
+
}
|
|
25
|
+
.x-progress--warning {
|
|
26
|
+
--x-progress-tone: var(--x-color-warning);
|
|
27
|
+
}
|
|
28
|
+
.x-progress--danger {
|
|
29
|
+
--x-progress-tone: var(--x-color-danger);
|
|
30
|
+
}
|
|
31
|
+
.x-progress--gradient {
|
|
32
|
+
--x-progress-end: color-mix(in srgb, var(--x-progress-tone) var(--x-progress, 100%), var(--x-progress-start));
|
|
33
|
+
}
|
|
34
|
+
.x-progress--from-default {
|
|
35
|
+
--x-progress-start: var(--x-progress-default, var(--x-color-accent));
|
|
36
|
+
}
|
|
37
|
+
.x-progress--from-info {
|
|
38
|
+
--x-progress-start: var(--x-color-info);
|
|
39
|
+
}
|
|
40
|
+
.x-progress--from-success {
|
|
41
|
+
--x-progress-start: var(--x-color-success);
|
|
42
|
+
}
|
|
43
|
+
.x-progress--from-warning {
|
|
44
|
+
--x-progress-start: var(--x-color-warning);
|
|
45
|
+
}
|
|
46
|
+
.x-progress--from-danger {
|
|
47
|
+
--x-progress-start: var(--x-color-danger);
|
|
48
|
+
}
|
|
49
|
+
.x-progress__track {
|
|
50
|
+
position: relative;
|
|
51
|
+
display: block;
|
|
52
|
+
flex: 1;
|
|
53
|
+
min-width: 0;
|
|
54
|
+
height: var(--x-progress-height);
|
|
55
|
+
background: var(--x-progress-track, var(--x-color-surface-3));
|
|
56
|
+
border: 1px solid var(--x-progress-edge, var(--x-color-line-strong));
|
|
57
|
+
container-type: inline-size;
|
|
58
|
+
}
|
|
59
|
+
.x-progress__fill {
|
|
60
|
+
position: absolute;
|
|
61
|
+
inset-block: var(--x-progress-inset, 0);
|
|
62
|
+
inset-inline-start: 0;
|
|
63
|
+
display: block;
|
|
64
|
+
width: var(--x-progress, 0%);
|
|
65
|
+
background: var(--x-progress-tone);
|
|
66
|
+
}
|
|
67
|
+
.x-progress--gradient .x-progress__fill {
|
|
68
|
+
background: linear-gradient(90deg, var(--x-progress-start), var(--x-progress-tone)) 0 0/100cqw 100% no-repeat;
|
|
69
|
+
}
|
|
70
|
+
.x-progress__value {
|
|
71
|
+
flex: none;
|
|
72
|
+
min-width: 4ch;
|
|
73
|
+
font-family: var(--x-font-mono);
|
|
74
|
+
font-size: var(--x-fs-label);
|
|
75
|
+
font-variant-numeric: tabular-nums;
|
|
76
|
+
line-height: 1;
|
|
77
|
+
color: var(--x-color-text-muted);
|
|
78
|
+
text-align: end;
|
|
79
|
+
}
|
|
80
|
+
.x-progress--indeterminate .x-progress__track {
|
|
81
|
+
clip-path: inset(-8px 0);
|
|
82
|
+
}
|
|
83
|
+
.x-progress--indeterminate .x-progress__fill {
|
|
84
|
+
width: 30%;
|
|
85
|
+
animation: x-progress-sweep var(--x-progress-sweep, 2.4s) cubic-bezier(0.45, 0, 0.55, 1) infinite;
|
|
86
|
+
}
|
|
87
|
+
.x-progress--indeterminate.x-progress--gradient .x-progress__fill {
|
|
88
|
+
animation-name: x-progress-sweep-track;
|
|
89
|
+
}
|
|
90
|
+
@media (prefers-reduced-motion: reduce) {
|
|
91
|
+
.x-progress--indeterminate .x-progress__fill {
|
|
92
|
+
width: 100%;
|
|
93
|
+
opacity: 0.6;
|
|
94
|
+
animation: none;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
@keyframes x-progress-sweep {
|
|
98
|
+
from {
|
|
99
|
+
inset-inline-start: -30%;
|
|
100
|
+
}
|
|
101
|
+
to {
|
|
102
|
+
inset-inline-start: 100%;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
@keyframes x-progress-sweep-track {
|
|
106
|
+
from {
|
|
107
|
+
inset-inline-start: -30%;
|
|
108
|
+
background-position-x: 30cqw;
|
|
109
|
+
}
|
|
110
|
+
to {
|
|
111
|
+
inset-inline-start: 100%;
|
|
112
|
+
background-position-x: -100cqw;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import './progress.scss';
|
|
2
|
+
import type { HTMLAttributes } from 'react';
|
|
3
|
+
import { type ProgressName, type ProgressOptions } from './index.ts';
|
|
4
|
+
export type ProgressProps = Omit<ProgressOptions, 'className'> & ProgressName & Omit<HTMLAttributes<HTMLDivElement>, 'style' | 'role' | 'children'>;
|
|
5
|
+
export declare function Progress({ value, max, tone, startTone, size, showValue, label, className, ...rest }: ProgressProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import './progress.css';
|
|
3
|
+
import { progressClass, progressProperty, progressState } from "./index.js";
|
|
4
|
+
export function Progress({ value, max, tone, startTone, size, showValue, label, className, ...rest }) {
|
|
5
|
+
const { width, text, attrs } = progressState({ value, max, label, showValue });
|
|
6
|
+
return (_jsxs("div", { ...rest, ...attrs, className: progressClass({ value, max, tone, startTone, size, className }), style: width === undefined ? undefined : { [progressProperty]: width }, children: [_jsx("span", { className: "x-progress__track", children: _jsx("span", { className: "x-progress__fill" }) }), text !== undefined && _jsx("span", { className: "x-progress__value", children: text })] }));
|
|
7
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './prose.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { codeBlockClass, codeHtml } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<'figure'>, 'class' | 'title'> & {
|
|
7
|
+
class?: string
|
|
8
|
+
code: string
|
|
9
|
+
lang?: string
|
|
10
|
+
title?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const { code, lang, title, class: className, slot: _slot, ...rest } = Astro.props
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
<figure {...rest} class={codeBlockClass({ className })}>
|
|
17
|
+
{
|
|
18
|
+
(title || lang) && (
|
|
19
|
+
<figcaption class="x-code__bar">
|
|
20
|
+
{title && <span class="x-code__title">{title}</span>}
|
|
21
|
+
{lang && <span class="x-code__lang">{lang}</span>}
|
|
22
|
+
</figcaption>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
<pre class="x-code__pre" tabindex="0"><code set:html={codeHtml(code, lang)} /></pre>
|
|
26
|
+
</figure>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type ProseOptions = {
|
|
2
|
+
className?: string;
|
|
3
|
+
};
|
|
4
|
+
export declare const proseClass: ({ className }?: ProseOptions) => string;
|
|
5
|
+
export type CodeBlockOptions = {
|
|
6
|
+
className?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const codeBlockClass: ({ className }?: CodeBlockOptions) => string;
|
|
9
|
+
export type CodeToken = 'kw' | 'str' | 'num' | 'com' | 'fn';
|
|
10
|
+
export declare const tokenizeCode: (code: string, lang?: string) => {
|
|
11
|
+
type?: CodeToken;
|
|
12
|
+
text: string;
|
|
13
|
+
}[];
|
|
14
|
+
export declare const codeHtml: (code: string, lang?: string) => string;
|