Skip to content

Commit 83e8fbd

Browse files
committed
Fix SVGs on Backstage component
1 parent 7df9ae4 commit 83e8fbd

8 files changed

Lines changed: 59 additions & 39 deletions

File tree

‎src/components/Home/Backstage/index.astro‎

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
* Backstage IDP Implementation section of the homepage
44
*/
55
import { Image } from 'astro:assets'
6+
import Icon from '@components/Icon/index.astro'
67
import backstageBackground from '@assets/images/backstage-background.jpg'
78
8-
type IconKey = keyof typeof svgPath
99
export interface Props {
1010
pretitle: string
1111
description: string
@@ -16,19 +16,12 @@ export interface Props {
1616
features: {
1717
title: string
1818
description: string
19-
icon: IconKey
19+
icon: string
2020
}[]
2121
}
2222
2323
const { pretitle, description, benefits, features } = Astro.props as Props
2424
25-
const svgPath = {
26-
'left-justified': 'M4 6h16M4 12h16M4 18h7',
27-
'clipboard': 'M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2',
28-
'lightning-bolt': 'M13 10V3L4 14h7v7l9-11h-7z',
29-
'graph': 'M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z',
30-
} as const
31-
3225
const visibleBenefits = benefits.slice(0, 3)
3326
const visibleFeatures = features.slice(0, 4)
3427
---
@@ -69,20 +62,7 @@ const visibleFeatures = features.slice(0, 4)
6962
<div class="bg-page-offset p-6 rounded-xl border border-trim">
7063
<div class="flex items-center gap-3 mb-4">
7164
<div class="w-10 h-10 bg-primary/10 rounded-lg flex items-center justify-center">
72-
<svg
73-
class="w-5 h-5 text-primary"
74-
fill="none"
75-
stroke="currentColor"
76-
viewBox="0 0 24 24"
77-
aria-hidden="true"
78-
>
79-
<path
80-
stroke-linecap="round"
81-
stroke-linejoin="round"
82-
stroke-width="2"
83-
d={svgPath[feature.icon]}
84-
></path>
85-
</svg>
65+
<Icon icon={feature.icon} size={5} color="primary" isListMarker={false} />
8666
</div>
8767
<span class="font-bold text-content-active">{feature.title}</span>
8868
</div>
@@ -99,7 +79,7 @@ const visibleFeatures = features.slice(0, 4)
9979
class="relative inline-flex items-center gap-2 bg-primary hover:bg-primary-offset text-page-base font-bold px-6 py-3 rounded-full transition-colors whitespace-nowrap focus-visible:outline-none after:pointer-events-none after:absolute after:-inset-1 after:rounded-none after:content-[''] focus-visible:after:border-2 focus-visible:after:border-spotlight"
10080
>
10181
Let's talk
102-
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"></path></svg>
82+
<Icon icon="exit-right-thin" size={4} classes="mb-1" />
10383
</a>
10484
</div>
10585
</div>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
export type Props = {
3+
color: string
4+
classes?: string
5+
size: number
6+
accessible: boolean
7+
focusable: boolean
8+
isListMarker?: boolean
9+
}
10+
11+
const { color, classes, size, accessible, focusable, isListMarker } = Astro.props
12+
---
13+
14+
<svg
15+
xmlns="http://www.w3.org/2000/svg"
16+
class:list={["shrink-0", `w-${size} h-${size}`, `text-${color}`, classes, isListMarker ? "mt-0.5" : ""]}
17+
fill="none"
18+
stroke="currentColor"
19+
viewBox="0 0 24 24"
20+
aria-hidden={accessible ? "false" : "true"}
21+
focusable={focusable ? "true" : "false"}
22+
>
23+
{accessible && <title>exit right thin icon</title>}
24+
<path
25+
stroke-linecap="round"
26+
stroke-linejoin="round"
27+
stroke-width="2"
28+
d="M17 8l4 4m0 0l-4 4m4-4H3"
29+
/>
30+
</svg>

‎src/components/Icon/index.astro‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ export type Props = {
2828
}
2929
3030
const { icon, color = 'inherit', inverseColor, size = 14, classes, accessible = false, focusable = false, isListMarker = true }: Props = Astro.props
31+
const resolvedIcon = typeof icon === 'string' ? icon.trim() : ''
3132
32-
const IconComponent = getIconComponent(icon) as unknown as (_props: {
33+
const IconComponent = resolvedIcon
34+
? getIconComponent(resolvedIcon)
35+
: null as unknown as (_props: {
3336
color?: string
3437
inverseColor?: string
3538
size?: number
@@ -50,4 +53,4 @@ const markerProps = {
5053
}
5154
---
5255

53-
<IconComponent {...markerProps} />
56+
{IconComponent && <IconComponent {...markerProps} />}

‎src/components/Icon/server/__tests__/index.spec.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ describe('getIconComponent', () => {
1919

2020
it('throws a descriptive error when icon is missing', () => {
2121
expect(() => getIconComponent(undefined, {})).toThrowError(
22-
'PlainIconList: missing icon value for list item. Expected an icon name that maps to src/components/List/markers/<icon>.astro'
22+
'Icon: missing icon value. Expected an icon name that maps to src/components/Icon/icons/<icon>.astro'
2323
)
2424
})
2525

@@ -30,7 +30,7 @@ describe('getIconComponent', () => {
3030
}
3131

3232
expect(() => getIconComponent('download', markerComponents)).toThrowError(
33-
'PlainIconList: marker file "download.astro" was not found in src/components/List/icons/. Requested icon path: "../icons/download.astro". Available markers: avatar.astro, company.astro'
33+
'Icon: icon file "download.astro" was not found in src/components/Icon/icons/. Requested icon path: "../icons/download.astro". Available icons: avatar.astro, company.astro'
3434
)
3535
})
3636
})

‎src/components/Icon/server/index.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ const formatAvailableIcons = (markerComponents: IconComponentMap): string => {
1818
}
1919

2020
/**
21-
* Resolve marker component by icon name.
22-
* Throws a descriptive error when icon is missing or marker file is not found.
21+
* Resolve icon component by icon name.
22+
* Throws a descriptive error when icon is missing or icon file is not found.
2323
*/
2424
export const getIconComponent = (
2525
icon?: string,
2626
markerComponents: IconComponentMap = defaultIconComponents
2727
): AstroComponentFactory => {
2828
if (!icon) {
2929
throw new Error(
30-
'PlainIconList: missing icon value for list item. Expected an icon name that maps to src/components/List/markers/<icon>.astro'
30+
'Icon: missing icon value. Expected an icon name that maps to src/components/Icon/icons/<icon>.astro'
3131
)
3232
}
3333

@@ -39,8 +39,8 @@ export const getIconComponent = (
3939
const availableIcons = formatAvailableIcons(markerComponents)
4040

4141
throw new Error(
42-
`PlainIconList: marker file "${iconFileName}" was not found in src/components/List/icons/. ` +
43-
`Requested icon path: "${iconPath}". Available markers: ${availableIcons || '(none)'}`
42+
`Icon: icon file "${iconFileName}" was not found in src/components/Icon/icons/. ` +
43+
`Requested icon path: "${iconPath}". Available icons: ${availableIcons || '(none)'}`
4444
)
4545
}
4646

‎src/components/List/index.astro‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ const itemsWithIconAndColor = items as Array<{
5959
inverseColor?: string
6060
bgColor?: string
6161
}>
62+
const plainIconItems = items.filter((item): item is Props['items'][number] & { icon: string } => {
63+
return typeof item.icon === 'string' && item.icon.trim().length > 0
64+
})
6265
---
6366

6467
{variant === 'accent-border-left-list' && <AccentBorderLeftList items={items} {...classesProps} />}
@@ -69,7 +72,7 @@ const itemsWithIconAndColor = items as Array<{
6972
{variant === 'colored-marker-list' && <ColoredMarkerList items={itemsWithColor} {...classesProps} {...sizeProps} />}
7073
{variant === 'download-page-list' && <DownloadPageList items={itemsWithIconAndColor} {...classesProps} {...sizeProps} />}
7174
{variant === 'numbered-with-background-list' && <NumberedWithBackgroundList items={items} {...classesProps} />}
72-
{variant === 'plain-icon-list' && <PlainIconList items={itemsWithIconAndColor} {...classesProps} {...sizeProps} />}
75+
{variant === 'plain-icon-list' && <PlainIconList items={plainIconItems} {...classesProps} {...sizeProps} />}
7376
{variant === 'side-by-side-list' && <SideBySideList items={items} {...classesProps} />}
7477
{variant === 'timeline-list' && <TimelineList items={items} {...classesProps} />}
7578
{variant === 'two-column-check-icons-list' && <TwoColumnCheckIconsList items={items} {...classesProps} {...sizeProps} />}

‎src/components/List/layouts/PlainIconList.astro‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export type Props = {
55
items: {
66
text: string
77
icon: string
8-
color: string
8+
color?: string
99
}[]
1010
classes?: {
1111
ul?: string
@@ -25,11 +25,15 @@ const markerClasses = props.classes?.svg
2525

2626
<ul class:list={ulClass}>
2727
{
28-
props.items.map(({ text, icon, color }: PlainIconListItem) => (
28+
props.items.map(({ text, icon, color }: PlainIconListItem) => {
29+
const resolvedColor = color?.trim() ? color : 'currentColor'
30+
31+
return (
2932
<li class:list={liClass}>
30-
<Icon icon={icon} color={color} size={props.size ?? 5} {...(markerClasses ? { classes: markerClasses } : {})} />
33+
<Icon icon={icon} color={resolvedColor} size={props.size ?? 5} {...(markerClasses ? { classes: markerClasses } : {})} />
3134
<span>{text}</span>
3235
</li>
33-
))
36+
)
37+
})
3438
}
3539
</ul>

‎src/pages/index.astro‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ const sectionClasses = 'container mx-auto px-4 sm:px-6 lg:px-8 py-4 md:py-8 lg:p
8989
{
9090
title: "CI/CD & Cloud Migration",
9191
description: "Lift-and-shift or re-architect—either way, your pipelines will be rock solid.",
92-
icon: "lightning-bolt",
92+
icon: "lightning",
9393
},
9494
{
9595
title: "Observability Plug-ins",

0 commit comments

Comments
 (0)