Skip to content

Commit 46018ad

Browse files
committed
add custom icon arxiv; NamedIcon that selects built-in or local icons based on name
1 parent 8a4f679 commit 46018ad

File tree

8 files changed

+2532
-2042
lines changed

8 files changed

+2532
-2042
lines changed

package-lock.json

+2,371-1,993
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+10-10
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@
1111
"test": "vitest"
1212
},
1313
"dependencies": {
14-
"@astrojs/check": "^0.9.3",
15-
"@astrojs/starlight": "^0.26.1",
16-
"@astrojs/starlight-tailwind": "^2.0.3",
17-
"@astrojs/tailwind": "^5.1.2",
18-
"@effect/platform-node": "^0.65.0",
19-
"astro": "^4.14.5",
14+
"@astrojs/check": "^0.9.4",
15+
"@astrojs/starlight": "^0.30.5",
16+
"@astrojs/starlight-tailwind": "^3.0.0",
17+
"@astrojs/tailwind": "^5.1.4",
18+
"@effect/platform-node": "^0.68.1",
19+
"astro": "^5.1.4",
2020
"date-fns": "^4.1.0",
21-
"effect": "^3.11.0",
21+
"effect": "^3.12.1",
2222
"sharp": "^0.33.5",
23-
"tailwindcss": "^3.4.15",
24-
"typescript": "^5.5.4",
25-
"vitest": "^2.1.7",
23+
"tailwindcss": "^3.4.17",
24+
"typescript": "^5.7.3",
25+
"vitest": "^2.1.8",
2626
"xml-js": "^1.6.11"
2727
}
2828
}

src/components/GrArxivPage.astro

+7-39
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import { format } from 'date-fns';
44

55
import {extractArxivID, getPaper} from '../lib/arxiv'
66

7+
import LinkSpan from './LinkSpan.astro'
8+
79
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
10+
import { Icon } from '@astrojs/starlight/components';
811

912
const props = Astro.props;
1013

@@ -18,21 +21,21 @@ const paper = getPaper(arxivid)
1821
<StarlightPage
1922
frontmatter={{ title: arxivEntry.title, editUrl:false, tableOfContents:false} }}
2023
>
21-
<p class="byline text-xs">
24+
<p class="byline text-sm">
2225
<time itemprop="published" datetime={format(arxivEntry.published, 'yyyy-MM-dd')}>
2326
Published {format(arxivEntry.published, 'MMMM do, yyyy')}
2427
</time>
25-
<address class="author text-xs">By
28+
<address class="author text-sm">By
2629
{arxivEntry.author.map( (author:any, i:number) => (
2730
<span>{(i ? ', ' : '')}<a rel="author" class="url fn n">{author.name}</a></span>
2831
))}
2932
</address>
30-
<cite class="arxivid text-xs">
33+
<cite class="arxivid text-sm">
3134
<a href={arxivEntry.id}>arXiv:{arxivid}</a>
3235
[ {arxivEntry.category.join(", ")}
3336
]
3437
</cite>
35-
<cite class="github text-xs">
38+
<cite class="github text-sm">
3639
{paper?.github !== undefined && paper.github !== "" ?
3740
(<a href={"https://github.com/" + paper?.github}>github:{paper?.github}</a>)
3841
: ''
@@ -45,38 +48,3 @@ const paper = getPaper(arxivid)
4548
<blockquote><p>{arxivEntry.summary}</p></blockquote>
4649

4750
</StarlightPage>
48-
49-
50-
51-
<!-- <StarlightPage
52-
frontmatter={{ title: `${entry.title.text}`, editUrl:false, tableOfContents:false} }}
53-
>
54-
55-
<p class="byline text-xs">
56-
<time pubdate={format(pubDate, 'yyyy-MM-dd')} title="August 28th, 2011">Published {format(pubDate, 'MMMM do, yyyy')}</time>
57-
<address class="author text-xs">By
58-
{authors.map( (author:any, i:number) => (
59-
<span key={i}>{(i ? ', ' : '')}
60-
<a rel="author" class="url fn n">{author.name.text}</a>
61-
</span>
62-
))}
63-
</address>
64-
<cite class="arxivid text-xs">
65-
<a href={entry.id.text}>arXiv:{arxivid}</a>
66-
[ {categories.map( (category:any) => category._attributes.term).join(", ")}
67-
]
68-
</cite>
69-
<cite class="github text-xs">
70-
{paper?.github !== undefined && paper.github !== "" ?
71-
(<a href={"https://github.com/" + paper?.github}>github:{paper?.github}</a>)
72-
: ''
73-
}
74-
75-
</cite>
76-
</p>
77-
78-
79-
<h2 id="quote">Abstract</h2>
80-
<blockquote><p>{entry.summary.text}</p></blockquote>
81-
82-
</StarlightPage> -->

