diff --git a/.storybook/main.js b/.storybook/main.js index bc6c29a5a8..4f11fcd6a5 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,10 +1,9 @@ module.exports = { - stories: ['../stories/**/*.@(mdx|stories.@(ts|tsx))'], + stories: ['../stories/**/*.@(mdx|stories.@(ts|tsx))', '../src/**/**/*.@(mdx|stories.@(ts|tsx))'], addons: [ '@storybook/addon-essentials', '@storybook/addon-storysource', - // '@storybook/addon-knobs', '@storybook/addon-mdx-gfm' ], @@ -26,6 +25,7 @@ module.exports = { }, docs: { - autodocs: true + autodocs: true, + defaultName: 'Stories', } }; diff --git a/.storybook/preview.js b/.storybook/preview.js index 9eb7b32b36..b60797cc23 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -2,6 +2,7 @@ import React from 'react'; import { QueryClient, QueryClientProvider } from 'react-query'; import { CoreUiThemeProvider } from '../src/lib/next'; import { brand, coreUIAvailableThemes} from '../src/lib/style/theme'; +import { Wrapper } from '../stories/common'; export const globalTypes = { @@ -19,10 +20,16 @@ export const globalTypes = { const withThemeProvider = (Story, context) => { const theme = coreUIAvailableThemes[context.globals.theme]; + const {viewMode} = context return ( - + {/* Wrapper to make the stories take the full screen but not in docs */} +
+ + + +
); @@ -31,6 +38,11 @@ const withThemeProvider = (Story, context) => { export const decorators = [withThemeProvider]; export const parameters = { + layout: 'fullscreen', + docs:{ + toc : {headingSelector: 'h2,h3', + title: "Table of Contents"}, + }, controls:{ //All props with color in name will automatically have a control 'color' //with colors presets to theme colors, possible to have the color name from theme in control @@ -47,6 +59,7 @@ export const parameters = { 'Guidelines', 'Templates', 'Components', + ['Navigation', 'Data Display', 'Inputs', 'Feedback', 'Progress & loading', 'Styling', 'Deprecated'] ], }, diff --git a/package-lock.json b/package-lock.json index ee5a16543b..100a4f19a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,6 @@ "@js-temporal/polyfill": "^0.4.3", "@storybook/addon-actions": "^7.5.3", "@storybook/addon-essentials": "^7.5.3", - "@storybook/addon-knobs": "^7.0.2", "@storybook/addon-links": "^7.5.3", "@storybook/addon-mdx-gfm": "^7.5.3", "@storybook/addon-storyshots": "^7.5.3", @@ -5382,88 +5381,6 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/addon-knobs": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-knobs/-/addon-knobs-7.0.2.tgz", - "integrity": "sha512-PzKuscxcBPhA2jpDxJ/F+BvBRqHJ8qBki1kS1IOjmJbAfE96WFnweXZ73ImyAJnRtmtReCL6p0ZmFkrNDMDpUw==", - "dev": true, - "dependencies": { - "copy-to-clipboard": "^3.3.3", - "core-js": "^3.29.0", - "escape-html": "^1.0.3", - "fast-deep-equal": "^3.1.3", - "global": "^4.4.0", - "lodash": "^4.17.21", - "prop-types": "^15.8.1", - "qs": "^6.11.1", - "react-colorful": "^5.6.1", - "react-lifecycles-compat": "^3.0.4", - "react-select": "^5.7.0" - }, - "peerDependencies": { - "@storybook/addons": "^7.0.0", - "@storybook/api": "^7.0.0", - "@storybook/components": "^7.0.0", - "@storybook/core-events": "^7.0.0", - "@storybook/theming": "^7.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/@storybook/addon-knobs/node_modules/@floating-ui/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", - "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", - "dev": true, - "dependencies": { - "@floating-ui/utils": "^0.1.3" - } - }, - "node_modules/@storybook/addon-knobs/node_modules/@floating-ui/dom": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", - "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", - "dev": true, - "dependencies": { - "@floating-ui/core": "^1.4.2", - "@floating-ui/utils": "^0.1.3" - } - }, - "node_modules/@storybook/addon-knobs/node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", - "dev": true - }, - "node_modules/@storybook/addon-knobs/node_modules/react-select": { - "version": "5.7.7", - "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.7.tgz", - "integrity": "sha512-HhashZZJDRlfF/AKj0a0Lnfs3sRdw/46VJIRd8IbB9/Ovr74+ZIwkAdSBjSPXsFMG+u72c5xShqwLSKIJllzqw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.0", - "@emotion/cache": "^11.4.0", - "@emotion/react": "^11.8.1", - "@floating-ui/dom": "^1.0.1", - "@types/react-transition-group": "^4.4.0", - "memoize-one": "^6.0.0", - "prop-types": "^15.6.0", - "react-transition-group": "^4.3.0", - "use-isomorphic-layout-effect": "^1.1.2" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/@storybook/addon-links": { "version": "7.5.3", "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.5.3.tgz", @@ -8482,15 +8399,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-transition-group": { - "version": "4.4.7", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.7.tgz", - "integrity": "sha512-ICCyBl5mvyqYp8Qeq9B5G/fyBSRC0zx3XM3sCC6KkcMsNeAHqXBKkmat4GqdJET5jtYUpZXrxI5flve5qhi2Eg==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-virtualized-auto-sizer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz", @@ -11815,15 +11723,6 @@ "node": ">=0.10.0" } }, - "node_modules/copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "dev": true, - "dependencies": { - "toggle-selection": "^1.0.6" - } - }, "node_modules/copyfiles": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", @@ -11893,17 +11792,6 @@ "node": ">=10" } }, - "node_modules/core-js": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.0.tgz", - "integrity": "sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-js-compat": { "version": "3.33.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", @@ -12900,12 +12788,6 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, "node_modules/domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -16172,16 +16054,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "node_modules/global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -21797,15 +21669,6 @@ "node": ">=6" } }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "dev": true, - "dependencies": { - "dom-walk": "^0.1.0" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -27107,12 +26970,6 @@ "integrity": "sha512-bAnyV6SU2n1AvuBvEgi8t7KiIn5rRiEmwFp4+elx/1ueuncAUyubITfXDMwOqStgUwh8pDzLdWgDKLicsJPikw==", "dev": true }, - "node_modules/toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", - "dev": true - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -27739,20 +27596,6 @@ } } }, - "node_modules/use-isomorphic-layout-effect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", - "dev": true, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/use-resize-observer": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-9.1.0.tgz", @@ -32708,69 +32551,6 @@ "@storybook/preview-api": "7.5.3" } }, - "@storybook/addon-knobs": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@storybook/addon-knobs/-/addon-knobs-7.0.2.tgz", - "integrity": "sha512-PzKuscxcBPhA2jpDxJ/F+BvBRqHJ8qBki1kS1IOjmJbAfE96WFnweXZ73ImyAJnRtmtReCL6p0ZmFkrNDMDpUw==", - "dev": true, - "requires": { - "copy-to-clipboard": "^3.3.3", - "core-js": "^3.29.0", - "escape-html": "^1.0.3", - "fast-deep-equal": "^3.1.3", - "global": "^4.4.0", - "lodash": "^4.17.21", - "prop-types": "^15.8.1", - "qs": "^6.11.1", - "react-colorful": "^5.6.1", - "react-lifecycles-compat": "^3.0.4", - "react-select": "^5.7.0" - }, - "dependencies": { - "@floating-ui/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.0.tgz", - "integrity": "sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==", - "dev": true, - "requires": { - "@floating-ui/utils": "^0.1.3" - } - }, - "@floating-ui/dom": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", - "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", - "dev": true, - "requires": { - "@floating-ui/core": "^1.4.2", - "@floating-ui/utils": "^0.1.3" - } - }, - "memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", - "dev": true - }, - "react-select": { - "version": "5.7.7", - "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.7.tgz", - "integrity": "sha512-HhashZZJDRlfF/AKj0a0Lnfs3sRdw/46VJIRd8IbB9/Ovr74+ZIwkAdSBjSPXsFMG+u72c5xShqwLSKIJllzqw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.0", - "@emotion/cache": "^11.4.0", - "@emotion/react": "^11.8.1", - "@floating-ui/dom": "^1.0.1", - "@types/react-transition-group": "^4.4.0", - "memoize-one": "^6.0.0", - "prop-types": "^15.6.0", - "react-transition-group": "^4.3.0", - "use-isomorphic-layout-effect": "^1.1.2" - } - } - } - }, "@storybook/addon-links": { "version": "7.5.3", "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.5.3.tgz", @@ -34974,15 +34754,6 @@ "@types/react": "*" } }, - "@types/react-transition-group": { - "version": "4.4.7", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.7.tgz", - "integrity": "sha512-ICCyBl5mvyqYp8Qeq9B5G/fyBSRC0zx3XM3sCC6KkcMsNeAHqXBKkmat4GqdJET5jtYUpZXrxI5flve5qhi2Eg==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, "@types/react-virtualized-auto-sizer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz", @@ -37481,15 +37252,6 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, - "copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "dev": true, - "requires": { - "toggle-selection": "^1.0.6" - } - }, "copyfiles": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", @@ -37545,12 +37307,6 @@ } } }, - "core-js": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.0.tgz", - "integrity": "sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw==", - "dev": true - }, "core-js-compat": { "version": "3.33.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", @@ -38289,12 +38045,6 @@ "entities": "^2.0.0" } }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, "domelementtype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", @@ -40760,16 +40510,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -44815,15 +44555,6 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -48960,12 +48691,6 @@ "integrity": "sha512-bAnyV6SU2n1AvuBvEgi8t7KiIn5rRiEmwFp4+elx/1ueuncAUyubITfXDMwOqStgUwh8pDzLdWgDKLicsJPikw==", "dev": true }, - "toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", - "dev": true - }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -49430,12 +49155,6 @@ "tslib": "^2.0.0" } }, - "use-isomorphic-layout-effect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", - "dev": true - }, "use-resize-observer": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-9.1.0.tgz", diff --git a/package.json b/package.json index 7589153c83..cc6f6cd11e 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ "@js-temporal/polyfill": "^0.4.3", "@storybook/addon-actions": "^7.5.3", "@storybook/addon-essentials": "^7.5.3", - "@storybook/addon-knobs": "^7.0.2", "@storybook/addon-links": "^7.5.3", "@storybook/addon-mdx-gfm": "^7.5.3", "@storybook/addon-storyshots": "^7.5.3", diff --git a/src/lib/components/buttonv2/Buttonv2.component.tsx b/src/lib/components/buttonv2/Buttonv2.component.tsx index 23877b52b4..19719289a6 100644 --- a/src/lib/components/buttonv2/Buttonv2.component.tsx +++ b/src/lib/components/buttonv2/Buttonv2.component.tsx @@ -1,8 +1,9 @@ import React, { ButtonHTMLAttributes } from 'react'; import styled, { css } from 'styled-components'; -import { Tooltip, Props as TooltipProps } from '../tooltip/Tooltip.component'; -import { fontSize, fontWeight } from '../../style/theme'; import { spacing } from '../../spacing'; +import { fontSize, fontWeight } from '../../style/theme'; +import { Loader } from '../loader/Loader.component'; +import { Tooltip, Props as TooltipProps } from '../tooltip/Tooltip.component'; export type Props = Omit< ButtonHTMLAttributes, 'size' | 'label' @@ -14,10 +15,12 @@ export type Props = Omit< icon?: React.ReactNode; label?: React.ReactNode; tooltip?: Omit; + isLoading?: boolean; }; export const ButtonStyled = styled.button` -webkit-appearance: none; -moz-appearance: none; + appearance: none; position: relative; display: inline-flex; user-select: none; @@ -35,7 +38,6 @@ export const ButtonStyled = styled.button` font-size: ${fontSize.base}; border-radius: ${spacing.r4}; height: ${(props) => (props.size === 'inline' ? spacing.r24 : spacing.r32)}; - ${(props) => { const brand = props.theme; @@ -185,6 +187,21 @@ export const ButtonIcon = styled.span<{ label: React.ReactNode }>` `} `; +export const ButtonLoader = styled(Loader)<{ label; variant }>` + ${(props) => { + return css` + margin-right: ${props.label ? spacing.r8 : '0'}; + svg { + fill: ${props.variant === 'danger' + ? props.theme.statusCritical + : props.variant === 'outline' + ? props.theme.textPrimary + : props.theme.textSecondary}; + } + `; + }} +`; + function Button({ variant, size, @@ -193,6 +210,7 @@ function Button({ icon, onClick, tooltip, + isLoading, ...rest }: Props) { if (!icon && !label) { @@ -214,7 +232,7 @@ function Button({ <> - {icon && ( - - {icon} - + {icon && + (isLoading ? ( + + ) : ( + + {icon} + + ))} + {!icon && isLoading && ( + )} {label} diff --git a/stories/Button/button.guideline.mdx b/stories/Button/button.guideline.mdx new file mode 100644 index 0000000000..37d7b695bc --- /dev/null +++ b/stories/Button/button.guideline.mdx @@ -0,0 +1,197 @@ +import { + Meta, + Story, + Canvas, + Primary, + Controls, + Unstyled, + Source, + Title, +} from '@storybook/blocks'; +import { Button } from '../../src/lib/components/buttonv2/Buttonv2.component'; + +import * as ButtonStories from './button.stories'; + + + +# Button + +Buttons are used to trigger an action or event when activated. + +## Size & style + +### Style + +- Height: 2rem +- Border-radius: 3px +- Minimum width: 5rem + +### Padding + +Button’s label measurement: + +- Line height: 1.25rem +- Vertical padding: 0.5rem +- Horizontal padding of 1rem +- Space between icon & label: 0.5rem + +### Button spacing + +- Horizontal spacing: 1rem +- Vertical spacing: 0.75rem +- Space between 2 buttons: 1.5rem - when there is no space constraint + +## Usage + +Button labels should be as short and clear as possible and should describe the action the button performs.\ + +- Use one or two words if possible, +- Remove most prepositions and articles (a, an, the). +- Examples: Cancel, Close, Create, Delete, Edit, Learn More, Review, Save, Study, View Scores, etc., +- Stick to using verbs (Complete, Start, Finish, Search) or a simple verb + noun combination for buttons (Next page, Submit post, Learn more), +- Capitalize the noun after the verb (Create Folder, Create Node, Edit Location). +- Maintain labelling method consistency across all of your buttons, +- Don't use punctuation or exclamation marks (!), +- And, most importantly, don't write "Click here". + +## Variations + +The button can be modified in different way to match its usage. + +### Variant + +Buttons have a set of predefined variants to use in different context. + + +
+ +#### Primary + +Used for the main action. It should only appear once within a group of buttons (or even a screen). +For example, “Continue” in a form. + + + +#### Secondary + +Used for a secondary action within a group of buttons. + + + +#### Outline + +Used for low-emphasis action, as an alternative to Primary or Secondary buttons. +It's suitable for dismissive action, such as the "Cancel" button. + + + +#### Danger + +Used for critical action, typically delete actions. +Actions triggered by such button often require additional validation, as the critical action cannot be undone. + + + +### Links + +The Button component can be used as a link to another element of the UI. +When the link send to another site, use the "External-link-alt" icon. + +### Size + +Only 2 sizes are available for the button component : default and inline. + +Inline size is use for constraint spaces, like in tables or in key/values sections. +On all others cases, use the default size. + + + +### States + +#### Disabled state + +Clicks on the button should trigger no action, and the cursor should display a "not-allowed" indicator. \ +A tooltip explaining the reason for the button’s disabled state should appear on hover. + + + +#### Loading State + +Display a spinner animation within the button. \ +Disable any interactions during the loading process. + + + +## Group of Button + +- Primary buttons placed on the right of a group. +- Dismissive actions placed on the left. It allows the user to return to the previous screen or step in the process. + +Align button groups with the container's right side by default; however, based on the use case and visual balance it can be aligned differently. + + + +## Icon on buttons + +### Usage + +Every button gets a label.\ +Icons are optional and mainly used to show how buttons are different, to aid memory and differentiation.\ +Universally understood icons work well (ie. print, close, play/pause, save).\ +Use standard icons when their use matches their meaning, or at least the user's intent.\ +Avoid creating new icons for every action, especially infrequently used ones.\ +Avoid using an icon alone in a button. If no label is provided, then use a tooltip. + +### Placement + +Icons are to be positioned only on the left side of the text.\ +Icons should be vertically center-aligned with the text.\ +The icon should be (approximately) the same height as the text.\ +Seeing the icon first help users to scan the page more easily, except for few cases such as navigation (right arrow). + + + + + +### Accessibility + +- Icons in Button Design: \ + Easily recognizable icons help with the quick recognition of a button’s function. If the icon is not clear enough, it loses its purpose, so in such cases, avoid using icons. +- Aria Labels: \ + Providing descriptive labels for screen readers is really helpful, especially for buttons that use icons only. + +## Ghost Buttons + +Ghost buttons are subtle and contribute to a minimalist interface design. +They are low-emphasis, making them ideal for non-primary actions in UIs. +They're also effective in space-limited areas like tables or key-value lists. + +- Ensure tooltips are included for clarity +- Don't confuse them with non-interactive elements like descriptive icons or status indicators +- Use them for secondary or less crucial actions. +- Don't opt for them over Outline buttons, which are more visibly recognizable as buttons. +- Create too many different instances of ghost buttons; limit them to common actions (e.g. link to other UIs). + + + +### Playground + + + + diff --git a/stories/buttonv2.stories.tsx b/stories/Button/button.stories.tsx similarity index 51% rename from stories/buttonv2.stories.tsx rename to stories/Button/button.stories.tsx index 26a7c2d739..3ae42183c9 100644 --- a/stories/buttonv2.stories.tsx +++ b/stories/Button/button.stories.tsx @@ -1,17 +1,11 @@ -import React from 'react'; import { action } from '@storybook/addon-actions'; -import { - Button, - Props, -} from '../src/lib/components/buttonv2/Buttonv2.component'; -import { Wrapper } from './common'; -import { CopyButton } from '../src/lib/next'; - -import { tooltipArgTypes, iconArgType } from './controls'; -import { Form, Icon, Input, Stack } from '../src/lib'; -import { StoryObj } from '@storybook/react'; -import { Position } from '../src/lib/components/tooltip/Tooltip.component'; -import { CSSProperties } from 'styled-components'; +import React from 'react'; +import { Form, FormGroup, FormSection, Icon, Stack } from '../../src/lib'; +import { Button } from '../../src/lib/components/buttonv2/Buttonv2.component'; +import { Input } from '../../src/lib/next'; +import { brand } from '../../src/lib/style/theme'; +import { iconArgType } from '../controls'; +import { Wrapper } from '../common'; export default { title: 'Components/Button', @@ -26,30 +20,18 @@ export default { args: { onClick: action('Button clicked'), }, + render: ({ icon, ...args }) => { + return - ); - }, }; export const Playground = { @@ -65,25 +47,25 @@ export const DefaultButtons = {