@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,35 @@
|
|
|
1
|
+
export type FooterLayout = 'columns' | 'row';
|
|
2
|
+
export type FooterLink = {
|
|
3
|
+
label: string;
|
|
4
|
+
href: string;
|
|
5
|
+
};
|
|
6
|
+
export type FooterGroup = {
|
|
7
|
+
title?: string;
|
|
8
|
+
links: FooterLink[];
|
|
9
|
+
};
|
|
10
|
+
export type FooterOptions = {
|
|
11
|
+
layout?: FooterLayout;
|
|
12
|
+
className?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const footerClass: ({ layout, className }?: FooterOptions) => string;
|
|
15
|
+
export declare const footerClasses: {
|
|
16
|
+
readonly inner: string;
|
|
17
|
+
readonly brand: string;
|
|
18
|
+
readonly note: string;
|
|
19
|
+
readonly nav: string;
|
|
20
|
+
readonly group: string;
|
|
21
|
+
readonly title: string;
|
|
22
|
+
readonly links: string;
|
|
23
|
+
readonly link: string;
|
|
24
|
+
};
|
|
25
|
+
export declare const footerBrandTag: (href?: string) => "a" | "div";
|
|
26
|
+
export declare const footerBrandState: (href?: string, label?: string) => {
|
|
27
|
+
tag: "div";
|
|
28
|
+
attrs: {};
|
|
29
|
+
} | {
|
|
30
|
+
tag: "a";
|
|
31
|
+
attrs: {
|
|
32
|
+
'aria-label'?: string | undefined;
|
|
33
|
+
href: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
const footer = bem('x-footer');
|
|
3
|
+
export const footerClass = ({ layout = 'columns', className } = {}) => footer({ layout }, className);
|
|
4
|
+
export const footerClasses = {
|
|
5
|
+
inner: footer.el('inner'),
|
|
6
|
+
brand: footer.el('brand'),
|
|
7
|
+
note: footer.el('note'),
|
|
8
|
+
nav: footer.el('nav'),
|
|
9
|
+
group: footer.el('group'),
|
|
10
|
+
title: footer.el('title'),
|
|
11
|
+
links: footer.el('links'),
|
|
12
|
+
link: footer.el('link'),
|
|
13
|
+
};
|
|
14
|
+
export const footerBrandTag = (href) => (href === undefined ? 'div' : 'a');
|
|
15
|
+
// Only the link takes a name: an aria-label on a plain div is not announced.
|
|
16
|
+
export const footerBrandState = (href, label) => href === undefined
|
|
17
|
+
? { tag: 'div', attrs: {} }
|
|
18
|
+
: { tag: 'a', attrs: { href, ...(label !== undefined && { 'aria-label': label }) } };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
import '../button/button.css'
|
|
3
|
+
import './header.css'
|
|
4
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
5
|
+
import {
|
|
6
|
+
brandState,
|
|
7
|
+
headerClass,
|
|
8
|
+
headerClasses as c,
|
|
9
|
+
navLinkAttrs,
|
|
10
|
+
type HeaderNavItem,
|
|
11
|
+
type HeaderOptions,
|
|
12
|
+
} from './index.js'
|
|
13
|
+
|
|
14
|
+
type Props = Omit<HTMLAttributes<'header'>, 'class'> &
|
|
15
|
+
Omit<HeaderOptions, 'className'> & {
|
|
16
|
+
class?: string
|
|
17
|
+
items?: HeaderNavItem[]
|
|
18
|
+
brandHref?: string
|
|
19
|
+
/** Accessible name for the brand link. Ignored without `brandHref`. */
|
|
20
|
+
brandLabel?: string
|
|
21
|
+
navLabel?: string
|
|
22
|
+
menuLabel?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const {
|
|
26
|
+
layout,
|
|
27
|
+
sticky,
|
|
28
|
+
class: className,
|
|
29
|
+
items = [],
|
|
30
|
+
brandHref,
|
|
31
|
+
brandLabel,
|
|
32
|
+
navLabel = 'Main',
|
|
33
|
+
menuLabel = 'Menu',
|
|
34
|
+
slot: _slot,
|
|
35
|
+
...rest
|
|
36
|
+
} = Astro.props
|
|
37
|
+
const { tag: Brand, attrs: brand } = brandState(brandHref, brandLabel)
|
|
38
|
+
const actions = Astro.slots.has('actions') ? await Astro.slots.render('actions') : undefined
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
<header {...rest} class={headerClass({ layout, sticky, className })}>
|
|
42
|
+
<div class={c.inner}>
|
|
43
|
+
{
|
|
44
|
+
Astro.slots.has('brand') && (
|
|
45
|
+
<Brand {...brand} class={c.brand}>
|
|
46
|
+
<slot name="brand" />
|
|
47
|
+
</Brand>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
{
|
|
51
|
+
items.length > 0 && (
|
|
52
|
+
<nav class={c.nav} aria-label={navLabel}>
|
|
53
|
+
<ul class={c.list}>
|
|
54
|
+
{items.map((item) => (
|
|
55
|
+
<li class={c.item}>
|
|
56
|
+
<a class={c.link} {...navLinkAttrs(item)}>
|
|
57
|
+
{item.label}
|
|
58
|
+
</a>
|
|
59
|
+
</li>
|
|
60
|
+
))}
|
|
61
|
+
</ul>
|
|
62
|
+
</nav>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
{actions && <div class={c.actions} set:html={actions} />}
|
|
66
|
+
{
|
|
67
|
+
items.length > 0 && (
|
|
68
|
+
<details class={c.menu}>
|
|
69
|
+
<summary class={c.toggle}>
|
|
70
|
+
<span class="x-button__label">{menuLabel}</span>
|
|
71
|
+
</summary>
|
|
72
|
+
<div class={c.panel}>
|
|
73
|
+
<nav aria-label={navLabel}>
|
|
74
|
+
<ul class={c.list}>
|
|
75
|
+
{items.map((item) => (
|
|
76
|
+
<li class={c.item}>
|
|
77
|
+
<a class={c.link} {...navLinkAttrs(item)}>
|
|
78
|
+
{item.label}
|
|
79
|
+
</a>
|
|
80
|
+
</li>
|
|
81
|
+
))}
|
|
82
|
+
</ul>
|
|
83
|
+
</nav>
|
|
84
|
+
</div>
|
|
85
|
+
</details>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
</div>
|
|
89
|
+
</header>
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-header {
|
|
4
|
+
--x-header-height: 72px;
|
|
5
|
+
--x-header-bg: transparent;
|
|
6
|
+
position: relative;
|
|
7
|
+
z-index: 50;
|
|
8
|
+
background: var(--x-header-bg);
|
|
9
|
+
}
|
|
10
|
+
.x-header--sticky {
|
|
11
|
+
position: sticky;
|
|
12
|
+
top: 0;
|
|
13
|
+
}
|
|
14
|
+
.x-header__inner {
|
|
15
|
+
position: relative;
|
|
16
|
+
width: 100%;
|
|
17
|
+
max-width: calc(var(--x-page) + 2 * var(--x-gutter));
|
|
18
|
+
padding-inline: var(--x-gutter);
|
|
19
|
+
margin-inline: auto;
|
|
20
|
+
}
|
|
21
|
+
.x-header__brand {
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
flex: 0 1 auto;
|
|
24
|
+
gap: var(--x-header-brand-gap, 10px);
|
|
25
|
+
align-items: center;
|
|
26
|
+
min-width: 0;
|
|
27
|
+
color: inherit;
|
|
28
|
+
text-decoration: none;
|
|
29
|
+
}
|
|
30
|
+
.x-header__brand > :not(svg) {
|
|
31
|
+
min-width: 0;
|
|
32
|
+
overflow: hidden;
|
|
33
|
+
text-overflow: ellipsis;
|
|
34
|
+
white-space: nowrap;
|
|
35
|
+
}
|
|
36
|
+
.x-header__brand svg {
|
|
37
|
+
flex: none;
|
|
38
|
+
width: var(--x-header-mark, 28px);
|
|
39
|
+
height: var(--x-header-mark, 28px);
|
|
40
|
+
}
|
|
41
|
+
.x-header__list {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
padding: 0;
|
|
45
|
+
margin: 0;
|
|
46
|
+
list-style: none;
|
|
47
|
+
}
|
|
48
|
+
.x-header__item {
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
}
|
|
52
|
+
.x-header__link {
|
|
53
|
+
position: relative;
|
|
54
|
+
display: flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
min-height: var(--x-control-md);
|
|
57
|
+
text-decoration: none;
|
|
58
|
+
white-space: nowrap;
|
|
59
|
+
}
|
|
60
|
+
.x-header__actions {
|
|
61
|
+
display: flex;
|
|
62
|
+
flex: none;
|
|
63
|
+
gap: var(--x-space-2);
|
|
64
|
+
align-items: center;
|
|
65
|
+
}
|
|
66
|
+
.x-header__menu {
|
|
67
|
+
display: none;
|
|
68
|
+
}
|
|
69
|
+
.x-header__menu > summary {
|
|
70
|
+
list-style: none;
|
|
71
|
+
}
|
|
72
|
+
.x-header__menu > summary::-webkit-details-marker {
|
|
73
|
+
display: none;
|
|
74
|
+
}
|
|
75
|
+
.x-header__panel {
|
|
76
|
+
display: grid;
|
|
77
|
+
gap: var(--x-space-2);
|
|
78
|
+
}
|
|
79
|
+
.x-header__panel .x-header__list {
|
|
80
|
+
display: grid;
|
|
81
|
+
align-items: stretch;
|
|
82
|
+
}
|
|
83
|
+
.x-header--inline .x-header__inner {
|
|
84
|
+
display: flex;
|
|
85
|
+
gap: var(--x-space-5);
|
|
86
|
+
align-items: center;
|
|
87
|
+
height: var(--x-header-height);
|
|
88
|
+
}
|
|
89
|
+
.x-header--inline .x-header__nav {
|
|
90
|
+
margin-left: auto;
|
|
91
|
+
}
|
|
92
|
+
.x-header--inline .x-header__list {
|
|
93
|
+
gap: var(--x-space-1);
|
|
94
|
+
}
|
|
95
|
+
.x-header--inline .x-header__menu {
|
|
96
|
+
position: relative;
|
|
97
|
+
}
|
|
98
|
+
.x-header--inline .x-header__panel {
|
|
99
|
+
position: absolute;
|
|
100
|
+
top: calc(100% + (var(--x-header-height) - var(--x-control-sm)) / 2);
|
|
101
|
+
right: 0;
|
|
102
|
+
min-width: 220px;
|
|
103
|
+
padding: var(--x-space-2);
|
|
104
|
+
}
|
|
105
|
+
.x-header--stacked .x-header__inner {
|
|
106
|
+
display: grid;
|
|
107
|
+
grid-template-areas: ". brand actions" "nav nav nav";
|
|
108
|
+
grid-template-columns: 1fr auto 1fr;
|
|
109
|
+
row-gap: var(--x-space-4);
|
|
110
|
+
align-items: center;
|
|
111
|
+
padding-top: var(--x-space-6);
|
|
112
|
+
}
|
|
113
|
+
.x-header--stacked .x-header__brand {
|
|
114
|
+
grid-area: brand;
|
|
115
|
+
justify-self: center;
|
|
116
|
+
}
|
|
117
|
+
.x-header--stacked .x-header__actions {
|
|
118
|
+
grid-area: actions;
|
|
119
|
+
justify-self: end;
|
|
120
|
+
}
|
|
121
|
+
.x-header--stacked .x-header__nav {
|
|
122
|
+
grid-area: nav;
|
|
123
|
+
}
|
|
124
|
+
.x-header--stacked .x-header__list {
|
|
125
|
+
flex-wrap: wrap;
|
|
126
|
+
justify-content: center;
|
|
127
|
+
}
|
|
128
|
+
.x-header--stacked .x-header__menu {
|
|
129
|
+
grid-area: menu;
|
|
130
|
+
}
|
|
131
|
+
.x-header--stacked .x-header__panel {
|
|
132
|
+
justify-items: center;
|
|
133
|
+
padding-bottom: var(--x-space-4);
|
|
134
|
+
}
|
|
135
|
+
.x-header--stacked .x-header__panel .x-header__list {
|
|
136
|
+
justify-items: center;
|
|
137
|
+
}
|
|
138
|
+
@media (width < 860px) {
|
|
139
|
+
.x-header .x-header__nav {
|
|
140
|
+
display: none;
|
|
141
|
+
}
|
|
142
|
+
.x-header .x-header__menu {
|
|
143
|
+
display: block;
|
|
144
|
+
}
|
|
145
|
+
.x-header--inline .x-header__inner {
|
|
146
|
+
gap: var(--x-space-3);
|
|
147
|
+
}
|
|
148
|
+
.x-header--inline .x-header__brand {
|
|
149
|
+
margin-right: auto;
|
|
150
|
+
}
|
|
151
|
+
.x-header--stacked .x-header__inner {
|
|
152
|
+
grid-template-areas: ". brand actions" "menu menu menu";
|
|
153
|
+
padding-top: var(--x-space-5);
|
|
154
|
+
}
|
|
155
|
+
.x-header--stacked .x-header__menu {
|
|
156
|
+
justify-self: stretch;
|
|
157
|
+
text-align: center;
|
|
158
|
+
}
|
|
159
|
+
.x-header--stacked .x-header__menu > summary {
|
|
160
|
+
margin-bottom: var(--x-space-3);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import '../button/button.scss';
|
|
2
|
+
import './header.scss';
|
|
3
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
4
|
+
import { type HeaderNavItem, type HeaderOptions } from './index.ts';
|
|
5
|
+
export type HeaderProps = Omit<HTMLAttributes<HTMLElement>, 'children'> & Omit<HeaderOptions, 'className'> & {
|
|
6
|
+
/** Logo and site name. */
|
|
7
|
+
brand?: ReactNode;
|
|
8
|
+
/** Makes the brand a link, usually to the home page. */
|
|
9
|
+
brandHref?: string;
|
|
10
|
+
/** Accessible name for the brand link, when the visible text is not enough. Ignored without `brandHref`. */
|
|
11
|
+
brandLabel?: string;
|
|
12
|
+
items?: HeaderNavItem[];
|
|
13
|
+
/** Shown at the end of the bar, for example a sign in button. Stays in the bar at every width. */
|
|
14
|
+
actions?: ReactNode;
|
|
15
|
+
navLabel?: string;
|
|
16
|
+
menuLabel?: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function Header({ layout, sticky, className, brand, brandHref, brandLabel, items, actions, navLabel, menuLabel, ...rest }: HeaderProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import '../button/button.css';
|
|
3
|
+
import './header.css';
|
|
4
|
+
import { brandState, headerClass, headerClasses as c, navLinkAttrs, } from "./index.js";
|
|
5
|
+
export function Header({ layout, sticky, className, brand, brandHref, brandLabel, items = [], actions, navLabel = 'Main', menuLabel = 'Menu', ...rest }) {
|
|
6
|
+
const list = (_jsx("ul", { className: c.list, children: items.map((item) => (_jsx("li", { className: c.item, children: _jsx("a", { className: c.link, ...navLinkAttrs(item), children: item.label }) }, item.href))) }));
|
|
7
|
+
const { tag: Brand, attrs: brandAttrs } = brandState(brandHref, brandLabel);
|
|
8
|
+
return (_jsx("header", { ...rest, className: headerClass({ layout, sticky, className }), children: _jsxs("div", { className: c.inner, children: [brand != null && (_jsx(Brand, { ...brandAttrs, className: c.brand, children: brand })), items.length > 0 && (_jsx("nav", { className: c.nav, "aria-label": navLabel, children: list })), actions != null && _jsx("div", { className: c.actions, children: actions }), items.length > 0 && (_jsxs("details", { className: c.menu, children: [_jsx("summary", { className: c.toggle, children: _jsx("span", { className: "x-button__label", children: menuLabel }) }), _jsx("div", { className: c.panel, children: _jsx("nav", { "aria-label": navLabel, children: list }) })] }))] }) }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type HeaderLayout = 'inline' | 'stacked';
|
|
2
|
+
export type HeaderNavItem = {
|
|
3
|
+
label: string;
|
|
4
|
+
href: string;
|
|
5
|
+
current?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type HeaderOptions = {
|
|
8
|
+
layout?: HeaderLayout;
|
|
9
|
+
sticky?: boolean;
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare const headerClass: ({ layout, sticky, className }?: HeaderOptions) => string;
|
|
13
|
+
export declare const headerClasses: {
|
|
14
|
+
readonly inner: string;
|
|
15
|
+
readonly brand: string;
|
|
16
|
+
readonly nav: string;
|
|
17
|
+
readonly list: string;
|
|
18
|
+
readonly item: string;
|
|
19
|
+
readonly link: string;
|
|
20
|
+
readonly actions: string;
|
|
21
|
+
readonly menu: string;
|
|
22
|
+
readonly toggle: string;
|
|
23
|
+
readonly panel: string;
|
|
24
|
+
};
|
|
25
|
+
export declare const navLinkAttrs: ({ href, current }: HeaderNavItem) => {
|
|
26
|
+
'aria-current'?: "page" | undefined;
|
|
27
|
+
href: string;
|
|
28
|
+
};
|
|
29
|
+
export declare const brandTag: (href?: string) => "a" | "div";
|
|
30
|
+
export declare const brandState: (href?: string, label?: string) => {
|
|
31
|
+
tag: "div";
|
|
32
|
+
attrs: {};
|
|
33
|
+
} | {
|
|
34
|
+
tag: "a";
|
|
35
|
+
attrs: {
|
|
36
|
+
'aria-label'?: string | undefined;
|
|
37
|
+
href: string;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
import { buttonClass } from "../button/index.js";
|
|
3
|
+
const header = bem('x-header');
|
|
4
|
+
export const headerClass = ({ layout = 'inline', sticky, className } = {}) => header({ layout, sticky }, className);
|
|
5
|
+
export const headerClasses = {
|
|
6
|
+
inner: header.el('inner'),
|
|
7
|
+
brand: header.el('brand'),
|
|
8
|
+
nav: header.el('nav'),
|
|
9
|
+
list: header.el('list'),
|
|
10
|
+
item: header.el('item'),
|
|
11
|
+
link: header.el('link'),
|
|
12
|
+
actions: header.el('actions'),
|
|
13
|
+
menu: header.el('menu'),
|
|
14
|
+
toggle: header.el('toggle', {}, buttonClass({ variant: 'tertiary', size: 'sm' })),
|
|
15
|
+
panel: header.el('panel'),
|
|
16
|
+
};
|
|
17
|
+
export const navLinkAttrs = ({ href, current }) => ({
|
|
18
|
+
href,
|
|
19
|
+
...(current && { 'aria-current': 'page' }),
|
|
20
|
+
});
|
|
21
|
+
export const brandTag = (href) => (href === undefined ? 'div' : 'a');
|
|
22
|
+
// Only the link takes a name: an aria-label on a plain div is not announced.
|
|
23
|
+
export const brandState = (href, label) => href === undefined
|
|
24
|
+
? { tag: 'div', attrs: {} }
|
|
25
|
+
: { tag: 'a', attrs: { href, ...(label !== undefined && { 'aria-label': label }) } };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './icon.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { iconClass, icons, iconState, type IconOptions } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<'svg'>, 'class' | 'name' | 'width' | 'height'> & Omit<IconOptions, 'className'> & { class?: string }
|
|
7
|
+
|
|
8
|
+
const { name, size, label, class: className, slot: _slot, ...rest } = Astro.props
|
|
9
|
+
const attrs = {
|
|
10
|
+
...rest,
|
|
11
|
+
viewBox: '0 0 24 24',
|
|
12
|
+
fill: 'none',
|
|
13
|
+
stroke: 'currentColor',
|
|
14
|
+
'stroke-width': '1.5',
|
|
15
|
+
'stroke-linecap': 'round' as const,
|
|
16
|
+
'stroke-linejoin': 'round' as const,
|
|
17
|
+
...iconState({ size, label }),
|
|
18
|
+
}
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
<svg {...attrs} class={iconClass({ className })}>{icons[name].map((d) => <path d={d} />)}</svg>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-icon {
|
|
4
|
+
display: inline-block;
|
|
5
|
+
flex: none;
|
|
6
|
+
vertical-align: -0.125em;
|
|
7
|
+
stroke-width: var(--x-icon-stroke, 1.5);
|
|
8
|
+
stroke-linecap: var(--x-icon-cap, round);
|
|
9
|
+
stroke-linejoin: var(--x-icon-join, round);
|
|
10
|
+
}
|
|
11
|
+
.x-icon:not([width]) {
|
|
12
|
+
width: 1em;
|
|
13
|
+
height: 1em;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import './icon.scss';
|
|
2
|
+
import type { SVGAttributes } from 'react';
|
|
3
|
+
import { type IconOptions } from './index.ts';
|
|
4
|
+
export type IconProps = Omit<IconOptions, 'className'> & Omit<SVGAttributes<SVGSVGElement>, 'name' | 'width' | 'height'>;
|
|
5
|
+
export declare function Icon({ name, size, label, className, ...rest }: IconProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import './icon.css';
|
|
3
|
+
import { iconClass, icons, iconState } from "./index.js";
|
|
4
|
+
export function Icon({ name, size, label, className, ...rest }) {
|
|
5
|
+
return (_jsx("svg", { ...rest, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", ...iconState({ size, label }), className: iconClass({ className }), children: icons[name].map((d) => (_jsx("path", { d: d }, d))) }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export declare const icons: {
|
|
2
|
+
readonly 'arrow-right': readonly ["M5 12l14 0", "M13 18l6 -6", "M13 6l6 6"];
|
|
3
|
+
readonly 'arrow-left': readonly ["M5 12l14 0", "M5 12l6 6", "M5 12l6 -6"];
|
|
4
|
+
readonly 'arrow-up': readonly ["M12 5l0 14", "M18 11l-6 -6", "M6 11l6 -6"];
|
|
5
|
+
readonly 'arrow-down': readonly ["M12 5l0 14", "M18 13l-6 6", "M6 13l6 6"];
|
|
6
|
+
readonly 'arrow-up-right': readonly ["M17 7l-10 10", "M8 7l9 0l0 9"];
|
|
7
|
+
readonly external: readonly ["M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6", "M11 13l9 -9", "M15 4h5v5"];
|
|
8
|
+
readonly 'chevron-down': readonly ["M6 9l6 6l6 -6"];
|
|
9
|
+
readonly 'chevron-up': readonly ["M6 15l6 -6l6 6"];
|
|
10
|
+
readonly 'chevron-left': readonly ["M15 6l-6 6l6 6"];
|
|
11
|
+
readonly 'chevron-right': readonly ["M9 6l6 6l-6 6"];
|
|
12
|
+
readonly check: readonly ["M5 12l5 5l10 -10"];
|
|
13
|
+
readonly close: readonly ["M18 6l-12 12", "M6 6l12 12"];
|
|
14
|
+
readonly menu: readonly ["M4 6l16 0", "M4 12l16 0", "M4 18l16 0"];
|
|
15
|
+
readonly search: readonly ["M3 10a7 7 0 1 0 14 0a7 7 0 1 0 -14 0", "M21 21l-6 -6"];
|
|
16
|
+
readonly info: readonly ["M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", "M12 9h.01", "M11 12h1v4h1"];
|
|
17
|
+
readonly success: readonly ["M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0", "M9 12l2 2l4 -4"];
|
|
18
|
+
readonly warning: readonly ["M12 9v4", "M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0z", "M12 16h.01"];
|
|
19
|
+
readonly danger: readonly ["M12.802 2.165l5.575 2.389c.48 .206 .863 .589 1.07 1.07l2.388 5.574c.22 .512 .22 1.092 0 1.604l-2.389 5.575c-.206 .48 -.589 .863 -1.07 1.07l-5.574 2.388c-.512 .22 -1.092 .22 -1.604 0l-5.575 -2.389a2.036 2.036 0 0 1 -1.07 -1.07l-2.388 -5.574a2.036 2.036 0 0 1 0 -1.604l2.389 -5.575c.206 -.48 .589 -.863 1.07 -1.07l5.574 -2.388a2.036 2.036 0 0 1 1.604 0z", "M12 8v4", "M12 16h.01"];
|
|
20
|
+
readonly copy: readonly ["M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667z", "M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1"];
|
|
21
|
+
readonly plus: readonly ["M12 5l0 14", "M5 12l14 0"];
|
|
22
|
+
readonly minus: readonly ["M5 12l14 0"];
|
|
23
|
+
readonly sort: readonly ["M3 9l4 -4l4 4m-4 -4v14", "M21 15l-4 4l-4 -4m4 4v-14"];
|
|
24
|
+
readonly 'sort-asc': readonly ["M4 6l7 0", "M4 12l7 0", "M4 18l9 0", "M15 9l3 -3l3 3", "M18 6l0 12"];
|
|
25
|
+
readonly 'sort-desc': readonly ["M4 6l9 0", "M4 12l7 0", "M4 18l7 0", "M15 15l3 3l3 -3", "M18 6l0 12"];
|
|
26
|
+
readonly filter: readonly ["M4 4h16v2.172a2 2 0 0 1 -.586 1.414l-4.414 4.414v7l-6 2v-8.5l-4.48 -4.928a2 2 0 0 1 -.52 -1.345v-2.227z"];
|
|
27
|
+
readonly user: readonly ["M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0", "M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2"];
|
|
28
|
+
readonly mail: readonly ["M3 7a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-10z", "M3 7l9 6l9 -6"];
|
|
29
|
+
readonly github: readonly ["M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5"];
|
|
30
|
+
readonly calendar: readonly ["M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12z", "M16 3v4", "M8 3v4", "M4 11h16", "M11 15h1", "M12 15v3"];
|
|
31
|
+
readonly clock: readonly ["M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", "M12 7v5l3 3"];
|
|
32
|
+
readonly link: readonly ["M9 15l6 -6", "M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464", "M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463"];
|
|
33
|
+
readonly download: readonly ["M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2", "M7 11l5 5l5 -5", "M12 4l0 12"];
|
|
34
|
+
readonly rss: readonly ["M4 19a1 1 0 1 0 2 0a1 1 0 1 0 -2 0", "M4 4a16 16 0 0 1 16 16", "M4 11a9 9 0 0 1 9 9"];
|
|
35
|
+
readonly 'map-pin': readonly ["M9 11a3 3 0 1 0 6 0a3 3 0 0 0 -6 0", "M17.657 16.657l-4.243 4.243a2 2 0 0 1 -2.827 0l-4.244 -4.243a8 8 0 1 1 11.314 0z"];
|
|
36
|
+
};
|
|
37
|
+
export type IconName = keyof typeof icons;
|
|
38
|
+
export declare const iconNames: IconName[];
|
|
39
|
+
export type IconOptions = {
|
|
40
|
+
name: IconName;
|
|
41
|
+
/** CSS length or px number. Without it the icon is 1em and follows the text size. */
|
|
42
|
+
size?: string | number;
|
|
43
|
+
/** Accessible name. Without it the icon is decorative and hidden from assistive tech. */
|
|
44
|
+
label?: string;
|
|
45
|
+
className?: string;
|
|
46
|
+
};
|
|
47
|
+
export declare const iconClass: ({ className }?: Pick<IconOptions, "className">) => string;
|
|
48
|
+
export declare const iconState: ({ size, label }: Pick<IconOptions, "size" | "label">) => {
|
|
49
|
+
role: "img";
|
|
50
|
+
'aria-label': string;
|
|
51
|
+
width?: string | number | undefined;
|
|
52
|
+
height?: string | number | undefined;
|
|
53
|
+
} | {
|
|
54
|
+
'aria-hidden': "true";
|
|
55
|
+
width?: string | number | undefined;
|
|
56
|
+
height?: string | number | undefined;
|
|
57
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
// Path data from Tabler Icons (MIT, https://tabler.io/icons), outline set on a 24px grid.
|
|
3
|
+
export const icons = {
|
|
4
|
+
'arrow-right': ['M5 12l14 0', 'M13 18l6 -6', 'M13 6l6 6'],
|
|
5
|
+
'arrow-left': ['M5 12l14 0', 'M5 12l6 6', 'M5 12l6 -6'],
|
|
6
|
+
'arrow-up': ['M12 5l0 14', 'M18 11l-6 -6', 'M6 11l6 -6'],
|
|
7
|
+
'arrow-down': ['M12 5l0 14', 'M18 13l-6 6', 'M6 13l6 6'],
|
|
8
|
+
'arrow-up-right': ['M17 7l-10 10', 'M8 7l9 0l0 9'],
|
|
9
|
+
external: ['M12 6h-6a2 2 0 0 0 -2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-6', 'M11 13l9 -9', 'M15 4h5v5'],
|
|
10
|
+
'chevron-down': ['M6 9l6 6l6 -6'],
|
|
11
|
+
'chevron-up': ['M6 15l6 -6l6 6'],
|
|
12
|
+
'chevron-left': ['M15 6l-6 6l6 6'],
|
|
13
|
+
'chevron-right': ['M9 6l6 6l-6 6'],
|
|
14
|
+
check: ['M5 12l5 5l10 -10'],
|
|
15
|
+
close: ['M18 6l-12 12', 'M6 6l12 12'],
|
|
16
|
+
menu: ['M4 6l16 0', 'M4 12l16 0', 'M4 18l16 0'],
|
|
17
|
+
search: ['M3 10a7 7 0 1 0 14 0a7 7 0 1 0 -14 0', 'M21 21l-6 -6'],
|
|
18
|
+
info: ['M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0', 'M12 9h.01', 'M11 12h1v4h1'],
|
|
19
|
+
success: ['M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0', 'M9 12l2 2l4 -4'],
|
|
20
|
+
warning: [
|
|
21
|
+
'M12 9v4',
|
|
22
|
+
'M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0z',
|
|
23
|
+
'M12 16h.01',
|
|
24
|
+
],
|
|
25
|
+
danger: [
|
|
26
|
+
'M12.802 2.165l5.575 2.389c.48 .206 .863 .589 1.07 1.07l2.388 5.574c.22 .512 .22 1.092 0 1.604l-2.389 5.575c-.206 .48 -.589 .863 -1.07 1.07l-5.574 2.388c-.512 .22 -1.092 .22 -1.604 0l-5.575 -2.389a2.036 2.036 0 0 1 -1.07 -1.07l-2.388 -5.574a2.036 2.036 0 0 1 0 -1.604l2.389 -5.575c.206 -.48 .589 -.863 1.07 -1.07l5.574 -2.388a2.036 2.036 0 0 1 1.604 0z',
|
|
27
|
+
'M12 8v4',
|
|
28
|
+
'M12 16h.01',
|
|
29
|
+
],
|
|
30
|
+
copy: [
|
|
31
|
+
'M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667z',
|
|
32
|
+
'M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1',
|
|
33
|
+
],
|
|
34
|
+
plus: ['M12 5l0 14', 'M5 12l14 0'],
|
|
35
|
+
minus: ['M5 12l14 0'],
|
|
36
|
+
sort: ['M3 9l4 -4l4 4m-4 -4v14', 'M21 15l-4 4l-4 -4m4 4v-14'],
|
|
37
|
+
'sort-asc': ['M4 6l7 0', 'M4 12l7 0', 'M4 18l9 0', 'M15 9l3 -3l3 3', 'M18 6l0 12'],
|
|
38
|
+
'sort-desc': ['M4 6l9 0', 'M4 12l7 0', 'M4 18l7 0', 'M15 15l3 3l3 -3', 'M18 6l0 12'],
|
|
39
|
+
filter: ['M4 4h16v2.172a2 2 0 0 1 -.586 1.414l-4.414 4.414v7l-6 2v-8.5l-4.48 -4.928a2 2 0 0 1 -.52 -1.345v-2.227z'],
|
|
40
|
+
user: ['M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0', 'M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2'],
|
|
41
|
+
mail: ['M3 7a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-10z', 'M3 7l9 6l9 -6'],
|
|
42
|
+
github: [
|
|
43
|
+
'M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5',
|
|
44
|
+
],
|
|
45
|
+
calendar: [
|
|
46
|
+
'M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12z',
|
|
47
|
+
'M16 3v4',
|
|
48
|
+
'M8 3v4',
|
|
49
|
+
'M4 11h16',
|
|
50
|
+
'M11 15h1',
|
|
51
|
+
'M12 15v3',
|
|
52
|
+
],
|
|
53
|
+
clock: ['M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0', 'M12 7v5l3 3'],
|
|
54
|
+
link: [
|
|
55
|
+
'M9 15l6 -6',
|
|
56
|
+
'M11 6l.463 -.536a5 5 0 0 1 7.071 7.072l-.534 .464',
|
|
57
|
+
'M13 18l-.397 .534a5.068 5.068 0 0 1 -7.127 0a4.972 4.972 0 0 1 0 -7.071l.524 -.463',
|
|
58
|
+
],
|
|
59
|
+
download: ['M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2', 'M7 11l5 5l5 -5', 'M12 4l0 12'],
|
|
60
|
+
rss: ['M4 19a1 1 0 1 0 2 0a1 1 0 1 0 -2 0', 'M4 4a16 16 0 0 1 16 16', 'M4 11a9 9 0 0 1 9 9'],
|
|
61
|
+
'map-pin': [
|
|
62
|
+
'M9 11a3 3 0 1 0 6 0a3 3 0 0 0 -6 0',
|
|
63
|
+
'M17.657 16.657l-4.243 4.243a2 2 0 0 1 -2.827 0l-4.244 -4.243a8 8 0 1 1 11.314 0z',
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
export const iconNames = Object.keys(icons);
|
|
67
|
+
const icon = bem('x-icon');
|
|
68
|
+
export const iconClass = ({ className } = {}) => icon({}, className);
|
|
69
|
+
export const iconState = ({ size, label }) => ({
|
|
70
|
+
...(size !== undefined && { width: size, height: size }),
|
|
71
|
+
...(label ? { role: 'img', 'aria-label': label } : { 'aria-hidden': 'true' }),
|
|
72
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './layout.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { containerClass, type ContainerOptions } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<'div'>, 'class'> &
|
|
7
|
+
Omit<ContainerOptions, 'className'> & {
|
|
8
|
+
class?: string
|
|
9
|
+
as?: 'div' | 'main' | 'header' | 'footer' | 'article' | 'nav'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const { width, as: Tag = 'div', class: className, slot: _slot, ...rest } = Astro.props
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<Tag {...rest} class={containerClass({ width, className })}><slot /></Tag>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './layout.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { gridClass } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<'div'>, 'class'> & {
|
|
7
|
+
class?: string
|
|
8
|
+
as?: 'div' | 'main' | 'section' | 'article' | 'ul' | 'ol'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const { as: Tag = 'div', class: className, slot: _slot, ...rest } = Astro.props
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
<Tag {...rest} class={gridClass({ className })}><slot /></Tag>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type ContainerWidth = 'page' | 'prose';
|
|
2
|
+
export type ContainerOptions = {
|
|
3
|
+
width?: ContainerWidth;
|
|
4
|
+
className?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const containerClass: ({ width, className }?: ContainerOptions) => string;
|
|
7
|
+
export type GridOptions = {
|
|
8
|
+
className?: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const gridClass: ({ className }?: GridOptions) => string;
|
|
11
|
+
export type ColSpan = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
12
|
+
export type ColStack = 'md' | 'sm' | 'never';
|
|
13
|
+
export type ColOptions = {
|
|
14
|
+
span: ColSpan;
|
|
15
|
+
stack?: ColStack;
|
|
16
|
+
className?: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const colClass: ({ span, stack, className }: ColOptions) => string;
|
|
19
|
+
export type SectionOptions = {
|
|
20
|
+
tight?: boolean;
|
|
21
|
+
className?: string;
|
|
22
|
+
};
|
|
23
|
+
export declare const sectionClass: ({ tight, className }?: SectionOptions) => string;
|
|
24
|
+
export type SectionHeadLink = {
|
|
25
|
+
label: string;
|
|
26
|
+
href: string;
|
|
27
|
+
};
|
|
28
|
+
export type SectionHeadOptions = {
|
|
29
|
+
className?: string;
|
|
30
|
+
};
|
|
31
|
+
export declare const sectionHeadClass: ({ className }?: SectionHeadOptions) => string;
|
|
32
|
+
export type SectionHeadLevel = 2 | 3;
|
|
33
|
+
export declare const sectionHeadTag: (level?: SectionHeadLevel) => "h2" | "h3";
|