Skip to content

Commit 92c7be0

Browse files
committed
✨ Add icons component for Astro, Svelte and React
1 parent 74aaf8a commit 92c7be0

File tree

17 files changed

+88
-85
lines changed

17 files changed

+88
-85
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
},
2929
"files": [
3030
"components",
31-
"public",
31+
"icons",
3232
"scss",
3333
"astro.d.ts",
3434
"astro.js",

scripts/build.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import fs from 'fs'
22

33
const folders = {
4-
'public': 'dist/public',
4+
'src/icons': 'dist/icons',
55
'src/components': 'dist/components',
66
'src/scss': 'dist/scss'
77
}

src/astro.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import AccordionComponent from './components/Accordion/Accordion.astro'
22
import ButtonComponent from './components/Button/Button.astro'
33
import CardComponent from './components/Card/Card.astro'
4+
import IconComponent from './components/Icon/Icon.astro'
45

56
export const Accordion = AccordionComponent
67
export const Button = ButtonComponent
78
export const Card = CardComponent
9+
export const Icon = IconComponent

src/components/Accordion/Accordion.astro

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
import type { AccordionProps } from './accordion'
3+
import Icon from '../Icon/Icon.astro'
34
45
interface Props extends AccordionProps {}
56
@@ -9,16 +10,11 @@ const {
910
---
1011

1112
<ul data-id="accordion">
12-
{items.map(item => (
13+
{items.map((item: AccordionProps['items'][0]) => (
1314
<li>
1415
<div class="accordion-title">
1516
{item.title}
16-
<img
17-
src="/icons/arrow-down.svg"
18-
alt="GitHub"
19-
width={15}
20-
height={15}
21-
/>
17+
<Icon type="arrow-down" size={15} />
2218
</div>
2319
<div class="accordion-wrapper">
2420
<div class="accordion-content">

src/components/Accordion/Accordion.svelte

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script lang="ts">
22
import type { AccordionProps } from './accordion'
3+
import ArrowDown from '../../icons/arrow-down.svg?raw'
34
45
export let items: AccordionProps['items']
56
@@ -22,12 +23,7 @@
2223
on:click={() => toggle(index)}
2324
>
2425
{item.title}
25-
<img
26-
src="/icons/arrow-down.svg"
27-
alt="GitHub"
28-
width={15}
29-
height={15}
30-
/>
26+
{@html ArrowDown}
3127
</div>
3228
<div class="accordion-wrapper">
3329
<div class="accordion-content">

src/components/Accordion/Accordion.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { useState } from 'react'
22
import type { AccordionProps } from './accordion'
3+
import ArrowDown from '../../icons/arrow-down.svg?raw'
34
import './accordion.scss'
45

56
export const Accordion = ({ items }: AccordionProps) => {
@@ -19,15 +20,8 @@ export const Accordion = ({ items }: AccordionProps) => {
1920
<div
2021
className={state[index] ? 'accordion-title open' : 'accordion-title'}
2122
onClick={() => toggle(index)}
22-
>
23-
{item.title}
24-
<img
25-
src="/icons/arrow-down.svg"
26-
alt="GitHub"
27-
width={15}
28-
height={15}
29-
/>
30-
</div>
23+
dangerouslySetInnerHTML={{ __html: `${item.title} ${ArrowDown}` }}
24+
/>
3125
<div className="accordion-wrapper">
3226
<div className="accordion-content">
3327
<div dangerouslySetInnerHTML={{ __html: item.content }} />

src/components/Accordion/accordion.scss

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,16 @@ ul {
2525
align-items: center;
2626
cursor: pointer;
2727

28-
img {
28+
svg {
2929
@include Transition(transform);
30-
filter: brightness(.7);
30+
color: #BBB;
31+
width: 15px;
32+
height: 15px;
33+
pointer-events: none;
3134
}
3235

3336
&.open {
34-
img {
37+
svg {
3538
transform: rotate(180deg);
3639
}
3740

src/components/Icon/Icon.astro

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
---
2+
import type { IconProps } from './icon'
3+
4+
interface Props extends IconProps {}
5+
26
const {
37
type,
48
size = 24,
59
color
610
} = Astro.props
711
8-
const { default: innerHTML } = await import(`../../icons/${type}.js`);
9-
12+
const { default: markup } = await import(`../../icons/${type}.svg?raw`)
13+
const icon = markup
14+
.replace('width="24"', `width=${size}`)
15+
.replace('height="24"', color
16+
? `height=${size} color=${color}`
17+
: `height=${size}`)
1018
---
1119

12-
<svg
13-
width={size}
14-
height={size}
15-
viewBox="0 0 24 24"
16-
color={color}
17-
set:html={innerHTML}
18-
/>
20+
<Fragment set:html={icon} />

src/components/Icon/Icon.svelte

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
<script>
2-
export let type
3-
export let size = 24
4-
export let color
2+
import type { IconProps } from './icon'
53
6-
const icon = () => import(`../../icons/${type}.js`)
7-
</script>
4+
import Github from '../../icons/github.svg?raw'
5+
import ArrowDown from '../../icons/arrow-down.svg?raw'
6+
7+
export let type: IconProps['type']
8+
export let size: IconProps['size'] = 24
9+
export let color: IconProps['color']
810
9-
{#await icon() then module}
10-
<svg
11-
width={size}
12-
height={size}
13-
viewBox="0 0 24 24"
14-
color={color}
15-
>{@html module.default}</svg>
16-
{/await}
11+
const iconMap = {
12+
'github': Github,
13+
'arrow-down': ArrowDown
14+
}
15+
16+
const icon = iconMap[type]
17+
.replace('width="24"', `width=${size}`)
18+
.replace('height="24"', color
19+
? `height=${size} color=${color}`
20+
: `height=${size}`)
21+
</script>
1722

23+
{@html icon}

src/components/Icon/Icon.tsx

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,24 @@
1-
import React, { useState, useEffect } from 'react'
1+
import React from 'react'
2+
import type { IconProps } from './icon'
23

3-
import github from '../../icons/github'
4+
import Github from '../../icons/github.svg?raw'
5+
import ArrowDown from '../../icons/arrow-down.svg?raw'
6+
7+
const iconMap = {
8+
'github': Github,
9+
'arrow-down': ArrowDown
10+
}
411

512
export const Icon = ({
613
type,
714
size = 24,
815
color
9-
}) => {
10-
const [icon, setIcon] = useState('')
11-
12-
useEffect(() => {
13-
(async () => {
14-
const icon = (await import(`../../icons/${type}.js`)).default;
16+
}: IconProps) => {
17+
const icon = iconMap[type]
18+
.replace('width="24"', `width=${size}`)
19+
.replace('height="24"', color
20+
? `height=${size} color=${color}`
21+
: `height=${size}`)
1522

16-
setIcon(icon)
17-
})()
18-
}, [])
19-
20-
return (
21-
<svg
22-
width={size}
23-
height={size}
24-
viewBox="0 0 24 24"
25-
color={color}
26-
dangerouslySetInnerHTML={{ __html: github }}
27-
/>
28-
)
23+
return <div dangerouslySetInnerHTML={{ __html: icon }} />
2924
}
30-

src/components/Icon/icon.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export type IconProps = {
2+
type: string
3+
size?: number
4+
color?: string
5+
}

src/env.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/// <reference types="astro/client" />
Lines changed: 1 addition & 1 deletion
Loading
Lines changed: 2 additions & 2 deletions
Loading

src/pages/button.astro

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import Layout from '@static/Layout.astro'
33
import ComponentWrapper from '@static/ComponentWrapper.astro'
44
5+
import Icon from '@components/Icon/Icon.astro'
56
import AstroButton from '@components/Button/Button.astro'
67
import SvelteButton from '@components/Button/Button.svelte'
78
import { Button as ReactButton } from '@components/Button/Button.tsx'
@@ -43,14 +44,9 @@ import { Button as ReactButton } from '@components/Button/Button.tsx'
4344
<AstroButton disabled>Disabled</AstroButton>
4445
</ComponentWrapper>
4546

46-
<ComponentWrapper title="Wiht Icon">
47+
<ComponentWrapper title="With Icon">
4748
<AstroButton theme="secondary">
48-
<img
49-
src="/icons/github.svg"
50-
alt="GitHub"
51-
width={20}
52-
height={20}
53-
/>
49+
<Icon type="github" size={20} />
5450
With Icon
5551
</AstroButton>
5652
</ComponentWrapper>

src/pages/index.astro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import CardWrapper from '@static/CardWrapper.astro'
44
55
import Button from '@components/Button/Button.astro'
66
import Accordion from '@components/Accordion/Accordion.astro'
7+
import Icon from '@components/Icon/Icon.astro'
78
---
89

910
<Layout>
@@ -22,7 +23,7 @@ import Accordion from '@components/Accordion/Accordion.astro'
2223
href="https://github.com/Frontendland/webcoreui" target="_blank"
2324
theme="secondary"
2425
>
25-
<img src="/icons/github.svg" alt="GitHub" width={20} height={20} />
26+
<Icon type="github" size={20} />
2627
GitHub
2728
</Button>
2829
</div>

svelte.config.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,21 @@ import { vitePreprocess } from '@astrojs/svelte'
33
export default {
44
preprocess: vitePreprocess(),
55
onwarn: (warning, handler) => {
6-
// Suppress false positive a11y warnings in terminal
6+
// Suppress false positive warnings in terminal
77
// Edit .vscode/settings.json to also suppress warnings in VSCode
88
const ignoreWarnings = [
99
'a11y-click-events-have-key-events',
10-
'a11y-no-static-element-interactions'
10+
'a11y-no-static-element-interactions',
11+
'.accordion-title'
1112
]
1213

13-
if (ignoreWarnings.includes(warning.code)) {
14+
const warningText = [
15+
warning.code,
16+
warning.message,
17+
warning.filename
18+
].join(' ')
19+
20+
if (new RegExp(ignoreWarnings.join('|'), 'gi').test(warningText)) {
1421
return
1522
}
1623

0 commit comments

Comments
 (0)