Skip to content

Commit

Permalink
✨ Create colour block component (#30)
Browse files Browse the repository at this point in the history
Co-authored-by: Rohan Gupta <rohan.gupta@gameskraft.com>
Co-authored-by: restyled-io[bot] <32688539+restyled-io[bot]@users.noreply.github.com>
Co-authored-by: Restyled.io <commits@restyled.io>
  • Loading branch information
4 people authored Oct 18, 2022
1 parent fc2bba7 commit 1e68b66
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 42 deletions.
5 changes: 2 additions & 3 deletions src/components/Navbar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ Style this navigation bar as follows:
vertical padding equal to their font size and horizontal padding equal to their font size multiplied by 1.5;
their font size should be 16px.
- Hovering over a list item should change its background color to #1E87B5 and the mouse cursor to a pointer.
- There should be a solid, #F4F5F6, 2px border
separating the list items. However this border shouldn't appear on the right side of Pricing or on the left
side of Team.
- There should be a solid, #F4F5F6, 2px border separating the list items. However this border shouldn't
appear on the right side of Pricing or on the left side of Team.
- The individual list items shouldn't have bullet points next to them.
16 changes: 9 additions & 7 deletions src/components/Navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { COLORS, PROJECT_COLORS } from '../../constants/theme';
import ProjectPage from '../ProjectPage';
import QuestionDetails from '../QuestionDetails';
import ColourBlock from '../UI/ColourBlock';
import classes from './styles.module.scss';

const Navbar: React.FC<Props> = () => {
Expand Down Expand Up @@ -39,8 +40,10 @@ const Navbar: React.FC<Props> = () => {
</li>
<li>
The navigation bar should have a background color of #265EF7
<span className={classes.questionPointBox} style={{ backgroundColor: '#265EF7' }}></span>and a white
<span className={classes.questionPointBox} style={{ backgroundColor: `${COLORS.WHITE}` }}></span>font color.
<ColourBlock colour='#265EF7' />
and a white
<ColourBlock colour={COLORS.WHITE} />
font color.
</li>
<li>
The unordered lists should have no margin or padding. However, the individual list items should have
Expand All @@ -49,14 +52,13 @@ const Navbar: React.FC<Props> = () => {
</li>
<li>
Hovering over a list item should change its background color to #1E87B5
<span className={classes.questionPointBox} style={{ backgroundColor: '#1E87B5' }}></span>and the mouse
cursor to a pointer.
<ColourBlock colour='#1E87B5' />
and the mouse cursor to a pointer.
</li>
<li>
There should be a solid, #F4F5F6
<span className={classes.questionPointBox} style={{ backgroundColor: '#F4F5F6' }}></span>, 2px border
separating the list items. However this border shouldn't appear on the right side of Pricing or on the left
side of Team.
<ColourBlock colour={COLORS.LIGHT} />, 2px border separating the list items. However this border shouldn't
appear on the right side of Pricing or on the left side of Team.
</li>
<li>The individual list items shouldn't have bullet points next to them.</li>
</ul>
Expand Down
6 changes: 0 additions & 6 deletions src/components/Navbar/styles.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,4 @@
@include spacing ($margin: 0.5rem 0);
}
}

.questionPointBox {
@include circle (0.75rem);
@include spacing ($margin: 0 0.5rem 0 0.25rem);
display: inline-block;
}
}
13 changes: 7 additions & 6 deletions src/components/RainbowCircles/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { PROJECT_COLORS } from '../../constants/theme';
import ProjectPage from '../ProjectPage';
import QuestionDetails from '../QuestionDetails';
import ColourBlock from '../UI/ColourBlock';
import classes from './styles.module.scss';

const RainbowCircles: React.FC<Props> = () => {
Expand All @@ -21,37 +22,37 @@ const RainbowCircles: React.FC<Props> = () => {
<li className={classes.questionPoint}>
<div className={classes.questionPointWrapper}>
300px by 300px, #ff0000
<span className={classes.questionPointBox} style={{ backgroundColor: '#ff0000' }}></span>
<ColourBlock colour='#FF0000' />
</div>
</li>
<li className={classes.questionPoint}>
<div className={classes.questionPointWrapper}>
250px by 250px, #ffa500
<span className={classes.questionPointBox} style={{ backgroundColor: '#ffa500' }}></span>
<ColourBlock colour='#FFA500' />
</div>
</li>
<li className={classes.questionPoint}>
<div className={classes.questionPointWrapper}>
200px by 200px, #ffff00
<span className={classes.questionPointBox} style={{ backgroundColor: '#fff000' }}></span>
<ColourBlock colour='#FFFF00' />
</div>
</li>
<li className={classes.questionPoint}>
<div className={classes.questionPointWrapper}>
150px by 150px, #008000
<span className={classes.questionPointBox} style={{ backgroundColor: '#008000' }}></span>
<ColourBlock colour='#008000' />
</div>
</li>
<li className={classes.questionPoint}>
<div className={classes.questionPointWrapper}>
100px by 100px, #0000ff
<span className={classes.questionPointBox} style={{ backgroundColor: '#0000ff' }}></span>
<ColourBlock colour='#0000FF' />
</div>
</li>
<li className={classes.questionPoint}>
<div className={classes.questionPointWrapper}>
50px by 50px, #800080
<span className={classes.questionPointBox} style={{ backgroundColor: '#800080' }}></span>
<ColourBlock colour='#800080' />
</div>
</li>
</ul>
Expand Down
5 changes: 0 additions & 5 deletions src/components/RainbowCircles/styles.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@
display: flex;
align-items: center;
gap: 0.35rem;

.questionPointBox {
@include circle (0.8rem);
display: inline-block;
}
}

.circlesContainer {
Expand Down
21 changes: 21 additions & 0 deletions src/components/UI/ColourBlock/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { useCallback } from 'react';
import { copyTextToClipboard } from '../../../utils';
import classes from './styles.module.scss';

const ColourBlock: React.FC<ColourBlockProps> = (props) => {
const { colour, className = '', style = {} } = props;

const handleBlockClick = useCallback(() => {
copyTextToClipboard(colour);
}, [colour]);

return (
<span
className={`${classes.colourBlock} ${className}`}
style={{ ...style, backgroundColor: colour }}
onClick={handleBlockClick}
/>
);
};

export default ColourBlock;
11 changes: 11 additions & 0 deletions src/components/UI/ColourBlock/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@import '../../../utils/mixins.scss';

.colourBlock {
@include circle (0.7rem);
@include spacing ($margin: 0 0.5rem 0 0.25rem);
display: inline-block;

&:hover {
cursor: pointer;
}
}
6 changes: 6 additions & 0 deletions src/types/props.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,9 @@ interface QuestionDetailsProps extends Props {
descriptionStyle?: React.CSSProperties;
descriptionClassName?: string;
}

interface ColourBlockProps {
colour: string;
className?: string;
style?: React.CSSProperties;
}
38 changes: 23 additions & 15 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
* @returns `boolean` indicating whether `value` is an empty string
*
*/
export const isEmptyString = <T>(value: string | T): boolean =>
typeof value !== 'string' || !value?.trim()?.length;
export const isEmptyString = <T>(value: string | T): boolean => typeof value !== 'string' || !value?.trim()?.length;

/**
*
Expand All @@ -16,9 +15,7 @@ export const isEmptyString = <T>(value: string | T): boolean =>
*
*/
export const isValidNumber = <T>(value: number | string | T): boolean =>
['number', 'string'].includes(typeof value) &&
value !== '' &&
!isNaN(Number(value));
['number', 'string'].includes(typeof value) && value !== '' && !isNaN(Number(value));

/**
*
Expand All @@ -38,10 +35,7 @@ export const isEmptyList = <T>(obj: Array<T> | T): boolean =>
*
*/
export const isEmptyObject = <T>(obj: Object | T): boolean =>
!obj ||
typeof obj !== 'object' ||
Array.isArray(obj) ||
Object.keys(obj).length === 0;
!obj || typeof obj !== 'object' || Array.isArray(obj) || Object.keys(obj).length === 0;

/**
*
Expand All @@ -51,12 +45,8 @@ export const isEmptyObject = <T>(obj: Object | T): boolean =>
* @returns truncated `value` if its length is greater than or equal to `length`
*
*/
export const truncateStringToLength = (
value: string,
length: number
): string => {
if (isEmptyString(value) || !isValidNumber(length) || length <= 0)
return value;
export const truncateStringToLength = (value: string, length: number): string => {
if (isEmptyString(value) || !isValidNumber(length) || length <= 0) return value;
return value?.length <= length ? value : `${value?.substring(0, length)}...`;
};

Expand All @@ -70,3 +60,21 @@ export const truncateStringToLength = (
*/
export const createListOfSize = (size: number, start: number = 1): number[] =>
size > 0 ? Array.from(Array(size)).map(() => start++) : [];

/**
*
* @function copyTextToClipboard - Copies `text` to the clipboard
* @param {string} text - specifies the text to be copied
* @returns promise of a boolean value depicting whether the copy was successful
*
*/
export const copyTextToClipboard = async (text: string = ''): Promise<boolean> => {
if (isEmptyString(text)) return false;

try {
await navigator.clipboard.writeText(text);
return true;
} catch (err) {
return false;
}
};
20 changes: 20 additions & 0 deletions src/utils/tests/copyTextToClipboard.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { copyTextToClipboard } from '..';

test('copyTextToClipboard with an empty string', async () => {
const isTextCopied = await copyTextToClipboard('');
expect(isTextCopied).toBeFalsy();
});

test('copyTextToClipboard with a non-empty string', async () => {
try {
const text = 'hello world';
const isTextCopied = await copyTextToClipboard(text);
if (isTextCopied) {
expect(isTextCopied).toBeTruthy();
} else {
expect(isTextCopied).toBeFalsy();
}
} catch (err) {
expect(err).toMatch('error');
}
});

0 comments on commit 1e68b66

Please sign in to comment.