Skip to content

Commit

Permalink
Merge branch 'rebrand' into 463/rebrand-proposal-details
Browse files Browse the repository at this point in the history
  • Loading branch information
peterjurco committed Dec 5, 2024
2 parents 0548feb + 887c6bf commit a75ac8e
Show file tree
Hide file tree
Showing 30 changed files with 699 additions and 256 deletions.
31 changes: 23 additions & 8 deletions cypress/e2e/footer.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,35 @@ import { HOME_PAGE } from '../support/common';
it('renders footer and error reporting', () => {
cy.visit(HOME_PAGE).dataCy('error-reporting').should('exist');

// Disallow error reporting
cy.dataCy('error-reporting').find('input').click();
cy.findByText('Done').click();
// Enable error report and analytics
cy.dataCy('error-reporting')
.findByRole('button', { name: /accept all/i })
.click();
cy.dataCy('error-reporting')
.should('not.exist')
.should(() => {
expect(localStorage.getItem('reportErrors')).to.equal('false');
.then(() => {
expect(localStorage.getItem('allow-error-reporting')).to.equal('true');
expect(localStorage.getItem('allow-analytics')).to.equal('true');
});

// On subsequent page visit there is no notice
cy.reload().should(() => {
expect(localStorage.getItem('reportErrors')).to.equal('false');
// On subsequent page visit the error reporting notice should not be shown
cy.reload().then(() => {
expect(cy.dataCy('error-reporting').should('not.exist'));
});

// Open the privacy settings modal from the footer and disable error reporting and analytics
cy.findByRole('button', { name: /error reporting/i }).click();
cy.findByRole('button', { name: /manage settings/i }).click();
cy.findByRole('checkbox', { name: /allow error reporting/i }).click();
cy.findByRole('checkbox', { name: /allow analytics cookies/i }).click();
cy.findByRole('button', { name: /save settings/i }).click();
cy.dataCy('error-reporting')
.should('not.exist')
.then(() => {
expect(localStorage.getItem('allow-error-reporting')).to.equal('false');
expect(localStorage.getItem('allow-analytics')).to.equal('false');
});

// Footer links should open the pages they link to in a new tab
cy.findByText('Github').should('have.attr', 'target', '_blank');
});
6 changes: 4 additions & 2 deletions cypress/support/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ export const abbrStr = (str: string) => {
export const EPOCH_LENGTH = 7 * 60 * 60 * 24; // in seconds

export const closeErrorReportingNotice = () => {
cy.dataCy('error-reporting').findByText('Done').click();
cy.findByText('Done').should('not.exist');
cy.dataCy('error-reporting')
.findByRole('button', { name: /accept all/i })
.click();
cy.dataCy('error-reporting').should('not.exist');
};

export const HOME_PAGE = 'http://localhost:3000/#/';
5 changes: 0 additions & 5 deletions public/api-icon.svg

This file was deleted.

5 changes: 5 additions & 0 deletions src/components/button/button.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
@import './variants/secondary-neutral.module.scss';
@import './variants/tertiary-color.module.scss';
@import './variants/link-blue.module.scss';
@import './variants/link-gray.module.scss';
@import './variants/menu-link-secondary.module.scss';
@import './variants/text-blue.module.scss';

Expand Down Expand Up @@ -43,6 +44,10 @@
@include link-blue;
}

&.link-gray {
@include link-gray;
}

&.menu-link-secondary {
@include menu-link-secondary;
}
Expand Down
3 changes: 2 additions & 1 deletion src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export interface Props extends BreakpointsProps {
| 'text'
| 'text-blue'
| 'menu-link-secondary'
| 'link-blue';
| 'link-blue'
| 'link-gray';
size?: Size;
disabled?: boolean;
href?: string;
Expand Down
36 changes: 36 additions & 0 deletions src/components/button/variants/link-gray.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@import '../../../styles/fonts.module.scss';

@mixin link-gray {
color: $color-gray-700;
height: 20px;
border: none;

&.xs {
@include font-overline-2;
}

&.sm {
@include font-link-3;
}

&.md {
@include font-link-2;
}

&.lg {
height: 24px;
@include font-link-1;
}

&:hover {
color: $color-green-800;
}

&:active {
color: $color-green-700;
}

&:disabled {
color: $color-gray-400;
}
}
123 changes: 123 additions & 0 deletions src/components/checkbox/checkbox.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
@import '../../styles/variables.module.scss';
@import '../../styles/fonts.module.scss';

.checkbox {
display: flex;
align-items: flex-start;
gap: 8px;

&,
* {
cursor: pointer;
transition: all 0.1s;
}

.checkmark {
display: flex;
align-items: center;
justify-content: center;
min-height: 16px;
min-width: 16px;
height: 16px;
width: 16px;
background-color: $color-gray-50;
border: 1px solid $color-dark-blue-50;
border-radius: 2px;
margin-top: 2px;

svg {
margin: auto;
width: 12px;
height: 12px;
color: $color-gray-50;
}
}

.checkboxTextBlock {
display: flex;
flex-direction: column;
@include font-body-12;

label {
color: $color-dark-blue-800;
}

.description {
color: $color-gray-500;
}
}

&[aria-checked='true'] {
.checkmark {
background-color: $color-dark-blue-400;
border-color: $color-gray-50;
}
}

&:hover:not([aria-disabled='true']) {
.checkmark {
background-color: $color-base-light;
border-color: $color-dark-blue-400;

svg {
color: $color-dark-blue-400;
}
}

.checkboxTextBlock {
label {
color: $color-gray-900;
}

.description {
color: $color-gray-600;
}
}
}

&[aria-disabled='true'] {
pointer-events: none;

.checkmark {
background-color: transparent;
border-color: $color-gray-200;

svg {
color: $color-gray-200;
}
}

.checkboxTextBlock {
label {
color: $color-gray-400;
}

.description {
color: $color-gray-200;
}
}
}
}

@media (min-width: $sm) {
.checkbox {
gap: 12px;

.checkmark {
min-height: 20px;
min-width: 20px;
height: 20px;
width: 20px;
margin-top: 2px;

svg {
width: 16px;
height: 16px;
}
}

.checkboxTextBlock {
@include font-body-9;
}
}
}
44 changes: 44 additions & 0 deletions src/components/checkbox/checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { KeyboardEvent, ReactNode } from 'react';
import { CheckIcon } from '../icons';
import styles from './checkbox.module.scss';

interface Props {
label?: string;
checked: boolean;
children?: ReactNode;
disabled?: boolean;
onChange: (checked: boolean) => void;
}

const CheckBox = ({ label, checked, children, disabled, onChange }: Props) => {
const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
onChange(!checked);
}
};

return (
<div
id={label}
className={styles.checkbox}
tabIndex={0}
role="checkbox"
aria-checked={checked}
aria-disabled={disabled}
onClick={() => {
onChange(!checked);
}}
onKeyDown={handleKeyDown}
>
<span className={styles.checkmark}>{checked && <CheckIcon />}</span>

<div className={styles.checkboxTextBlock}>
<label htmlFor={label}>{label}</label>
{children && <div className={styles.description}>{children}</div>}
</div>
</div>
);
};

export default CheckBox;
2 changes: 2 additions & 0 deletions src/components/checkbox/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './checkbox';
export * from './checkbox';
31 changes: 18 additions & 13 deletions src/components/external-link/external-link.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
import { ReactNode, useEffect } from 'react';
import { ComponentPropsWithoutRef, useEffect } from 'react';

interface Props {
className?: string;
interface Props extends Omit<ComponentPropsWithoutRef<'a'>, 'target' | 'rel'> {
href: string;
children: ReactNode;
}

const ExternalLink = (props: Props) => {
const { className, children } = props;
const { children, href: incomingHref, ...rest } = props;

let href = props.href.trim();
const urlRegex = /^https?:\/\//i; // Starts with https:// or http:// (case insensitive)
if (!urlRegex.test(href)) {
href = 'about:blank';
}
const href = cleanHref(incomingHref);

useEffect(() => {
if (process.env.NODE_ENV === 'development' && href === 'about:blank') {
// eslint-disable-next-line no-console
console.warn(`An invalid URL has been provided: "${props.href}". Only https:// or http:// URLs are allowed.`);
console.warn(`An invalid URL has been provided: "${incomingHref}". Only https:// or http:// URLs are allowed.`);
}
}, [href, props.href]);
}, [href, incomingHref]);

return (
<a href={href} className={className} target="_blank" rel="noopener noreferrer">
<a target="_blank" rel="noopener noreferrer" href={href} {...rest}>
{children}
</a>
);
};

const cleanHref = (href: string) => {
const urlRegex = /^https?:\/\//i; // Starts with https:// or http:// (case insensitive)
const trimmedHref = href.trim();

if (!urlRegex.test(trimmedHref)) {
return 'about:blank';
}

return trimmedHref;
};

export default ExternalLink;
15 changes: 15 additions & 0 deletions src/components/icons/check.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ComponentProps } from 'react';

export const CheckIcon = (props: ComponentProps<'svg'>) => {
return (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<path
d="M13 4.25L6.125 11.125L3 8"
stroke="currentColor"
strokeWidth="1.25"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
2 changes: 2 additions & 0 deletions src/components/icons/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CheckCircleIcon } from './check-circle';
import { CheckCircleFillIcon } from './check-circle-fill';
import { CheckboxRadioIcon } from './checkbox-radio';
import { CheckIcon } from './check';
import { CloseIcon } from './close';
import { CrossIcon } from './cross';
import { ErrorCircleIcon } from './error-circle';
Expand All @@ -11,6 +12,7 @@ import { InfoCircleIcon } from './info-circle';
export {
CheckCircleIcon,
CheckCircleFillIcon,
CheckIcon,
CheckboxRadioIcon,
CloseIcon,
CrossIcon,
Expand Down
Loading

0 comments on commit a75ac8e

Please sign in to comment.