Skip to content

Commit

Permalink
feat: add grid, row, & column with tests and story
Browse files Browse the repository at this point in the history
  • Loading branch information
davidnixon committed Jan 31, 2023
1 parent 11ae1ae commit f70835f
Show file tree
Hide file tree
Showing 6 changed files with 611 additions and 0 deletions.
147 changes: 147 additions & 0 deletions src/components/CvGrid/CvColumn.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<template>
<div class="cv-column" :class="classes">
<slot></slot>
</div>
</template>

<script setup>
import { carbonPrefix } from '../../global/settings';
import { computed } from 'vue';
const props = defineProps({
sm: {
type: [Boolean, Number, Object],
validator: value => {
if (typeof value === 'number' || typeof value === 'boolean') {
return true;
} else if (typeof value === 'object') {
return (
'span' in value &&
typeof value.span === 'number' &&
'offset' in value &&
typeof value.offset === 'number'
);
}
return false;
},
},
md: {
type: [Boolean, Number, Object],
validator: value => {
if (typeof value === 'number' || typeof value === 'boolean') {
return true;
} else if (typeof value === 'object') {
return (
'span' in value &&
typeof value.span === 'number' &&
'offset' in value &&
typeof value.offset === 'number'
);
}
return false;
},
},
lg: {
type: [Boolean, Number, Object],
validator: value => {
if (typeof value === 'number' || typeof value === 'boolean') {
return true;
} else if (typeof value === 'object') {
return (
'span' in value &&
typeof value.span === 'number' &&
'offset' in value &&
typeof value.offset === 'number'
);
}
return false;
},
},
xlg: {
type: [Boolean, Number, Object],
validator: value => {
if (typeof value === 'number' || typeof value === 'boolean') {
return true;
} else if (typeof value === 'object') {
return (
'span' in value &&
typeof value.span === 'number' &&
'offset' in value &&
typeof value.offset === 'number'
);
}
return false;
},
},
max: {
type: [Boolean, Number, Object],
validator: value => {
if (typeof value === 'number' || typeof value === 'boolean') {
return true;
} else if (typeof value === 'object') {
return (
'span' in value &&
typeof value.span === 'number' &&
'offset' in value &&
typeof value.offset === 'number'
);
}
return false;
},
},
});
const classes = computed(() => {
const classnames = [];
const breakpoints = [
{ name: 'sm', value: props.sm },
{ name: 'md', value: props.md },
{ name: 'lg', value: props.lg },
{ name: 'xlg', value: props.xlg },
{ name: 'max', value: props.max },
].filter(breakpoint => breakpoint.value !== false);
for (let i = 0; i < breakpoints.length; i += 1) {
const { name, value } = breakpoints[i];
if (typeof value === 'boolean') {
// auto-column
classnames.push(`${carbonPrefix}--col-${name}`);
} else if (typeof value === 'number') {
classnames.push(`${carbonPrefix}--col-${name}-${value}`);
} else {
const { span, offset, start, end } = value;
if (typeof span === 'boolean') {
classnames.push(`${carbonPrefix}--col-${name}`);
} else if (typeof span === 'number') {
classnames.push(`${carbonPrefix}--col-${name}-${span}`);
}
if (typeof offset === 'number') {
classnames.push(`${carbonPrefix}--offset-${name}-${offset}`);
}
if (typeof start === 'number') {
classnames.push(`${carbonPrefix}--${name}:col-start-${start}`);
}
if (typeof end === 'number') {
classnames.push(`${carbonPrefix}--${name}:col-end-${end}`);
}
}
}
if (classnames.length === 0) {
// no breakpoints were defined. use auto-column
classnames.push(`${carbonPrefix}--col`);
}
return classnames;
});
</script>
36 changes: 36 additions & 0 deletions src/components/CvGrid/CvGrid.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<template>
<div
class="cv-grid"
:class="[
`${carbonPrefix}--grid`,
{
[`${carbonPrefix}--grid--full-width`]: fullWidth,
[`${carbonPrefix}--grid--condensed`]: kind === 'condensed',
[`${carbonPrefix}--grid--narrow`]: kind === 'narrow',
},
]"
>
<slot></slot>
</div>
</template>

<script setup>
import { carbonPrefix } from '../../global/settings';
defineProps({
/**
* Remove the default max width that the grid has set
*/
fullWidth: Boolean,
/**
* - wide - default
* - condensed - Collapse the gutter to 1px. Useful for fluid layouts. Rows have 1px of margin between them to match gutter.
* - narrow - Container hangs 16px into the gutter. Useful for typographic alignment with and without containers.
*/
kind: {
type: String,
default: 'wide',
validator: val => ['wide', 'narrow', 'condensed'].includes(val),
},
});
</script>
26 changes: 26 additions & 0 deletions src/components/CvGrid/CvRow.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<template>
<div
class="cv-row"
:class="[
`${carbonPrefix}--row`,
{
[`${carbonPrefix}--row--condensed`]: kind === 'condensed',
[`${carbonPrefix}--row--narrow`]: kind === 'narrow',
},
]"
>
<slot></slot>
</div>
</template>

<script setup>
import { carbonPrefix } from '../../global/settings';
defineProps({
kind: {
type: String,
default: 'wide',
validator: val => ['wide', 'narrow', 'condensed'].includes(val),
},
});
</script>
Loading

0 comments on commit f70835f

Please sign in to comment.