Skip to content

Commit

Permalink
media-object-layout
Browse files Browse the repository at this point in the history
  • Loading branch information
sikhote committed Dec 6, 2024
1 parent 2b5db4f commit 9686b6c
Show file tree
Hide file tree
Showing 18 changed files with 497 additions and 515 deletions.
98 changes: 67 additions & 31 deletions src/components/mediaObject/CdrMediaObject.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@
import { useCssModule, computed } from 'vue';
import mapClasses from '../../utils/mapClasses';
import { MediaObject, NameValuePair, HtmlAttributes } from '../../types/interfaces';
import type { Breakpoint } from '../../types/other';
import { modifyClassName } from '../../utils/buildClass';
import { getLayoutStyling } from '../../utils/mediaObject';
import CdrLayout from '../layout/CdrLayout.vue';
import { breakpoints, spacing } from '../../utils/other';
/** Component for buttons that have a checked state. */
defineOptions({ name: 'CdrMediaObject' });
// go back to using media height and width to set cols/rows, that way we can still use 1fr if desired. discard the opposite height/width dependong on content position
const props = withDefaults(defineProps<MediaObject>(), {
contentPosition: 'right',
contentAlignment: 'start',
align: 'start',
mediaPosition: 'left',
mediaWidth: '1fr',
mediaHeight: 'auto',
mediaFit: 'none',
mediaPosition: 'center',
cover: false,
overlay: false,
overlayRowAlign: 'start',
overlayColumnAlign: 'start',
contentPadding: 'zero',
});
const style = useCssModule();
Expand All @@ -26,43 +31,72 @@ const rootProps = computed(() => {
const classes = [baseClass];
const inlineStyles: NameValuePair = {};
const {
contentPosition,
contentAlignment,
mediaFit,
align,
mediaPosition,
mediaWidth,
mediaHeight,
cover,
overlay,
overlayRowAlign,
overlayColumnAlign,
contentPadding,
...otherProps
} = props;
const additionalProps: HtmlAttributes = { ...otherProps };
// Add in class for object fit
if (props.mediaFit !== 'none') {
classes.push(modifyClassName(baseClass, 'media-fit'));
// Determine how the media will take up space
inlineStyles['--cdr-media-object-media-fit'] = mediaFit;
if (contentPadding !== 'zero') {
if (typeof contentPadding === 'string') {
inlineStyles['--cdr-media-object-content-padding'] = spacing[contentPadding];
} else {
classes.push(modifyClassName(baseClass, 'content-padding-cq'));
// Determine media position within cell
inlineStyles['--cdr-media-object-media-position'] = mediaPosition;
breakpoints.forEach((breakpoint: Breakpoint) => {
// Add in padding styles for various breakpoints
inlineStyles[`--cdr-media-object-content-padding-${breakpoint}`] =
spacing[contentPadding[breakpoint]];
});
}
}
// Get layout related props and inline styles based on media measurements and
// content position, both of which can be dynamic
const layoutStyling = getLayoutStyling(contentPosition, mediaWidth, mediaHeight);
Object.assign(inlineStyles, layoutStyling.inlineStyles);
// Add overlay class, which skips most other props
if (overlay) {
classes.push(modifyClassName(baseClass, 'overlay'));
Object.assign(additionalProps, { rows: 'auto', columns: 'auto' });
inlineStyles['--cdr-media-object-row-align'] = overlayRowAlign;
inlineStyles['--cdr-media-object-column-align'] = overlayColumnAlign;
} else {
// Get layout related props and inline styles based on media measurements and
// content position, both of which can be dynamic
const layoutStyling = getLayoutStyling(mediaPosition, mediaWidth, mediaHeight);
Object.assign(inlineStyles, layoutStyling.inlineStyles);
Object.assign(additionalProps, layoutStyling.props);
// Add in class for allowing dynamic content positioning
if (typeof props.contentPosition !== 'string') {
classes.push(modifyClassName(baseClass, 'content-position-cq'));
}
// Add in class for allowing dynamic content positioning
if (typeof mediaPosition !== 'string') {
classes.push(modifyClassName(baseClass, 'media-position-cq'));
}
// Add align class and inline styles for allowing dynamic align values
// or set the static value
if (typeof align !== 'string') {
classes.push(modifyClassName(baseClass, 'align-cq'));
// Add content alignment
classes.push(modifyClassName(baseClass, `content-alignment-${contentAlignment}`));
breakpoints.forEach((breakpoint: Breakpoint) => {
// Add in media position styles for various breakpoints
inlineStyles[`--cdr-media-object-align-${breakpoint}`] = align[breakpoint];
});
} else {
inlineStyles['--cdr-media-object-align'] = align;
}
// Add cover class
if (cover) {
classes.push(modifyClassName(baseClass, 'cover'));
}
}
return {
...additionalProps,
...layoutStyling.props,
class: mapClasses(style, ...classes) || undefined,
style: inlineStyles,
};
Expand All @@ -71,12 +105,14 @@ const rootProps = computed(() => {

<template>
<CdrLayout v-bind="rootProps">
<div>
<!-- @slot Where the media should be placed. -->
<div :class="style['cdr-media-object__media']">
<!-- @slot Where the media should be placed. Should be a single node. -->
<slot name="media" />
</div>
<!-- @slot Where all content should be placed. -->
<slot name="content" />
<div :class="style['cdr-media-object__content']">
<!-- @slot Where all content should be placed. Can be multiple nodes. -->
<slot name="content" />
</div>
</CdrLayout>
</template>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,25 @@
exports[`CdrMediaObject > snapshot test > renders correctly 1`] = `
<div
checked="false"
class="cdr-layout cdr-layout--rows cdr-layout--columns cdr-media-object cdr-media-object--content-alignment-start"
style="--cdr-layout-rows: auto; --cdr-layout-columns: 1fr 1fr; --cdr-media-object-content-position: 'media content';"
class="cdr-layout cdr-layout--rows cdr-layout--columns cdr-media-object"
style="--cdr-layout-rows: auto; --cdr-layout-columns: 1fr 1fr; --cdr-media-object-media-position: 'media content'; --cdr-media-object-align: start;"
>
<!-- @slot Where all default content should be placed. -->
<div>
<!-- @slot Where the media should be placed. -->
<div
class="cdr-media-object__media"
>
<!-- @slot Where the media should be placed. Should be a single node. -->
</div>
<div
class="cdr-media-object__content"
>
<!-- @slot Where all content should be placed. Can be multiple nodes. -->
</div>
<!-- @slot Where all content should be placed. -->
</div>
`;
72 changes: 0 additions & 72 deletions src/components/mediaObject/examples/Demo.vue

This file was deleted.

120 changes: 0 additions & 120 deletions src/components/mediaObject/examples/MediaObject copy.vue

This file was deleted.

Loading

0 comments on commit 9686b6c

Please sign in to comment.