From eac519d442075b991d5f283962c58cc68a0ae964 Mon Sep 17 00:00:00 2001 From: "roseb.04" Date: Thu, 27 Apr 2023 15:12:42 +0100 Subject: [PATCH] feat: new Button component Adds a new Button component to the design system. Removes old Button component and replaces with the new component and where relevant uses the NextJS Link instead. --- .storybook/preview.js | 1 + cypress/e2e/desktop/index.cy.ts | 1 + src/components/Button/Button.md | 21 ----- src/components/Button/Button.stories.tsx | 25 ----- src/components/Button/Button.tsx | 93 ------------------- src/components/Drawer/Drawer.md | 11 ++- src/components/Feedback/Feedback.tsx | 11 ++- src/components/Header/Header.tsx | 16 ++-- src/components/Header/MainMenu.tsx | 11 ++- src/components/Sidebar/Sidebar.tsx | 13 ++- src/components/ToiletDetailsPanel.tsx | 73 +++++++-------- .../components/Button/Button.css | 48 ++++++++++ .../components/Button/Button.stories.tsx | 31 +++++++ .../components/Button/Button.tsx | 35 +++++++ .../components/Button/Button.types.tsx | 14 +++ .../components/Button/index.tsx} | 0 src/design-system/components/stylesheet.css | 2 + src/pages/404.page.tsx | 7 +- src/pages/500.page.tsx | 11 +-- src/pages/_app.page.tsx | 2 +- src/pages/about.page.tsx | 89 +++++++----------- src/pages/contact.page.tsx | 9 +- src/pages/explorer/search.page.tsx | 4 +- src/pages/login.page.tsx | 23 +++-- src/pages/loos/[id]/edit.page.tsx | 21 ++--- src/pages/loos/[id]/remove.page.tsx | 6 +- src/pages/loos/add.page.tsx | 9 +- src/pages/privacy.page.tsx | 8 +- 28 files changed, 288 insertions(+), 307 deletions(-) delete mode 100644 src/components/Button/Button.md delete mode 100644 src/components/Button/Button.stories.tsx delete mode 100644 src/components/Button/Button.tsx create mode 100644 src/design-system/components/Button/Button.css create mode 100644 src/design-system/components/Button/Button.stories.tsx create mode 100644 src/design-system/components/Button/Button.tsx create mode 100644 src/design-system/components/Button/Button.types.tsx rename src/{components/Button/index.ts => design-system/components/Button/index.tsx} (100%) create mode 100644 src/design-system/components/stylesheet.css diff --git a/.storybook/preview.js b/.storybook/preview.js index 9abcbfcb0..b8aef7430 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -6,6 +6,7 @@ import { MockedProvider } from '@apollo/client/testing'; // Import design system component styles for our Stories. import '../src/design-system/components/Badge/Badge.css'; +import '../src/design-system/components/Button/Button.css'; export const parameters = { actions: { argTypesRegex: '^on[A-Z].*' }, diff --git a/cypress/e2e/desktop/index.cy.ts b/cypress/e2e/desktop/index.cy.ts index 0bc49cc28..e1a531c10 100644 --- a/cypress/e2e/desktop/index.cy.ts +++ b/cypress/e2e/desktop/index.cy.ts @@ -566,6 +566,7 @@ describe('Home page tests', () => { cy.findByText('Directions') .scrollIntoView() + .parent() .invoke('attr', 'href') .should('include', 'https://maps.apple.com/?dirflg=w&daddr='); }); diff --git a/src/components/Button/Button.md b/src/components/Button/Button.md deleted file mode 100644 index a8274fa33..000000000 --- a/src/components/Button/Button.md +++ /dev/null @@ -1,21 +0,0 @@ -### Primary - -```jsx - -``` - -### Secondary - -```jsx - -``` - -### Link - -The most common use can would be combine the `link` variant with `as="a"` to render the component as an anchor element. - -```jsx - -``` diff --git a/src/components/Button/Button.stories.tsx b/src/components/Button/Button.stories.tsx deleted file mode 100644 index eeca2db18..000000000 --- a/src/components/Button/Button.stories.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { Meta } from '@storybook/react'; -import { default as ButtonComponent } from '.'; - -export default { - name: 'Button', - component: ButtonComponent, -} as Meta; - -export const Default = (props) => ( - - Click me! - -); - -export const Secondary = (props) => ( - - Click me! - -); - -export const Tertiary = (props) => ( - - Click me! - -); diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx deleted file mode 100644 index f8b884be0..000000000 --- a/src/components/Button/Button.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import React from 'react'; -import styled from '@emotion/styled'; -import { variant } from 'styled-system'; - -import Box from '../Box'; -import Text from '../Text'; - -const BUTTON_HEIGHT = 34; - -const StyledButton = styled.button( - (props) => - ` - display: inline-flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - user-select: none; - min-height: ${BUTTON_HEIGHT}px; - max-width: 300px; - border-radius: ${BUTTON_HEIGHT / 2}px; - border: none; - padding: 0 ${props.theme.space[3]}px; - border-style: solid; - border-width: 2px; - color: ${props.theme.colors.primary}; - box-sizing: border-box; - - &:disabled { - border-color: ${props.theme.colors.lightGrey}; - background-color: ${props.theme.colors.lightGrey}; - } - - &:disabled:hover { - color: ${props.theme.colors.primary}; - } - `, - variant({ - variants: { - primary: { - color: 'primary', - fontWeight: 'bold', - bg: 'secondary', - borderColor: 'secondary', - ':not(:disabled):hover, :not(:disabled):focus': { - color: 'aqua', - bg: 'primary', - borderColor: 'primary', - }, - }, - secondary: { - color: 'primary', - bg: 'white', - fontWeight: 'bold', - borderColor: 'primary', - ':not(:disabled):hover, :not(:disabled):focus': { - color: 'white', - bg: 'primary', - borderColor: 'primary', - }, - }, - link: { - color: 'primary', - border: 'none', - background: 'none', - textDecoration: 'underline', - fontWeight: 'normal', - padding: 0, - minHeight: 0, - }, - }, - }) -); - -const ButtonIcon = ({ icon }) => { - return {icon}; -}; - -const Button = ({ children, icon, ...props }) => ( - - {Boolean(icon) && } - - {children} - -); - -// eslint-disable-next-line functional/immutable-data -Button.defaultProps = { - variant: 'primary', - as: 'button', -}; - -/** @component */ -export default StyledButton; diff --git a/src/components/Drawer/Drawer.md b/src/components/Drawer/Drawer.md index d22abbee8..6b8a3939d 100644 --- a/src/components/Drawer/Drawer.md +++ b/src/components/Drawer/Drawer.md @@ -1,11 +1,18 @@ ```jsx -import Button from '../Button'; +import Button from '../../design-system/components/Button'; import Spacer from '../Spacer'; const [isVisible, setIsVisible] = React.useState(false); <> - +

