Skip to content

Commit

Permalink
media-object-refinement (#197)
Browse files Browse the repository at this point in the history
CdrChoreographer: updates to support more components
CdrLayout: always has container-type: inline-size; applied
CdrLayout: now accepts a containerName prop
CdrMediaObject: overlay works slightly differently, applying a media height and not relying on media's natural height
CdrMediaObject: applies media and content styles differently after use in other apps
CdrMediaObject: expanded examples
CdrMediaObject: changed some structure of sass mixins for easier reuse
CdrMediaObject: inner img, picture, video are applied display: block
CdrMediaObject" inner content has container-type: inline-size; applied for fluid content compatibility
interfaces: updates for accuracy
  • Loading branch information
sikhote authored Jan 13, 2025
1 parent 7a224b9 commit 5029e92
Show file tree
Hide file tree
Showing 11 changed files with 308 additions and 210 deletions.
84 changes: 62 additions & 22 deletions src/components/choreographer/CdrChoreographer.vue
Original file line number Diff line number Diff line change
@@ -1,50 +1,90 @@
<script setup lang="ts">
import { useCssModule, type PropType } from 'vue';
import { CdrAbstract, CdrKicker, CdrTitle, CdrImg, CdrRating, CdrLink, CdrCard } from '../../lib';
import { choreographerSchema } from '../../types/interfaces';
import { useCssModule, computed } from 'vue';
import {
CdrAbstract,
CdrKicker,
CdrTitle,
CdrBody,
CdrImg,
CdrRating,
CdrLink,
CdrCard,
CdrLayout,
CdrPicture,
CdrButton,
CdrContainer,
} from '../../lib';
import {
Choreographer,
ChoreographerComponents,
ChoreographerSchema,
} from '../../types/interfaces';
/** Choreographer is in an experimental stage and should be considered unstable */
defineOptions({
name: 'CdrChoreographer',
});
const componentMap = {
abstract: CdrAbstract,
kicker: CdrKicker,
title: CdrTitle,
image: CdrImg,
rating: CdrRating,
link: CdrLink,
card: CdrCard,
};
defineProps({
schema: { type: Array as PropType<choreographerSchema[]>, default: () => [] }
const props = withDefaults(defineProps<Choreographer>(), {
components: () => ({}),
});
const componentMap = computed(
() =>
({
abstract: CdrAbstract,
kicker: CdrKicker,
title: CdrTitle,
body: CdrBody,
image: CdrImg,
picture: CdrPicture,
rating: CdrRating,
link: CdrLink,
card: CdrCard,
layout: CdrLayout,
button: CdrButton,
container: CdrContainer,
...props.components,
}) as ChoreographerComponents,
);
const baseClass = 'cdr-choreographer';
const style = useCssModule();
</script>

<template>
<component
v-for="(entry, i) in schema"
:key="`entry-${i}`"
:is="componentMap[entry.type as keyof typeof componentMap]"
:is="
entry.type && componentMap[entry.type]
? componentMap[entry.type as keyof typeof componentMap]
: 'div'
"
v-bind="entry?.props"
:class="style[`${baseClass}__${entry.type}`]"
>
<template v-if="Array.isArray(entry?.content)">
<CdrChoreographer :schema="(entry?.content)" />
<template v-if="entry.content && Array.isArray(entry.content)">
<CdrChoreographer
:schema="entry.content as [ChoreographerSchema]"
:components="components"
/>
</template>
<template v-else>
{{ entry?.content }}
</template>
<template
v-for="(value, key) in entry.slots"
#[key]
>
<CdrChoreographer
:key="key"
:schema="[value]"
:components="components"
/>
</template>
</component>
</template>

<style lang="scss" module src="./styles/CdrChoreographer.module.scss">
</style>
<style lang="scss" module src="./styles/CdrChoreographer.module.scss"></style>
136 changes: 97 additions & 39 deletions src/components/choreographer/examples/Choreographer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<div class="foo">
<h2>choreographer</h2>
<h3>Standalone card built from schema</h3>
<div style="max-width: 550px; margin-bottom: 6.4rem;">
<CdrChoreographer :schema="schemaB"/>
<div style="max-width: 550px; margin-bottom: 6.4rem">
<CdrChoreographer :schema="schemaB" />
</div>
<CdrChoreographer :schema="schemaA" />
<h3>Card</h3>
Expand All @@ -16,6 +16,10 @@
<CdrChoreographer :schema="schemaA" />
</cdr-card>

<CdrChoreographer
:schema="schemaC"
:components="{ CdrSurface, CdrMediaObject }"
/>
</div>
</template>

Expand All @@ -26,105 +30,161 @@ export default {
name: 'Choreographer',
components: {
...Components,
},
},
data() {
return {
CdrSurface: Components.CdrSurface,
CdrMediaObject: Components.CdrMediaObject,
schemaA: [
{
type: 'mediaObject',
slots: {
media: {
type: 'image',
props: {
alt: 'A sample image',
src: 'https://www.rei.com/dam/gerlach_090622_0135_web_lg.jpeg?t=ea16by9md',
},
},
content: {
content: [
{ type: 'kicker', content: 'Example kicker' },
{ type: 'title', content: 'Example title' },
],
},
},
},
{
type: 'image',
props: {
alt: "standard landscape",
src: "https://www.rei.com/dam/gerlach_090622_0135_web_lg.jpeg?t=ea16by9md",
alt: 'standard landscape',
src: 'https://www.rei.com/dam/gerlach_090622_0135_web_lg.jpeg?t=ea16by9md',
responsive: true,
cover: true
cover: true,
},
},
{
type: 'kicker',
content: 'skills'
content: 'skills',
},
{
type: 'link',
props: {
href: '#',
modifier: 'standalone'
modifier: 'standalone',
},
content: [
{
type: 'title',
props: { tag: 'p' },
content: 'Running nutrition basics'
}
]
content: 'Running nutrition basics',
},
],
},
{
type: 'rating',
props: {
rating: "4.0",
count: "49",
size: "small"
}
rating: '4.0',
count: '49',
size: 'small',
},
},
{
type: 'abstract',
content: 'Fueling well is the key to longevity and improvement in running. Our experts guide you on filling your plate for your goals.'
}
content:
'Fueling well is the key to longevity and improvement in running. Our experts guide you on filling your plate for your goals.',
},
],
schemaB: [
{
type: 'card',
props: {
as: 'lead'
as: 'lead',
},
content: [
{
type: 'image',
props: {
alt: "standard landscape",
src: "https://www.rei.com/dam/gerlach_090622_0135_web_lg.jpeg?t=ea16by9md",
alt: 'standard landscape',
src: 'https://www.rei.com/dam/gerlach_090622_0135_web_lg.jpeg?t=ea16by9md',
responsive: true,
cover: true
cover: true,
},
},
{
type: 'kicker',
props: {
tag: 'span',
},
content: 'skills'
content: 'skills',
},
{
type: 'link',
props: {
href: '#',
modifier: 'standalone',
class: "cdr-card__link"
class: 'cdr-card__link',
},
content: [
{
type: 'title',
props: { tag: 'p' },
content: 'Running nutrition basics'
}
]
content: 'Running nutrition basics',
},
],
},
{
type: 'rating',
props: {
rating: "4.0",
count: "49",
size: "small"
}
rating: '4.0',
count: '49',
size: 'small',
},
},
{
type: 'abstract',
content: 'Fueling well is the key to longevity and improvement in running. Our experts guide you on filling your plate for your goals.'
}
]
}
]
}
}
content:
'Fueling well is the key to longevity and improvement in running. Our experts guide you on filling your plate for your goals.',
},
],
},
],
schemaC: [
{
type: 'CdrSurface',
props: {
background: 'secondary',
},
content: 'Using passed-in components',
},
{
type: 'CdrMediaObject',
props: {
as: 'CdrSurface',
background: 'secondary',
gap: 'one-x',
},
slots: {
media: {
type: 'image',
props: {
alt: 'A sample image',
src: 'https://www.rei.com/dam/gerlach_090622_0135_web_lg.jpeg?t=ea16by9md',
},
},
content: {
content: [
{
type: 'body',
content: 'This media object uses an overlay and has responsive heights',
},
],
},
},
},
],
};
},
};
</script>

