From d3e9c565b77b1cdedd615eb17a58d91e8aba98e3 Mon Sep 17 00:00:00 2001 From: Elizabeth Thompson Date: Wed, 16 Sep 2020 12:03:14 -0700 Subject: [PATCH] feat: use svg for checkbox component (#10799) * use svg for checkbox component * add vertical align to svg * use emotion styling * update import to superset core Co-authored-by: Elizabeth Thompson --- superset-frontend/package-lock.json | 312 ++++++++++++++---- superset-frontend/package.json | 1 + .../javascripts/components/Checkbox_spec.jsx | 55 --- .../src/components/Button/Button.stories.jsx | 103 +++--- .../src/components/Button/Button.test.tsx | 8 +- .../components/Checkbox/Checkbox.stories.jsx | 63 ++++ .../src/components/Checkbox/Checkbox.test.tsx | 75 +++++ .../{Checkbox.tsx => Checkbox/index.tsx} | 42 ++- 8 files changed, 472 insertions(+), 187 deletions(-) delete mode 100644 superset-frontend/spec/javascripts/components/Checkbox_spec.jsx create mode 100644 superset-frontend/src/components/Checkbox/Checkbox.stories.jsx create mode 100644 superset-frontend/src/components/Checkbox/Checkbox.test.tsx rename superset-frontend/src/components/{Checkbox.tsx => Checkbox/index.tsx} (68%) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 07765d2c8..0a8b674d0 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -6611,6 +6611,21 @@ "util-deprecate": "^1.0.2" } }, + "@storybook/channel-postmessage": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.0.13.tgz", + "integrity": "sha512-WglkGiX0tAdftQVaNK8xlGW5gOjA9HQ+095G3cPehrPg7Rc7mEMCFvACVL2BlZBUCPljh2DA+fv7aQMcjuW/Xg==", + "dev": true, + "requires": { + "@storybook/channels": "6.0.13", + "@storybook/client-logger": "6.0.13", + "@storybook/core-events": "6.0.13", + "core-js": "^3.0.1", + "global": "^4.3.2", + "qs": "^6.6.0", + "telejson": "^5.0.2" + } + }, "@storybook/channels": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.13.tgz", @@ -6622,6 +6637,31 @@ "util-deprecate": "^1.0.2" } }, + "@storybook/client-api": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.0.13.tgz", + "integrity": "sha512-AL5YywpZo1LPi8FlIRiUXFBnV1h5039hUAVXMlVlOBud0iZuGlBZTsmgttL3GQUdC2hNQsbwZu7vAO/uqCsfRw==", + "dev": true, + "requires": { + "@storybook/addons": "6.0.13", + "@storybook/channel-postmessage": "6.0.13", + "@storybook/channels": "6.0.13", + "@storybook/client-logger": "6.0.13", + "@storybook/core-events": "6.0.13", + "@storybook/csf": "0.0.1", + "@types/qs": "^6.9.0", + "@types/webpack-env": "^1.15.2", + "core-js": "^3.0.1", + "global": "^4.3.2", + "lodash": "^4.17.15", + "memoizerific": "^1.11.3", + "qs": "^6.6.0", + "stable": "^0.1.8", + "store2": "^2.7.1", + "ts-dedent": "^1.1.1", + "util-deprecate": "^1.0.2" + } + }, "@storybook/client-logger": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.13.tgz", @@ -7321,6 +7361,21 @@ "util-deprecate": "^1.0.2" } }, + "@storybook/channel-postmessage": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.0.13.tgz", + "integrity": "sha512-WglkGiX0tAdftQVaNK8xlGW5gOjA9HQ+095G3cPehrPg7Rc7mEMCFvACVL2BlZBUCPljh2DA+fv7aQMcjuW/Xg==", + "dev": true, + "requires": { + "@storybook/channels": "6.0.13", + "@storybook/client-logger": "6.0.13", + "@storybook/core-events": "6.0.13", + "core-js": "^3.0.1", + "global": "^4.3.2", + "qs": "^6.6.0", + "telejson": "^5.0.2" + } + }, "@storybook/channels": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.13.tgz", @@ -7332,6 +7387,31 @@ "util-deprecate": "^1.0.2" } }, + "@storybook/client-api": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.0.13.tgz", + "integrity": "sha512-AL5YywpZo1LPi8FlIRiUXFBnV1h5039hUAVXMlVlOBud0iZuGlBZTsmgttL3GQUdC2hNQsbwZu7vAO/uqCsfRw==", + "dev": true, + "requires": { + "@storybook/addons": "6.0.13", + "@storybook/channel-postmessage": "6.0.13", + "@storybook/channels": "6.0.13", + "@storybook/client-logger": "6.0.13", + "@storybook/core-events": "6.0.13", + "@storybook/csf": "0.0.1", + "@types/qs": "^6.9.0", + "@types/webpack-env": "^1.15.2", + "core-js": "^3.0.1", + "global": "^4.3.2", + "lodash": "^4.17.15", + "memoizerific": "^1.11.3", + "qs": "^6.6.0", + "stable": "^0.1.8", + "store2": "^2.7.1", + "ts-dedent": "^1.1.1", + "util-deprecate": "^1.0.2" + } + }, "@storybook/client-logger": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.13.tgz", @@ -8628,6 +8708,21 @@ "util-deprecate": "^1.0.2" } }, + "@storybook/channel-postmessage": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.0.13.tgz", + "integrity": "sha512-WglkGiX0tAdftQVaNK8xlGW5gOjA9HQ+095G3cPehrPg7Rc7mEMCFvACVL2BlZBUCPljh2DA+fv7aQMcjuW/Xg==", + "dev": true, + "requires": { + "@storybook/channels": "6.0.13", + "@storybook/client-logger": "6.0.13", + "@storybook/core-events": "6.0.13", + "core-js": "^3.0.1", + "global": "^4.3.2", + "qs": "^6.6.0", + "telejson": "^5.0.2" + } + }, "@storybook/channels": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.13.tgz", @@ -8639,6 +8734,31 @@ "util-deprecate": "^1.0.2" } }, + "@storybook/client-api": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.0.13.tgz", + "integrity": "sha512-AL5YywpZo1LPi8FlIRiUXFBnV1h5039hUAVXMlVlOBud0iZuGlBZTsmgttL3GQUdC2hNQsbwZu7vAO/uqCsfRw==", + "dev": true, + "requires": { + "@storybook/addons": "6.0.13", + "@storybook/channel-postmessage": "6.0.13", + "@storybook/channels": "6.0.13", + "@storybook/client-logger": "6.0.13", + "@storybook/core-events": "6.0.13", + "@storybook/csf": "0.0.1", + "@types/qs": "^6.9.0", + "@types/webpack-env": "^1.15.2", + "core-js": "^3.0.1", + "global": "^4.3.2", + "lodash": "^4.17.15", + "memoizerific": "^1.11.3", + "qs": "^6.6.0", + "stable": "^0.1.8", + "store2": "^2.7.1", + "ts-dedent": "^1.1.1", + "util-deprecate": "^1.0.2" + } + }, "@storybook/client-logger": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.13.tgz", @@ -9543,6 +9663,21 @@ "util-deprecate": "^1.0.2" } }, + "@storybook/channel-postmessage": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.0.13.tgz", + "integrity": "sha512-WglkGiX0tAdftQVaNK8xlGW5gOjA9HQ+095G3cPehrPg7Rc7mEMCFvACVL2BlZBUCPljh2DA+fv7aQMcjuW/Xg==", + "dev": true, + "requires": { + "@storybook/channels": "6.0.13", + "@storybook/client-logger": "6.0.13", + "@storybook/core-events": "6.0.13", + "core-js": "^3.0.1", + "global": "^4.3.2", + "qs": "^6.6.0", + "telejson": "^5.0.2" + } + }, "@storybook/channels": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.13.tgz", @@ -9554,6 +9689,31 @@ "util-deprecate": "^1.0.2" } }, + "@storybook/client-api": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.0.13.tgz", + "integrity": "sha512-AL5YywpZo1LPi8FlIRiUXFBnV1h5039hUAVXMlVlOBud0iZuGlBZTsmgttL3GQUdC2hNQsbwZu7vAO/uqCsfRw==", + "dev": true, + "requires": { + "@storybook/addons": "6.0.13", + "@storybook/channel-postmessage": "6.0.13", + "@storybook/channels": "6.0.13", + "@storybook/client-logger": "6.0.13", + "@storybook/core-events": "6.0.13", + "@storybook/csf": "0.0.1", + "@types/qs": "^6.9.0", + "@types/webpack-env": "^1.15.2", + "core-js": "^3.0.1", + "global": "^4.3.2", + "lodash": "^4.17.15", + "memoizerific": "^1.11.3", + "qs": "^6.6.0", + "stable": "^0.1.8", + "store2": "^2.7.1", + "ts-dedent": "^1.1.1", + "util-deprecate": "^1.0.2" + } + }, "@storybook/client-logger": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.13.tgz", @@ -9917,6 +10077,21 @@ "util-deprecate": "^1.0.2" } }, + "@storybook/channel-postmessage": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.0.13.tgz", + "integrity": "sha512-WglkGiX0tAdftQVaNK8xlGW5gOjA9HQ+095G3cPehrPg7Rc7mEMCFvACVL2BlZBUCPljh2DA+fv7aQMcjuW/Xg==", + "dev": true, + "requires": { + "@storybook/channels": "6.0.13", + "@storybook/client-logger": "6.0.13", + "@storybook/core-events": "6.0.13", + "core-js": "^3.0.1", + "global": "^4.3.2", + "qs": "^6.6.0", + "telejson": "^5.0.2" + } + }, "@storybook/channels": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.13.tgz", @@ -9928,6 +10103,31 @@ "util-deprecate": "^1.0.2" } }, + "@storybook/client-api": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.0.13.tgz", + "integrity": "sha512-AL5YywpZo1LPi8FlIRiUXFBnV1h5039hUAVXMlVlOBud0iZuGlBZTsmgttL3GQUdC2hNQsbwZu7vAO/uqCsfRw==", + "dev": true, + "requires": { + "@storybook/addons": "6.0.13", + "@storybook/channel-postmessage": "6.0.13", + "@storybook/channels": "6.0.13", + "@storybook/client-logger": "6.0.13", + "@storybook/core-events": "6.0.13", + "@storybook/csf": "0.0.1", + "@types/qs": "^6.9.0", + "@types/webpack-env": "^1.15.2", + "core-js": "^3.0.1", + "global": "^4.3.2", + "lodash": "^4.17.15", + "memoizerific": "^1.11.3", + "qs": "^6.6.0", + "stable": "^0.1.8", + "store2": "^2.7.1", + "ts-dedent": "^1.1.1", + "util-deprecate": "^1.0.2" + } + }, "@storybook/client-logger": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.13.tgz", @@ -10604,14 +10804,14 @@ } }, "@storybook/channel-postmessage": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.0.13.tgz", - "integrity": "sha512-WglkGiX0tAdftQVaNK8xlGW5gOjA9HQ+095G3cPehrPg7Rc7mEMCFvACVL2BlZBUCPljh2DA+fv7aQMcjuW/Xg==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.0.21.tgz", + "integrity": "sha512-ArRnoaS+b7qpAku/SO27z/yjRDCXb37mCPYGX0ntPbiQajootUbGO7otfnjFkaP44hCEC9uDYlOfMU1hYU1N6A==", "dev": true, "requires": { - "@storybook/channels": "6.0.13", - "@storybook/client-logger": "6.0.13", - "@storybook/core-events": "6.0.13", + "@storybook/channels": "6.0.21", + "@storybook/client-logger": "6.0.21", + "@storybook/core-events": "6.0.21", "core-js": "^3.0.1", "global": "^4.3.2", "qs": "^6.6.0", @@ -10619,9 +10819,9 @@ }, "dependencies": { "@storybook/channels": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.13.tgz", - "integrity": "sha512-99qcxeFFPP2FBNA/dSSKGrzuQaU1FQ8BjZlBubvYhWJku2kvXuCkUFHAWSgGc3aqb+lIZCXF3OWUFZ1fYMFmIA==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.21.tgz", + "integrity": "sha512-G6gjcEotSwDmOlxSmOMgsO3VhQ42RLJK7kFp6D5eg0Q6S8vsypltdT8orxdu+6+AbcBrL+5Sla8lThzaCvXsVQ==", "dev": true, "requires": { "core-js": "^3.0.1", @@ -10630,9 +10830,9 @@ } }, "@storybook/client-logger": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.13.tgz", - "integrity": "sha512-9Qt6v5bmec/DKdoj2TU2bL2CIRMFjoXoys7rMf82MX5PgtkaYk9IYa0i2i5tlfsT/Pw+E+Jv26QUwQkTCt++bQ==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.21.tgz", + "integrity": "sha512-8aUEbhjXV+UMYQWukVYnp+kZafF+LD4Dm7eMo37IUZvt3VIjV1VvhxIDVJtqjk2vv0KZTepESFBkZQLmBzI9Zg==", "dev": true, "requires": { "core-js": "^3.0.1", @@ -10640,9 +10840,9 @@ } }, "@storybook/core-events": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.0.13.tgz", - "integrity": "sha512-lnHnXXAkProci1G2qkPn3qorWkIiwukT4YSSYfwqZfuvbQZJIA1oiaBmQYpTU8CeQ1F73kHDpk2E2aTnUNJ29g==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.0.21.tgz", + "integrity": "sha512-p84fbPcsAhnqDhp+HJ4P8+vI2BqJus4IRoVAemLAwuPjyPElrV9UvOa/RHy1BN8Z6jXwFA+FFzfGl2kPJ3WYcA==", "dev": true, "requires": { "core-js": "^3.0.1" @@ -10712,16 +10912,16 @@ } }, "@storybook/client-api": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.0.13.tgz", - "integrity": "sha512-AL5YywpZo1LPi8FlIRiUXFBnV1h5039hUAVXMlVlOBud0iZuGlBZTsmgttL3GQUdC2hNQsbwZu7vAO/uqCsfRw==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.0.21.tgz", + "integrity": "sha512-emBXd/ml6pc3G8gP3MsR9zQsAq1zZbqof9MxB51tG/jpTXdqWQ8ce1pt1tJS8Xj0QDM072jR6wsY+mmro0GZnA==", "dev": true, "requires": { - "@storybook/addons": "6.0.13", - "@storybook/channel-postmessage": "6.0.13", - "@storybook/channels": "6.0.13", - "@storybook/client-logger": "6.0.13", - "@storybook/core-events": "6.0.13", + "@storybook/addons": "6.0.21", + "@storybook/channel-postmessage": "6.0.21", + "@storybook/channels": "6.0.21", + "@storybook/client-logger": "6.0.21", + "@storybook/core-events": "6.0.21", "@storybook/csf": "0.0.1", "@types/qs": "^6.9.0", "@types/webpack-env": "^1.15.2", @@ -10737,36 +10937,36 @@ }, "dependencies": { "@storybook/addons": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.0.13.tgz", - "integrity": "sha512-0flK0xe1LxNa3ZVOpFJoTG7PPU0ri+Gb9qHxcGwRMJt/qVQVcuF7BL+CC1R5gg2fa8Z0A867X4quLPfUOJvCmQ==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.0.21.tgz", + "integrity": "sha512-yDttNLc3vXqBxwK795ykgzTC6MpvuXDQuF4LHSlHZQe6wsMu1m3fljnbYdafJWdx6cNZwUblU3KYcR11PqhkPg==", "dev": true, "requires": { - "@storybook/api": "6.0.13", - "@storybook/channels": "6.0.13", - "@storybook/client-logger": "6.0.13", - "@storybook/core-events": "6.0.13", - "@storybook/router": "6.0.13", - "@storybook/theming": "6.0.13", + "@storybook/api": "6.0.21", + "@storybook/channels": "6.0.21", + "@storybook/client-logger": "6.0.21", + "@storybook/core-events": "6.0.21", + "@storybook/router": "6.0.21", + "@storybook/theming": "6.0.21", "core-js": "^3.0.1", "global": "^4.3.2", "regenerator-runtime": "^0.13.3" } }, "@storybook/api": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.0.13.tgz", - "integrity": "sha512-0LU9XWqSCQMFm9+C4JvQsv7reLv61Qc2Ev+btbvps2Bdg0MG6MKT8Qc4dzCc3vSbp0wh9b9DYMx/r7EvTRzUXA==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.0.21.tgz", + "integrity": "sha512-cRRGf/KGFwYiDouTouEcDdp45N1AbYnAfvLqYZ3KuUTGZ+CiU/PN/vavkp07DQeM4FIQO8TLhzHdsLFpLT7Lkw==", "dev": true, "requires": { "@reach/router": "^1.3.3", - "@storybook/channels": "6.0.13", - "@storybook/client-logger": "6.0.13", - "@storybook/core-events": "6.0.13", + "@storybook/channels": "6.0.21", + "@storybook/client-logger": "6.0.21", + "@storybook/core-events": "6.0.21", "@storybook/csf": "0.0.1", - "@storybook/router": "6.0.13", + "@storybook/router": "6.0.21", "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.0.13", + "@storybook/theming": "6.0.21", "@types/reach__router": "^1.3.5", "core-js": "^3.0.1", "fast-deep-equal": "^3.1.1", @@ -10782,9 +10982,9 @@ } }, "@storybook/channels": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.13.tgz", - "integrity": "sha512-99qcxeFFPP2FBNA/dSSKGrzuQaU1FQ8BjZlBubvYhWJku2kvXuCkUFHAWSgGc3aqb+lIZCXF3OWUFZ1fYMFmIA==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.0.21.tgz", + "integrity": "sha512-G6gjcEotSwDmOlxSmOMgsO3VhQ42RLJK7kFp6D5eg0Q6S8vsypltdT8orxdu+6+AbcBrL+5Sla8lThzaCvXsVQ==", "dev": true, "requires": { "core-js": "^3.0.1", @@ -10793,9 +10993,9 @@ } }, "@storybook/client-logger": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.13.tgz", - "integrity": "sha512-9Qt6v5bmec/DKdoj2TU2bL2CIRMFjoXoys7rMf82MX5PgtkaYk9IYa0i2i5tlfsT/Pw+E+Jv26QUwQkTCt++bQ==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.0.21.tgz", + "integrity": "sha512-8aUEbhjXV+UMYQWukVYnp+kZafF+LD4Dm7eMo37IUZvt3VIjV1VvhxIDVJtqjk2vv0KZTepESFBkZQLmBzI9Zg==", "dev": true, "requires": { "core-js": "^3.0.1", @@ -10803,18 +11003,18 @@ } }, "@storybook/core-events": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.0.13.tgz", - "integrity": "sha512-lnHnXXAkProci1G2qkPn3qorWkIiwukT4YSSYfwqZfuvbQZJIA1oiaBmQYpTU8CeQ1F73kHDpk2E2aTnUNJ29g==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.0.21.tgz", + "integrity": "sha512-p84fbPcsAhnqDhp+HJ4P8+vI2BqJus4IRoVAemLAwuPjyPElrV9UvOa/RHy1BN8Z6jXwFA+FFzfGl2kPJ3WYcA==", "dev": true, "requires": { "core-js": "^3.0.1" } }, "@storybook/router": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.0.13.tgz", - "integrity": "sha512-aLDMEDsTbqOv1pcOH+ovRVgdf8exqtTRGIcNTbEhBBnaDsbdo2sxoXHJ8n8xHw1TbpYx7zLD0HXbzSSJIlj1lg==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.0.21.tgz", + "integrity": "sha512-46SsKJfcd12lRrISnfrWhicJx8EylkgGDGohfH0n5p7inkkGOkKV8QFZoYPRKZueMXmUKpzJ0Z3HmVsLTCrCDw==", "dev": true, "requires": { "@reach/router": "^1.3.3", @@ -10844,15 +11044,15 @@ } }, "@storybook/theming": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.0.13.tgz", - "integrity": "sha512-XsiQv0I5NQ2gGcmpIS31zbfAS6HK8IJdAgltSSuF/Yzkwks+guqG4MYWaWGEQPPwYvPDZp+/gproWacQJgrjug==", + "version": "6.0.21", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.0.21.tgz", + "integrity": "sha512-n97DfB9kG6WrV1xBGDyeQibTrh8pBBCp3dSL3UTGH+KX3C2+4sm6QHlTgyekbi5FrbFEbnuZOKAS3YbLVONsRQ==", "dev": true, "requires": { "@emotion/core": "^10.0.20", "@emotion/is-prop-valid": "^0.8.6", "@emotion/styled": "^10.0.17", - "@storybook/client-logger": "6.0.13", + "@storybook/client-logger": "6.0.21", "core-js": "^3.0.1", "deep-object-diff": "^1.1.0", "emotion-theming": "^10.0.19", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 839dec8a2..f8f098012 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -189,6 +189,7 @@ "@storybook/addon-knobs": "^6.0.13", "@storybook/addon-links": "^5.3.19", "@storybook/addons": "^5.3.19", + "@storybook/client-api": "^6.0.21", "@storybook/preset-typescript": "^3.0.0", "@storybook/react": "^6.0.13", "@svgr/webpack": "^5.4.0", diff --git a/superset-frontend/spec/javascripts/components/Checkbox_spec.jsx b/superset-frontend/spec/javascripts/components/Checkbox_spec.jsx deleted file mode 100644 index 56b9c0255..000000000 --- a/superset-frontend/spec/javascripts/components/Checkbox_spec.jsx +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import React from 'react'; -import sinon from 'sinon'; -import { shallow } from 'enzyme'; - -import Checkbox from 'src/components/Checkbox'; - -describe('Checkbox', () => { - const defaultProps = { - checked: true, - onChange: sinon.spy(), - }; - - let wrapper; - const factory = o => { - const props = { ...defaultProps, ...o }; - return shallow(); - }; - beforeEach(() => { - wrapper = factory({}); - }); - it('is a valid element', () => { - expect(React.isValidElement()).toBe(true); - }); - it('inits checked when checked', () => { - expect(wrapper.find('i.fa-check.text-primary')).toExist(); - }); - it('inits unchecked when not checked', () => { - const el = factory({ checked: false }); - expect(el.find('i.fa-check.text-primary')).toHaveLength(0); - expect(el.find('i.fa-check.text-transparent')).toHaveLength(1); - }); - it('unchecks when clicked', () => { - expect(wrapper.find('i.fa-check.text-transparent')).not.toExist(); - wrapper.find('i').first().simulate('click'); - expect(defaultProps.onChange.calledOnce).toBe(true); - }); -}); diff --git a/superset-frontend/src/components/Button/Button.stories.jsx b/superset-frontend/src/components/Button/Button.stories.jsx index 3c578e82d..ac153b572 100644 --- a/superset-frontend/src/components/Button/Button.stories.jsx +++ b/superset-frontend/src/components/Button/Button.stories.jsx @@ -17,18 +17,15 @@ * under the License. */ import React from 'react'; -import { action } from '@storybook/addon-actions'; -import { withKnobs, boolean, select, text } from '@storybook/addon-knobs'; import Button from './index'; export default { title: 'Button', component: Button, - decorators: [withKnobs], - excludeStories: /.*Knob$/, + includeStories: ['ButtonGallery', 'InteractiveButton'], }; -export const buttonStyleKnob = { +export const STYLES = { label: 'Types', options: { Primary: 'primary', @@ -46,7 +43,7 @@ export const buttonStyleKnob = { // groupId: 'ButtonType', }; -export const buttonSizeKnob = { +export const SIZES = { label: 'Sizes', options: { XS: 'xsmall', @@ -76,7 +73,8 @@ export const buttonSizeKnob = { // }, // defaultValue: null, // }; -const typeKnob = { + +const TYPES = { label: 'Type', options: { Submit: 'submit', @@ -85,7 +83,7 @@ const typeKnob = { }, defaultValue: null, }; -const targetKnob = { +const TARGETS = { label: 'Target', options: { Blank: '_blank', @@ -93,7 +91,7 @@ const targetKnob = { }, defaultValue: null, }; -const hrefKnob = { +const HREFS = { label: 'HREF', options: { Superset: 'http://https://superset.incubator.apache.org/', @@ -104,18 +102,16 @@ const hrefKnob = { export const ButtonGallery = () => ( <> - {Object.entries(buttonSizeKnob.options).map(([name, size]) => ( + {Object.entries(SIZES.options).map(([name, size]) => (

{name}

- {Object.values(buttonStyleKnob.options) + {Object.values(STYLES.options) .filter(o => o) .map(style => ( -); +export const InteractiveButton = args => { + const { label, ...btnArgs } = args; + return ; +}; + +InteractiveButton.args = { + buttonStyle: STYLES.defaultValue, + size: SIZES.defaultValue, + type: TYPES.defaultValue, + target: TARGETS.defaultValue, + href: HREFS.defaultValue, + label: 'Button!', +}; +InteractiveButton.argTypes = { + buttonStyle: { + name: STYLES.label, + control: { type: 'select', options: Object.values(STYLES.options) }, + }, + size: { + name: SIZES.label, + control: { type: 'select', options: Object.values(SIZES.options) }, + }, + type: { + name: TYPES.label, + control: { type: 'select', options: Object.values(TYPES.options) }, + }, + target: { + name: TARGETS.label, + control: { type: 'select', options: Object.values(TARGETS.options) }, + }, + href: { + name: HREFS.label, + control: { type: 'select', options: Object.values(HREFS.options) }, + }, + onClick: { action: 'clicked' }, + label: { name: 'Label', control: { type: 'text' } }, +}; + +ButtonGallery.argTypes = { onClick: { action: 'clicked' } }; diff --git a/superset-frontend/src/components/Button/Button.test.tsx b/superset-frontend/src/components/Button/Button.test.tsx index 611a7db0b..ab0f368fd 100644 --- a/superset-frontend/src/components/Button/Button.test.tsx +++ b/superset-frontend/src/components/Button/Button.test.tsx @@ -23,8 +23,8 @@ import { styledMount as mount } from 'spec/helpers/theming'; import Button from '.'; import { ButtonGallery, - buttonSizeKnob, - buttonStyleKnob, + SIZES as buttonSizes, + STYLES as buttonStyles, } from './Button.stories'; describe('Button', () => { @@ -54,8 +54,8 @@ describe('Button', () => { wrapper = mount(); const permutationCount = - Object.values(buttonStyleKnob.options).filter(o => o).length * - Object.values(buttonSizeKnob.options).length; + Object.values(buttonStyles.options).filter(o => o).length * + Object.values(buttonSizes.options).length; expect(wrapper.find(Button).length).toEqual(permutationCount); }); diff --git a/superset-frontend/src/components/Checkbox/Checkbox.stories.jsx b/superset-frontend/src/components/Checkbox/Checkbox.stories.jsx new file mode 100644 index 000000000..10be17604 --- /dev/null +++ b/superset-frontend/src/components/Checkbox/Checkbox.stories.jsx @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { useArgs } from '@storybook/client-api'; +import Checkbox from './'; + +export default { + title: 'Checkbox', + component: Checkbox, +}; + +const STATUSES = { + checked: true, + unchecked: false, +}; + +export const CheckboxGallery = () => + Object.keys(STATUSES).map(status => ( +
+ {}} + checked={STATUSES[status]} + style={{ marginRight: '8px' }} + /> + {`I'm a${STATUSES[status] ? '' : 'n'} ${status} checkbox`} +
+ )); + +// eslint-disable-next-line no-unused-vars +export const InteractiveCheckbox = _args => { + const [{ checked, style }, updateArgs] = useArgs(); + const toggleCheckbox = () => { + updateArgs({ checked: !checked }); + }; + + return ( + <> + + I'm an interactive checkbox + + ); +}; + +InteractiveCheckbox.args = { + checked: false, + style: { marginRight: '8px' }, +}; diff --git a/superset-frontend/src/components/Checkbox/Checkbox.test.tsx b/superset-frontend/src/components/Checkbox/Checkbox.test.tsx new file mode 100644 index 000000000..37b4d7316 --- /dev/null +++ b/superset-frontend/src/components/Checkbox/Checkbox.test.tsx @@ -0,0 +1,75 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { ReactWrapper } from 'enzyme'; +import { + styledMount as mount, + styledShallow as shallow, +} from 'spec/helpers/theming'; + +import Checkbox from '.'; +import { CheckboxChecked, CheckboxUnchecked } from './../CheckboxIcons'; + +describe('Checkbox', () => { + let wrapper: ReactWrapper; + + it('renders the base component', () => { + expect( + React.isValidElement( + true} />, + ), + ).toBe(true); + }); + + describe('when unchecked', () => { + it('renders the unchecked component', () => { + const shallowWrapper = shallow( + true} />, + ); + expect(shallowWrapper.dive().dive().find(CheckboxUnchecked)).toExist(); + }); + }); + + describe('when checked', () => { + it('renders the checked component', () => { + const shallowWrapper = shallow( + true} />, + ); + expect(shallowWrapper.dive().dive().find(CheckboxChecked)).toExist(); + }); + }); + + it('works with an onChange handler', () => { + const mockAction = jest.fn(); + wrapper = mount( + , + ); + wrapper.find('Checkbox').first().simulate('click'); + expect(mockAction).toHaveBeenCalled(); + }); + + it('renders custom Checkbox styles without melting', () => { + wrapper = mount( + true} checked={false} style={{ foo: 'foo' }} />, + ); + expect(wrapper.find('Checkbox')).toExist(); + expect(wrapper.find('Checkbox')).toHaveStyle({ foo: 'foo' }); + }); +}); diff --git a/superset-frontend/src/components/Checkbox.tsx b/superset-frontend/src/components/Checkbox/index.tsx similarity index 68% rename from superset-frontend/src/components/Checkbox.tsx rename to superset-frontend/src/components/Checkbox/index.tsx index f5ceeb450..621ce1755 100644 --- a/superset-frontend/src/components/Checkbox.tsx +++ b/superset-frontend/src/components/Checkbox/index.tsx @@ -17,6 +17,11 @@ * under the License. */ import React from 'react'; +import { styled } from '@superset-ui/core'; +import { + CheckboxChecked, + CheckboxUnchecked, +} from 'src/components/CheckboxIcons'; interface CheckboxProps { checked: boolean; @@ -24,25 +29,26 @@ interface CheckboxProps { style: object; } +const Styles = styled.span` + &, + & svg { + vertical-align: top; + } +`; + export default function Checkbox({ checked, onChange, style }: CheckboxProps) { return ( - - { - onChange(!checked); - }} - style={{ - border: '1px solid #aaa', - borderRadius: '2px', - cursor: 'pointer', - }} - /> - + { + onChange(!checked); + }} + role="checkbox" + tabIndex={0} + aria-checked={checked} + aria-label="Checkbox" + > + {checked ? : } + ); }