mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-02-27 11:04:01 -05:00
feat: add col component (#51012)
Co-authored-by: Naomi Carrigan <nhcarrigan@gmail.com>
This commit is contained in:
35
tools/ui-components/src/col/col.stories.tsx
Normal file
35
tools/ui-components/src/col/col.stories.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
import { Story } from '@storybook/react';
|
||||
import { Col, ColProps } from '.';
|
||||
|
||||
const story = {
|
||||
title: 'Example/Col',
|
||||
component: Col,
|
||||
argTypes: {
|
||||
className: { control: { type: 'text' } },
|
||||
xs: { options: [8, 12, undefined] },
|
||||
sm: { options: [2, 4, 6, 8, 10, 12, undefined] },
|
||||
md: { options: [4, 6, 8, 10, undefined] },
|
||||
lg: { options: [6, 8, 10, undefined] },
|
||||
xsOffset: { options: [2, 3, undefined] },
|
||||
smOffset: { options: [1, 2, 3, 4, undefined] },
|
||||
mdOffset: { options: [1, 2, 3, 4, undefined] },
|
||||
lgOffset: { options: [0, 1, 2, undefined] },
|
||||
smPush: { options: [1, undefined] }
|
||||
}
|
||||
};
|
||||
|
||||
const Template: Story<ColProps> = args => {
|
||||
return (
|
||||
<Col className='bg-gray-700' {...args}>
|
||||
<p>Random text to test the element width</p>
|
||||
</Col>
|
||||
);
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
// default props go here
|
||||
};
|
||||
|
||||
export default story;
|
||||
25
tools/ui-components/src/col/col.test.tsx
Normal file
25
tools/ui-components/src/col/col.test.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { Col } from '.';
|
||||
|
||||
describe('<Col />', () => {
|
||||
it('should change className when props are passed', () => {
|
||||
render(
|
||||
<Col lg={8} lgOffset={2} sm={10} smOffset={1} xs={12}>
|
||||
Learn to code for free.
|
||||
</Col>
|
||||
);
|
||||
expect(screen.getByText('Learn to code for free.')).toHaveClass(
|
||||
'relative min-h-[1px] px-[15px] float-left sm:w-full md:w-[83.3%] min-[1200px]:w-[66.6%] md:ml-[8.3%] min-[1200px]:ml-[16.6%]'
|
||||
);
|
||||
});
|
||||
it('should add className to it', () => {
|
||||
render(
|
||||
<Col className='certificate-outer-wrapper'>Learn to code for free.</Col>
|
||||
);
|
||||
expect(screen.getByText('Learn to code for free.')).toHaveClass(
|
||||
'relative min-h-[1px] px-[15px] float-left certificate-outer-wrapper'
|
||||
);
|
||||
});
|
||||
});
|
||||
92
tools/ui-components/src/col/col.tsx
Normal file
92
tools/ui-components/src/col/col.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
import React from 'react';
|
||||
|
||||
import { ColProps } from './types';
|
||||
|
||||
const ExtraSmallClasses = {
|
||||
12: 'sm:w-full',
|
||||
8: 'sm:w-[66.6%]'
|
||||
};
|
||||
|
||||
const ExtraSmallOffsetClasses = {
|
||||
3: 'ml-[25%]',
|
||||
2: 'ml-[16.6%]'
|
||||
};
|
||||
|
||||
const SmallClasses = {
|
||||
12: 'md:w-full',
|
||||
10: 'md:w-[83.3%]',
|
||||
8: 'md:w-[66.6%]',
|
||||
6: 'md:w-[50%]',
|
||||
5: 'md:w-[41.6%]',
|
||||
4: 'md:w-[33.3%]',
|
||||
2: 'md:w-[16.6%]'
|
||||
};
|
||||
|
||||
const SmallOffsetClasses = {
|
||||
1: 'md:ml-[8.3%]',
|
||||
2: 'md:ml-[16.6%]',
|
||||
3: 'md:ml-[25%]',
|
||||
4: 'md:ml-[33.3%]'
|
||||
};
|
||||
|
||||
const MediumClasses = {
|
||||
10: 'min-[992px]:w-[83.3%]',
|
||||
8: 'min-[992px]:w-[66.6%]',
|
||||
6: 'min-[992px]:w-[50%]',
|
||||
4: 'min-[992px]:w-[33.3%]'
|
||||
};
|
||||
|
||||
const MediumOffsetClasses = {
|
||||
1: 'min-[992px]:ml-[8.3%]',
|
||||
2: 'min-[992px]:ml-[16.6%]',
|
||||
3: 'min-[992px]:ml-[25%]',
|
||||
4: 'min-[992px]:ml-[33.3%]'
|
||||
};
|
||||
|
||||
const LargeClasses = {
|
||||
10: 'min-[1200px]:w-[83.3%]',
|
||||
8: 'min-[1200px]:w-[66.6%]',
|
||||
6: 'min-[1200px]:w-[50%]'
|
||||
};
|
||||
|
||||
const LargeOffsetClasses = {
|
||||
0: 'min-[1200px]:ml-0',
|
||||
1: 'min-[1200px]:ml-[8.3%]',
|
||||
2: 'min-[1200px]:ml-[16.6%]'
|
||||
};
|
||||
|
||||
export const Col = ({
|
||||
className,
|
||||
children,
|
||||
xs,
|
||||
sm,
|
||||
md,
|
||||
lg,
|
||||
smPush,
|
||||
xsOffset,
|
||||
smOffset,
|
||||
mdOffset,
|
||||
lgOffset,
|
||||
...props
|
||||
}: ColProps) => {
|
||||
const xsClass = xs ? ExtraSmallClasses[xs] : '';
|
||||
const xsOffsetClass = xsOffset ? ExtraSmallOffsetClasses[xsOffset] : '';
|
||||
const smPushClass = smPush ? 'md:left-[8.3%]' : '';
|
||||
const smClass = sm ? SmallClasses[sm] : '';
|
||||
const smOffsetClass = smOffset ? SmallOffsetClasses[smOffset] : '';
|
||||
const mdClass = md ? MediumClasses[md] : '';
|
||||
const mdOffsetClass = mdOffset ? MediumOffsetClasses[mdOffset] : '';
|
||||
const lgClass = lg ? LargeClasses[lg] : '';
|
||||
const lgOffsetClass = lgOffset ? LargeOffsetClasses[lgOffset] : '';
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`relative min-h-[1px] px-[15px] float-left ${
|
||||
className ?? ''
|
||||
} ${xsClass} ${smClass} ${mdClass} ${lgClass} ${xsOffsetClass} ${smOffsetClass} ${mdOffsetClass} ${lgOffsetClass} ${smPushClass}`}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
2
tools/ui-components/src/col/index.ts
Normal file
2
tools/ui-components/src/col/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { Col } from './col';
|
||||
export type { ColProps } from './types';
|
||||
13
tools/ui-components/src/col/types.ts
Normal file
13
tools/ui-components/src/col/types.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export interface ColProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
xs?: 8 | 12;
|
||||
sm?: 2 | 4 | 5 | 6 | 8 | 10 | 12;
|
||||
md?: 4 | 6 | 8 | 10;
|
||||
lg?: 6 | 8 | 10;
|
||||
xsOffset?: 2 | 3;
|
||||
smOffset?: 1 | 2 | 3 | 4;
|
||||
mdOffset?: 1 | 2 | 3 | 4;
|
||||
lgOffset?: 0 | 1 | 2;
|
||||
smPush?: 1;
|
||||
}
|
||||
Reference in New Issue
Block a user