Remove astro image (#146)
This commit is contained in:
parent
41a516c283
commit
94f8196a4c
14 changed files with 53 additions and 84 deletions
24
src/components/photo.astro
Normal file
24
src/components/photo.astro
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
import { Image } from '@astrojs/image/components';
|
||||||
|
|
||||||
|
import type { Photo } from '@/types/common';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
src: Photo;
|
||||||
|
alt: string;
|
||||||
|
class?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { src, alt } = Astro.props;
|
||||||
|
const className = Astro.props.class ?? '';
|
||||||
|
|
||||||
|
const isRemoteImage = typeof src === 'string';
|
||||||
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
isRemoteImage ? (
|
||||||
|
<img class={className} src={src} alt={alt} />
|
||||||
|
) : (
|
||||||
|
<Image class={className} format="webp" fit={'cover'} src={src} alt={alt} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,7 @@ const favoritesData: FavoritesSection = {
|
||||||
url: 'https://www.goodreads.com/book/show/4099.The_Pragmatic_Programmer',
|
url: 'https://www.goodreads.com/book/show/4099.The_Pragmatic_Programmer',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cover: import('@/assets/favorites/books/book-2.jpeg'),
|
cover: 'https://m.media-amazon.com/images/I/61aFldsgAmL._SY344_BO1,204,203,200_QL70_ML2_.jpg',
|
||||||
title: 'Domain-Driven Design: Tackling Complexity in the Heart of Software',
|
title: 'Domain-Driven Design: Tackling Complexity in the Heart of Software',
|
||||||
author: 'Eric Evans',
|
author: 'Eric Evans',
|
||||||
url: 'https://www.goodreads.com/book/show/179133.Domain_Driven_Design',
|
url: 'https://www.goodreads.com/book/show/179133.Domain_Driven_Design',
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
---
|
---
|
||||||
import { Image } from '@astrojs/image/components';
|
import Photo from '@/components/photo.astro';
|
||||||
|
|
||||||
import Typography from '@/components/typography.astro';
|
import Typography from '@/components/typography.astro';
|
||||||
import type { Book } from '@/types/favorites-section';
|
import type { Book } from '@/types/favorites-section';
|
||||||
|
|
||||||
|
|
@ -14,15 +13,7 @@ const {
|
||||||
---
|
---
|
||||||
|
|
||||||
<a href={url} class="flex w-full max-w-[200px] flex-col gap-3 transition duration-300 hover:translate-y-2">
|
<a href={url} class="flex w-full max-w-[200px] flex-col gap-3 transition duration-300 hover:translate-y-2">
|
||||||
<Image
|
<Photo src={cover} alt={title} class="aspect-[3/4] rounded-lg object-cover shadow-md'" />
|
||||||
class="rounded-lg shadow-md aspect-[3/4] object-cover"
|
|
||||||
format="webp"
|
|
||||||
fit={'cover'}
|
|
||||||
aspectRatio={3 / 4}
|
|
||||||
quality={100}
|
|
||||||
src={cover}
|
|
||||||
alt={title}
|
|
||||||
/>
|
|
||||||
<div class="w-full gap-1">
|
<div class="w-full gap-1">
|
||||||
<Typography variant="tile-title">
|
<Typography variant="tile-title">
|
||||||
{title}
|
{title}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
---
|
---
|
||||||
import { Image } from '@astrojs/image/components';
|
import Photo from '@/components/photo.astro';
|
||||||
|
|
||||||
import Typography from '@/components/typography.astro';
|
import Typography from '@/components/typography.astro';
|
||||||
import type { Media } from '@/types/favorites-section';
|
import type { Media } from '@/types/favorites-section';
|
||||||
|
|
||||||
|
|
@ -14,15 +13,7 @@ const {
|
||||||
---
|
---
|
||||||
|
|
||||||
<a href={url} class="flex w-full max-w-[120px] flex-col gap-3 transition duration-300 hover:translate-y-2">
|
<a href={url} class="flex w-full max-w-[120px] flex-col gap-3 transition duration-300 hover:translate-y-2">
|
||||||
<Image
|
<Photo class="rounded-lg shadow-md aspect-square object-cover" src={image} alt={title} />
|
||||||
class="rounded-lg shadow-md aspect-square object-cover"
|
|
||||||
fit="cover"
|
|
||||||
format="webp"
|
|
||||||
aspectRatio={1}
|
|
||||||
quality={100}
|
|
||||||
src={image}
|
|
||||||
alt={title}
|
|
||||||
/>
|
|
||||||
<div class="gap-1">
|
<div class="gap-1">
|
||||||
<Typography variant="tile-title">
|
<Typography variant="tile-title">
|
||||||
{title}
|
{title}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
---
|
---
|
||||||
import { Image } from '@astrojs/image/components';
|
import Photo from '@/components/photo.astro';
|
||||||
|
|
||||||
import Typography from '@/components/typography.astro';
|
import Typography from '@/components/typography.astro';
|
||||||
import type { Person } from '@/types/favorites-section';
|
import type { Person } from '@/types/favorites-section';
|
||||||
|
|
||||||
|
|
@ -14,15 +13,7 @@ const {
|
||||||
---
|
---
|
||||||
|
|
||||||
<a href={url} class="flex w-full max-w-[120px] flex-col gap-3 transition duration-300 hover:translate-y-2">
|
<a href={url} class="flex w-full max-w-[120px] flex-col gap-3 transition duration-300 hover:translate-y-2">
|
||||||
<Image
|
<Photo class="rounded-lg shadow-md transition duration-300 aspect-square object-cover" src={image} alt={name} />
|
||||||
class="rounded-lg shadow-md transition duration-300 aspect-square object-cover"
|
|
||||||
format="webp"
|
|
||||||
fit="cover"
|
|
||||||
quality={100}
|
|
||||||
aspectRatio={1}
|
|
||||||
src={image}
|
|
||||||
alt={name}
|
|
||||||
/>
|
|
||||||
<Typography variant="tile-title">
|
<Typography variant="tile-title">
|
||||||
{name}
|
{name}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
---
|
---
|
||||||
import { Image } from '@astrojs/image/components';
|
import Photo from '@/components/photo.astro';
|
||||||
|
|
||||||
import Typography from '@/components/typography.astro';
|
import Typography from '@/components/typography.astro';
|
||||||
import type { Video } from '@/types/favorites-section';
|
import type { Video } from '@/types/favorites-section';
|
||||||
|
|
||||||
|
|
@ -17,14 +16,7 @@ const thumbnail = `https://img.youtube.com/vi/${id}/0.jpg`;
|
||||||
---
|
---
|
||||||
|
|
||||||
<a href={url} class="flex w-full max-w-[240px] flex-col gap-3 transition duration-300 hover:translate-y-2">
|
<a href={url} class="flex w-full max-w-[240px] flex-col gap-3 transition duration-300 hover:translate-y-2">
|
||||||
<Image
|
<Photo class="rounded-lg shadow-md aspect-video object-cover" src={thumbnail} alt={title} />
|
||||||
class="rounded-lg shadow-md aspect-video object-cover"
|
|
||||||
format="webp"
|
|
||||||
width={240}
|
|
||||||
height={180}
|
|
||||||
src={thumbnail}
|
|
||||||
alt={title}
|
|
||||||
/>
|
|
||||||
<Typography variant="tile-title">
|
<Typography variant="tile-title">
|
||||||
{title}
|
{title}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
---
|
---
|
||||||
import { Image } from '@astrojs/image/components';
|
|
||||||
|
|
||||||
import Button from '@/components/button.astro';
|
import Button from '@/components/button.astro';
|
||||||
import IconButton from '@/components/icon-button.astro';
|
import IconButton from '@/components/icon-button.astro';
|
||||||
|
import Photo from '@/components/photo.astro';
|
||||||
import SectionCard from '@/components/section-card.astro';
|
import SectionCard from '@/components/section-card.astro';
|
||||||
import TagsList from '@/components/tags-list.astro';
|
import TagsList from '@/components/tags-list.astro';
|
||||||
import Typography from '@/components/typography.astro';
|
import Typography from '@/components/typography.astro';
|
||||||
|
|
@ -28,13 +27,7 @@ const section: SectionKey = 'main';
|
||||||
<SectionCard section={section}>
|
<SectionCard section={section}>
|
||||||
<div class="flex flex-col items-start gap-6 sm:flex-row">
|
<div class="flex flex-col items-start gap-6 sm:flex-row">
|
||||||
<div class="flex items-center gap-4 sm:flex-col">
|
<div class="flex items-center gap-4 sm:flex-col">
|
||||||
<Image
|
<Photo src={image} alt={fullName} class="w-24 h-24 sm:w-36 sm:h-36 md:w-52 md:h-52 rounded-lg max-w-none" />
|
||||||
src={image}
|
|
||||||
alt={fullName}
|
|
||||||
class="w-24 h-24 sm:w-36 sm:h-36 md:w-52 md:h-52 rounded-lg max-w-none"
|
|
||||||
format="webp"
|
|
||||||
aspectRatio={1}
|
|
||||||
/>
|
|
||||||
<Button href={url} download={downloadedFileName}>{label}</Button>
|
<Button href={url} download={downloadedFileName}>{label}</Button>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex w-full flex-col gap-5">
|
<div class="flex w-full flex-col gap-5">
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
---
|
---
|
||||||
import { Image } from '@astrojs/image/components';
|
|
||||||
|
|
||||||
import IconButton from '@/components/icon-button.astro';
|
import IconButton from '@/components/icon-button.astro';
|
||||||
import LabelledValue from '@/components/labelled-value.astro';
|
import LabelledValue from '@/components/labelled-value.astro';
|
||||||
|
import Photo from '@/components/photo.astro';
|
||||||
import TagsList from '@/components/tags-list.astro';
|
import TagsList from '@/components/tags-list.astro';
|
||||||
import Timestamp from '@/components/timestamp.astro';
|
import Timestamp from '@/components/timestamp.astro';
|
||||||
import Typography from '@/components/typography.astro';
|
import Typography from '@/components/typography.astro';
|
||||||
|
|
@ -16,24 +15,13 @@ export interface Props {
|
||||||
const { project, i18n } = Astro.props;
|
const { project, i18n } = Astro.props;
|
||||||
const { description, details, endDate, name, socials, startDate, tags, image } = project;
|
const { description, details, endDate, name, socials, startDate, tags, image } = project;
|
||||||
|
|
||||||
// Alt has to destructured separately, because otherwise eslint complains about
|
const alt = `Thumbnail for ${name} project`;
|
||||||
// the missing alt attribute on the Image component.
|
|
||||||
const { alt, ...sharedImageProps } = {
|
|
||||||
src: image,
|
|
||||||
aspectRatio: 1,
|
|
||||||
alt: `Thumbnail for ${name} project`,
|
|
||||||
format: 'webp',
|
|
||||||
} as const;
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="flex flex-col gap-6">
|
<div class="flex flex-col gap-6">
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex gap-6">
|
<div class="flex gap-6">
|
||||||
<Image
|
<Photo class="rounded-lg object-cover max-w-[120px] overflow-hidden sm:block hidden" src={image} alt={alt} />
|
||||||
class="rounded-lg object-cover max-w-[120px] overflow-hidden sm:block hidden"
|
|
||||||
{...sharedImageProps}
|
|
||||||
alt={alt}
|
|
||||||
/>
|
|
||||||
<div class="flex w-full flex-col gap-4">
|
<div class="flex w-full flex-col gap-4">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -53,7 +41,7 @@ const { alt, ...sharedImageProps } = {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Image class="rounded-lg object-cover max-w-[120px] sm:hidden" {...sharedImageProps} alt={alt} />
|
<Photo class="rounded-lg object-cover max-w-[120px] sm:hidden" src={image} alt={alt} />
|
||||||
<div class="inline-grid w-full xl:grid-cols-[auto_auto]">
|
<div class="inline-grid w-full xl:grid-cols-[auto_auto]">
|
||||||
{
|
{
|
||||||
details.map(({ label: detailLabel, value: detailValue }) => (
|
details.map(({ label: detailLabel, value: detailValue }) => (
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
import { Image } from '@astrojs/image/components';
|
|
||||||
|
|
||||||
import IconButton from '@/components/icon-button.astro';
|
import IconButton from '@/components/icon-button.astro';
|
||||||
|
import Photo from '@/components/photo.astro';
|
||||||
import Typography from '@/components/typography.astro';
|
import Typography from '@/components/typography.astro';
|
||||||
import type { Testimonial } from '@/types/testimonials-section';
|
import type { Testimonial } from '@/types/testimonials-section';
|
||||||
|
|
||||||
|
|
@ -17,7 +16,7 @@ const {
|
||||||
<div class="flex w-full flex-col gap-4">
|
<div class="flex w-full flex-col gap-4">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<div class="flex flex-col gap-4 sm:flex-row">
|
<div class="flex flex-col gap-4 sm:flex-row">
|
||||||
<Image src={image} alt={author} format="webp" class="w-14 h-14 rounded-lg" />
|
<Photo src={image} alt={author} class="w-14 h-14 rounded-lg" />
|
||||||
<div>
|
<div>
|
||||||
<Typography variant="item-title">{author}</Typography>
|
<Typography variant="item-title">{author}</Typography>
|
||||||
<Typography variant="item-subtitle">{relation}</Typography>
|
<Typography variant="item-subtitle">{relation}</Typography>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import type { IconName } from './icon';
|
import type { IconName } from './icon';
|
||||||
|
|
||||||
export type LocalImage = Promise<{ default: ImageMetadata }>;
|
export type Photo = Promise<{ default: ImageMetadata }> | string;
|
||||||
|
|
||||||
export interface Detail {
|
export interface Detail {
|
||||||
label: string;
|
label: string;
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,28 @@
|
||||||
import type { LocalImage, SectionConfig } from './common';
|
import type { Photo, SectionConfig } from './common';
|
||||||
|
|
||||||
export interface Book {
|
export interface Book {
|
||||||
title: string;
|
title: string;
|
||||||
cover: LocalImage;
|
cover: Photo;
|
||||||
author: string;
|
author: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Person {
|
export interface Person {
|
||||||
name: string;
|
name: string;
|
||||||
image: LocalImage;
|
image: Photo;
|
||||||
url?: string;
|
url?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Video {
|
export interface Video {
|
||||||
title: string;
|
title: string;
|
||||||
thumbnail: LocalImage;
|
thumbnail: Photo;
|
||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Media {
|
export interface Media {
|
||||||
title: string;
|
title: string;
|
||||||
type: string;
|
type: string;
|
||||||
image: LocalImage;
|
image: Photo;
|
||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import type { Detail, LocalImage, SectionConfig, Social, Tag } from './common';
|
import type { Detail, Photo, SectionConfig, Social, Tag } from './common';
|
||||||
|
|
||||||
export interface MainSection {
|
export interface MainSection {
|
||||||
image: LocalImage;
|
image: Photo;
|
||||||
fullName: string;
|
fullName: string;
|
||||||
role: string;
|
role: string;
|
||||||
details: Detail[];
|
details: Detail[];
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import type { Detail, LocalImage, SectionConfig, Social, Tag } from './common';
|
import type { Detail, Photo, SectionConfig, Social, Tag } from './common';
|
||||||
|
|
||||||
export interface Project {
|
export interface Project {
|
||||||
name: string;
|
name: string;
|
||||||
image?: LocalImage;
|
image: Photo;
|
||||||
startDate: Date;
|
startDate: Date;
|
||||||
endDate: Date | null;
|
endDate: Date | null;
|
||||||
details: Detail[];
|
details: Detail[];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import type { LocalImage, SectionConfig, Social } from './common';
|
import type { Photo, SectionConfig, Social } from './common';
|
||||||
|
|
||||||
export interface Testimonial {
|
export interface Testimonial {
|
||||||
image: LocalImage;
|
image: Photo;
|
||||||
author: string;
|
author: string;
|
||||||
relation: string;
|
relation: string;
|
||||||
content: string;
|
content: string;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue