Skip to content

Commit

Permalink
feat: cv tile components & story working
Browse files Browse the repository at this point in the history
  • Loading branch information
davidnixon committed Apr 11, 2023
1 parent 18c9396 commit 926341e
Show file tree
Hide file tree
Showing 29 changed files with 323 additions and 191 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 0 additions & 2 deletions src/components/CvCheckbox/CvCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,3 @@ const cvId = useCvId(props);
const emit = defineEmits(['update:modelValue', 'change']);
const { onChange, isChecked } = useCheck(toRefs(props), emit);
</script>

<style scoped></style>
133 changes: 114 additions & 19 deletions src/components/CvTile/CvTile.stories.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Canvas, Meta, Story } from '@storybook/addon-docs';
import CvTile from './CvTile.vue';
import CvTileStandard from "./CvTileStandard.vue";
import CvTileClickable from "./CvTileClickable.vue";
import CvTileStandard from './CvTileStandard.vue';
import CvTileClickable from './CvTileClickable.vue';
import { sbCompPrefix } from '../../global/storybook-utils';
import { action } from '@storybook/addon-actions';

Expand All @@ -10,50 +10,145 @@ import { action } from '@storybook/addon-actions';
export const Template = args => ({
// Components used in your story `template` are defined in the `components` object
components: {
CvTile,CvTileStandard,CvTileClickable
CvTile,
CvTileStandard,
CvTileClickable,
},
// The story's `args` need to be mapped into the template through the `setup()` method
setup() {
return {
args: { light: args.light, kind: args.kind, disabled: args.disabled},
args: {
light: args.light,
kind: args.kind,
disabled: args.disabled,
expanded: args.expanded,
tileCollapsedLabel: args.tileCollapsedLabel,
tileExpandedLabel: args.tileExpandedLabel,
},
onChange: action('change'),
onExpanded: action('expanded'),
onClick: action('click'),
};
},
// And then the `args` are bound to your component with `v-bind="args"`
template: args.template,
});
const defaultTemplate = `
<div>
<cv-tile v-bind='args' @change="onChange">Hello!</cv-tile>
</div>
`;
const defaultTemplate = `<cv-tile v-bind='args'>Hello!</cv-tile>`;
const defaultCode = defaultTemplate.replace("v-bind='args'", '');
const expandableTemplate = `<cv-tile v-bind='args' kind="expandable" @expanded="onExpanded">Hello expandable!<template #below><h1>More Content</h1><p>Expanded</p></template></cv-tile>`;
const expandableCode = expandableTemplate.replace("v-bind='args'", '');
const clickableTemplate = `<cv-tile v-bind='args' kind="clickable" @click="onClick" to="{name: 'something'}">Hello clickable!</cv-tile>`;
const clickableCode = clickableTemplate.replace("v-bind='args'", '');
const selectableTemplate = `<cv-tile v-bind='args' kind="selectable" value="my-selection" @change="onChange">Hello selectable! </cv-tile>`;
const selectableCode = selectableTemplate.replace("v-bind='args'", '');

# CvTile

**Migration notes:**

- The `light` and '`theme` options continue to be supported but neither seem to have any effect with Carbon 10.
The React component does not have these properties listed at all. Even so the `--content-switcher--light` is still
applied if `light` is set to true.
- In the Vue 2 component `cv-content-switcher-content` is set to visible if the controlling `cv-content-switcher` is
removed from the DOM. This is no longer supported. If you need this behaviour you can probably achieve the same effect
with the direct DOM version of the component plus some visibility logic.
- The `light` and '`theme` options continue to be supported but the boolean `light` is preferred.
- The expandable tile now emits a `expanded` event with a Boolean value.

