Skip to content

Commit

Permalink
Merge pull request #1524 from EnergySage/ced-1786-es-support-card
Browse files Browse the repository at this point in the history
feat: v3 EsSupportCard
  • Loading branch information
hroth1994 authored Sep 12, 2024
2 parents 250c0c5 + ce106bc commit 29f6468
Show file tree
Hide file tree
Showing 4 changed files with 332 additions and 1 deletion.
150 changes: 150 additions & 0 deletions es-ds-components/components/es-support-card.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<script setup lang="ts">
const props = defineProps({
constrained: {
type: Boolean,
default: false,
},
imageAltText: {
type: String,
default: '',
},
imageSrc: {
type: String,
default: '',
},
primaryCtaTarget: {
type: String,
default: '_blank',
},
primaryCtaText: {
type: String,
required: true,
},
primaryCtaUrl: {
type: String,
required: true,
},
secondaryCtaTarget: {
type: String,
default: '_blank',
},
secondaryCtaText: {
type: String,
default: '',
},
secondaryCtaUrl: {
type: String,
default: '',
},
});
const showSecondaryCta = computed(() => {
return !!props.secondaryCtaText && !!props.secondaryCtaUrl;
});
</script>

<template>
<es-card
class="p-100 px-sm-200 text-center text-lg-left"
:class="{
'px-md-100 py-md-200': constrained,
'px-md-300': !constrained,
}">
<b-row class="align-items-lg-center justify-content-xl-between">
<b-col
class="EsSupportCard-contentColumn d-flex flex-column justify-content-lg-center position-relative"
:class="{ 'pr-lg-0': constrained }"
cols="12"
lg="8">
<!-- h2 is first in DOM order for semantics; using order utility classes to rearrange -->
<h2
class="align-items-center d-flex font-size-300 justify-content-center justify-content-lg-start mb-150 mb-lg-100 order-1"
:class="{
'pl-lg-100': constrained,
'pl-lg-200': !constrained,
}">
<slot name="headline" />
</h2>
<div class="EsSupportCard-imageContainer mb-150 mb-lg-0 order-0">
<slot name="image">
<nuxt-img
v-if="imageAltText && imageSrc"
:alt="imageAltText"
class="bg-teal-200 rounded-circle"
height="100px"
:src="imageSrc"
width="100px" />
</slot>
</div>
<!--
we are giving 'EsSupportCard-description' a unique class (that we don't use directly in this
component) for consuming applications to use in targeting ::v-deep styles on <p> tags to remove
the natural <p> bottom margin, for example.
e.g. a CMS rich text component may generate a <p> tag within this that automatically
gets a bottom margin, which throws off the vertical centering. we are intentionally leaving
the removal of that bottom margin up to consuming applications rather than removing it on all
<p> tags within this element, in case they may want two <p> tags or any other markup in here.
-->
<div
class="EsSupportCard-description font-size-75 font-size-lg-100 mb-150 mb-lg-0 order-2"
:class="{
'pl-lg-100': constrained,
'pl-lg-200': !constrained,
}">
<slot name="description" />
</div>
</b-col>
<b-col
cols="12"
lg="4"
xxl="3">
<es-button
class="w-100"
:class="{ 'mb-100': showSecondaryCta }"
:href="primaryCtaUrl"
:target="primaryCtaTarget"
variant="primary">
{{ primaryCtaText }}
</es-button>
<es-button
v-if="showSecondaryCta"
class="w-100"
:href="secondaryCtaUrl"
outline
:target="secondaryCtaTarget"
variant="primary">
{{ secondaryCtaText }}
</es-button>
</b-col>
</b-row>
</es-card>
</template>

