From 487cdb0e4c83041ea1ea5d3fa63b7a5d73b5cbb3 Mon Sep 17 00:00:00 2001 From: Anya Stasiuk Date: Tue, 2 Jun 2020 16:27:00 +0300 Subject: [PATCH 01/10] fix: fix contrast ratio for response titles --- src/theme.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/theme.ts b/src/theme.ts index f6554cb051..6679f9d521 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -20,7 +20,7 @@ const defaultTheme: ThemeInterface = { contrastText: ({ colors }) => readableColor(colors.primary.main), }, success: { - main: '#37d247', + main: '#1d8127', light: ({ colors }) => lighten(colors.tonalOffset * 2, colors.success.main), dark: ({ colors }) => darken(colors.tonalOffset, colors.success.main), contrastText: ({ colors }) => readableColor(colors.success.main), @@ -32,7 +32,7 @@ const defaultTheme: ThemeInterface = { contrastText: '#ffffff', }, error: { - main: '#e53935', + main: '#d41f1c', light: ({ colors }) => lighten(colors.tonalOffset, colors.error.main), dark: ({ colors }) => darken(colors.tonalOffset, colors.error.main), contrastText: ({ colors }) => readableColor(colors.error.main), @@ -52,11 +52,11 @@ const defaultTheme: ThemeInterface = { responses: { success: { color: ({ colors }) => colors.success.main, - backgroundColor: ({ colors }) => transparentize(0.9, colors.success.main), + backgroundColor: ({ colors }) => transparentize(0.93, colors.success.main), }, error: { color: ({ colors }) => colors.error.main, - backgroundColor: ({ colors }) => transparentize(0.9, colors.error.main), + backgroundColor: ({ colors }) => transparentize(0.93, colors.error.main), }, redirect: { color: ({ colors }) => colors.warning.main, From c5e1c46e9584beb3c0e871365de7d92e26def22c Mon Sep 17 00:00:00 2001 From: Anya Stasiuk Date: Tue, 2 Jun 2020 16:30:14 +0300 Subject: [PATCH 02/10] fix: make response sections focusable --- src/common-elements/shelfs.tsx | 1 + src/components/Responses/ResponseTitle.tsx | 9 +++++++-- src/components/Responses/styled.elements.ts | 12 +++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/common-elements/shelfs.tsx b/src/common-elements/shelfs.tsx index 649bc904e6..278a1c40c9 100644 --- a/src/common-elements/shelfs.tsx +++ b/src/common-elements/shelfs.tsx @@ -26,6 +26,7 @@ class IntShelfIcon extends React.PureComponent<{ x="0" xmlns="http://www.w3.org/2000/svg" y="0" + aria-hidden="true" > diff --git a/src/components/Responses/ResponseTitle.tsx b/src/components/Responses/ResponseTitle.tsx index 382c24ad2f..3058f8d301 100644 --- a/src/components/Responses/ResponseTitle.tsx +++ b/src/components/Responses/ResponseTitle.tsx @@ -17,7 +17,12 @@ export class ResponseTitle extends React.PureComponent { render() { const { title, type, empty, code, opened, className, onClick } = this.props; return ( -
+
+ ); } } diff --git a/src/components/Responses/styled.elements.ts b/src/components/Responses/styled.elements.ts index bb0735da7d..a705812186 100644 --- a/src/components/Responses/styled.elements.ts +++ b/src/components/Responses/styled.elements.ts @@ -5,6 +5,10 @@ import styled from '../../styled-components'; import { ResponseTitle } from './ResponseTitle'; export const StyledResponseTitle = styled(ResponseTitle)` + display: block; + border: 0; + width: 100%; + text-align: left; padding: 10px; border-radius: 2px; margin-bottom: 4px; @@ -14,7 +18,10 @@ export const StyledResponseTitle = styled(ResponseTitle)` color: ${props => props.theme.colors.responses[props.type].color}; background-color: ${props => props.theme.colors.responses[props.type].backgroundColor}; - + &:focus { + outline: auto; + outline-color: ${props => props.theme.colors.responses[props.type].color}; + } ${props => (props.empty && ` @@ -26,6 +33,9 @@ cursor: default; text-align: center; display: inline-block; } +&:focus { + outline: 0; +} `) || ''}; `; From 9f86fc87623eb60f375acf6c4e597cd7988a29f1 Mon Sep 17 00:00:00 2001 From: Anya Stasiuk Date: Tue, 2 Jun 2020 16:33:24 +0300 Subject: [PATCH 03/10] fix: make properties focusable --- src/common-elements/fields-layout.ts | 2 +- src/common-elements/fields.ts | 15 +++++++++++++-- src/components/Fields/Field.tsx | 19 ++++++++++++++++--- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/common-elements/fields-layout.ts b/src/common-elements/fields-layout.ts index e3a696ed11..533ccb01bc 100644 --- a/src/common-elements/fields-layout.ts +++ b/src/common-elements/fields-layout.ts @@ -62,7 +62,7 @@ export const PropertyNameCell = styled(PropertyCell)` vertical-align: top; line-height: 20px; white-space: nowrap; - font-size: 0.929em; + font-size: 13px; font-family: ${props => props.theme.typography.code.fontFamily}; &.deprecated { diff --git a/src/common-elements/fields.ts b/src/common-elements/fields.ts index ef1c07e8c1..8147dfd97b 100644 --- a/src/common-elements/fields.ts +++ b/src/common-elements/fields.ts @@ -5,8 +5,19 @@ import { PropertyNameCell } from './fields-layout'; import { ShelfIcon } from './shelfs'; export const ClickablePropertyNameCell = styled(PropertyNameCell)` - cursor: pointer; - + button { + background-color: transparent; + border: 0; + outline: 0; + font-size: 13px; + font-family: ${props => props.theme.typography.code.fontFamily}; + cursor: pointer; + padding: 0; + color: ${props => props.theme.colors.text.primary}; + &:focus { + font-weight: ${({ theme }) => theme.typography.fontWeightBold}; + } + } ${ShelfIcon} { height: ${({ theme }) => theme.schema.arrow.size}; width: ${({ theme }) => theme.schema.arrow.size}; diff --git a/src/components/Fields/Field.tsx b/src/components/Fields/Field.tsx index d1584b23de..53bedc772c 100644 --- a/src/components/Fields/Field.tsx +++ b/src/components/Fields/Field.tsx @@ -37,6 +37,14 @@ export class Field extends React.Component { this.props.field.toggle(); } }; + + handleKeyPress = e => { + if (e.key === 'Enter') { + e.preventDefault(); + this.toggle(); + } + }; + render() { const { className, field, isLast, expandByDefault } = this.props; const { name, deprecated, required, kind } = field; @@ -46,14 +54,19 @@ export class Field extends React.Component { const paramName = withSubSchema ? ( - {name} - + {required && required } ) : ( From 1e4720535c65dfbd6c46ab4ea28c49e916e57e29 Mon Sep 17 00:00:00 2001 From: Anya Stasiuk Date: Wed, 3 Jun 2020 13:32:45 +0300 Subject: [PATCH 04/10] fix: make sample controls focusable --- src/common-elements/CopyButtonWrapper.tsx | 4 ++-- src/common-elements/samples.tsx | 13 ++++++++++--- src/components/JsonViewer/JsonViewer.tsx | 4 ++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/common-elements/CopyButtonWrapper.tsx b/src/common-elements/CopyButtonWrapper.tsx index c1b5e4684b..3111af8d21 100644 --- a/src/common-elements/CopyButtonWrapper.tsx +++ b/src/common-elements/CopyButtonWrapper.tsx @@ -34,14 +34,14 @@ export class CopyButtonWrapper extends React.PureComponent< renderCopyButton = () => { return ( - + ); }; diff --git a/src/common-elements/samples.tsx b/src/common-elements/samples.tsx index f4855a433c..a250972401 100644 --- a/src/common-elements/samples.tsx +++ b/src/common-elements/samples.tsx @@ -6,12 +6,19 @@ export const SampleControls = styled.div` transition: opacity 0.3s ease; text-align: right; - > span { - display: inline-block; + > button { + background-color: transparent; + border: 0; + color: inherit; padding: 2px 10px; + font-family: ${({ theme }) => theme.typography.fontFamily}; + font-size: ${({ theme }) => theme.typography.fontSize}; + line-height: ${({ theme }) => theme.typography.lineHeight}; cursor: pointer; + outline: 0; - :hover { + :hover, + :focus { background: rgba(255, 255, 255, 0.1); } } diff --git a/src/components/JsonViewer/JsonViewer.tsx b/src/components/JsonViewer/JsonViewer.tsx index d42c9df7d6..0ef0da51a2 100644 --- a/src/components/JsonViewer/JsonViewer.tsx +++ b/src/components/JsonViewer/JsonViewer.tsx @@ -30,8 +30,8 @@ class Json extends React.PureComponent { {renderCopyButton()} - Expand all - Collapse all + + {options => ( From 70cb00a76b77bb48e183fbe055ed174cec495449 Mon Sep 17 00:00:00 2001 From: Anya Stasiuk Date: Thu, 4 Jun 2020 16:10:30 +0300 Subject: [PATCH 05/10] fix: make dropdowns accessible by keyboard --- package-lock.json | 270 +++++++++++++++--- package.json | 2 +- src/common-elements/dropdown.ts | 159 ++++++----- .../CallbackSamples/CallbackSamples.tsx | 4 +- .../DropdownOrLabel/DropdownOrLabel.tsx | 4 +- .../GenericChildrenSwitcher.tsx | 7 +- .../MediaTypeSwitch/MediaTypesSwitch.tsx | 11 +- .../PayloadSamples/MediaTypeSamples.tsx | 11 +- .../PayloadSamples/PayloadSamples.tsx | 4 - .../PayloadSamples/styled.elements.ts | 55 ++-- .../Schema/DiscriminatorDropdown.tsx | 18 +- 11 files changed, 375 insertions(+), 170 deletions(-) diff --git a/package-lock.json b/package-lock.json index c45f8201a4..a51057a1c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -184,7 +184,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", - "dev": true, "requires": { "@babel/types": "^7.8.3" } @@ -966,7 +965,6 @@ "version": "7.8.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", - "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", @@ -1071,6 +1069,36 @@ } } }, + "@emotion/babel-utils": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/@emotion/babel-utils/-/babel-utils-0.6.10.tgz", + "integrity": "sha512-/fnkM/LTEp3jKe++T0KyTszVGWNKPNOUJfjNKLO17BzQ6QPxgbg3whayom1Qr2oLFH3V92tDymU+dT5q676uow==", + "requires": { + "@emotion/hash": "^0.6.6", + "@emotion/memoize": "^0.6.6", + "@emotion/serialize": "^0.9.1", + "convert-source-map": "^1.5.1", + "find-root": "^1.1.0", + "source-map": "^0.7.2" + }, + "dependencies": { + "@emotion/memoize": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.6.6.tgz", + "integrity": "sha512-h4t4jFjtm1YV7UirAFuSuFGyLa+NNxjdkq6DpFLANNQY5rHueFZHVY+8Cu1HYVP6DrheB0kv4m5xPjo7eKT7yQ==" + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "@emotion/hash": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.6.6.tgz", + "integrity": "sha512-ojhgxzUHZ7am3D2jHkMzPpsBAiB005GF5YU4ea+8DNPybMk01JJUM9V9YRlF/GE95tcOm8DxQvWA2jq19bGalQ==" + }, "@emotion/is-prop-valid": { "version": "0.8.8", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", @@ -1086,12 +1114,45 @@ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", "dev": true }, + "@emotion/serialize": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.9.1.tgz", + "integrity": "sha512-zTuAFtyPvCctHBEL8KZ5lJuwBanGSutFEncqLn/m9T1a6a93smBStK+bZzcNPgj4QS8Rkw9VTwJGhRIUVO8zsQ==", + "requires": { + "@emotion/hash": "^0.6.6", + "@emotion/memoize": "^0.6.6", + "@emotion/unitless": "^0.6.7", + "@emotion/utils": "^0.8.2" + }, + "dependencies": { + "@emotion/memoize": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.6.6.tgz", + "integrity": "sha512-h4t4jFjtm1YV7UirAFuSuFGyLa+NNxjdkq6DpFLANNQY5rHueFZHVY+8Cu1HYVP6DrheB0kv4m5xPjo7eKT7yQ==" + }, + "@emotion/unitless": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.6.7.tgz", + "integrity": "sha512-Arj1hncvEVqQ2p7Ega08uHLr1JuRYBuO5cIvcA+WWEQ5+VmkOE3ZXzl04NbQxeQpWX78G7u6MqxKuNX3wvYZxg==" + } + } + }, + "@emotion/stylis": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.7.1.tgz", + "integrity": "sha512-/SLmSIkN13M//53TtNxgxo57mcJk/UJIDFRKwOiLIBEyBHEcipgR6hNMQ/59Sl4VjCJ0Z/3zeAZyvnSLPG/1HQ==" + }, "@emotion/unitless": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", "dev": true }, + "@emotion/utils": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.8.2.tgz", + "integrity": "sha512-rLu3wcBWH4P5q1CGoSSH/i9hrXs7SlbRLkoq9IGuoPYNGQvDJ3pt/wmOM+XgYjIDRMVIdkUWt0RsfzF50JfnCw==" + }, "@hot-loader/react-dom": { "version": "16.13.0", "resolved": "https://registry.npmjs.org/@hot-loader/react-dom/-/react-dom-16.13.0.tgz", @@ -1717,6 +1778,11 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-13.11.1.tgz", "integrity": "sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==" }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, "@types/prismjs": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.16.0.tgz", @@ -2173,8 +2239,7 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "accepts": { "version": "1.3.7", @@ -2692,6 +2757,32 @@ "object.assign": "^4.1.0" } }, + "babel-plugin-emotion": { + "version": "9.2.11", + "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-9.2.11.tgz", + "integrity": "sha512-dgCImifnOPPSeXod2znAmgc64NhaaOjGEHROR/M+lmStb3841yK1sgaDYAYMnlvWNz8GnpwIPN0VmNpbWYZ+VQ==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@emotion/babel-utils": "^0.6.4", + "@emotion/hash": "^0.6.2", + "@emotion/memoize": "^0.6.1", + "@emotion/stylis": "^0.7.0", + "babel-plugin-macros": "^2.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "convert-source-map": "^1.5.0", + "find-root": "^1.1.0", + "mkdirp": "^0.5.1", + "source-map": "^0.5.7", + "touch": "^2.0.1" + }, + "dependencies": { + "@emotion/memoize": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.6.6.tgz", + "integrity": "sha512-h4t4jFjtm1YV7UirAFuSuFGyLa+NNxjdkq6DpFLANNQY5rHueFZHVY+8Cu1HYVP6DrheB0kv4m5xPjo7eKT7yQ==" + } + } + }, "babel-plugin-istanbul": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", @@ -2713,6 +2804,60 @@ "@types/babel__traverse": "^7.0.6" } }, + "babel-plugin-macros": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "requires": { + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + } + } + }, "babel-plugin-styled-components": { "version": "1.10.7", "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.7.tgz", @@ -2728,8 +2873,7 @@ "babel-plugin-syntax-jsx": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", - "dev": true + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" }, "babel-preset-jest": { "version": "24.9.0", @@ -3972,7 +4116,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, "requires": { "safe-buffer": "~5.1.1" } @@ -4112,6 +4255,32 @@ "elliptic": "^6.0.0" } }, + "create-emotion": { + "version": "9.2.12", + "resolved": "https://registry.npmjs.org/create-emotion/-/create-emotion-9.2.12.tgz", + "integrity": "sha512-P57uOF9NL2y98Xrbl2OuiDQUZ30GVmASsv5fbsjF4Hlraip2kyAvMm+2PoYUvFFw03Fhgtxk3RqZSm2/qHL9hA==", + "requires": { + "@emotion/hash": "^0.6.2", + "@emotion/memoize": "^0.6.1", + "@emotion/stylis": "^0.7.0", + "@emotion/unitless": "^0.6.2", + "csstype": "^2.5.2", + "stylis": "^3.5.0", + "stylis-rule-sheet": "^0.0.10" + }, + "dependencies": { + "@emotion/memoize": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.6.6.tgz", + "integrity": "sha512-h4t4jFjtm1YV7UirAFuSuFGyLa+NNxjdkq6DpFLANNQY5rHueFZHVY+8Cu1HYVP6DrheB0kv4m5xPjo7eKT7yQ==" + }, + "@emotion/unitless": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.6.7.tgz", + "integrity": "sha512-Arj1hncvEVqQ2p7Ega08uHLr1JuRYBuO5cIvcA+WWEQ5+VmkOE3ZXzl04NbQxeQpWX78G7u6MqxKuNX3wvYZxg==" + } + } + }, "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -4293,8 +4462,7 @@ "csstype": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.9.tgz", - "integrity": "sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q==", - "dev": true + "integrity": "sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q==" }, "currently-unhandled": { "version": "0.4.1", @@ -5226,6 +5394,15 @@ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "dev": true }, + "emotion": { + "version": "9.2.12", + "resolved": "https://registry.npmjs.org/emotion/-/emotion-9.2.12.tgz", + "integrity": "sha512-hcx7jppaI8VoXxIWEhxpDW7I+B4kq9RNzQLmsrF6LY8BGKqe2N+gFAQr0EfuFucFlPs2A9HM4+xNj4NeqEWIOQ==", + "requires": { + "babel-plugin-emotion": "^9.2.11", + "create-emotion": "^9.2.12" + } + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -5351,7 +5528,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -6475,6 +6651,11 @@ "pkg-dir": "^3.0.0" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -8292,8 +8473,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-binary-path": { "version": "2.1.0", @@ -10586,8 +10766,7 @@ "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" }, "json-pointer": { "version": "0.6.0", @@ -10794,6 +10973,11 @@ } } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + }, "listr": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", @@ -11065,8 +11249,7 @@ "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash._reinterpolate": { "version": "3.0.0", @@ -11643,7 +11826,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" }, @@ -11651,8 +11833,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" } } }, @@ -12486,7 +12667,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "requires": { "callsites": "^3.0.0" }, @@ -12494,8 +12674,7 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" } } }, @@ -12593,8 +12772,7 @@ "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "path-to-regexp": { "version": "0.1.7", @@ -13241,12 +13419,12 @@ "scheduler": "^0.19.0" } }, - "react-dropdown": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/react-dropdown/-/react-dropdown-1.7.0.tgz", - "integrity": "sha512-zFZ73pgLA32hArpE4j/7DtOEhOMg240XG5QvbAb0/VinGekkHDVIakMyAFUKC5jDz8jqXEltgriqFW9R5iCtPQ==", + "react-dropdown-aria": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/react-dropdown-aria/-/react-dropdown-aria-2.0.6.tgz", + "integrity": "sha512-/9NlFopChlSKmuGL2P6S3oDwl9ddXcbNLnd1a7POov4f5/oGtSc3qBFmS4wH5xmLJe/38MhPOKF3e2q3laRi1g==", "requires": { - "classnames": "^2.2.3" + "emotion": "^9.2.6" } }, "react-hot-loader": { @@ -13714,7 +13892,6 @@ "version": "1.15.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "dev": true, "requires": { "path-parse": "^1.0.6" } @@ -13850,8 +14027,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-json-stringify": { "version": "1.2.0", @@ -14486,8 +14662,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, "source-map-loader": { "version": "0.2.4", @@ -14969,14 +15144,12 @@ "stylis": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", - "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==", - "dev": true + "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" }, "stylis-rule-sheet": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", - "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==", - "dev": true + "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==" }, "supports-color": { "version": "5.5.0", @@ -15320,8 +15493,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" }, "to-object-path": { "version": "0.3.0", @@ -15382,6 +15554,24 @@ "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", "dev": true }, + "touch": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/touch/-/touch-2.0.2.tgz", + "integrity": "sha512-qjNtvsFXTRq7IuMLweVgFxmEuQ6gLbRs2jQxL80TtZ31dEKWYIxRXquij6w6VimyDek5hD3PytljHmEtAs2u0A==", + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1" + } + } + } + }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", diff --git a/package.json b/package.json index f12a0afcd6..a08ab6d98d 100644 --- a/package.json +++ b/package.json @@ -152,7 +152,7 @@ "polished": "^3.4.4", "prismjs": "^1.19.0", "prop-types": "^15.7.2", - "react-dropdown": "^1.7.0", + "react-dropdown-aria": "^2.0.6", "react-tabs": "^3.1.0", "slugify": "^1.4.0", "stickyfill": "^1.1.1", diff --git a/src/common-elements/dropdown.ts b/src/common-elements/dropdown.ts index 08c886b406..b7cf2bcab0 100644 --- a/src/common-elements/dropdown.ts +++ b/src/common-elements/dropdown.ts @@ -1,113 +1,128 @@ -import Dropdown from 'react-dropdown'; +import Dropdown from 'react-dropdown-aria'; import styled from '../styled-components'; export interface DropdownOption { - label: string; + idx: number; value: string; } export interface DropdownProps { options: DropdownOption[]; - value: DropdownOption; - onChange: (val: DropdownOption) => void; + value: string; + onChange: (option: DropdownOption) => void; + ariaLabel: string; } export const StyledDropdown = styled(Dropdown)` - min-width: 100px; - display: inline-block; - position: relative; - width: auto; - font-family: ${props => props.theme.typography.headings.fontFamily}; - - .Dropdown-control { - font-family: ${props => props.theme.typography.headings.fontFamily}; + && { + box-sizing: border-box; + min-width: 100px; + outline: none; + display: inline-block; + border-radius: 2px; + border: 1px solid rgba(38, 50, 56, 0.5); + vertical-align: bottom; + padding: 2px 0px 2px 6px; position: relative; + width: auto; + background: white; + color: #263238; + font-family: ${props => props.theme.typography.headings.fontFamily}; font-size: 0.929em; - width: 100%; line-height: 1.5em; - vertical-align: middle; cursor: pointer; - border-color: rgba(38, 50, 56, 0.5); - color: #263238; - outline: none; - padding: 0.15em 1.5em 0.2em 0.5em; - border-radius: 2px; - border-width: 1px; - border-style: solid; - margin-top: 5px; - background: white; - - box-sizing: border-box; - - &:hover { - border-color: ${props => props.theme.colors.primary.main}; + &:hover, + &:focus-within { + border: 1px solid ${props => props.theme.colors.primary.main}; color: ${props => props.theme.colors.primary.main}; box-shadow: 0px 2px 4px 0px rgba(34, 36, 38, 0.12); } - } - - .Dropdown-arrow { - border-color: ${props => props.theme.colors.primary.main} transparent transparent; - border-style: solid; - border-width: 0.35em 0.35em 0; - content: ' '; - display: block; - height: 0; - position: absolute; - right: 0.3em; - top: 50%; - margin-top: -0.125em; - width: 0; - } + .dropdown-selector { + display: inline-flex; + padding: 0; + height: auto; + padding-right: 20px; + position: relative; + margin-bottom: 5px; + } + .dropdown-selector-value { + font-family: ${props => props.theme.typography.headings.fontFamily}; + position: relative; + font-size: 0.929em; + width: 100%; + line-height: 1; + vertical-align: middle; + color: #263238; + left: 0; + } + .dropdown-arrow { + position: absolute; + right: 3px; + top: 50%; + transform: translateY(-50%); + border-color: ${props => props.theme.colors.primary.main} transparent transparent; + border-style: solid; + border-width: 0.35em 0.35em 0; + width: 0; + svg { + display: none; + } + } - .Dropdown-menu { - position: absolute; - margin-top: 2px; - left: 0; - right: 0; + .dropdown-selector-content { + position: absolute; + margin-top: 2px; + left: -1px; + right: 0; - z-index: 10; - min-width: 100px; + z-index: 10; + min-width: 100px; - background: white; - border: 1px solid rgba(38, 50, 56, 0.2); - box-shadow: 0px 2px 4px 0px rgba(34, 36, 38, 0.12), 0px 2px 10px 0px rgba(34, 36, 38, 0.08); + background: white; + border: 1px solid rgba(38, 50, 56, 0.2); + box-shadow: 0px 2px 4px 0px rgba(34, 36, 38, 0.12), 0px 2px 10px 0px rgba(34, 36, 38, 0.08); - max-height: 220px; - overflow: auto; - } + max-height: 220px; + overflow: auto; + } - .Dropdown-option { - font-size: 0.9em; - color: #263238; - cursor: pointer; - padding: 0.4em; + .dropdown-option { + font-size: 0.9em; + color: #263238; + background-color: #fff; + cursor: pointer; + padding: 0.4em; - &.is-selected { - background-color: rgba(0, 0, 0, 0.05); - } + &[aria-selected='true'] { + background-color: rgba(0, 0, 0, 0.05); + } - &:hover { - background-color: rgba(38, 50, 56, 0.12); + &:hover { + background-color: rgba(38, 50, 56, 0.12); + } } } `; export const SimpleDropdown = styled(StyledDropdown)` - margin-left: 10px; - text-transform: none; - font-size: 0.969em; + && { + margin-left: 10px; + text-transform: none; + font-size: 0.969em; - .Dropdown-control { font-size: 1em; border: none; padding: 0 1.2em 0 0; background: transparent; - &:hover { - color: ${props => props.theme.colors.primary.main}; + &:hover, + &:focus-within { + border: none; box-shadow: none; + .dropdown-selector-value { + color: ${props => props.theme.colors.primary.main}; + } } } `; diff --git a/src/components/CallbackSamples/CallbackSamples.tsx b/src/components/CallbackSamples/CallbackSamples.tsx index b5064d5c00..fe7cab33df 100644 --- a/src/components/CallbackSamples/CallbackSamples.tsx +++ b/src/components/CallbackSamples/CallbackSamples.tsx @@ -43,8 +43,8 @@ export class CallbackSamples extends React.Component { const dropdownOptions = operations.map((callback, idx) => { return { - label: `${callback.httpVerb.toUpperCase()}: ${callback.name}`, - value: idx.toString(), + value: `${callback.httpVerb.toUpperCase()}: ${callback.name}`, + idx, }; }); diff --git a/src/components/DropdownOrLabel/DropdownOrLabel.tsx b/src/components/DropdownOrLabel/DropdownOrLabel.tsx index 220c56febd..74db230798 100644 --- a/src/components/DropdownOrLabel/DropdownOrLabel.tsx +++ b/src/components/DropdownOrLabel/DropdownOrLabel.tsx @@ -10,7 +10,7 @@ export interface DropdownOrLabelProps extends DropdownProps { export function DropdownOrLabel(props: DropdownOrLabelProps): JSX.Element { const { Label = MimeLabel, Dropdown = SimpleDropdown } = props; if (props.options.length === 1) { - return ; + return ; } - return ; + return ; } diff --git a/src/components/GenericChildrenSwitcher/GenericChildrenSwitcher.tsx b/src/components/GenericChildrenSwitcher/GenericChildrenSwitcher.tsx index b850fd9992..5162ed0517 100644 --- a/src/components/GenericChildrenSwitcher/GenericChildrenSwitcher.tsx +++ b/src/components/GenericChildrenSwitcher/GenericChildrenSwitcher.tsx @@ -32,10 +32,10 @@ export class GenericChildrenSwitcher extends React.Component< }; } - switchItem = ({ value }) => { + switchItem = ({ idx }) => { if (this.props.items) { this.setState({ - activeItemIdx: parseInt(value, 10), + activeItemIdx: idx, }); } }; @@ -61,9 +61,10 @@ export class GenericChildrenSwitcher extends React.Component< <> {this.props.renderDropdown({ - value: this.props.options[this.state.activeItemIdx], + value: this.props.options[this.state.activeItemIdx].value, options: this.props.options, onChange: this.switchItem, + ariaLabel: this.props.label || 'Callback', })} diff --git a/src/components/MediaTypeSwitch/MediaTypesSwitch.tsx b/src/components/MediaTypeSwitch/MediaTypesSwitch.tsx index f25b303f4e..36bb384c84 100644 --- a/src/components/MediaTypeSwitch/MediaTypesSwitch.tsx +++ b/src/components/MediaTypeSwitch/MediaTypesSwitch.tsx @@ -20,9 +20,9 @@ export interface MediaTypesSwitchProps { @observer export class MediaTypesSwitch extends React.Component { - switchMedia = ({ value }) => { + switchMedia = ({ idx }) => { if (this.props.content) { - this.props.content.activate(parseInt(value, 10)); + this.props.content.activate(idx); } }; @@ -35,8 +35,8 @@ export class MediaTypesSwitch extends React.Component { const options = content.mediaTypes.map((mime, idx) => { return { - label: mime.name, - value: idx.toString(), + value: mime.name, + idx, }; }); @@ -54,9 +54,10 @@ export class MediaTypesSwitch extends React.Component { <> {this.props.renderDropdown({ - value: options[activeMimeIdx], + value: options[activeMimeIdx].value, options, onChange: this.switchMedia, + ariaLabel: 'Content type', })} {this.props.children(content.active)} diff --git a/src/components/PayloadSamples/MediaTypeSamples.tsx b/src/components/PayloadSamples/MediaTypeSamples.tsx index 5fedce0157..b54d112e4e 100644 --- a/src/components/PayloadSamples/MediaTypeSamples.tsx +++ b/src/components/PayloadSamples/MediaTypeSamples.tsx @@ -21,9 +21,9 @@ export class MediaTypeSamples extends React.Component { + switchMedia = ({ idx }) => { this.setState({ - activeIdx: parseInt(value, 10), + activeIdx: idx, }); }; render() { @@ -41,8 +41,8 @@ export class MediaTypeSamples extends React.Component 1) { const options = examplesNames.map((name, idx) => { return { - label: examples[name].summary || name, - value: idx.toString(), + value: examples[name].summary || name, + idx, }; }); @@ -54,9 +54,10 @@ export class MediaTypeSamples extends React.Component Example {this.props.renderDropdown({ - value: options[activeIdx], + value: options[activeIdx].value, options, onChange: this.switchMedia, + ariaLabel: 'Example', })}
diff --git a/src/components/PayloadSamples/PayloadSamples.tsx b/src/components/PayloadSamples/PayloadSamples.tsx index 36f232fff9..7e2a85f038 100644 --- a/src/components/PayloadSamples/PayloadSamples.tsx +++ b/src/components/PayloadSamples/PayloadSamples.tsx @@ -1,7 +1,3 @@ -// @ts-ignore -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import ReactDropdown from 'react-dropdown'; - import { observer } from 'mobx-react'; import * as React from 'react'; import { MediaTypeSamples } from './MediaTypeSamples'; diff --git a/src/components/PayloadSamples/styled.elements.ts b/src/components/PayloadSamples/styled.elements.ts index a2d75d6b71..55e97ba37e 100644 --- a/src/components/PayloadSamples/styled.elements.ts +++ b/src/components/PayloadSamples/styled.elements.ts @@ -1,7 +1,3 @@ -// @ts-ignore -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import ReactDropdown from 'react-dropdown'; - import { transparentize } from 'polished'; import styled from '../../styled-components'; import { StyledDropdown } from '../../common-elements'; @@ -32,40 +28,43 @@ export const DropdownWrapper = styled.div` `; export const InvertedSimpleDropdown = styled(StyledDropdown)` - margin-left: 10px; - text-transform: none; - font-size: 0.929em; - margin: 0 0 10px 0; - display: block; - background-color: ${({ theme }) => transparentize(0.6, theme.rightPanel.backgroundColor)}; - .Dropdown-placeholder { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - } - .Dropdown-control { - margin-top: 0; - } - .Dropdown-control, - .Dropdown-control:hover { + && { + margin-left: 10px; + text-transform: none; + font-size: 0.929em; + margin: 0 0 10px 0; + display: block; + background-color: ${({ theme }) => transparentize(0.6, theme.rightPanel.backgroundColor)}; font-size: 1em; border: none; padding: 0.9em 1.6em 0.9em 0.9em; - background: transparent; - color: ${({ theme }) => theme.rightPanel.textColor}; box-shadow: none; + &:hover, + &:focus-within { + border: none; + } + &:focus-within { + background-color: ${({ theme }) => transparentize(0.3, theme.rightPanel.backgroundColor)}; + } - .Dropdown-arrow { + .dropdown-arrow { border-top-color: ${({ theme }) => theme.rightPanel.textColor}; } - } - .Dropdown-menu { - margin: 0; - margin-top: 2px; - .Dropdown-option { + .dropdown-selector-value { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; + color: ${({ theme }) => theme.rightPanel.textColor}; + } + + .dropdown-selector-content { + margin: 0; + margin-top: 2px; + .dropdown-option { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } } } `; diff --git a/src/components/Schema/DiscriminatorDropdown.tsx b/src/components/Schema/DiscriminatorDropdown.tsx index e2443e7cd4..73e22d5c22 100644 --- a/src/components/Schema/DiscriminatorDropdown.tsx +++ b/src/components/Schema/DiscriminatorDropdown.tsx @@ -21,7 +21,7 @@ export class DiscriminatorDropdown extends React.Component<{ }); options.sort((a, b) => { - return enumOrder[a.label] > enumOrder[b.label] ? 1 : -1; + return enumOrder[a.value] > enumOrder[b.value] ? 1 : -1; }); } @@ -33,21 +33,23 @@ export class DiscriminatorDropdown extends React.Component<{ const options = parent.oneOf.map((subSchema, idx) => { return { - value: idx.toString(), - label: subSchema.title, + value: subSchema.title, + idx, }; }); - const activeItem = options[parent.activeOneOf]; this.sortOptions(options, enumValues); return ( - + ); } - changeActiveChild = ({ value }) => { - const idx = parseInt(value, 10); - this.props.parent.activateOneOf(idx); + changeActiveChild = (option: DropdownOption) => { + this.props.parent.activateOneOf(option.idx); }; } From 1c9923f1cfbf0480e9584691cd289429e121867f Mon Sep 17 00:00:00 2001 From: Anya Stasiuk Date: Thu, 4 Jun 2020 16:37:28 +0300 Subject: [PATCH 06/10] fix: make endpoint dropdown accessible --- src/components/Endpoint/styled.elements.ts | 10 +++++++++- src/components/SelectOnClick/SelectOnClick.tsx | 9 +++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/components/Endpoint/styled.elements.ts b/src/components/Endpoint/styled.elements.ts index b2a45fde97..4eb5e1d145 100644 --- a/src/components/Endpoint/styled.elements.ts +++ b/src/components/Endpoint/styled.elements.ts @@ -14,7 +14,12 @@ export const ServerRelativeURL = styled.span` text-overflow: ellipsis; `; -export const EndpointInfo = styled.div<{ expanded?: boolean; inverted?: boolean }>` +export const EndpointInfo = styled.button<{ expanded?: boolean; inverted?: boolean }>` + outline: 0; + color: inherit; + width: 100%; + text-align: left; + cursor: pointer; padding: 10px 30px 10px ${props => (props.inverted ? '10px' : '20px')}; border-radius: ${props => (props.inverted ? '0' : '4px 4px 0 0')}; background-color: ${props => @@ -32,6 +37,9 @@ export const EndpointInfo = styled.div<{ expanded?: boolean; inverted?: boolean .${ServerRelativeURL} { color: ${props => (props.inverted ? props.theme.colors.text.primary : '#ffffff')} } + &:focus { + box-shadow: inset 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(128, 128, 128, 0.15); + } `; export const HttpVerb = styled.span.attrs((props: { type: string; compact?: boolean }) => ({ diff --git a/src/components/SelectOnClick/SelectOnClick.tsx b/src/components/SelectOnClick/SelectOnClick.tsx index 9856905c2f..1cd966d309 100644 --- a/src/components/SelectOnClick/SelectOnClick.tsx +++ b/src/components/SelectOnClick/SelectOnClick.tsx @@ -4,14 +4,19 @@ import { ClipboardService } from '../../services'; export class SelectOnClick extends React.PureComponent { private child: HTMLDivElement | null; - handleClick = () => { + selectElement = () => { ClipboardService.selectElement(this.child); }; render() { const { children } = this.props; return ( -
(this.child = el)} onClick={this.handleClick}> +
(this.child = el)} + onClick={this.selectElement} + onFocus={this.selectElement} + tabIndex={0} + > {children}
); From 8180bffbf60d568f80d9da7ec3544b926cd9f4ee Mon Sep 17 00:00:00 2001 From: Anya Stasiuk Date: Wed, 10 Jun 2020 15:20:18 +0300 Subject: [PATCH 07/10] fix: update focus styling --- src/common-elements/dropdown.ts | 12 +++++++++--- src/common-elements/linkify.tsx | 1 + src/common-elements/samples.tsx | 4 +++- src/common-elements/tabs.ts | 3 +++ src/components/Endpoint/styled.elements.ts | 2 +- src/components/PayloadSamples/styled.elements.ts | 1 + 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/common-elements/dropdown.ts b/src/common-elements/dropdown.ts index b7cf2bcab0..295480b8be 100644 --- a/src/common-elements/dropdown.ts +++ b/src/common-elements/dropdown.ts @@ -32,11 +32,12 @@ export const StyledDropdown = styled(Dropdown)` font-size: 0.929em; line-height: 1.5em; cursor: pointer; + transition: border 0.25s ease, color 0.25s ease, box-shadow 0.25s ease; &:hover, &:focus-within { border: 1px solid ${props => props.theme.colors.primary.main}; color: ${props => props.theme.colors.primary.main}; - box-shadow: 0px 2px 4px 0px rgba(34, 36, 38, 0.12); + box-shadow: 0px 0px 0px 1px ${props => props.theme.colors.primary.main}; } .dropdown-selector { display: inline-flex; @@ -55,6 +56,7 @@ export const StyledDropdown = styled(Dropdown)` vertical-align: middle; color: #263238; left: 0; + transition: color 0.25s ease, text-shadow 0.25s ease; } .dropdown-arrow { position: absolute; @@ -73,7 +75,7 @@ export const StyledDropdown = styled(Dropdown)` .dropdown-selector-content { position: absolute; margin-top: 2px; - left: -1px; + left: -2px; right: 0; z-index: 10; @@ -90,7 +92,6 @@ export const StyledDropdown = styled(Dropdown)` .dropdown-option { font-size: 0.9em; color: #263238; - background-color: #fff; cursor: pointer; padding: 0.4em; @@ -102,6 +103,10 @@ export const StyledDropdown = styled(Dropdown)` background-color: rgba(38, 50, 56, 0.12); } } + input { + cursor: pointer; + height: 1px; + } } `; @@ -122,6 +127,7 @@ export const SimpleDropdown = styled(StyledDropdown)` box-shadow: none; .dropdown-selector-value { color: ${props => props.theme.colors.primary.main}; + text-shadow: 0px 0px 0px ${props => props.theme.colors.primary.main}; } } } diff --git a/src/common-elements/linkify.tsx b/src/common-elements/linkify.tsx index 24dec73591..e5d7bd6243 100644 --- a/src/common-elements/linkify.tsx +++ b/src/common-elements/linkify.tsx @@ -14,6 +14,7 @@ export const linkifyMixin = className => css` line-height: 1; width: 20px; display: inline-block; + outline: 0; } ${className}:before { content: ''; diff --git a/src/common-elements/samples.tsx b/src/common-elements/samples.tsx index a250972401..329ec88f6c 100644 --- a/src/common-elements/samples.tsx +++ b/src/common-elements/samples.tsx @@ -5,7 +5,9 @@ export const SampleControls = styled.div` opacity: 0.4; transition: opacity 0.3s ease; text-align: right; - + &:focus-within { + opacity: 1; + } > button { background-color: transparent; border: 0; diff --git a/src/common-elements/tabs.ts b/src/common-elements/tabs.ts index 5063d64b92..1c4ef1b992 100644 --- a/src/common-elements/tabs.ts +++ b/src/common-elements/tabs.ts @@ -33,6 +33,9 @@ export const Tabs = styled(ReactTabs)` &.react-tabs__tab--selected { color: ${props => props.theme.colors.text.primary}; background: ${({ theme }) => theme.rightPanel.textColor}; + &:focus { + outline: auto; + } } &:only-child { diff --git a/src/components/Endpoint/styled.elements.ts b/src/components/Endpoint/styled.elements.ts index 4eb5e1d145..9524e9a4d4 100644 --- a/src/components/Endpoint/styled.elements.ts +++ b/src/components/Endpoint/styled.elements.ts @@ -38,7 +38,7 @@ export const EndpointInfo = styled.button<{ expanded?: boolean; inverted?: boole color: ${props => (props.inverted ? props.theme.colors.text.primary : '#ffffff')} } &:focus { - box-shadow: inset 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(128, 128, 128, 0.15); + box-shadow: inset 0 2px 2px rgba(0, 0, 0, 0.45), 0 2px 0 rgba(128, 128, 128, 0.25); } `; diff --git a/src/components/PayloadSamples/styled.elements.ts b/src/components/PayloadSamples/styled.elements.ts index 55e97ba37e..fa7f912037 100644 --- a/src/components/PayloadSamples/styled.elements.ts +++ b/src/components/PayloadSamples/styled.elements.ts @@ -42,6 +42,7 @@ export const InvertedSimpleDropdown = styled(StyledDropdown)` &:hover, &:focus-within { border: none; + box-shadow: none; } &:focus-within { background-color: ${({ theme }) => transparentize(0.3, theme.rightPanel.backgroundColor)}; From 78c8f70eea62b2a6bafe20f95214e06eb0d35905 Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Mon, 6 Jul 2020 15:53:31 +0300 Subject: [PATCH 08/10] chore: fix tests --- src/components/Endpoint/Endpoint.tsx | 2 +- src/components/Endpoint/styled.elements.ts | 3 ++- src/components/__tests__/JsonViewer.tsx | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/Endpoint/Endpoint.tsx b/src/components/Endpoint/Endpoint.tsx index e59ceff5e9..9e9a5f922d 100644 --- a/src/components/Endpoint/Endpoint.tsx +++ b/src/components/Endpoint/Endpoint.tsx @@ -62,7 +62,7 @@ export class Endpoint extends React.Component { style={{ marginRight: '-25px' }} /> - + {operation.servers.map(server => { const normalizedUrl = options.expandDefaultServerVariables ? expandDefaultServerVariables(server.url, server.variables) diff --git a/src/components/Endpoint/styled.elements.ts b/src/components/Endpoint/styled.elements.ts index 9524e9a4d4..041de2d4a6 100644 --- a/src/components/Endpoint/styled.elements.ts +++ b/src/components/Endpoint/styled.elements.ts @@ -67,7 +67,8 @@ export const ServersOverlay = styled.div<{ expanded: boolean }>` border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; transition: all 0.25s ease; - ${props => (props.expanded ? '' : 'transform: translateY(-50%) scaleY(0);')} + visibility: hidden; + ${props => (props.expanded ? 'visibility: visible;' : 'transform: translateY(-50%) scaleY(0);')} `; export const ServerItem = styled.div` diff --git a/src/components/__tests__/JsonViewer.tsx b/src/components/__tests__/JsonViewer.tsx index 8f8f745ee7..8649c14d3f 100644 --- a/src/components/__tests__/JsonViewer.tsx +++ b/src/components/__tests__/JsonViewer.tsx @@ -25,11 +25,11 @@ describe('Components', () => { test('should collapse/uncollapse', () => { expect(component.html()).not.toContain('class="hoverable"'); // all are collapsed by default - const expandAll = component.find('div > span[children=" Expand all "]'); + const expandAll = component.find('div > button[children=" Expand all "]'); expandAll.simulate('click'); expect(component.html()).toContain('class="hoverable"'); // all are collapsed - const collapseAll = component.find('div > span[children=" Collapse all "]'); + const collapseAll = component.find('div > button[children=" Collapse all "]'); collapseAll.simulate('click'); expect(component.html()).not.toContain('class="hoverable"'); // all are collapsed }); @@ -37,7 +37,7 @@ describe('Components', () => { test('should collapse/uncollapse', () => { ClipboardService.copySelected = jest.fn(); - const copy = component.find('span[onClick]').first(); + const copy = component.find('button[onClick]').first(); copy.simulate('click'); expect(ClipboardService.copySelected as jest.Mock).toHaveBeenCalled(); From 1c6254efd03dce26f1d5e81aa0163e5e6a0b02e4 Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Mon, 13 Jul 2020 10:05:19 +0300 Subject: [PATCH 09/10] chore: skipLibCheck --- tsconfig.lib.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tsconfig.lib.json b/tsconfig.lib.json index eb81bb904e..f67f175771 100644 --- a/tsconfig.lib.json +++ b/tsconfig.lib.json @@ -1,10 +1,11 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "declarationDir": "typings" + "declarationDir": "typings", + "skipLibCheck": true, }, "include": [ "./custom.d.ts", "src/index.ts" ] -} \ No newline at end of file +} From eb79b2ed7069db92cb61098bb671a4fed74a961e Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Mon, 13 Jul 2020 10:05:19 +0300 Subject: [PATCH 10/10] chore: trigger ci