@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
package/dist/astro.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Generated by scripts/generate.ts. Do not edit.
|
|
2
|
+
export { default as Alert } from './components/alert/alert.astro'
|
|
3
|
+
export { default as Avatar } from './components/avatar/avatar.astro'
|
|
4
|
+
export { default as Badge } from './components/badge/badge.astro'
|
|
5
|
+
export { default as Breadcrumbs } from './components/breadcrumbs/breadcrumbs.astro'
|
|
6
|
+
export { default as Button } from './components/button/button.astro'
|
|
7
|
+
export { default as Card } from './components/card/card.astro'
|
|
8
|
+
export { default as DescriptionList } from './components/description-list/description-list.astro'
|
|
9
|
+
export { default as Divider } from './components/divider/divider.astro'
|
|
10
|
+
export { default as EmptyState } from './components/empty-state/empty-state.astro'
|
|
11
|
+
export { default as CheckboxGroup } from './components/field/checkbox-group.astro'
|
|
12
|
+
export { default as Checkbox } from './components/field/checkbox.astro'
|
|
13
|
+
export { default as Field } from './components/field/field.astro'
|
|
14
|
+
export { default as Input } from './components/field/input.astro'
|
|
15
|
+
export { default as RadioGroup } from './components/field/radio-group.astro'
|
|
16
|
+
export { default as Radio } from './components/field/radio.astro'
|
|
17
|
+
export { default as Select } from './components/field/select.astro'
|
|
18
|
+
export { default as Switch } from './components/field/switch.astro'
|
|
19
|
+
export { default as Textarea } from './components/field/textarea.astro'
|
|
20
|
+
export { default as FilterLayout } from './components/filters/filter-layout.astro'
|
|
21
|
+
export { default as FilterPanel } from './components/filters/filter-panel.astro'
|
|
22
|
+
export { default as Footer } from './components/footer/footer.astro'
|
|
23
|
+
export { default as Header } from './components/header/header.astro'
|
|
24
|
+
export { default as Icon } from './components/icon/icon.astro'
|
|
25
|
+
export { default as Container } from './components/layout/container.astro'
|
|
26
|
+
export { default as Grid } from './components/layout/grid.astro'
|
|
27
|
+
export { default as SectionHead } from './components/layout/section-head.astro'
|
|
28
|
+
export { default as Section } from './components/layout/section.astro'
|
|
29
|
+
export { default as PageHead } from './components/page-head/page-head.astro'
|
|
30
|
+
export { default as Pagination } from './components/pagination/pagination.astro'
|
|
31
|
+
export { default as Panel } from './components/panel/panel.astro'
|
|
32
|
+
export { default as Progress } from './components/progress/progress.astro'
|
|
33
|
+
export { default as CodeBlock } from './components/prose/code-block.astro'
|
|
34
|
+
export { default as Prose } from './components/prose/prose.astro'
|
|
35
|
+
export { default as StatGroup } from './components/stat/stat-group.astro'
|
|
36
|
+
export { default as Stat } from './components/stat/stat.astro'
|
|
37
|
+
export { default as Table } from './components/table/table.astro'
|
|
38
|
+
export { default as Tabs } from './components/tabs/tabs.astro'
|
|
39
|
+
export { default as Tag } from './components/tag/tag.astro'
|
|
40
|
+
export { default as Timeline } from './components/timeline/timeline.astro'
|
|
41
|
+
export { default as Tooltip } from './components/tooltip/tooltip.astro'
|
package/dist/astro.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Generated by scripts/generate.ts. Do not edit.
|
|
2
|
+
export { default as Alert } from './components/alert/alert.astro'
|
|
3
|
+
export { default as Avatar } from './components/avatar/avatar.astro'
|
|
4
|
+
export { default as Badge } from './components/badge/badge.astro'
|
|
5
|
+
export { default as Breadcrumbs } from './components/breadcrumbs/breadcrumbs.astro'
|
|
6
|
+
export { default as Button } from './components/button/button.astro'
|
|
7
|
+
export { default as Card } from './components/card/card.astro'
|
|
8
|
+
export { default as DescriptionList } from './components/description-list/description-list.astro'
|
|
9
|
+
export { default as Divider } from './components/divider/divider.astro'
|
|
10
|
+
export { default as EmptyState } from './components/empty-state/empty-state.astro'
|
|
11
|
+
export { default as CheckboxGroup } from './components/field/checkbox-group.astro'
|
|
12
|
+
export { default as Checkbox } from './components/field/checkbox.astro'
|
|
13
|
+
export { default as Field } from './components/field/field.astro'
|
|
14
|
+
export { default as Input } from './components/field/input.astro'
|
|
15
|
+
export { default as RadioGroup } from './components/field/radio-group.astro'
|
|
16
|
+
export { default as Radio } from './components/field/radio.astro'
|
|
17
|
+
export { default as Select } from './components/field/select.astro'
|
|
18
|
+
export { default as Switch } from './components/field/switch.astro'
|
|
19
|
+
export { default as Textarea } from './components/field/textarea.astro'
|
|
20
|
+
export { default as FilterLayout } from './components/filters/filter-layout.astro'
|
|
21
|
+
export { default as FilterPanel } from './components/filters/filter-panel.astro'
|
|
22
|
+
export { default as Footer } from './components/footer/footer.astro'
|
|
23
|
+
export { default as Header } from './components/header/header.astro'
|
|
24
|
+
export { default as Icon } from './components/icon/icon.astro'
|
|
25
|
+
export { default as Container } from './components/layout/container.astro'
|
|
26
|
+
export { default as Grid } from './components/layout/grid.astro'
|
|
27
|
+
export { default as SectionHead } from './components/layout/section-head.astro'
|
|
28
|
+
export { default as Section } from './components/layout/section.astro'
|
|
29
|
+
export { default as PageHead } from './components/page-head/page-head.astro'
|
|
30
|
+
export { default as Pagination } from './components/pagination/pagination.astro'
|
|
31
|
+
export { default as Panel } from './components/panel/panel.astro'
|
|
32
|
+
export { default as Progress } from './components/progress/progress.astro'
|
|
33
|
+
export { default as CodeBlock } from './components/prose/code-block.astro'
|
|
34
|
+
export { default as Prose } from './components/prose/prose.astro'
|
|
35
|
+
export { default as StatGroup } from './components/stat/stat-group.astro'
|
|
36
|
+
export { default as Stat } from './components/stat/stat.astro'
|
|
37
|
+
export { default as Table } from './components/table/table.astro'
|
|
38
|
+
export { default as Tabs } from './components/tabs/tabs.astro'
|
|
39
|
+
export { default as Tag } from './components/tag/tag.astro'
|
|
40
|
+
export { default as Timeline } from './components/timeline/timeline.astro'
|
|
41
|
+
export { default as Tooltip } from './components/tooltip/tooltip.astro'
|
package/dist/bem.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ClassValue } from 'clsx';
|
|
2
|
+
type Modifier = string | number | boolean | null | undefined;
|
|
3
|
+
export type BemOptions = {
|
|
4
|
+
defaults?: Record<string, string | number>;
|
|
5
|
+
prefixed?: string[];
|
|
6
|
+
};
|
|
7
|
+
export type Bem = {
|
|
8
|
+
(modifiers?: Record<string, Modifier>, ...extra: ClassValue[]): string;
|
|
9
|
+
el: (element: string, modifiers?: Record<string, Modifier>, ...extra: ClassValue[]) => string;
|
|
10
|
+
};
|
|
11
|
+
export declare function bem(block: string, { defaults, prefixed }?: BemOptions): Bem;
|
|
12
|
+
export {};
|
package/dist/bem.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { clsx } from 'clsx';
|
|
2
|
+
// Class names for one BEM block. `true` gives `--key`, a string gives `--value`, false-ish gives nothing.
|
|
3
|
+
export function bem(block, { defaults = {}, prefixed = [] } = {}) {
|
|
4
|
+
const build = (name, modifiers = {}, extra = []) => clsx(name, Object.entries(modifiers).map(([key, value]) => {
|
|
5
|
+
if (value === true) {
|
|
6
|
+
return `${name}--${key}`;
|
|
7
|
+
}
|
|
8
|
+
if ((typeof value === 'string' && value !== '') || typeof value === 'number') {
|
|
9
|
+
if (defaults[key] === value) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
return prefixed.includes(key) ? `${name}--${key}-${value}` : `${name}--${value}`;
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
}), extra);
|
|
16
|
+
const fn = ((modifiers, ...extra) => build(block, modifiers, extra));
|
|
17
|
+
fn.el = (element, modifiers, ...extra) => build(`${block}__${element}`, modifiers, extra);
|
|
18
|
+
return fn;
|
|
19
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './alert.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { alertClass, alertIcon, alertRole, type AlertOptions } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<'div'>, 'class' | 'title'> &
|
|
7
|
+
Omit<AlertOptions, 'className'> & {
|
|
8
|
+
class?: string
|
|
9
|
+
/** Plain-text title; the `title` slot takes markup. */
|
|
10
|
+
title?: string
|
|
11
|
+
/** Sets role="alert" so screen readers interrupt. Only for messages shown in response to an action. */
|
|
12
|
+
urgent?: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { tone, framed, title, urgent, role, class: className, slot: _slot, ...rest } = Astro.props
|
|
16
|
+
const hasTitle = title !== undefined || Astro.slots.has('title')
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
<div {...rest} role={alertRole(urgent, role)} class={alertClass({ tone, framed, className })}>
|
|
20
|
+
<svg class="x-alert__icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
21
|
+
{alertIcon(tone).map(({ className, d }) => <path class={className} d={d} />)}
|
|
22
|
+
</svg>
|
|
23
|
+
<div class="x-alert__content">
|
|
24
|
+
{
|
|
25
|
+
hasTitle && (
|
|
26
|
+
<p class="x-alert__title">
|
|
27
|
+
<slot name="title">{title}</slot>
|
|
28
|
+
</p>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
{
|
|
32
|
+
Astro.slots.has('default') && (
|
|
33
|
+
<div class="x-alert__body">
|
|
34
|
+
<slot />
|
|
35
|
+
</div>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
{
|
|
39
|
+
Astro.slots.has('actions') && (
|
|
40
|
+
<div class="x-alert__actions">
|
|
41
|
+
<slot name="actions" />
|
|
42
|
+
</div>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-alert {
|
|
4
|
+
--x-alert-tone: var(--x-color-info);
|
|
5
|
+
--x-alert-wash: var(--x-color-info-wash);
|
|
6
|
+
display: grid;
|
|
7
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
8
|
+
gap: var(--x-alert-gap, var(--x-space-3));
|
|
9
|
+
align-items: start;
|
|
10
|
+
padding: var(--x-space-4) var(--x-space-5) var(--x-space-4) var(--x-space-4);
|
|
11
|
+
font-family: var(--x-font-ui);
|
|
12
|
+
background: var(--x-alert-bg, var(--x-alert-wash));
|
|
13
|
+
border-left: 2px solid var(--x-alert-tone);
|
|
14
|
+
}
|
|
15
|
+
.x-alert--success {
|
|
16
|
+
--x-alert-tone: var(--x-color-success);
|
|
17
|
+
--x-alert-wash: var(--x-color-success-wash);
|
|
18
|
+
}
|
|
19
|
+
.x-alert--warning {
|
|
20
|
+
--x-alert-tone: var(--x-color-warning);
|
|
21
|
+
--x-alert-wash: var(--x-color-warning-wash);
|
|
22
|
+
}
|
|
23
|
+
.x-alert--danger {
|
|
24
|
+
--x-alert-tone: var(--x-color-danger);
|
|
25
|
+
--x-alert-wash: var(--x-color-danger-wash);
|
|
26
|
+
}
|
|
27
|
+
.x-alert__icon {
|
|
28
|
+
width: 20px;
|
|
29
|
+
height: 20px;
|
|
30
|
+
margin-top: 2px;
|
|
31
|
+
color: var(--x-alert-tone);
|
|
32
|
+
fill: none;
|
|
33
|
+
stroke: currentcolor;
|
|
34
|
+
stroke-width: 1.5;
|
|
35
|
+
}
|
|
36
|
+
.x-alert__glyph {
|
|
37
|
+
stroke-width: var(--x-alert-glyph-width, 2);
|
|
38
|
+
}
|
|
39
|
+
.x-alert__frame--round {
|
|
40
|
+
display: none;
|
|
41
|
+
}
|
|
42
|
+
.x-alert__content {
|
|
43
|
+
display: grid;
|
|
44
|
+
gap: var(--x-space-1);
|
|
45
|
+
min-width: 0;
|
|
46
|
+
}
|
|
47
|
+
.x-alert__title {
|
|
48
|
+
font-size: var(--x-fs-ui);
|
|
49
|
+
font-weight: var(--x-alert-title-weight, 600);
|
|
50
|
+
line-height: 1.4;
|
|
51
|
+
color: var(--x-color-text);
|
|
52
|
+
}
|
|
53
|
+
.x-alert__body {
|
|
54
|
+
font-size: var(--x-alert-fs, var(--x-fs-small));
|
|
55
|
+
line-height: var(--x-alert-lh, 1.5);
|
|
56
|
+
color: var(--x-color-text-muted);
|
|
57
|
+
}
|
|
58
|
+
.x-alert__body > * + * {
|
|
59
|
+
margin-top: var(--x-space-2);
|
|
60
|
+
}
|
|
61
|
+
.x-alert__actions {
|
|
62
|
+
display: flex;
|
|
63
|
+
flex-wrap: wrap;
|
|
64
|
+
gap: var(--x-space-2);
|
|
65
|
+
align-items: center;
|
|
66
|
+
margin-top: var(--x-space-2);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import './alert.scss';
|
|
2
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
import { type AlertOptions } from './index.ts';
|
|
4
|
+
export type AlertProps = Omit<AlertOptions, 'className'> & Omit<HTMLAttributes<HTMLDivElement>, 'title'> & {
|
|
5
|
+
title?: ReactNode;
|
|
6
|
+
/** Sets role="alert" so screen readers interrupt. Only for messages shown in response to an action. */
|
|
7
|
+
urgent?: boolean;
|
|
8
|
+
/** Row under the text, usually small buttons or a link. */
|
|
9
|
+
actions?: ReactNode;
|
|
10
|
+
};
|
|
11
|
+
export declare function Alert({ tone, framed, title, urgent, role, actions, className, children, ...rest }: AlertProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import './alert.css';
|
|
3
|
+
import { alertClass, alertIcon, alertRole } from "./index.js";
|
|
4
|
+
export function Alert({ tone, framed, title, urgent, role, actions, className, children, ...rest }) {
|
|
5
|
+
return (_jsxs("div", { ...rest, role: alertRole(urgent, role), className: alertClass({ tone, framed, className }), children: [_jsx("svg", { className: "x-alert__icon", viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: alertIcon(tone).map(({ className: pathClass, d }) => (_jsx("path", { className: pathClass, d: d }, d))) }), _jsxs("div", { className: "x-alert__content", children: [title != null && _jsx("p", { className: "x-alert__title", children: title }), children != null && _jsx("div", { className: "x-alert__body", children: children }), actions != null && _jsx("div", { className: "x-alert__actions", children: actions })] })] }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type AlertTone = 'info' | 'success' | 'warning' | 'danger';
|
|
2
|
+
export type AlertOptions = {
|
|
3
|
+
tone?: AlertTone;
|
|
4
|
+
/** Toned frame and caps title, for alerts that sit in a tool page rather than in text. */
|
|
5
|
+
framed?: boolean;
|
|
6
|
+
className?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const alertClass: ({ tone, framed, className }?: AlertOptions) => string;
|
|
9
|
+
export declare const alertRole: <R extends string>(urgent?: boolean, role?: R | null) => R | "alert" | "status";
|
|
10
|
+
export type AlertIconPath = {
|
|
11
|
+
className: string;
|
|
12
|
+
d: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const alertIcon: (tone?: AlertTone) => AlertIconPath[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
const alert = bem('x-alert');
|
|
3
|
+
export const alertClass = ({ tone = 'info', framed, className } = {}) => alert({ tone, framed }, className);
|
|
4
|
+
// status is silent for content present on load; alert interrupts, so keep it for messages inserted after an action.
|
|
5
|
+
export const alertRole = (urgent, role) => role ?? (urgent ? 'alert' : 'status');
|
|
6
|
+
// Every icon carries both outline shapes; each theme shows one.
|
|
7
|
+
const frames = {
|
|
8
|
+
badge: { facet: 'M12 2 21 7v10l-9 5-9-5V7z', round: 'M12 2 22 12 12 22 2 12z' },
|
|
9
|
+
stop: { facet: 'M8 2h8l6 6v8l-6 6H8l-6-6V8z', round: 'M21.5 12a9.5 9.5 0 1 1-19 0 9.5 9.5 0 0 1 19 0z' },
|
|
10
|
+
};
|
|
11
|
+
const frame = (shape) => [
|
|
12
|
+
{ className: alert.el('frame', { facet: true }), d: frames[shape].facet },
|
|
13
|
+
{ className: alert.el('frame', { round: true }), d: frames[shape].round },
|
|
14
|
+
];
|
|
15
|
+
const glyph = (d) => ({ className: alert.el('glyph'), d });
|
|
16
|
+
export const alertIcon = (tone = 'info') => {
|
|
17
|
+
switch (tone) {
|
|
18
|
+
case 'success':
|
|
19
|
+
return [...frame('badge'), glyph('m8 12 3 3 5-6')];
|
|
20
|
+
case 'warning':
|
|
21
|
+
return [{ className: alert.el('frame'), d: 'M12 3 22 20H2z' }, glyph('M12 9v5M12 16.5v.5')];
|
|
22
|
+
case 'danger':
|
|
23
|
+
return [...frame('stop'), glyph('m9 9 6 6M15 9l-6 6')];
|
|
24
|
+
default:
|
|
25
|
+
return [...frame('badge'), glyph('M12 11v6M12 7.5v.5')];
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './avatar.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { avatarClass, avatarState, type AvatarOptions } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<'span'>, 'class'> & Omit<AvatarOptions, 'className'> & { class?: string }
|
|
7
|
+
|
|
8
|
+
const { name, src, alt, initials, size, class: className, slot: _slot, ...rest } = Astro.props
|
|
9
|
+
const state = avatarState({ name, src, alt, initials })
|
|
10
|
+
const attrs = { ...rest, ...state.root }
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<span {...attrs} class={avatarClass({ size, src, className })}>
|
|
14
|
+
{
|
|
15
|
+
src ? (
|
|
16
|
+
<img class="x-avatar__image" src={src} alt={state.alt} loading="lazy" decoding="async" />
|
|
17
|
+
) : (
|
|
18
|
+
<span class="x-avatar__initials" aria-hidden="true">
|
|
19
|
+
{state.initials}
|
|
20
|
+
</span>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
</span>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-avatar {
|
|
4
|
+
--x-avatar-size: 64px;
|
|
5
|
+
position: relative;
|
|
6
|
+
isolation: isolate;
|
|
7
|
+
display: inline-grid;
|
|
8
|
+
flex: none;
|
|
9
|
+
place-items: center;
|
|
10
|
+
width: var(--x-avatar-size);
|
|
11
|
+
height: var(--x-avatar-size);
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
font-family: var(--x-font-display);
|
|
14
|
+
font-size: calc(var(--x-avatar-size) * var(--x-avatar-scale, 0.4));
|
|
15
|
+
font-weight: var(--x-avatar-weight, 600);
|
|
16
|
+
line-height: 1;
|
|
17
|
+
color: var(--x-color-text);
|
|
18
|
+
background: var(--x-color-surface-2);
|
|
19
|
+
user-select: none;
|
|
20
|
+
}
|
|
21
|
+
.x-avatar--sm {
|
|
22
|
+
--x-avatar-size: 40px;
|
|
23
|
+
}
|
|
24
|
+
.x-avatar--lg {
|
|
25
|
+
--x-avatar-size: 96px;
|
|
26
|
+
}
|
|
27
|
+
.x-avatar--xl {
|
|
28
|
+
--x-avatar-size: 128px;
|
|
29
|
+
}
|
|
30
|
+
.x-avatar__image {
|
|
31
|
+
width: 100%;
|
|
32
|
+
height: 100%;
|
|
33
|
+
object-fit: cover;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import './avatar.scss';
|
|
2
|
+
import type { HTMLAttributes } from 'react';
|
|
3
|
+
import { type AvatarOptions } from './index.ts';
|
|
4
|
+
export type AvatarProps = Omit<AvatarOptions, 'className'> & HTMLAttributes<HTMLSpanElement>;
|
|
5
|
+
export declare function Avatar({ name, src, alt, initials, size, className, ...rest }: AvatarProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import './avatar.css';
|
|
3
|
+
import { avatarClass, avatarState } from "./index.js";
|
|
4
|
+
export function Avatar({ name, src, alt, initials, size, className, ...rest }) {
|
|
5
|
+
const state = avatarState({ name, src, alt, initials });
|
|
6
|
+
return (_jsx("span", { ...rest, ...state.root, className: avatarClass({ size, src, className }), children: src ? (_jsx("img", { className: "x-avatar__image", src: src, alt: state.alt, loading: "lazy", decoding: "async" })) : (_jsx("span", { className: "x-avatar__initials", "aria-hidden": "true", children: state.initials })) }));
|
|
7
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type AvatarSize = 'sm' | 'md' | 'lg' | 'xl';
|
|
2
|
+
export type AvatarOptions = {
|
|
3
|
+
/** The person's name: the accessible name and the source of the initials. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** Image URL. Without it the avatar shows initials. */
|
|
6
|
+
src?: string;
|
|
7
|
+
/** Overrides the accessible name. Pass '' when the name is already printed next to the avatar. */
|
|
8
|
+
alt?: string;
|
|
9
|
+
/** Overrides the initials taken from `name`. */
|
|
10
|
+
initials?: string;
|
|
11
|
+
size?: AvatarSize;
|
|
12
|
+
className?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const avatarClass: ({ size, src, className, }?: Pick<AvatarOptions, "size" | "src" | "className">) => string;
|
|
15
|
+
export declare const avatarInitials: (name: string) => string;
|
|
16
|
+
export declare const avatarState: ({ name, src, alt, initials }: Pick<AvatarOptions, "name" | "src" | "alt" | "initials">) => {
|
|
17
|
+
root: {
|
|
18
|
+
'aria-hidden'?: undefined;
|
|
19
|
+
role?: undefined;
|
|
20
|
+
'aria-label'?: undefined;
|
|
21
|
+
} | {
|
|
22
|
+
'aria-hidden': "true";
|
|
23
|
+
role?: undefined;
|
|
24
|
+
'aria-label'?: undefined;
|
|
25
|
+
} | {
|
|
26
|
+
role: "img";
|
|
27
|
+
'aria-label': string;
|
|
28
|
+
'aria-hidden'?: undefined;
|
|
29
|
+
};
|
|
30
|
+
alt: string;
|
|
31
|
+
initials: string;
|
|
32
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { bem } from "../../bem.js";
|
|
2
|
+
const avatar = bem('x-avatar');
|
|
3
|
+
export const avatarClass = ({ size = 'md', src, className, } = {}) => avatar({ size, image: Boolean(src) }, className);
|
|
4
|
+
// First letter of the first and last word, so "Xaroth Brook" gives "XB" and "Xaroth" gives "X".
|
|
5
|
+
export const avatarInitials = (name) => {
|
|
6
|
+
const words = name.trim().split(/\s+/).filter(Boolean);
|
|
7
|
+
const first = words[0]?.[0] ?? '';
|
|
8
|
+
const last = words.length > 1 ? (words[words.length - 1]?.[0] ?? '') : '';
|
|
9
|
+
return (first + last).toUpperCase();
|
|
10
|
+
};
|
|
11
|
+
// An image carries its own alt. Initials are not a name, so the box is an img with the full name as label.
|
|
12
|
+
export const avatarState = ({ name, src, alt, initials }) => {
|
|
13
|
+
const label = alt ?? name;
|
|
14
|
+
const root = src
|
|
15
|
+
? {}
|
|
16
|
+
: label === ''
|
|
17
|
+
? { 'aria-hidden': 'true' }
|
|
18
|
+
: { role: 'img', 'aria-label': label };
|
|
19
|
+
return {
|
|
20
|
+
root,
|
|
21
|
+
alt: label,
|
|
22
|
+
initials: initials ?? avatarInitials(name),
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './badge.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { badgeClass, type BadgeOptions } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<'span'>, 'class'> & Omit<BadgeOptions, 'className'> & { class?: string }
|
|
7
|
+
|
|
8
|
+
const { tone, class: className, slot: _slot, ...rest } = Astro.props
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<span {...rest} class={badgeClass({ tone, className })}><slot /></span>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-badge {
|
|
4
|
+
--x-badge-tone: var(--x-badge-default, var(--x-color-text-muted));
|
|
5
|
+
--x-badge-wash: transparent;
|
|
6
|
+
display: inline-flex;
|
|
7
|
+
flex: none;
|
|
8
|
+
gap: var(--x-badge-gap, 6px);
|
|
9
|
+
align-items: center;
|
|
10
|
+
min-height: 24px;
|
|
11
|
+
padding: 0 var(--x-space-2);
|
|
12
|
+
font-family: var(--x-font-ui);
|
|
13
|
+
font-size: var(--x-fs-label);
|
|
14
|
+
font-weight: 600;
|
|
15
|
+
line-height: 1;
|
|
16
|
+
letter-spacing: var(--x-track-label);
|
|
17
|
+
text-transform: uppercase;
|
|
18
|
+
white-space: nowrap;
|
|
19
|
+
color: var(--x-badge-tone);
|
|
20
|
+
background: var(--x-badge-wash);
|
|
21
|
+
border: 1px solid color-mix(in srgb, var(--x-badge-tone) var(--x-badge-edge-mix, 45%), transparent);
|
|
22
|
+
}
|
|
23
|
+
.x-badge::before {
|
|
24
|
+
content: "";
|
|
25
|
+
flex: none;
|
|
26
|
+
width: 5px;
|
|
27
|
+
height: 5px;
|
|
28
|
+
background: currentcolor;
|
|
29
|
+
}
|
|
30
|
+
.x-badge--info {
|
|
31
|
+
--x-badge-tone: var(--x-color-info);
|
|
32
|
+
--x-badge-wash: var(--x-color-info-wash);
|
|
33
|
+
}
|
|
34
|
+
.x-badge--success {
|
|
35
|
+
--x-badge-tone: var(--x-color-success);
|
|
36
|
+
--x-badge-wash: var(--x-color-success-wash);
|
|
37
|
+
}
|
|
38
|
+
.x-badge--warning {
|
|
39
|
+
--x-badge-tone: var(--x-color-warning);
|
|
40
|
+
--x-badge-wash: var(--x-color-warning-wash);
|
|
41
|
+
}
|
|
42
|
+
.x-badge--danger {
|
|
43
|
+
--x-badge-tone: var(--x-color-danger);
|
|
44
|
+
--x-badge-wash: var(--x-color-danger-wash);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import './badge.scss';
|
|
2
|
+
import type { HTMLAttributes } from 'react';
|
|
3
|
+
import { type BadgeOptions } from './index.ts';
|
|
4
|
+
export type BadgeProps = Omit<BadgeOptions, 'className'> & HTMLAttributes<HTMLSpanElement>;
|
|
5
|
+
export declare function Badge({ tone, className, children, ...rest }: BadgeProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import './badge.css';
|
|
3
|
+
import { badgeClass } from "./index.js";
|
|
4
|
+
export function Badge({ tone, className, children, ...rest }) {
|
|
5
|
+
return (_jsx("span", { ...rest, className: badgeClass({ tone, className }), children: children }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
import './breadcrumbs.css'
|
|
3
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
4
|
+
import { breadcrumbState, breadcrumbsClass, breadcrumbsClasses as c, type BreadcrumbItem } from './index.js'
|
|
5
|
+
|
|
6
|
+
type Props = Omit<HTMLAttributes<'nav'>, 'class'> & {
|
|
7
|
+
class?: string
|
|
8
|
+
items: BreadcrumbItem[]
|
|
9
|
+
label?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const { class: className, items, label = 'Breadcrumb', slot: _slot, ...rest } = Astro.props
|
|
13
|
+
const attrs = { ...rest, 'aria-label': label }
|
|
14
|
+
const crumbs = items.map((item, i) => ({ item, ...breadcrumbState(item, i, items.length) }))
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
<nav {...attrs} class={breadcrumbsClass({ className })}>
|
|
18
|
+
<ol class={c.list}>
|
|
19
|
+
{
|
|
20
|
+
crumbs.map(({ item, tag: El, attrs }) => (
|
|
21
|
+
<li class={c.item}>
|
|
22
|
+
<El {...attrs}>{item.label}</El>
|
|
23
|
+
</li>
|
|
24
|
+
))
|
|
25
|
+
}
|
|
26
|
+
</ol>
|
|
27
|
+
</nav>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@layer x.reset, x.core, x.theme, x.utility;
|
|
2
|
+
@layer x.core {
|
|
3
|
+
.x-breadcrumbs__list {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-wrap: wrap;
|
|
6
|
+
gap: var(--x-space-1) var(--x-breadcrumbs-gap, 10px);
|
|
7
|
+
align-items: center;
|
|
8
|
+
padding: 0;
|
|
9
|
+
margin: 0;
|
|
10
|
+
list-style: none;
|
|
11
|
+
}
|
|
12
|
+
.x-breadcrumbs__item {
|
|
13
|
+
display: inline-flex;
|
|
14
|
+
gap: var(--x-breadcrumbs-gap, 10px);
|
|
15
|
+
align-items: center;
|
|
16
|
+
min-width: 0;
|
|
17
|
+
color: var(--x-color-text-faint);
|
|
18
|
+
}
|
|
19
|
+
.x-breadcrumbs__item + .x-breadcrumbs__item::before {
|
|
20
|
+
flex: none;
|
|
21
|
+
}
|
|
22
|
+
.x-breadcrumbs__link {
|
|
23
|
+
color: var(--x-color-text-muted);
|
|
24
|
+
text-decoration: none;
|
|
25
|
+
transition: color var(--x-duration) var(--x-ease);
|
|
26
|
+
}
|
|
27
|
+
.x-breadcrumbs__link:hover {
|
|
28
|
+
color: var(--x-color-accent);
|
|
29
|
+
}
|
|
30
|
+
.x-breadcrumbs__current {
|
|
31
|
+
color: var(--x-color-text);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import './breadcrumbs.scss';
|
|
2
|
+
import { type HTMLAttributes } from 'react';
|
|
3
|
+
import { type BreadcrumbItem } from './index.ts';
|
|
4
|
+
export type BreadcrumbsProps = Omit<HTMLAttributes<HTMLElement>, 'children'> & {
|
|
5
|
+
/** Trail from the root to the current page. The last item is the current page. */
|
|
6
|
+
items: BreadcrumbItem[];
|
|
7
|
+
label?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function Breadcrumbs({ className, items, label, ...rest }: BreadcrumbsProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import './breadcrumbs.css';
|
|
3
|
+
import { createElement } from 'react';
|
|
4
|
+
import { breadcrumbState, breadcrumbsClass, breadcrumbsClasses as c } from "./index.js";
|
|
5
|
+
export function Breadcrumbs({ className, items, label = 'Breadcrumb', ...rest }) {
|
|
6
|
+
return (_jsx("nav", { ...rest, "aria-label": label, className: breadcrumbsClass({ className }), children: _jsx("ol", { className: c.list, children: items.map((item, i) => {
|
|
7
|
+
const { tag, attrs } = breadcrumbState(item, i, items.length);
|
|
8
|
+
const { class: cls, ...other } = attrs;
|
|
9
|
+
return (_jsx("li", { className: c.item, children: createElement(tag, { ...other, className: cls }, item.label) }, `${i}-${item.label}`));
|
|
10
|
+
}) }) }));
|
|
11
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type BreadcrumbItem = {
|
|
2
|
+
label: string;
|
|
3
|
+
href?: string;
|
|
4
|
+
};
|
|
5
|
+
export type BreadcrumbsOptions = {
|
|
6
|
+
className?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const breadcrumbsClass: ({ className }?: BreadcrumbsOptions) => string;
|
|
9
|
+
export declare const breadcrumbsClasses: {
|
|
10
|
+
readonly list: string;
|
|
11
|
+
readonly item: string;
|
|
12
|
+
readonly link: string;
|
|
13
|
+
readonly text: string;
|
|
14
|
+
readonly current: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const breadcrumbState: (item: BreadcrumbItem, index: number, count: number) => {
|
|
17
|
+
tag: "span";
|
|
18
|
+
attrs: {
|
|
19
|
+
class: string;
|
|
20
|
+
'aria-current': "page";
|
|
21
|
+
href?: undefined;
|
|
22
|
+
};
|
|
23
|
+
} | {
|
|
24
|
+
tag: "a";
|
|
25
|
+
attrs: {
|
|
26
|
+
class: string;
|
|
27
|
+
href: string;
|
|
28
|
+
'aria-current'?: undefined;
|
|
29
|
+
};
|
|
30
|
+
} | {
|
|
31
|
+
tag: "span";
|
|
32
|
+
attrs: {
|
|
33
|
+
class: string;
|
|
34
|
+
'aria-current'?: undefined;
|
|
35
|
+
href?: undefined;
|
|
36
|
+
};
|
|
37
|
+
};
|