diff --git a/package.json b/package.json index 8e9591d0..bae8cfc3 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "styled-components": "5.2.1" }, "scripts": { - "start": "start-storybook -p 6006 -s public" + "start": "NODE_OPTIONS=--openssl-legacy-provider start-storybook -p 6006 -s public" }, "eslintConfig": { "extends": [ diff --git a/src/components/IconInput/IconInput.js b/src/components/IconInput/IconInput.js index 987d8b8a..d66fb128 100644 --- a/src/components/IconInput/IconInput.js +++ b/src/components/IconInput/IconInput.js @@ -1,19 +1,73 @@ -import React from 'react'; -import styled from 'styled-components'; - -import { COLORS } from '../../constants'; - -import Icon from '../Icon'; -import VisuallyHidden from '../VisuallyHidden'; - -const IconInput = ({ - label, - icon, - width = 250, - size, - placeholder, -}) => { - return 'TODO'; +import React from "react"; +import styled from "styled-components"; + +import { COLORS } from "../../constants"; + +import Icon from "../Icon"; +import VisuallyHidden from "../VisuallyHidden"; + +const SIZES = { + small: { + iconSize: 16 + "px", + "--textOffset": 16 + 8 + "px", + "--height": 24 + "px", + "--iconTopOffset": (24 - 16) / 2 + "px", + "--fontSize": 1 + "em", + }, + large: { + iconSize: 24 + "px", + "--textOffset": 24 + 8 + "px", + "--height": 36 + "px", + "--iconTopOffset": (36 - 24) / 2 + "px", + "--fontSize": 1.3125 + "em", + }, +}; + +const Input = styled.input` + appearance: none; + border: none; + border-bottom: 1px solid ${COLORS.black}; + width: ${(p) => p.width}px; + height: var(--height); + padding-left: var(--textOffset); + outline-offset: 2px; + + font-size: var(--fontSize); + font-weight: 700; + color: ${COLORS.gray700}; + + &::placeholder { + color: ${COLORS.gray500}; + font-weight: 400; + } +`; +const IconWrapper = styled(Icon)` + position: absolute; + left: 0; + top: var(--iconTopOffset); + pointer-events: none; + color: ${COLORS.gray700}; +`; + +const Wrapper = styled.div` + position: relative; + :hover { + ${IconWrapper}, ${Input} { + color: ${COLORS.black}; + } + } +`; +const IconInput = ({ label, icon, width = 250, size, placeholder }) => { + const styles = SIZES[size]; + return ( + <> + + {icon && } + + + {label} + + ); }; export default IconInput; diff --git a/src/components/ProgressBar/ProgressBar copy.js b/src/components/ProgressBar/ProgressBar copy.js new file mode 100644 index 00000000..96623de5 --- /dev/null +++ b/src/components/ProgressBar/ProgressBar copy.js @@ -0,0 +1,109 @@ +/* eslint-disable no-unused-vars */ +import React from 'react'; +import styled from 'styled-components'; + +import { COLORS } from '../../constants'; +import VisuallyHidden from '../VisuallyHidden'; + +const SIZES = { + small: { + "--wrapperHeight": "8px", + "--innerHeight": "8px", + "--borderRadius": "4px", + }, + medium: { + "--wrapperHeight": "12px", + "--innerHeight": "12px", + "--borderRadius": "4px", + }, + large: { + "--wrapperHeight": "24px", + "--innerHeight": "16px", + "--padding": "4px", + "--borderRadius": "8px", + }, +} + +const ProgressWrapper = styled.div` + max-width: 370px; + width: 100%; + height: var(--wrapperHeight); + color: ${COLORS.transparentGray15}; + box-shadow: inset 0px 2px 4px ${COLORS.transparentGray35}; + padding: var(--padding); + border-radius: var(--borderRadius); + background-color: ${COLORS.transparentGray15}; + ` +const ProgressInner = styled(ProgressWrapper)` + background-color: ${COLORS.primary}; + width: ${props => props.value}%; + border-radius: ${p => p.value >= 99 ? `4px` : `4px 0 0 4px`}; + height: var(--innerHeight); +` +const ProgressAlt = styled.div` + progress[value] { + appearance: none; + -webkit-appearance: none; + width: 100%; + max-width: 370px; + + ::-webkit-progress-bar { + background-color: ${COLORS.transparentGray15}; + border-radius: var(--borderRadius); + box-shadow: inset 0px 2px 4px ${COLORS.transparentGray35}; + height: var(--wrapperHeight); + padding: var(--padding); + } + ::-webkit-progress-value { + background-color: ${COLORS.primary}; + border-radius: ${p => p.value >= 99 ? `4px` : `4px 0 0 4px`}; + height: var(--innerHeight); + width: ${props => props.value}%; + } + } + ` +const ProgressAlt2 = styled.progress` + &[value] { + appearance: none; + -webkit-appearance: none; + width: 100%; + max-width: 370px; + + ::-webkit-progress-bar { + background-color: ${COLORS.transparentGray15}; + border-radius: var(--borderRadius); + box-shadow: inset 0px 2px 4px ${COLORS.transparentGray35}; + height: var(--wrapperHeight); + padding: var(--padding); + } + ::-webkit-progress-value { + background-color: ${COLORS.primary}; + border-radius: ${p => p.value >= 99 ? `4px` : `4px 0 0 4px`}; + height: var(--innerHeight); + width: ${props => props.value}%; + } + } + ` + +const ProgressBar = ({ value, size }) => { + const styles = SIZES[size]; + return <> + + Three different solutions. All work. However, the third appears to be the "simplest". + +

First solution - `div` wrapping a `div`

+ + + +

Second solution - `div` wrapping a `progress` element

+ + + +
+

A "pure" `progress` element.

+ + {value}% + ; +}; + +export default ProgressBar; diff --git a/src/components/ProgressBar/ProgressBar.js b/src/components/ProgressBar/ProgressBar.js index 29b94ba2..7ef71526 100644 --- a/src/components/ProgressBar/ProgressBar.js +++ b/src/components/ProgressBar/ProgressBar.js @@ -1,12 +1,61 @@ /* eslint-disable no-unused-vars */ -import React from 'react'; -import styled from 'styled-components'; +import React from "react"; +import styled from "styled-components"; -import { COLORS } from '../../constants'; -import VisuallyHidden from '../VisuallyHidden'; +import { COLORS } from "../../constants"; +import VisuallyHidden from "../VisuallyHidden"; + +const SIZES = { + small: { + "--height": "8px", + "--padding": "0px", + "--radius": "4px", + }, + medium: { + "--height": "12px", + "--radius": "4px", + "--padding": "0px", + }, + large: { + "--height": "16px", + "--radius": "8px", + "--padding": "4px", + }, +}; + +const Wrapper = styled.div` + background-color: ${COLORS.transparentGray15}; + border-radius: var(--radius); + padding: var(--padding); +`; +const BarWrapper = styled.div` + border-radius: 4px; + /* Hide overflow when bar is nearly full */ + overflow: hidden; +`; +const Bar = styled.div` + background-color: ${COLORS.primary}; + border-radius: 4px 0 0 4px; + height: var(--height); + width: ${(props) => props.value}%; +`; const ProgressBar = ({ value, size }) => { - return {value}; + const styles = SIZES[size]; + if (!styles) { + throw new Error(`Unknown size passed to ProgressBar: ${size}`); + } + + return ( + <> + + + + + + {value}% + + ); }; export default ProgressBar; diff --git a/src/components/Select/Select.js b/src/components/Select/Select.js index 5d96ae05..247964bb 100644 --- a/src/components/Select/Select.js +++ b/src/components/Select/Select.js @@ -5,13 +5,52 @@ import { COLORS } from '../../constants'; import Icon from '../Icon'; import { getDisplayedValue } from './Select.helpers'; + +const InternalSelect = styled.select` + appearance: none; + padding: 12px 52px 12px 16px; + + color: ${COLORS.gray700}; + &:hover { + color: ${COLORS.black}; + } + width: ${p => p.displayedValue.length * 8 + 68 - 8}px; + background-color: ${COLORS.transparentGray15}; + border-radius: 8px; + +` + +const Wrapper = styled.div` + position: relative; + color: ${COLORS.gray700}; + &:hover { + color: ${COLORS.black}; + ${InternalSelect} { + color: ${COLORS.black}; + } + } + ` +const IconWrapper = styled(Icon)` + position: absolute; + top: 8px; + left: ${p => p.displayedValue.length * 8 + 24}px; + pointer-events: none; +` + + const Select = ({ label, value, onChange, children }) => { const displayedValue = getDisplayedValue(value, children); - return ( - + + + {children} + + + ); };