<Canvas>
<Story
name="Default"
parameters={{
controls: { exclude: ['default', 'selected', 'template', 'data'] },
controls: {
exclude: [
'default',
'selected',
'template',
'data',
'kind',
'expanded',
'tileExpandedLabel',
'tileCollapsedLabel',
],
},
docs: { source: { code: defaultCode } },
}}
args={{
light: true,
kind: '',
light: false,
disabled: false,
template: defaultTemplate,
}}
argTypes={{
kind: { control: 'select', default: 'standard', options: ['clickable', 'expandable', 'selectable', 'standard'] },
>
{Template.bind({})}
</Story>
</Canvas>

<Canvas>
<Story
name="Expandable"
parameters={{
controls: {
exclude: ['default', 'selected', 'template', 'data', 'kind', 'slots'],
},
docs: { source: { code: expandableCode } },
}}
args={{
light: false,
disabled: false,
template: expandableTemplate,
}}
>
{Template.bind({})}
</Story>
</Canvas>

<Canvas>
<Story
name="Clickable"
parameters={{
controls: {
exclude: [
'default',
'selected',
'template',
'data',
'kind',
'slots',
'expanded',
'tileExpandedLabel',
'tileCollapsedLabel',
],
},
docs: { source: { code: clickableCode } },
}}
args={{
light: false,
disabled: false,
template: clickableTemplate,
}}
>
{Template.bind({})}
</Story>
</Canvas>

<Canvas>
<Story
name="Selectable"
parameters={{
controls: {
exclude: [
'default',
'selected',
'template',
'data',
'kind',
'slots',
'expanded',
'tileExpandedLabel',
'tileCollapsedLabel',
],
},
docs: { source: { code: selectableCode } },
}}
args={{
light: false,
disabled: false,
template: selectableTemplate,
}}
>
{Template.bind({})}
Expand Down
8 changes: 8 additions & 0 deletions src/components/CvTile/CvTile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
:expanded="checkProp('expanded', expanded)"
:tileCollapsedLabel="checkProp('tileCollapsedLabel', tileCollapsedLabel)"
:tileExpandedLabel="checkProp('tileCollapsedLabel', tileExpandedLabel)"
:class="[
`cv-tile ${carbonPrefix}--tile`,
{ [`${carbonPrefix}--tile--light`]: isLight },
]"
>
<template v-for="(_, name) in $slots" v-slot:[name]="slotData"
><slot :name="name" v-bind="slotData"
Expand All @@ -14,6 +18,8 @@

<script setup>
import { computed } from 'vue';
import { carbonPrefix } from '../../global/settings';
import { props as propsTheme, useIsLight } from '../../use/cvTheme';
import CvTileStandard from './CvTileStandard.vue';
import CvTileClickable from './CvTileClickable.vue';
import CvTileSelectable from './CvTileSelectable.vue';
Expand All @@ -30,6 +36,7 @@ const props = defineProps({
validator: value =>
['clickable', 'expandable', 'selectable', 'standard', ''].includes(value),
},
...propsTheme,
});
const tagType = computed(() => {
Expand All @@ -44,6 +51,7 @@ const tagType = computed(() => {
return CvTileStandard;
}
});
const isLight = useIsLight(props);
/**
* If the prop is defined on the tagType pass it along otherwise, discard it.
Expand Down
24 changes: 16 additions & 8 deletions src/components/CvTile/CvTileClickable.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
<template>
<bx-clickable-tile
:color-scheme="light ? 'light' : undefined"
:disabled="disabled ? 'disabled' : undefined"
><slot>Clickable tile</slot></bx-clickable-tile
<component
:is="tagType"
ref="target"
data-tile="clickable"
:class="`cv-tile-clickable ${carbonPrefix}--tile--clickable`"
v-bind="{ ...$attrs, ...linkProps }"
tabindex="0"
>
<slot></slot>
</component>
</template>

<script setup>
import '@carbon/web-components/es/components/tile/index.js';
defineProps({
light: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
import { carbonPrefix } from '../../global/settings';
import { props as propsLink, useLinkProps, useTagType } from '../../use/cvLink';
const props = defineProps({
...propsLink,
});
const tagType = useTagType(props);
const linkProps = useLinkProps(props);
</script>
105 changes: 93 additions & 12 deletions src/components/CvTile/CvTileExpandable.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,103 @@
<template>
<bx-expandable-tile>
<bx-tile-above-the-fold-content slot="above-the-fold-content">
<slot>
<!-- Above the fold content here -->
</slot>
</bx-tile-above-the-fold-content>
<bx-tile-below-the-fold-content>
<slot name="below"> Below the fold content here </slot>
</bx-tile-below-the-fold-content>
</bx-expandable-tile>
<button
type="button"
:style="data.styleObject"
@click="toggle"
:class="[
`cv-tile-expandable ${carbonPrefix}--tile--expandable`,
{ [`${carbonPrefix}--tile--is-expanded`]: data.internalExpanded },
]"
ref="el"
>
<div :class="`${carbonPrefix}--tile-content`">
<span
data-tile-atf
:class="`${carbonPrefix}--tile-content__above-the-fold`"
ref="aboveFold"
>
<slot>
<!-- Above the fold content here -->
</slot>
</span>
<div :class="`${carbonPrefix}--tile__chevron`">
<span>{{ chevronLabel }}</span>
<ChevronDown16 />
</div>
<span
:class="`${carbonPrefix}--tile-content__below-the-fold`"
ref="belowFold"
v-show="data.internalExpanded || data.initialized"
>
<slot name="below">
<!-- Rest of the content here -->
</slot>
</span>
</div>
</button>
</template>

<script setup>
import '@carbon/web-components/es/components/tile/index.js';
import { carbonPrefix } from '../../global/settings';
import ChevronDown16 from '@carbon/icons-vue/es/chevron--down/16';
import { computed, nextTick, reactive, ref, watch } from 'vue';
defineProps({
const props = defineProps({
expanded: Boolean,
tileCollapsedLabel: String,
tileExpandedLabel: String,
});
const data = reactive({
styleObject: {
maxHeight: 'initial',
},
initialized: false,
internalExpanded: props.expanded,
});
watch(
() => props.expanded,
val => {
if (val !== data.internalExpanded) {
toggle(val);
}
}
);
const chevronLabel = computed(() => {
return data.internalExpanded
? props.tileExpandedLabel
: props.tileCollapsedLabel;
});
const el = ref(null);
const belowFold = ref(null);
function toggle(force) {
let currentHeight = el?.value.getBoundingClientRect().height;
if (!data.initialized) {
data.styleObject.maxHeight = `${currentHeight}px`;
data.initialized = true;
}
nextTick(() => {
const forceType = typeof force;
data.internalExpanded =
forceType === 'boolean' ? force : !data.internalExpanded;
const belowFoldHeight = belowFold?.value.getBoundingClientRect().height;
if (data.internalExpanded) {
currentHeight += belowFoldHeight;
} else {
currentHeight -= belowFoldHeight;
}
data.styleObject.maxHeight = `${currentHeight}px`;
});
}
const emit = defineEmits(['expanded']);
watch(
() => data.internalExpanded,
val => {
emit('expanded', val);
}
);
</script>
Loading

0 comments on commit 926341e

Please sign in to comment.