Last active
November 4, 2022 14:07
-
-
Save antoniopresto/dc27637b340a0e39bfac9d7032f2dd7d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cx from 'classnames'; | |
import { createType, Infer, tuple, tupleNum } from 'backland'; | |
export const ViewportSizeEnum = tuple('xs', 'sm', 'md', 'lg', 'xl'); | |
export const ViewportSizes = Object.values(ViewportSizeEnum); | |
export type ViewportSize = typeof ViewportSizes[number]; | |
export const ViewportSizeType = createType('ViewportSize', { | |
enum: ViewportSizes, | |
optional: true, | |
}); | |
v | |
export const ColumnSizeUnionType = createType('ColumnSizesUnion', () => { | |
const str = tuple( | |
'1', | |
'2', | |
'3', | |
'4', | |
'5', | |
'6', | |
'7', | |
'8', | |
'9', | |
'10', | |
'11', | |
'12' | |
); | |
const num = tupleNum( | |
// | |
1, | |
2, | |
3, | |
4, | |
5, | |
6, | |
7, | |
8, | |
9, | |
10, | |
11, | |
12 | |
); | |
return { | |
optional: true, | |
union: [...num, ...str].map((el) => ({ | |
literal: el, | |
})), | |
}; | |
}); | |
export const ColumnSizesType = createType('ColumnSizes', { | |
description: | |
'Sizes of a Column in different ' + // | |
'screens. See: http://flexboxgrid.com/', | |
object: { | |
_kind: { | |
defaultValue: names.ColumnSizes, | |
literal: names.ColumnSizes, | |
optional: true, | |
}, | |
first: ViewportSizeType, | |
fluid: 'boolean?', | |
last: ViewportSizeType, | |
lg: ColumnSizeUnionType, | |
lgOffset: 'int?', | |
md: ColumnSizeUnionType, | |
mdOffset: 'int?', | |
sm: ColumnSizeUnionType, | |
smOffset: 'int?', | |
xl: ColumnSizeUnionType, | |
xlOffset: 'int?', | |
xs: ColumnSizeUnionType, | |
xsOffset: 'int?', | |
}, | |
}); | |
export type ColumnSizes = Infer<typeof ColumnSizesType> extends infer R | |
? { [K in keyof R as K extends '_kind' ? never : K]: R[K] } & {} | |
: never; | |
export const RowSizesType = createType('RowSizes', { | |
object: { | |
around: ViewportSizeType, | |
between: ViewportSizeType, | |
bottom: ViewportSizeType, | |
center: ViewportSizeType, | |
end: ViewportSizeType, | |
middle: ViewportSizeType, | |
reverse: 'boolean?', | |
start: ViewportSizeType, | |
top: ViewportSizeType, | |
}, | |
}); | |
export type RowSizes = Infer<typeof RowSizesType> extends infer R | |
? { [K in keyof R as K extends '_kind' ? never : K]: R[K] } & {} | |
: never; | |
export function sizeToClass( | |
kind: 'col', | |
sizes: ColumnSizes, | |
className?: string | |
): string; | |
export function sizeToClass( | |
kind: 'row', | |
sizes: RowSizes, | |
className?: string | |
): string; | |
export function sizeToClass( | |
...args: | |
| [kind: 'row', sizes: RowSizes, className?: string] | |
| [kind: 'col', sizes: ColumnSizes, className?: string] | |
) { | |
const [kind, sizes, className] = args; | |
if (!sizes) return ''; | |
if (kind === 'row') { | |
return cx( | |
Object.entries(sizes).map(([k, v]) => { | |
if (k === 'reverse') return ''; | |
return `${k}-${v}`; | |
}), | |
{ row: !sizes.reverse, 'row-reverse': sizes.reverse }, | |
className | |
); | |
} | |
const { | |
sm, | |
lg, | |
md, | |
lgOffset, | |
smOffset, | |
mdOffset, | |
xsOffset, | |
xs, | |
xlOffset, | |
xl, | |
last, | |
first, | |
} = sizes; | |
return cx( | |
{ | |
[`${numberLike.test(`${xs}`) ? `col-xs-${xs}` : ''}`]: xs, | |
[`${numberLike.test(`${sm}`) ? `col-sm-${sm}` : ''}`]: sm, | |
[`${numberLike.test(`${md}`) ? `col-md-${md}` : ''}`]: md, | |
[`${numberLike.test(`${lg}`) ? `col-lg-${lg}` : ''}`]: lg, | |
[`${numberLike.test(`${xl}`) ? `col-xl-${xl}` : ''}`]: xl, | |
[`${last ? `last-${last}` : ''}`]: last, | |
[`${first ? `first-${first}` : ''}`]: first, | |
[`col-xs-offset-${xsOffset}`]: xsOffset, | |
[`col-sm-offset-${smOffset}`]: smOffset, | |
[`col-md-offset-${mdOffset}`]: mdOffset, | |
[`col-lg-offset-${lgOffset}`]: lgOffset, | |
[`col-xl-offset-${xlOffset}`]: xlOffset, | |
}, | |
className | |
); | |
} | |
const numberLike = /^\d*$/; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { sizeToClass } from '../sizeToClass'; | |
describe('sizesToClass', () => { | |
test('col', async () => { | |
const sut = sizeToClass('col', { | |
sm: '1', | |
lgOffset: 2, | |
last: 'xl', | |
first: 'sm', | |
}); | |
expect(sut).toBe('col-sm-1 last-xl first-sm col-lg-offset-2'); | |
}); | |
test('row', () => { | |
const sut = sizeToClass('row', { top: 'xs', start: 'xs', reverse: true }); | |
expect(sut).toBe('top-xs start-xs row-reverse'); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment