Skip to content

Instantly share code, notes, and snippets.

@jantimon
Created August 8, 2018 14:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jantimon/7c8ceadb431f462c3e162e5276f24dad to your computer and use it in GitHub Desktop.
Save jantimon/7c8ceadb431f462c3e162e5276f24dad to your computer and use it in GitHub Desktop.
const viewportClassPrefix = (viewport: 'xs' | 'sm' | 'md' | 'lg') => viewport === 'xs' ? '' : ('-' + viewport);
const flexAlignment = {
col: {
direction: {
outer: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `flex${viewportClassPrefix(viewport)}-column`,
inner: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `flex${viewportClassPrefix(viewport)}-row`,
},
vertical: {
top: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `justifified-content${viewportClassPrefix(viewport)}-start`,
center: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `justifified-content${viewportClassPrefix(viewport)}-center`,
bottom: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `justifified-content${viewportClassPrefix(viewport)}-end`,
justified: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `justifified-content${viewportClassPrefix(viewport)}-between`,
},
horizontal: {
left: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `align-self${viewportClassPrefix(viewport)}-start`,
right: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `align-self${viewportClassPrefix(viewport)}-center`,
center: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `align-self${viewportClassPrefix(viewport)}-end`,
stretch: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `align-self${viewportClassPrefix(viewport)}-stretch`,
}
},
row: {
direction: {
outer: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `flex${viewportClassPrefix(viewport)}-row`,
inner: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `flex${viewportClassPrefix(viewport)}-column`,
},
vertical: {
top: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `align-self${viewportClassPrefix(viewport)}-start`,
center: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `align-self${viewportClassPrefix(viewport)}-center`,
bottom: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `align-self${viewportClassPrefix(viewport)}-end`,
justified: (viewport: 'xs' | 'sm' | 'md' | 'lg') => { throw new Error("Justified does not work for flex direction row")},
},
horizontal: {
left: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `justifified-content${viewportClassPrefix(viewport)}-start`,
right: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `justifified-content${viewportClassPrefix(viewport)}-center`,
center: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `justifified-content${viewportClassPrefix(viewport)}-end`,
stretch: (viewport: 'xs' | 'sm' | 'md' | 'lg') => `${viewportClassPrefix(viewport)}`,
}
},
}
function getDirectionForBreakpoints(directionBreakpoints: { xs?: 'col' | 'row', sm?: 'col' | 'row', md?: 'col' | 'row', lg?: 'col' | 'row' }): { xs: 'col' | 'row', sm: 'col' | 'row', md: 'col' | 'row', lg: 'col' | 'row' } {
let lastBreakpoint = directionBreakpoints.xs || 'top';
const breakpointDirections = {
xs: lastBreakpoint
};
['sm', 'md', 'lg'].forEach((viewport) => {
breakpointDirections[viewport] = directionBreakpoints[viewport] || lastBreakpoint;
lastBreakpoint = breakpointDirections[viewport];
})
return breakpointDirections as any;
}
function Col(props: {
direction?: 'col' | 'row' | { xs?: 'col' | 'row', sm?: 'col' | 'row', md?: 'col' | 'row', lg?: 'col' | 'row' },
verticalAlignment?: 'top' | 'center' | 'bottom' | 'justified' | { xs?: 'top' | 'center' | 'bottom' | 'justified', sm?: 'top' | 'center' | 'bottom' | 'justified', md?: 'top' | 'center' | 'bottom' | 'justified', lg?: 'top' | 'center' | 'bottom' | 'justified' },
horizontalAlignment?: 'left' | 'right' | 'center' | 'stretch' | { xs?: 'left' | 'right' | 'center' | 'stretch', sm?: 'left' | 'right' | 'center' | 'stretch', md?: 'left' | 'right' | 'center' | 'stretch', lg?: 'left' | 'right' | 'center' | 'stretch' },
} = {}) {
const { direction, verticalAlignment, horizontalAlignment } = props;
let directionBreakpoints = typeof direction === 'string' ? { xs: direction } : (direction || {});
let verticalAlignmentBreakpoints = typeof verticalAlignment === 'string' ? { xs: verticalAlignment } : (verticalAlignment || {});
let horizontalAlignmentBreakpoints = typeof horizontalAlignment === 'string' ? { xs: horizontalAlignment } : (horizontalAlignment || {});
if (!directionBreakpoints.xs) {
directionBreakpoints.xs = 'row';
}
if (!verticalAlignmentBreakpoints.xs) {
verticalAlignmentBreakpoints.xs = 'top';
}
if (!horizontalAlignmentBreakpoints.xs) {
horizontalAlignmentBreakpoints.xs = 'stretch';
}
let innerClassName = ['flex'];
let outerClassName = ['flex'];
Object.keys(directionBreakpoints).forEach((directionBreakpointName: keyof typeof directionBreakpoints) => {
const direction = directionBreakpoints[directionBreakpointName];
outerClassName.push(flexAlignment[direction].direction.outer(directionBreakpointName));
innerClassName.push(flexAlignment[direction].direction.inner(directionBreakpointName));
});
const calculatedFlexDirections = getDirectionForBreakpoints(directionBreakpoints);
Object.keys(verticalAlignmentBreakpoints).forEach((verticalAlignmentBreakpointName: keyof typeof verticalAlignmentBreakpoints) => {
const direction = calculatedFlexDirections[verticalAlignmentBreakpointName];
const verticalAlignment = verticalAlignmentBreakpoints[verticalAlignmentBreakpointName];
innerClassName.push(flexAlignment[direction].vertical[verticalAlignment](verticalAlignmentBreakpointName));
});
Object.keys(horizontalAlignmentBreakpoints).forEach((horizontalAlignmentBreakpointName: keyof typeof horizontalAlignmentBreakpoints) => {
const direction = calculatedFlexDirections[horizontalAlignmentBreakpointName];
const horizontalAlignment = horizontalAlignmentBreakpoints[horizontalAlignmentBreakpointName];
innerClassName.push(flexAlignment[direction].horizontal[horizontalAlignment](horizontalAlignmentBreakpointName));
});
return `
<div class="${outerClassName.join(' ')}">
<div class="${innerClassName.join(' ')}">
Content
</div>
</div>
`
}
document.write(`<textarea style="width:100%; height: 100%">
row
${ Col({ direction: 'row' }) }
col
${ Col({ direction: 'col' }) }
row xs & col md
${ Col({ direction: { xs: 'row', md: 'col' } }) }
row top left
${ Col({ verticalAlignment: 'bottom', horizontalAlignment: 'right' }) }
col top left
${ Col({ direction: 'col', verticalAlignment: 'bottom', horizontalAlignment: 'right' }) }
row xs & col md
sm center center & lg bottom right
${ Col({ direction: { xs: 'row', md: 'col' }, horizontalAlignment: { sm: 'center', lg: 'right'}, verticalAlignment: { sm: 'center', 'lg': 'bottom'} }) }
`);
@jantimon
Copy link
Author

jantimon commented Aug 8, 2018

Result:

    row
    
	<div class="flex flex-row">
		<div class="flex flex-column align-self-start ">
			Content
		</div>
	</div>	
	

    col
    
	<div class="flex flex-column">
		<div class="flex flex-row justifified-content-start align-self-stretch">
			Content
		</div>
	</div>	
	

    row xs  &  col md
    
	<div class="flex flex-row flex-md-column">
		<div class="flex flex-column flex-md-row align-self-start ">
			Content
		</div>
	</div>	
	

    row top left
    
	<div class="flex flex-row">
		<div class="flex flex-column align-self-end justifified-content-center">
			Content
		</div>
	</div>	
	

    col top left
    
	<div class="flex flex-column">
		<div class="flex flex-row justifified-content-end align-self-center">
			Content
		</div>
	</div>	
	

    row xs  &  col md
    sm center center & lg bottom right
    
	<div class="flex flex-row flex-md-column">
		<div class="flex flex-column flex-md-row align-self-sm-center justifified-content-lg-end align-self-start justifified-content-sm-end align-self-lg-center ">
			Content
		</div>
	</div>	
	
    
    ```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment