feat: add evidence-led project media layouts
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { PublicProject } from '@/content/types';
|
||||
import ProjectMedia from './ProjectMedia.vue';
|
||||
import ProjectMediaGallery from './ProjectMediaGallery.vue';
|
||||
|
||||
withDefaults(defineProps<{ project: Readonly<PublicProject>; allowAutomaticVideo?: boolean }>(), {
|
||||
allowAutomaticVideo: false,
|
||||
@@ -8,13 +8,17 @@ withDefaults(defineProps<{ project: Readonly<PublicProject>; allowAutomaticVideo
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<article class="project-card" :data-project-id="project.id" :data-maturity="project.maturity">
|
||||
<article
|
||||
class="project-card"
|
||||
:data-project-id="project.id"
|
||||
:data-maturity="project.maturity"
|
||||
:data-media-layout="project.mediaLayout ?? 'none'"
|
||||
>
|
||||
<h3>{{ project.title }}</h3>
|
||||
<p>{{ project.summary }}</p>
|
||||
<ProjectMedia
|
||||
v-for="media in project.media ?? []"
|
||||
:key="`${media.kind}-${media.assetId}`"
|
||||
:presentation="media"
|
||||
<ProjectMediaGallery
|
||||
:media="project.media ?? []"
|
||||
:layout="project.mediaLayout ?? 'single'"
|
||||
:allow-automatic-video="allowAutomaticVideo"
|
||||
/>
|
||||
<p>{{ project.contribution }}</p>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type { PublicProject } from '@/content/types';
|
||||
import ProjectMedia from './ProjectMedia.vue';
|
||||
import ProjectMediaGallery from './ProjectMediaGallery.vue';
|
||||
|
||||
withDefaults(defineProps<{
|
||||
project: Readonly<PublicProject>;
|
||||
@@ -13,15 +13,19 @@ withDefaults(defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<article class="project-case-study" :data-project-id="project.id" :data-project-priority="priority">
|
||||
<article
|
||||
class="project-case-study"
|
||||
:data-project-id="project.id"
|
||||
:data-project-priority="priority"
|
||||
:data-media-layout="project.mediaLayout ?? 'none'"
|
||||
>
|
||||
<header class="project-case-study__header">
|
||||
<h3>{{ project.title }}</h3>
|
||||
<p>{{ project.summary }}</p>
|
||||
</header>
|
||||
<ProjectMedia
|
||||
v-for="media in project.media ?? []"
|
||||
:key="`${media.kind}-${media.assetId}`"
|
||||
:presentation="media"
|
||||
<ProjectMediaGallery
|
||||
:media="project.media ?? []"
|
||||
:layout="project.mediaLayout ?? 'single'"
|
||||
:allow-automatic-video="allowAutomaticVideo"
|
||||
/>
|
||||
<dl class="project-evidence">
|
||||
|
||||
21
src/components/ProjectMediaGallery.vue
Normal file
21
src/components/ProjectMediaGallery.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import ProjectMedia from './ProjectMedia.vue';
|
||||
import type { MediaPresentation, ProjectMediaLayout } from '@/content/types';
|
||||
|
||||
withDefaults(defineProps<{
|
||||
media: readonly MediaPresentation[];
|
||||
layout?: ProjectMediaLayout;
|
||||
allowAutomaticVideo?: boolean;
|
||||
}>(), { layout: 'single', allowAutomaticVideo: false });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="media.length > 0" class="project-media-gallery" :data-media-layout="layout">
|
||||
<ProjectMedia
|
||||
v-for="presentation in media"
|
||||
:key="`${presentation.kind}-${presentation.assetId}`"
|
||||
:presentation="presentation"
|
||||
:allow-automatic-video="allowAutomaticVideo"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -485,6 +485,17 @@
|
||||
background: var(--surface-soft);
|
||||
}
|
||||
|
||||
@media (min-width: 100rem) {
|
||||
.project-case-study[data-project-id="private-medication-tracker"][data-media-layout]:not([data-media-layout="none"]) {
|
||||
inline-size: min(72rem, 88%);
|
||||
}
|
||||
|
||||
.project-case-study[data-project-id="footy-tracker"][data-media-layout]:not([data-media-layout="none"]) {
|
||||
inline-size: min(68rem, 82%);
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.project-case-study__header {
|
||||
display: grid;
|
||||
gap: var(--space-1);
|
||||
@@ -661,6 +672,56 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.project-media-gallery {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: var(--space-3);
|
||||
min-inline-size: 0;
|
||||
margin-block: var(--space-3);
|
||||
isolation: isolate;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.project-media-gallery .project-media {
|
||||
position: relative;
|
||||
min-inline-size: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.project-media-gallery .project-media:focus-within {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.project-media-gallery[data-media-layout="single"] {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
@media (min-width: 48rem) {
|
||||
.project-media-gallery[data-media-layout="portrait-strip"] {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 0;
|
||||
align-items: start;
|
||||
padding-inline: 0.5rem;
|
||||
}
|
||||
|
||||
.project-media-gallery[data-media-layout="portrait-strip"] > .project-media + .project-media {
|
||||
margin-inline-start: -0.75rem;
|
||||
}
|
||||
|
||||
.project-media-gallery[data-media-layout="portrait-strip"] > .project-media:nth-child(even) {
|
||||
margin-block-start: 1rem;
|
||||
}
|
||||
|
||||
.project-media-gallery[data-media-layout="portrait-strip"] > .project-media:nth-child(3n) {
|
||||
margin-block-start: 0.5rem;
|
||||
}
|
||||
|
||||
.project-media-gallery[data-media-layout="chart-pair"] {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
align-items: start;
|
||||
}
|
||||
}
|
||||
|
||||
.project-media img,
|
||||
.project-media video {
|
||||
inline-size: 100%;
|
||||
@@ -822,9 +883,23 @@
|
||||
}
|
||||
|
||||
.project-card[data-maturity] {
|
||||
inline-size: 100%;
|
||||
margin-inline: 0;
|
||||
}
|
||||
|
||||
.project-media-gallery,
|
||||
.project-media-gallery[data-media-layout="portrait-strip"],
|
||||
.project-media-gallery[data-media-layout="chart-pair"] {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
padding-inline: 0;
|
||||
}
|
||||
|
||||
.project-media-gallery[data-media-layout="portrait-strip"] > .project-media,
|
||||
.project-media-gallery[data-media-layout="portrait-strip"] > .project-media + .project-media {
|
||||
margin-block-start: 0;
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
.contact-destination__copy {
|
||||
font-size: var(--step-1);
|
||||
}
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
|
||||
.portfolio-section[data-layout="project-stage"] {
|
||||
inline-size: 92%;
|
||||
min-inline-size: 0;
|
||||
margin-inline: 4%;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
@@ -143,6 +144,10 @@
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.portfolio-section[data-layout="project-stage"] .project-stage__projects {
|
||||
min-inline-size: 0;
|
||||
}
|
||||
|
||||
.portfolio-section[data-layout="project-stage"] > h2,
|
||||
.portfolio-section[data-layout="project-stage"] > .section-eyebrow {
|
||||
inline-size: fit-content;
|
||||
|
||||
@@ -101,6 +101,25 @@
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.project-media-gallery,
|
||||
.project-media-gallery[data-media-layout] {
|
||||
display: block;
|
||||
overflow: visible;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.project-media-gallery .project-media {
|
||||
break-inside: avoid;
|
||||
margin: 0 0 0.9rem;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.project-media-gallery img,
|
||||
.project-media-gallery video {
|
||||
max-inline-size: 100%;
|
||||
block-size: auto;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: underline;
|
||||
|
||||
Reference in New Issue
Block a user