src/components/GrIcon.astro

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
import { LocalIcons } from './LocalIcons';
3+
4+
interface Props {
5+
name: keyof typeof LocalIcons;
6+
label?: string;
7+
color?: string;
8+
size?: string;
9+
class?: string;
10+
}
11+
12+
const { name, label, size = '1em', color } = Astro.props;
13+
const a11yAttrs = label ? ({ 'aria-label': label } as const) : ({ 'aria-hidden': 'true' } as const);
14+
---
15+
16+
<svg
17+
{...a11yAttrs}
18+
class={Astro.props.class}
19+
width="16"
20+
height="16"
21+
viewBox="0 0 24 24"
22+
fill="currentColor"
23+
set:html={LocalIcons[name]}
24+
/>
25+
26+
<style define:vars={{ 'sl-icon-color': color, 'sl-icon-size': size }}>
27+
svg {
28+
color: var(--sl-icon-color);
29+
font-size: var(--sl-icon-size, 1em);
30+
width: 1em;
31+
height: 1em;
32+
}
33+
</style>

src/components/LinkSpan.astro

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
import type { HTMLAttributes } from 'astro/types';
3+
import NamedIcon, { type IconNames } from './NamedIcon.astro';
4+
5+
6+
interface Props extends Omit<HTMLAttributes<'a'>, 'href'> {
7+
href: string | URL;
8+
icon?: IconNames | undefined;
9+
iconPlacement?: 'start' | 'end' | undefined;
10+
variant?: 'primary' | 'secondary' | 'minimal';
11+
}
12+
13+
const {
14+
class: className,
15+
icon,
16+
iconPlacement = 'start',
17+
variant = 'primary',
18+
...attrs
19+
} = Astro.props;
20+
---
21+
22+
<a class:list={['gr-link-span not-content', variant, className]} {...attrs}>
23+
24+
{icon && iconPlacement === 'start' && <NamedIcon size="2.0rem" name={icon}/>}
25+
<slot />
26+
{icon && iconPlacement === 'end' && <NamedIcon size="2.0rem" name={icon}/>}
27+
</a>
28+
29+
<style>
30+
.gr-link-span {
31+
align-items: center;
32+
border: 1px solid transparent;
33+
display: inline-flex;
34+
font-size: var(--sl-text-sm);
35+
gap: 0.5em;
36+
line-height: 1.1875;
37+
outline-offset: 0.25rem;
38+
padding: 0.4375rem 1.125rem;
39+
text-decoration: none;
40+
}
41+
42+
.gr-link-span.primary {
43+
background: var(--sl-color-text-accent);
44+
border-color: var(--sl-color-text-accent);
45+
color: var(--sl-color-black);
46+
}
47+
.gr-link-span.primary:hover {
48+
color: var(--sl-color-black);
49+
}
50+
.gr-link-span.secondary {
51+
border-color: inherit;
52+
color: var(--sl-color-white);
53+
}
54+
.gr-link-span.minimal {
55+
color: var(--sl-color-white);
56+
padding-inline: 0;
57+
}
58+
59+
.gr-link-span :global(svg) {
60+
flex-shrink: 0;
61+
}
62+
63+
@media (min-width: 50rem) {
64+
.gr-link-span {
65+
font-size: var(--sl-text-base);
66+
padding: 0.9375rem 1.25rem;
67+
}
68+
}
69+
70+
:global(.sl-markdown-content) .gr-link-span {
71+
margin-inline-end: 1rem;
72+
}
73+
:global(.sl-markdown-content) .gr-link-span:not(:where(p *)) {
74+
margin-block: 1rem;
75+
}
76+
</style>

src/components/LocalIcons.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
export const LocalIcons = {
3+
'arxiv':
4+
`<path d="M3.8423 0a1.0037 1.0037 0 0 0 -0.922 0.6078c-0.1536 0.3687 -0.0438 0.6275 0.2938 1.1113l6.9185 8.3597 -1.0223 1.1058a1.0393 1.0393 0 0 0 0.003 1.4229l1.2292 1.3135 -5.4391 6.4444c-0.2803 0.299 -0.4538 0.823 -0.2971 1.1986a1.0253 1.0253 0 0 0 0.9585 0.635 0.9133 0.9133 0 0 0 0.6891 -0.3405l5.783 -6.126 7.4902 8.0051a0.8527 0.8527 0 0 0 0.6835 0.2597 0.9575 0.9575 0 0 0 0.8777 -0.6138c0.1577 -0.377 -0.017 -0.7502 -0.306 -1.1407l-7.0518 -8.3418 1.0632 -1.13a0.9626 0.9626 0 0 0 0.0089 -1.3165L4.6336 0.4639s-0.3733 -0.4535 -0.768 -0.463zm0 0.272h0.0166c0.2179 0.0052 0.4874 0.2715 0.5644 0.3639l0.005 0.006 0.0052 0.0055 10.169 10.9905a0.6915 0.6915 0 0 1 -0.0072 0.945l-1.0666 1.133 -1.4982 -1.7724 -8.5994 -10.39c-0.3286 -0.472 -0.352 -0.6183 -0.2592 -0.841a0.7307 0.7307 0 0 1 0.6704 -0.4401Zm14.341 1.5701a0.877 0.877 0 0 0 -0.6554 0.2418l-5.6962 6.1584 1.6944 1.8319 5.3089 -6.5138c0.3251 -0.4335 0.479 -0.6603 0.3247 -1.0292a1.1205 1.1205 0 0 0 -0.9763 -0.689zm-7.6557 12.2823 1.3186 1.4135 -5.7864 6.1295a0.6494 0.6494 0 0 1 -0.4959 0.26 0.7516 0.7516 0 0 1 -0.706 -0.4669c-0.1119 -0.2682 0.0359 -0.6864 0.2442 -0.9083l0.0051 -0.0055 0.0047 -0.0055z" fill="#000000" stroke-width="1"></path>`
5+
};
6+

src/components/NamedIcon.astro

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
import { Icon as SlIcon } from '@astrojs/starlight/components'
3+
import GrIcon from './GrIcon.astro'
4+
5+
import { LocalIcons } from './LocalIcons';
6+
7+
const localIconNames = Object.keys(LocalIcons)
8+
type IconParams = Parameters<typeof SlIcon>
9+
type SlIconNames = IconParams[0]['name']
10+
type LocalIconNames = keyof typeof LocalIcons
11+
export type IconNames = LocalIconNames | SlIconNames
12+
13+
interface Props {
14+
name: IconNames;
15+
label?: string;
16+
color?: string;
17+
size?: string;
18+
class?: string;
19+
}
20+
21+
const { name, label, size = '1em', color } = Astro.props;
22+
const a11yAttrs = label ? ({ 'aria-label': label } as const) : ({ 'aria-hidden': 'true' } as const);
23+
---
24+
25+
{localIconNames.includes(name) ? (<GrIcon name={name as LocalIconNames} />) : (<SlIcon name={name as SlIconNames}/>)}

src/data/papers.json

+4
Original file line numberDiff line numberDiff line change
@@ -106,5 +106,9 @@
106106
{
107107
"arxivid": "2410.19494",
108108
"github": ""
109+
},
110+
{
111+
"arxivid": "2501.00309",
112+
"github": "https://github.com/Graph-RAG/GraphRAG/"
109113
}
110114
]

0 commit comments

Comments
 (0)