<style lang="scss">
@use '@energysage/es-ds-styles/scss/mixins/breakpoints' as breakpoints;
@include breakpoints.media-breakpoint-up(lg) {
.EsSupportCard {
&-contentColumn {
/* account for the size of the image */
min-height: 100px;
/* 15px standard column padding + 100px image width */
padding-left: 115px;
}
&-description {
/* limit line length on larger breakpoints */
max-width: 450px;
}
&-imageContainer {
/* account for 15px standard column padding */
left: 15px;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
}
}
</style>
3 changes: 3 additions & 0 deletions es-ds-docs/components/ds-organisms-list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@
<li>
<ds-link to="/organisms/reviews-io-card-carousel"> Reviews.io card carousel </ds-link>
</li>
<li>
<ds-link to="/organisms/support-card"> Support card </ds-link>
</li>
</ul>
</template>
7 changes: 6 additions & 1 deletion es-ds-docs/components/ds-prop-table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ export default {
{{ column }}
</template>
<template #value>
<code v-if="columnIndex < 3 && row[columnIndex] !== 'n/a'">
<code
v-if="
// Applies code formatting to the first 2 out of 3 columns or 3 out of 4+ columns
((widths.md.length > 3 && columnIndex < 3) || columnIndex < 2) &&
row[columnIndex] !== 'n/a'
">
{{ row[columnIndex] }}
</code>
<span v-else>
Expand Down
173 changes: 173 additions & 0 deletions es-ds-docs/pages/organisms/support-card.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<script setup>
definePageMeta({
layout: 'full-width-component',
});
const { $prism } = useNuxtApp();
const compCode = ref('');
const docCode = ref('');
const placeholderImage = 'https://a-us.storyblok.com/f/1006156/110x110/d215996a95/default-installer-logo.png';
const propTableRows = [
[
'constrained',
'Boolean',
'false',
'When set to `true`, reduces padding on desktop viewports to better accommodate a limited-width layout.',
],
[
'imageAltText',
'String',
"''",
'The alternate text for the image. Used by default unless content is supplied to the `image` slot.',
],
[
'imageSrc',
'String',
"''",
'The URL of the image to display. Used by default unless content is supplied to the `image` slot.',
],
[
'primaryCtaTarget',
'String',
"'_blank'",
'Controls whether or not the link should open in a new window. Defaults to opening in a new window.',
],
['primaryCtaText', 'String', 'n/a', 'Required. The text for the primary CTA button.'],
['primaryCtaUrl', 'String', 'n/a', 'Required. The URL to which the primary CTA button should link.'],
[
'secondaryCtaTarget',
'String',
"'_blank'",
'Controls whether or not the link should open in a new window. Defaults to opening in a new window.',
],
['secondaryCtaText', 'String', "''", 'The text for the secondary CTA button, if any.'],
['secondaryCtaUrl', 'String', "''", 'The URL to which the secondary CTA button (if any) should link.'],
];
const slotTableRows = [
['headline', 'n/a', "The content to insert into the card's heading."],
[
'image',
'<nuxt-img>',
'Optional. Replaces the default <nuxt-img> tag that uses the `imageSrc` and `imageAltText` props. Allows full customization of the image component used.',
],
['description', 'n/a', "The content to display in the card's main paragraph."],
];
if ($prism) {
/* eslint-disable import/no-webpack-loader-syntax, import/no-self-import */
const compSource = await import('@energysage/es-ds-components/components/es-support-card.vue?raw');
const docSource = await import('./support-card.vue?raw');
/* eslint-enable import/no-webpack-loader-syntax, import/no-self-import */
compCode.value = $prism.normalizeCode(compSource.default);
docCode.value = $prism.normalizeCode(docSource.default);
$prism.highlight();
}
</script>

<template>
<div>
<h1 class="mb-300">Support card</h1>
<div class="mb-500">
<h2>Default</h2>
<es-support-card
image-alt-text="Donec consequat auctor"
:image-src="placeholderImage"
primary-cta-text="Schedule a call"
primary-cta-url="https://www.energysage.com">
<template #headline>
<span class="align-items-center d-flex text-success">
<icon-verified
class="mr-50"
height="22px"
width="22px" />
</span>
We’re here to help
</template>
<template #description>
Our Energy Advisors provide expert, unbiased energy advice at no cost to you.
<strong> No annoying sales pitches, and no spam calls. </strong>
</template>
</es-support-card>
</div>
<div class="mb-500">
<h2>With secondary CTA</h2>
<es-support-card
image-alt-text="Donec consequat auctor"
:image-src="placeholderImage"
primary-cta-text="Schedule a call"
primary-cta-url="https://www.energysage.com"
secondary-cta-text="Send an email"
secondary-cta-url="mailto:[email protected]">
<template #headline>
<span class="align-items-center d-flex text-success">
<icon-verified
class="mr-50"
height="22px"
width="22px" />
</span>
We’re here to help
</template>
<template #description>
Our Energy Advisors provide expert, unbiased energy advice at no cost to you.
<strong> No annoying sales pitches, and no spam calls. </strong>
</template>
</es-support-card>
</div>
<div class="mb-500">
<h2>Constrained</h2>
<p class="mb-200">
The <code>constrained</code> prop is set to demonstrate a limited-width container. There are no
differences on mobile viewports from the default example.
</p>
<b-row class="justify-content-center">
<b-col
cols="12"
lg="8"
xl="7">
<es-support-card
constrained
image-alt-text="Donec consequat auctor"
:image-src="placeholderImage"
primary-cta-text="Schedule a call"
primary-cta-url="https://www.energysage.com"
secondary-cta-text="Send an email"
secondary-cta-url="mailto:[email protected]">
<template #headline>
<span class="align-items-center d-flex text-success">
<icon-verified
class="mr-50"
height="22px"
width="22px" />
</span>
We’re here to help
</template>
<template #description>
Our Energy Advisors provide expert, unbiased energy advice at no cost to you.
<strong> No annoying sales pitches, and no spam calls. </strong>
</template>
</es-support-card>
</b-col>
</b-row>
</div>
<div class="mb-500">
<h2>EsSupportCard props</h2>
<ds-prop-table :rows="propTableRows" />
</div>
<div class="mb-500">
<h2>EsSupportCard slots</h2>
<ds-prop-table
:rows="slotTableRows"
:columns="['Name', 'Default', 'Description']"
:widths="{ md: ['3', '2', '7'] }" />
</div>
<ds-doc-source
:comp-code="compCode"
comp-source="es-ds-components/src/lib-components/es-support-card.vue"
:doc-code="docCode"
doc-source="es-ds-docs/pages/molecules/support-card.vue" />
</div>
</template>

0 comments on commit 29f6468

Please sign in to comment.