Expand All @@ -140,7 +200,5 @@ export default {
max-width: 600px;
margin-bottom: 5rem;
padding-bottom: 2.4rem;
}
</style>
10 changes: 9 additions & 1 deletion src/components/layout/CdrLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getStructureStyles } from '../../utils/layout';
import type { Layout, NameValuePair } from '../../types/interfaces';
import type { Structure } from '../../types/other';
import { modifyClassName } from '../../utils/buildClass';
import CdrSurface from '../surface/CdrSurface.vue';
/** Foundational container for creating structured layouts */
Expand All @@ -20,6 +21,7 @@ const props = withDefaults(defineProps<Layout>(), {
queryType: 'container',
flow: undefined,
flowValue: 'auto',
containerName: undefined,
});
const style = useCssModule();
Expand All @@ -29,6 +31,10 @@ const rootProps = computed(() => {
const classes = [baseClass];
const inlineStyles: NameValuePair = {};
if (props.containerName) {
inlineStyles['container-name'] = props.containerName;
}
// Add gap for entire grid
if (props.gap !== 'zero') {
classes.push(modifyClassName(baseClass, `gap-${props.gap}`));
Expand Down Expand Up @@ -72,11 +78,13 @@ const rootProps = computed(() => {
return { class: mapClasses(style, ...classes) || undefined, style: inlineStyles };
});
const componentIs = props.as === 'CdrSurface' ? CdrSurface : props.as;
</script>

<template>
<component
:is="props.as"
:is="componentIs"
v-bind="rootProps"
>
<!-- @slot Where all default content should be placed. -->
Expand Down
1 change: 1 addition & 0 deletions src/components/layout/styles/vars/CdrLayout.vars.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ $flows: row, column;

@mixin cdr-layout-base-mixin() {
display: grid;
container-type: inline-size;
}

// Adds in media and container queries for layouts that change at various breakpoints
Expand Down
Loading

0 comments on commit 5029e92

Please sign in to comment.