Drawer content here!

diff --git a/src/components/Feedback/Feedback.tsx b/src/components/Feedback/Feedback.tsx index 7896b49bb..53a3ffa65 100644 --- a/src/components/Feedback/Feedback.tsx +++ b/src/components/Feedback/Feedback.tsx @@ -1,6 +1,6 @@ import { Stack } from '@mui/material'; import React, { useRef, useState } from 'react'; -import Button from '../Button'; +import Button from '../../design-system/components/Button'; import Box from '../Box'; import Badge from '../../design-system/components/Badge'; @@ -60,7 +60,14 @@ const Feedback = () => { We'd be so grateful if you could take a moment to give us feedback on how we could make your experience even better.`} /> - + ); }; diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index f770c580b..c1db4472b 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -1,5 +1,6 @@ import React, { useCallback, useState } from 'react'; import { faBars, faComments } from '@fortawesome/free-solid-svg-icons'; +import Link from 'next/link'; import Box from '../Box'; import VisuallyHidden from '../VisuallyHidden'; @@ -10,7 +11,6 @@ import Logo from '../Logo'; import MainMenu from './MainMenu'; import { useMapState } from '../MapState'; import { useRouter } from 'next/router'; -import Button from '../Button'; import dynamic from 'next/dynamic'; import { useFeedbackPopover } from './hooks'; @@ -43,14 +43,14 @@ const Header = ({ children }) => { minHeight={'60px'} > - + @@ -59,16 +59,12 @@ const Header = ({ children }) => { - + @@ -86,7 +89,9 @@ const MainMenu = ({ children }: IMainMenu) => { diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx index 7002e70fb..2972426bc 100644 --- a/src/components/Sidebar/Sidebar.tsx +++ b/src/components/Sidebar/Sidebar.tsx @@ -17,7 +17,7 @@ import Text from '../Text'; import Icon from '../Icon'; import LocationSearch from '../LocationSearch'; import Filters from '../Filters'; -import Button from '../Button'; +import Button from '../../design-system/components/Button'; import { useMapState } from '../MapState'; import config from '../../config'; import { usePlausible } from 'next-plausible'; @@ -117,9 +117,9 @@ const Sidebar = () => { - + + Directions + ); const openingTimes = data.openingTimes || WEEKDAYS.map(() => null); @@ -221,6 +213,8 @@ const ToiletDetailsPanel: React.FC = ({ No? - - - + @@ -442,10 +435,8 @@ const ToiletDetailsPanel: React.FC = ({ Hours may vary with national holidays or seasonal changes. If you know these hours to be out of date please{' '} - - + + edit this toilet . @@ -464,9 +455,7 @@ const ToiletDetailsPanel: React.FC = ({ padding={2} marginBottom={2} > - + Back to top @@ -523,23 +512,27 @@ const ToiletDetailsPanel: React.FC = ({ {getDirectionsFragment} diff --git a/src/design-system/components/Button/Button.css b/src/design-system/components/Button/Button.css new file mode 100644 index 000000000..4c56b3d72 --- /dev/null +++ b/src/design-system/components/Button/Button.css @@ -0,0 +1,48 @@ +.button { + display: inline-flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + user-select: none; + min-height: 34px; + max-width: 300px; + border-radius: 17px; + padding: 0 var(--space-s); + border-style: solid; + border-width: 2px; + border-color: var(--color-turquoise); + color: var(--color-blue); + font-weight: bold; + background-color: var(--color-turquoise); +} + +.button > * + * { + margin-left: var(--space-2xs); +} + +.button:disabled { + border-color: var(--color-light-grey); + background-color: var(--color-light-grey); +} + +.button:disabled:hover { + color: var(--color-blue); + cursor: not-allowed; +} + +.button:not(:disabled):hover, +.button:not(:disabled):focus { + color: var(--color-turquoise); + background-color: var(--color-blue); + border-color: var(--color-blue); +} + +.button--secondary { + background-color: var(--color-white); + border-color: var(--color-blue); +} + +.button--secondary:not(:disabled):hover, +.button--secondary:not(:disabled):focus { + color: var(--color-white); +} diff --git a/src/design-system/components/Button/Button.stories.tsx b/src/design-system/components/Button/Button.stories.tsx new file mode 100644 index 000000000..e4dfe734d --- /dev/null +++ b/src/design-system/components/Button/Button.stories.tsx @@ -0,0 +1,31 @@ +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import Button from './Button'; + +export default { + title: 'Design-System/Button', + component: Button, + argTypes: { + children: { table: { disable: true } }, + variant: { table: { disable: true } }, + }, + args: { href: 'www.google.com' }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => + ); +}); + +Button.displayName = 'Button'; + +export default Button; diff --git a/src/design-system/components/Button/Button.types.tsx b/src/design-system/components/Button/Button.types.tsx new file mode 100644 index 000000000..1f1fd8f03 --- /dev/null +++ b/src/design-system/components/Button/Button.types.tsx @@ -0,0 +1,14 @@ +interface Button extends React.ButtonHTMLAttributes { + htmlElement: 'button'; + variant: 'primary' | 'secondary'; + children: React.ReactNode; +} + +interface Link extends React.AnchorHTMLAttributes { + htmlElement: 'a'; + variant: 'primary' | 'secondary'; + children: React.ReactNode; + href: string; +} + +export type ButtonProps = Link | Button; diff --git a/src/components/Button/index.ts b/src/design-system/components/Button/index.tsx similarity index 100% rename from src/components/Button/index.ts rename to src/design-system/components/Button/index.tsx diff --git a/src/design-system/components/stylesheet.css b/src/design-system/components/stylesheet.css new file mode 100644 index 000000000..f5105cac9 --- /dev/null +++ b/src/design-system/components/stylesheet.css @@ -0,0 +1,2 @@ +@import 'src/design-system/components/Badge/Badge.css'; +@import 'src/design-system/components/Button/Button.css'; diff --git a/src/pages/404.page.tsx b/src/pages/404.page.tsx index 34cc09a69..d3734928e 100644 --- a/src/pages/404.page.tsx +++ b/src/pages/404.page.tsx @@ -1,8 +1,9 @@ import React from 'react'; +import Link from 'next/link'; + import Box from '../components/Box'; import Spacer from '../components/Spacer'; import Text from '../components/Text'; -import Button from '../components/Button'; const NotFound = ({ children }) => ( <> @@ -31,9 +32,7 @@ const NotFound = ({ children }) => ( - + Take me back home! diff --git a/src/pages/500.page.tsx b/src/pages/500.page.tsx index 9887d1717..44ddf2a51 100644 --- a/src/pages/500.page.tsx +++ b/src/pages/500.page.tsx @@ -1,8 +1,9 @@ import React from 'react'; +import Link from 'next/link'; + import Box from '../components/Box'; import Spacer from '../components/Spacer'; import Text from '../components/Text'; -import Button from '../components/Button'; const ThereWasAProblem = ({ children }) => ( <> @@ -27,17 +28,15 @@ const ThereWasAProblem = ({ children }) => (

Please try again later or, if the problem persists, please contact us at{' '} - + .

- + Take me back home! diff --git a/src/pages/_app.page.tsx b/src/pages/_app.page.tsx index f303ed753..ef054b014 100644 --- a/src/pages/_app.page.tsx +++ b/src/pages/_app.page.tsx @@ -9,7 +9,7 @@ import '@fortawesome/fontawesome-svg-core/styles.css'; config.autoAddCss = false; // Tell Font Awesome to skip adding the CSS automatically since it's being imported above import { useRouter } from 'next/router'; import LooMap from '../components/LooMap/LooMapLoader'; -import '../design-system/components/Badge/Badge.css'; +import '../design-system/components/stylesheet.css'; const App = (props) => { const router = useRouter(); diff --git a/src/pages/about.page.tsx b/src/pages/about.page.tsx index eaea0f63e..d97bdf0f7 100644 --- a/src/pages/about.page.tsx +++ b/src/pages/about.page.tsx @@ -3,7 +3,7 @@ import Link from 'next/link'; import Head from 'next/head'; import styled from '@emotion/styled'; import Container from '../components/Container'; -import Button from '../components/Button'; +import Button from '../design-system/components/Button'; import Text, { TextProps } from '../components/Text'; import Spacer from '../components/Spacer'; import Box, { BoxProps } from '../components/Box'; @@ -56,34 +56,25 @@ const AboutPage = () => { joint venture between researchers Dr Jo-Anne Bichard and Gail Ramster (who created the map at the RCA Helen Hamlyn Centre for Design) and software development company{' '} - - + + Neontribe {' '} (who designed and built it).

The information comes from the public - anyone can go on the website - and{' '} - - - - . We also use open data and request information from councils,{' '} - - + and add, edit or remove toilets. We also use + open data and request information from councils,{' '} + + OpenStreetMap , private companies and organisations.

@@ -94,20 +85,15 @@ const AboutPage = () => { to download below.

- - - + Download volunteer help guide +

A handy printable checklist designed to make it easier for you to @@ -115,16 +101,15 @@ const AboutPage = () => { also available for download.

- - - + Publicly Accessible Toilets

The project aims to map all publicly-accessible toilets - that means @@ -163,19 +148,13 @@ const AboutPage = () => {

If you have any problems updating the toilets, or wish to send us toilet details or comments, please contact{' '} - - - + gbtoiletmap@gmail.com .

The Explorer

- - + + Visit the Explorer  to get an overview of the statistics and details related to the Toilet Map. These statistics are calculated on-demand, so will be up diff --git a/src/pages/contact.page.tsx b/src/pages/contact.page.tsx index 54808a76a..030f82cc3 100644 --- a/src/pages/contact.page.tsx +++ b/src/pages/contact.page.tsx @@ -1,11 +1,12 @@ import Head from 'next/head'; +import Link from 'next/link'; +import { NextPage } from 'next'; + import Container from '../components/Container'; -import Button from '../components/Button'; import Text from '../components/Text'; import Spacer from '../components/Spacer'; import Box from '../components/Box'; import config from '../config'; -import { NextPage } from 'next'; const ContactPage = () => { return ( @@ -22,9 +23,7 @@ const ContactPage = () => {

If you have any problems updating the toilets, or wish to send us toilet details or comments, please contact{' '} - + gbtoiletmap@gmail.com .

diff --git a/src/pages/explorer/search.page.tsx b/src/pages/explorer/search.page.tsx index 049f22860..1ad247130 100644 --- a/src/pages/explorer/search.page.tsx +++ b/src/pages/explorer/search.page.tsx @@ -12,7 +12,7 @@ import Spacer from '../../components/Spacer'; import Box from '../../components/Box'; import styled from '@emotion/styled'; import { useRouter } from 'next/router'; -import Button from '../../components/Button'; +import Button from '../../design-system/components/Button'; import { css } from '@emotion/react'; import theme from '../../theme'; import Link from 'next/link'; @@ -246,7 +246,7 @@ const UnstyledTable = () => { } > - diff --git a/src/pages/login.page.tsx b/src/pages/login.page.tsx index 806fe22ca..f2a5d9526 100644 --- a/src/pages/login.page.tsx +++ b/src/pages/login.page.tsx @@ -1,14 +1,15 @@ import Head from 'next/head'; import { useRouter } from 'next/router'; import styled from '@emotion/styled'; +import Link from 'next/link'; + import Container from '../components/Container'; -import Button from '../components/Button'; +import Button from '../design-system/components/Button'; import Text from '../components/Text'; import Spacer from '../components/Spacer'; import Box, { BoxProps } from '../components/Box'; import config from '../config'; -import Link from 'next/link'; const List = styled.ul` list-style: initial; @@ -40,14 +41,14 @@ const LoginPage = () => { Up:

- - - + > + Log In/Sign Up +

Examples of Public toilets

@@ -91,9 +92,7 @@ const LoginPage = () => {

If you have any problems updating the toilets, or wish to send us toilet details or comments, please contact{' '} - + gbtoiletmap@gmail.com .

diff --git a/src/pages/loos/[id]/edit.page.tsx b/src/pages/loos/[id]/edit.page.tsx index 35178c03f..5a50412ff 100644 --- a/src/pages/loos/[id]/edit.page.tsx +++ b/src/pages/loos/[id]/edit.page.tsx @@ -1,10 +1,10 @@ import React from 'react'; - import Head from 'next/head'; -import Link from 'next/link'; - import { useUser } from '@auth0/nextjs-auth0'; -import Button from '../../../components/Button'; +import { useEffect } from 'react'; +import { css } from '@emotion/react'; + +import Button from '../../../design-system/components/Button'; import Spacer from '../../../components/Spacer'; import EntryForm from '../../../components/EntryForm'; import Box from '../../../components/Box'; @@ -22,9 +22,7 @@ import { UpdateLooMutationVariables, useUpdateLooMutation, } from '../../../api-client/graphql'; -import { useEffect } from 'react'; import LocationSearch from '../../../components/LocationSearch'; -import { css } from '@emotion/react'; import NotFound from '../../404.page'; const EditPage: PageFindLooByIdComp | React.FC<{ notFound?: boolean }> = ( @@ -158,10 +156,9 @@ const EditPage: PageFindLooByIdComp | React.FC<{ notFound?: boolean }> = ( > + {loadingRemove && ( diff --git a/src/pages/loos/add.page.tsx b/src/pages/loos/add.page.tsx index b5ec55e3a..5d62d8645 100644 --- a/src/pages/loos/add.page.tsx +++ b/src/pages/loos/add.page.tsx @@ -5,7 +5,7 @@ import { useUser } from '@auth0/nextjs-auth0'; import EntryForm from '../../components/EntryForm'; import Box from '../../components/Box'; import Spacer from '../../components/Spacer'; -import Button from '../../components/Button'; +import Button from '../../design-system/components/Button'; import LocationSearch from '../../components/LocationSearch'; import Login from '../login.page'; @@ -119,7 +119,12 @@ const AddPage = () => { onSubmit={saveLoo} > - diff --git a/src/pages/privacy.page.tsx b/src/pages/privacy.page.tsx index b8e9fac07..14dfc3557 100644 --- a/src/pages/privacy.page.tsx +++ b/src/pages/privacy.page.tsx @@ -1,9 +1,9 @@ import Head from 'next/head'; +import Link from 'next/link'; import Container from '../components/Container'; import Text from '../components/Text'; import Spacer from '../components/Spacer'; -import Button from '../components/Button'; import Box from '../components/Box'; import config from '../config'; @@ -72,15 +72,13 @@ const PrivacyPage = () => { If you'd like to know what we've stored about you, or ask us to forget you, or to let us know about something you'd like changed please drop us a line at{' '} - + . If you'd like to exercise any of your rights under the GDPR that's the address to use.