diff --git a/.gitignore b/.gitignore index 50ea6320..4da9fc9b 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ yarn-error.log* /src/stories/ *storybook.log +/dist/ diff --git a/.storybook/manager.ts b/.storybook/manager.ts index 82740ee6..afe6c8c9 100644 --- a/.storybook/manager.ts +++ b/.storybook/manager.ts @@ -2,5 +2,5 @@ import { addons } from 'storybook/manager-api'; import yourTheme from './theme'; addons.setConfig({ - theme: yourTheme, -}); \ No newline at end of file + theme: yourTheme, +}); diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 731460e9..f86cfc33 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import 'react-loading-skeleton/dist/skeleton.css'; import type { Preview } from '@storybook/react-vite'; @@ -16,11 +16,35 @@ const GlobalStyles = createGlobalStyle` const preview: Preview = { // tags: ['autodocs'], // turn on when fix some components stories decorators: [ - (Story) => ( - - - - ), + (Story) => { + useEffect(() => { + // Google Analytics tracking code + const script = document.createElement('script'); + script.async = true; + script.src = 'https://www.googletagmanager.com/gtag/js?id=G-H4X1J4017T'; // Replace with your GA4 Measurement ID + document.head.appendChild(script); + + script.onload = () => { + window.dataLayer = window.dataLayer || []; + function gtag() { + dataLayer.push(arguments); + } + gtag('js', new Date()); + gtag('config', 'G-H4X1J4017T'); // Replace with your GA4 Measurement ID + }; + + return () => { + // Optional: Clean up the script if needed + document.head.removeChild(script); + }; + }, []); + + return ( + + + + ); + }, withThemeFromJSXProvider({ themes: { light: themeConfig.light, diff --git a/dist/lib/components/cspr/cspr.d.ts b/dist/lib/components/cspr/cspr.d.ts index 490ca67c..b5505192 100644 --- a/dist/lib/components/cspr/cspr.d.ts +++ b/dist/lib/components/cspr/cspr.d.ts @@ -4,6 +4,6 @@ export interface CsprProps { precisionCase?: PrecisionCase; hideCsprCurrency?: boolean; } -export declare function Cspr({ motes, precisionCase, hideCsprCurrency }: CsprProps): import("react/jsx-runtime").JSX.Element; -export default Cspr; +export declare function CSPR({ motes, precisionCase, hideCsprCurrency }: CsprProps): import("react/jsx-runtime").JSX.Element; +export default CSPR; //# sourceMappingURL=cspr.d.ts.map \ No newline at end of file diff --git a/favicon-16x16.png b/favicon-16x16.png index 8bc93a7d..e9bed07a 100644 Binary files a/favicon-16x16.png and b/favicon-16x16.png differ diff --git a/favicon-32x32.png b/favicon-32x32.png index fabf52de..e9bed07a 100644 Binary files a/favicon-32x32.png and b/favicon-32x32.png differ diff --git a/favicon.ico b/favicon.ico index 19e44bbe..e9bed07a 100644 Binary files a/favicon.ico and b/favicon.ico differ diff --git a/manifest.json b/manifest.json index 3161052d..8c32d887 100644 --- a/manifest.json +++ b/manifest.json @@ -8,13 +8,13 @@ "type": "image/x-icon" }, { - "src": "favicon-16x16.png", - "type": "image/png", + "src": "favicon-16x16.svg", + "type": "image/svg", "sizes": "192x192" }, { - "src": "favicon-32x32.png", - "type": "image/png", + "src": "favicon-32x32.svg", + "type": "image/svg", "sizes": "512x512" } ], diff --git a/package-lock.json b/package-lock.json index bf78b8d6..e947e79e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "@make-software/cspr.design", - "version": "2.0.0-beta1", + "name": "@make-software/cspr-design", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@make-software/cspr.design", + "name": "@make-software/cspr-design", "version": "2.0.0", "dependencies": { "@formatjs/intl": "^3.1.6", @@ -20,7 +20,6 @@ "react-loading-skeleton": "^3.5.0", "react-modal": "^3.16.1", "reakit": "^1.3.11", - "remark-gfm": "^4.0.1", "styled-components": "^5.3.11", "web-vitals": "^4.2.4" }, @@ -42,6 +41,7 @@ "@vitejs/plugin-react": "^4.7.0", "babel-plugin-named-exports-order": "^0.0.2", "eslint-plugin-storybook": "^9.0.18", + "remark-gfm": "^4.0.1", "shx": "^0.4.0", "storybook": "^9.0.18", "typescript": "^5.8.3", @@ -2272,6 +2272,7 @@ "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/ms": "*" @@ -2360,6 +2361,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "*" @@ -2376,6 +2378,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, "license": "MIT" }, "node_modules/@types/node": { @@ -2456,6 +2459,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, "license": "MIT" }, "node_modules/@types/yargs": { @@ -3034,6 +3038,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -3192,6 +3197,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -3236,6 +3242,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -3444,6 +3451,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", + "dev": true, "license": "MIT", "dependencies": { "character-entities": "^2.0.0" @@ -3477,6 +3485,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -3486,6 +3495,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, "license": "MIT", "dependencies": { "dequal": "^2.0.0" @@ -3875,6 +3885,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, "license": "MIT" }, "node_modules/facepaint": { @@ -4308,6 +4319,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -4599,6 +4611,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -4658,6 +4671,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -4668,6 +4682,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -4684,6 +4699,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -4696,6 +4712,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -4720,6 +4737,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "dev": true, "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^2.0.0", @@ -4739,6 +4757,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -4756,6 +4775,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -4773,6 +4793,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -4788,6 +4809,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -4805,6 +4827,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -4821,6 +4844,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -4835,6 +4859,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -4856,6 +4881,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0" @@ -4879,6 +4905,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -4914,6 +4941,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -4948,6 +4976,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dev": true, "license": "MIT", "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", @@ -4968,6 +4997,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", @@ -4984,6 +5014,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -5004,6 +5035,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dev": true, "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -5022,6 +5054,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -5039,6 +5072,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dev": true, "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" @@ -5052,6 +5086,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dev": true, "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -5069,6 +5104,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5090,6 +5126,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5112,6 +5149,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5132,6 +5170,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5154,6 +5193,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5176,6 +5216,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5196,6 +5237,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5215,6 +5257,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5236,6 +5279,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5256,6 +5300,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5275,6 +5320,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5297,6 +5343,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5313,6 +5360,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5329,6 +5377,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5348,6 +5397,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5367,6 +5417,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5388,6 +5439,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5410,6 +5462,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -5426,6 +5479,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -6250,6 +6304,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -6268,6 +6323,7 @@ "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -6284,6 +6340,7 @@ "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -6923,6 +6980,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -7018,6 +7076,7 @@ "version": "11.0.5", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -7037,6 +7096,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -7050,6 +7110,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -7063,6 +7124,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -7078,6 +7140,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -7157,6 +7220,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -7171,6 +7235,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -7481,6 +7546,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, "license": "MIT", "funding": { "type": "github", diff --git a/package.json b/package.json index e9f1ddd8..e5ee4024 100644 --- a/package.json +++ b/package.json @@ -93,9 +93,9 @@ "@types/react-modal": "^3.16.3", "@types/styled-components": "^5.1.34", "@vitejs/plugin-react": "^4.7.0", - "remark-gfm": "^4.0.1", "babel-plugin-named-exports-order": "^0.0.2", "eslint-plugin-storybook": "^9.0.18", + "remark-gfm": "^4.0.1", "shx": "^0.4.0", "storybook": "^9.0.18", "typescript": "^5.8.3", diff --git a/src/01-Home.mdx b/src/01-Home.mdx index d9dea0aa..13529a41 100644 --- a/src/01-Home.mdx +++ b/src/01-Home.mdx @@ -1,5 +1,5 @@ import {Meta} from '@storybook/addon-docs/blocks'; -import {MenuBlocks, StyledHeaderWrapper, StyledWrapper} from "./storybook-components.tsx"; +import {StyledHeaderWrapper, StyledWrapper} from "./storybook-components.tsx"; diff --git a/src/03-ColorPalette.mdx b/src/03-ColorPalette.mdx index 64a30c95..81cdebc1 100644 --- a/src/03-ColorPalette.mdx +++ b/src/03-ColorPalette.mdx @@ -6,7 +6,7 @@ import {StyledHeaderWrapper, StyledWrapper} from "./storybook-components.tsx"; - # Palette of colors + # Color palette diff --git a/src/lib/components/accordion/accordion.stories.tsx b/src/lib/components/accordion/accordion.stories.tsx new file mode 100644 index 00000000..019b1631 --- /dev/null +++ b/src/lib/components/accordion/accordion.stories.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; +import FlexColumn from '../flex-column/flex-column'; +import Accordion from './accordion'; + +export default { + component: Accordion, + // tags: ['autodocs', '!dev'], + excludeStories: ['Primary'], + title: 'Components/Display/Accordion', + args: { + children: (render) => ( + <> +
Accordion
+
Accordion
+
Accordion
+
Accordion
+
Accordion
+ + ), + }, + argTypes: {}, +} as Meta; + +const Template: StoryFn = (args) => ( + + + +); + +export const Primary = Template.bind({}); diff --git a/src/lib/components/account-info-row/account-info-row.stories.tsx b/src/lib/components/account-info-row/account-info-row.stories.tsx index cab8ace9..2b34d41e 100644 --- a/src/lib/components/account-info-row/account-info-row.stories.tsx +++ b/src/lib/components/account-info-row/account-info-row.stories.tsx @@ -5,8 +5,9 @@ import FlexColumn from '../flex-column/flex-column'; export default { component: AccountInfoRow, + excludeStories: ['Primary'], // tags: ['autodocs', '!dev'], - title: 'Components/Forms and inputs/Account Info Row', + title: 'Components/Display/AccountInfoRow', parameters: { controls: { sort: 'requiredFirst', diff --git a/src/lib/components/account-info-row/account-info-row.tsx b/src/lib/components/account-info-row/account-info-row.tsx index 8c9e19b8..ad5ad42e 100644 --- a/src/lib/components/account-info-row/account-info-row.tsx +++ b/src/lib/components/account-info-row/account-info-row.tsx @@ -8,7 +8,7 @@ import { DEFAULT_PRECISION, formatHash } from '../../utils/formatters'; import { Tooltip } from '../tooltip/tooltip'; import { useMatchMedia } from '../../utils/match-media'; import { CopyHash } from '../copy-hash/copy-hash'; -import { Cspr } from '../cspr/cspr'; +import { CSPR } from '../cspr/cspr'; import { PrecisionCase } from '../../utils/currency'; import { HashLength } from '../../utils/formatters'; @@ -53,7 +53,7 @@ interface TickerProps { const Ticker = ({ ticker, cep18Config, ...props }: TickerProps) => { return ticker === 'CSPR' ? ( - + ) : ( ( - - Rank - Balance{' '} - Owner - - ), - renderData: () => ( - <> - {mockedData.map((data) => ( - - - {data.rank} - - - - - - - - {data.owner} - - - ))} - - ), - }, -} as Meta; - -const Template: StoryFn = (args: BaseTableProps) => { - return ( - - - - ); -}; - -export const Primary = Template.bind({}); diff --git a/src/lib/components/base-table/base-table.tsx b/src/lib/components/base-table/base-table.tsx deleted file mode 100644 index df322d2e..00000000 --- a/src/lib/components/base-table/base-table.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import React, { ReactNode } from 'react'; -import styled from 'styled-components'; -import TableHead from '../table-head/table-head'; -import TableBody from '../table-body/table-body'; -import BodyText from '../body-text/body-text'; - -export interface BaseTableProps { - renderHeader?: () => ReactNode; - renderDataHeaders?: () => ReactNode; - renderData?: () => ReactNode; - renderFooter?: () => ReactNode; - noData?: boolean; - noDataMessage?: string; - paddingBottom?: number; -} - -export const TableContainer = styled.div<{ paddingBottom?: number }>( - ({ theme, paddingBottom }) => ({ - overflowX: 'auto', - ...(paddingBottom && { paddingBottom }), - }), -); - -const StyledTable = styled.table(({ theme }) => ({ - width: '100%', - position: 'relative', - borderCollapse: 'collapse', -})); - -const NoDataContainer = styled.div(({ theme }) => ({ - position: 'absolute', - top: 0, - width: '100%', - height: '100%', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', -})); - -export function BaseTable(props: BaseTableProps) { - const { - renderHeader, - renderDataHeaders, - renderData, - renderFooter, - noData, - noDataMessage, - paddingBottom, - } = props; - - return ( - <> - {renderHeader && renderHeader()} - - - {renderDataHeaders && {renderDataHeaders()}} - {renderData && {renderData()}} - - - {renderFooter && renderFooter()} - {noDataMessage && noData && ( - - {noDataMessage} - - )} - - ); -} - -export default BaseTable; diff --git a/src/lib/components/body-text/body-text.stories.tsx b/src/lib/components/body-text/body-text.stories.tsx index 18a5883a..de2b2367 100644 --- a/src/lib/components/body-text/body-text.stories.tsx +++ b/src/lib/components/body-text/body-text.stories.tsx @@ -8,7 +8,7 @@ import TruncateBox from '../truncate-box/truncate-box'; export default { component: BodyText, - title: 'Components/Primitives/Body Text', + title: 'Components/Display/BodyText', // tags: ['autodocs', '!dev'], args: { size: 1, diff --git a/src/lib/components/button/button.stories.tsx b/src/lib/components/button/button.stories.tsx index b29ac737..b6d99da2 100644 --- a/src/lib/components/button/button.stories.tsx +++ b/src/lib/components/button/button.stories.tsx @@ -19,7 +19,7 @@ const Container = styled.div(({ theme }) => ({ export default { component: Button, - title: 'Components/Forms and inputs/Button', + title: 'Components/Form/Button', // tags: ['autodocs', '!dev'], argTypes: { height: '36', diff --git a/src/lib/components/caption-text/caption-text.stories.tsx b/src/lib/components/caption-text/caption-text.stories.tsx index 763fbe18..62845aba 100644 --- a/src/lib/components/caption-text/caption-text.stories.tsx +++ b/src/lib/components/caption-text/caption-text.stories.tsx @@ -8,7 +8,7 @@ import TruncateBox from '../truncate-box/truncate-box'; export default { component: CaptionText, - title: 'Components/Primitives/Caption Text', + title: 'Components/Display/CaptionText', // tags: ['autodocs', '!dev'], args: { size: 1, diff --git a/src/lib/components/cep18-token/cep18-token.stories.tsx b/src/lib/components/cep18-token/cep18-token.stories.tsx index 5407947d..3e2bc621 100644 --- a/src/lib/components/cep18-token/cep18-token.stories.tsx +++ b/src/lib/components/cep18-token/cep18-token.stories.tsx @@ -6,7 +6,8 @@ import FlexColumn from '../flex-column/flex-column'; export default { component: CEP18Token, - title: 'Components/Primitives/CEP18Token', + title: 'Components/Display/CEP18Token', + excludeStories: ['Primary'], // tags: ['autodocs', '!dev'], args: { motes: '50000123456789', diff --git a/src/lib/components/cep18-token/cep18-token.tsx b/src/lib/components/cep18-token/cep18-token.tsx index 9f3c2f22..3e8fadd2 100644 --- a/src/lib/components/cep18-token/cep18-token.tsx +++ b/src/lib/components/cep18-token/cep18-token.tsx @@ -13,6 +13,7 @@ export interface CEP18TokenProps { hideCurrency?: boolean; } +/** @deprecated */ export function CEP18Token({ motes, precision, decimals, ticker, hideCurrency }: CEP18TokenProps) { if (motes == null) { return <>{'N/A'}; diff --git a/src/lib/components/checkbox/checkbox.stories.tsx b/src/lib/components/checkbox/checkbox.stories.tsx index ecbcbe87..685353a2 100644 --- a/src/lib/components/checkbox/checkbox.stories.tsx +++ b/src/lib/components/checkbox/checkbox.stories.tsx @@ -6,7 +6,7 @@ import FlexColumn from '../flex-column/flex-column'; export default { component: Checkbox, - title: 'Components/Forms and inputs/Checkbox', + title: 'Components/Form/Checkbox', // tags: ['autodocs', '!dev'], args: { checked: true, diff --git a/src/lib/components/circular-indicator/circular-indicator.stories.tsx b/src/lib/components/circular-indicator/circular-indicator.stories.tsx index 76be682f..39ce7c71 100644 --- a/src/lib/components/circular-indicator/circular-indicator.stories.tsx +++ b/src/lib/components/circular-indicator/circular-indicator.stories.tsx @@ -7,7 +7,7 @@ import BodyText from '../body-text/body-text'; export default { component: CircularIndicator, - title: 'Components/Status indicators/Circular Indicator', + title: 'Components/Display/CircularIndicator', // tags: ['autodocs', '!dev'], args: { size: 'medium', diff --git a/src/lib/components/confirmation-window/confirmation-window.stories.tsx b/src/lib/components/confirmation-window/confirmation-window.stories.tsx index 4a6b1cf8..0df3259e 100644 --- a/src/lib/components/confirmation-window/confirmation-window.stories.tsx +++ b/src/lib/components/confirmation-window/confirmation-window.stories.tsx @@ -11,6 +11,7 @@ export default { component: ConfirmationWindow, title: 'Components/Overlays and layering/Confirmation Window', // tags: ['autodocs', '!dev'], + excludeStories: ['Primary'], args: { isOpen: true, position: ModalPosition.TopRight, diff --git a/src/lib/components/copy-hash/copy-hash.stories.tsx b/src/lib/components/copy-hash/copy-hash.stories.tsx index 7440844c..40538418 100644 --- a/src/lib/components/copy-hash/copy-hash.stories.tsx +++ b/src/lib/components/copy-hash/copy-hash.stories.tsx @@ -6,7 +6,8 @@ import FlexColumn from '../flex-column/flex-column'; export default { component: CopyHash, - title: 'Components/Forms and inputs/Copy To Clipboard', + title: 'Components/Display/Copy To Clipboard', + excludeStories: ['Primary'], // tags: ['autodocs', '!dev'], args: { value: 'some value', diff --git a/src/lib/components/copy-hash/copy-hash.tsx b/src/lib/components/copy-hash/copy-hash.tsx index f97948ec..c24c8d43 100644 --- a/src/lib/components/copy-hash/copy-hash.tsx +++ b/src/lib/components/copy-hash/copy-hash.tsx @@ -26,7 +26,7 @@ const StyledSvgIcon = styled(SvgIcon)<{ variation?: CopyHashColor }>( path: { fill: theme.styleguideColors[copyHashColorMapper[variation]], }, - }) + }), ); export interface CopyHashProps { @@ -38,6 +38,7 @@ export interface CopyHashProps { variation?: CopyHashColor; } +/** @deprecated use Copy component instead */ export const CopyHash = ({ value, label = 'Copy Public Key', diff --git a/src/lib/components/copy/copy.stories.tsx b/src/lib/components/copy/copy.stories.tsx new file mode 100644 index 00000000..a365a0b3 --- /dev/null +++ b/src/lib/components/copy/copy.stories.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; +import BodyText from '../body-text/body-text'; +import FlexColumn from '../flex-column/flex-column'; +import { Copy } from './copy'; + +export default { + component: Copy, + title: 'Components/Display/Copy', + // tags: ['autodocs', '!dev'], + args: { + value: 'some value', + label: 'Copy Public Key', + copiedLabel: 'Copied!', + minified: false, + }, + argTypes: { + value: { control: 'text', description: 'Value to copy' }, + }, +} as Meta; + +const Template: StoryFn = (args) => ( + + + + NOTE: Copy button allow you to copy value, which you can provide in + `value` property to clipboard + + +); + +export const Primary = Template.bind({}); diff --git a/src/lib/components/copy/copy.tsx b/src/lib/components/copy/copy.tsx new file mode 100644 index 00000000..b9360aa2 --- /dev/null +++ b/src/lib/components/copy/copy.tsx @@ -0,0 +1,83 @@ +import React, { useState } from 'react'; +import FlexRow from '../flex-row/flex-row'; +import BodyText from '../body-text/body-text'; +import styled from 'styled-components'; +import SvgIcon from '../svg-icon/svg-icon'; +import copy from 'copy-to-clipboard'; + +import SuccessIcon from '../../assets/icons/ic-success.svg'; +import CopyIcon from '../../assets/icons/ic-copy.svg'; + +type CopyColor = 'blue' | 'gray'; + +const copyColorMapper = { + blue: 'contentBlue', + gray: 'contentTertiary', +}; + +const SuccessIconWrapper = styled(SvgIcon)(({ theme }) => ({ + color: theme.styleguideColors.contentGreen, +})); + +const StyledSvgIcon = styled(SvgIcon)<{ variation?: CopyColor }>( + ({ theme, variation = 'blue' }) => + theme.withMedia({ + color: theme.styleguideColors[copyColorMapper[variation]], + path: { + fill: theme.styleguideColors[copyColorMapper[variation]], + }, + }), +); + +export interface CopyProps { + value: string; + styles?: React.CSSProperties; + label?: string; + copiedLabel?: string; + minified?: boolean; + variation?: CopyColor; +} + +export const Copy = ({ + value, + label = 'Copy Public Key', + copiedLabel = 'Copied!', + variation, + styles, + minified = false, +}: CopyProps) => { + const [isCopied, setIsCopied] = useState(false); + return ( + { + copy(value); + setIsCopied(true); + setTimeout(() => setIsCopied(false), 3000); + }} + > + {isCopied ? ( + + + {!minified && ( + + {copiedLabel} + + )} + + ) : ( + + + {!minified && ( + + {label} + + )} + + )} + + ); +}; + +export default Copy; diff --git a/src/lib/components/cspr/cspr.stories.tsx b/src/lib/components/cspr/cspr.stories.tsx index eae0b450..7e17b5ff 100644 --- a/src/lib/components/cspr/cspr.stories.tsx +++ b/src/lib/components/cspr/cspr.stories.tsx @@ -1,14 +1,14 @@ import React from 'react'; import { Meta, StoryFn } from '@storybook/react'; -import Cspr from './cspr'; +import CSPR from './cspr'; import FlexRow from '../flex-row/flex-row'; import FlexColumn from '../flex-column/flex-column'; import BodyText from '../body-text/body-text'; import { PrecisionCase } from '../../utils/currency'; export default { - component: Cspr, - title: 'Components/Primitives/Cspr', + component: CSPR, + title: 'Components/Display/CSPR', // tags: ['autodocs', '!dev'], args: { motes: '3000', @@ -32,12 +32,12 @@ export default { control: 'boolean', }, }, -} as Meta; +} as Meta; -const Template: StoryFn = (args) => ( +const Template: StoryFn = (args) => ( - + ); diff --git a/src/lib/components/cspr/cspr.tsx b/src/lib/components/cspr/cspr.tsx index f2c1f64b..b5ec29fe 100644 --- a/src/lib/components/cspr/cspr.tsx +++ b/src/lib/components/cspr/cspr.tsx @@ -12,7 +12,7 @@ export interface CsprProps { hideCsprCurrency?: boolean; } -export function Cspr({ motes, precisionCase, hideCsprCurrency }: CsprProps) { +export function CSPR({ motes, precisionCase, hideCsprCurrency }: CsprProps) { const precision = currencyPrecisionByCase(precisionCase); if (motes == null) { @@ -26,4 +26,4 @@ export function Cspr({ motes, precisionCase, hideCsprCurrency }: CsprProps) { return <>{hideCsprCurrency ? formattedCsprAmount : formattedText}; } -export default Cspr; +export default CSPR; diff --git a/src/lib/components/dropdown/dropdown.stories.tsx b/src/lib/components/dropdown/dropdown.stories.tsx index acda29a9..d12e0782 100644 --- a/src/lib/components/dropdown/dropdown.stories.tsx +++ b/src/lib/components/dropdown/dropdown.stories.tsx @@ -7,7 +7,7 @@ import SearchableDropdown from '../dropdown-with-search/searchable-dropdown'; export default { component: Dropdown, - title: 'Components/Forms and inputs/Dropdown', + title: 'Components/Form/Dropdown', // tags: ['autodocs', '!dev'], args: { value: { value: 'faucet', label: 'Faucet' }, diff --git a/src/lib/components/flex-box/flex-box.stories.tsx b/src/lib/components/flex-box/flex-box.stories.tsx index a46853b7..7cf25641 100644 --- a/src/lib/components/flex-box/flex-box.stories.tsx +++ b/src/lib/components/flex-box/flex-box.stories.tsx @@ -7,7 +7,7 @@ import styled from 'styled-components'; export default { component: FlexBox, - title: 'Components/Layout and structure/Flex Box', + title: 'Components/Layout/FlexBox', // tags: ['autodocs', '!dev'], args: { gap: 10, diff --git a/src/lib/components/flex-column/flex-column.stories.tsx b/src/lib/components/flex-column/flex-column.stories.tsx index 77c4bf45..656eab22 100644 --- a/src/lib/components/flex-column/flex-column.stories.tsx +++ b/src/lib/components/flex-column/flex-column.stories.tsx @@ -7,7 +7,7 @@ import styled from 'styled-components'; export default { component: FlexColumn, - title: 'Components/Layout and structure/Flex Column', + title: 'Components/Layout/FlexColumn', // tags: ['autodocs', '!dev'], args: { itemsSpacing: 10, diff --git a/src/lib/components/flex-row/flex-row.stories.tsx b/src/lib/components/flex-row/flex-row.stories.tsx index 66028393..b6848893 100644 --- a/src/lib/components/flex-row/flex-row.stories.tsx +++ b/src/lib/components/flex-row/flex-row.stories.tsx @@ -7,7 +7,7 @@ import styled from 'styled-components'; export default { component: FlexRow, - title: 'Components/Layout and structure/Flex Row', + title: 'Components/Layout/FlexRow', // tags: ['autodocs', '!dev'], args: { itemsSpacing: 10, diff --git a/src/lib/components/form-field/form-field.stories.tsx b/src/lib/components/form-field/form-field.stories.tsx index 54ce0a97..4e986fc5 100644 --- a/src/lib/components/form-field/form-field.stories.tsx +++ b/src/lib/components/form-field/form-field.stories.tsx @@ -7,7 +7,7 @@ import Input from '../input/input'; export default { component: FormField, - title: 'Components/Forms and inputs/FormField', + title: 'Components/Form/FormField', // tags: ['autodocs', '!dev'], args: { id: 'form', diff --git a/src/lib/components/header-tab-menu-item/header-tab-menu-item.stories.tsx b/src/lib/components/header-tab-menu-item/header-tab-menu-item.stories.tsx index 908036e0..fc693744 100644 --- a/src/lib/components/header-tab-menu-item/header-tab-menu-item.stories.tsx +++ b/src/lib/components/header-tab-menu-item/header-tab-menu-item.stories.tsx @@ -7,7 +7,8 @@ import TabMenu from '../tab-menu/tab-menu'; export default { component: HeaderTabMenuItem, - title: 'Components/Navigation/Header Tab Menu Item', + title: 'Components/Navigation/HeaderTabMenuItem', + excludeStories: ['Primary'], // tags: ['autodocs', '!dev'], args: { active: false, diff --git a/src/lib/components/header-text/header-text.stories.tsx b/src/lib/components/header-text/header-text.stories.tsx index 47b6759c..d97b31e7 100644 --- a/src/lib/components/header-text/header-text.stories.tsx +++ b/src/lib/components/header-text/header-text.stories.tsx @@ -8,7 +8,7 @@ import TruncateBox from '../truncate-box/truncate-box'; export default { component: HeaderText, - title: 'Components/Primitives/Header Text', + title: 'Components/Display/HeaderText', // tags: ['autodocs', '!dev'], args: { size: 1, diff --git a/src/lib/components/input/input.stories.tsx b/src/lib/components/input/input.stories.tsx index ddb4313c..5dd97f13 100644 --- a/src/lib/components/input/input.stories.tsx +++ b/src/lib/components/input/input.stories.tsx @@ -6,7 +6,7 @@ import FlexColumn from '../flex-column/flex-column'; export default { component: Input, - title: 'Components/Forms and inputs/Input', + title: 'Components/Form/Input', // tags: ['autodocs', '!dev'], args: { value: 'USA', diff --git a/src/lib/components/label/label.stories.tsx b/src/lib/components/label/label.stories.tsx index e3beb285..8376d24e 100644 --- a/src/lib/components/label/label.stories.tsx +++ b/src/lib/components/label/label.stories.tsx @@ -8,7 +8,7 @@ import BodyText from '../body-text/body-text'; export default { component: Label, - title: 'Components/Primitives/Label', + title: 'Components/Display/Label', // tags: ['autodocs', '!dev'], args: { size: 2, diff --git a/src/lib/components/modal-content-header/modal-content-header.stories.tsx b/src/lib/components/modal-content-header/modal-content-header.stories.tsx index 3bc8ab72..1f3ba921 100644 --- a/src/lib/components/modal-content-header/modal-content-header.stories.tsx +++ b/src/lib/components/modal-content-header/modal-content-header.stories.tsx @@ -7,6 +7,7 @@ import FlexColumn from '../flex-column/flex-column'; export default { component: ModalContentHeader, title: 'Components/Tooling/ModalContentHeader', + excludeStories: ['Primary'], // tags: ['autodocs', '!dev'], args: { title: 'Choose a provider', diff --git a/src/lib/components/multiline-text-row/multiline-text-row.stories.tsx b/src/lib/components/multiline-text-row/multiline-text-row.stories.tsx index cf39bb08..16d543eb 100644 --- a/src/lib/components/multiline-text-row/multiline-text-row.stories.tsx +++ b/src/lib/components/multiline-text-row/multiline-text-row.stories.tsx @@ -4,7 +4,8 @@ import { MultilineTextRow } from './multiline-text-row'; export default { component: MultilineTextRow, - title: 'Components/Forms and inputs/Multiline Text Row', + title: 'Components/Form/MultilineTextRow', + excludeStories: ['Primary'], // tags: ['autodocs', '!dev'], args: { label: 'Message', diff --git a/src/lib/components/multiselect-dropdown/multiselect-dropdown.spec.tsx b/src/lib/components/multiselect-dropdown/multiselect-dropdown.spec.tsx new file mode 100644 index 00000000..946320e8 --- /dev/null +++ b/src/lib/components/multiselect-dropdown/multiselect-dropdown.spec.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { render } from '@testing-library/react'; + +import { MultiselectDropdown } from './multiselect-dropdown'; + +describe('Dropdown', () => { + it('should render successfully', () => { + const { baseElement } = render(); + expect(baseElement).toBeTruthy(); + }); +}); diff --git a/src/lib/components/multiselect-dropdown/multiselect-dropdown.stories.tsx b/src/lib/components/multiselect-dropdown/multiselect-dropdown.stories.tsx new file mode 100644 index 00000000..c8c5d1ff --- /dev/null +++ b/src/lib/components/multiselect-dropdown/multiselect-dropdown.stories.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; +import FlexRow from '../flex-row/flex-row'; +import FlexColumn from '../flex-column/flex-column'; +import { MultiselectDropdown } from './multiselect-dropdown'; + +export default { + component: MultiselectDropdown, + title: 'Components/Form/MultiselectDropdown', + // tags: ['autodocs', '!dev'], + args: { + items: [ + { value: '2022', label: 'CSPR 2022', chipLabel: 'CSPR 2022' }, + { value: '2023', label: 'CSPR 2023', chipLabel: 'CSPR 2023' }, + { value: '2024', label: 'CSPR 2024', chipLabel: 'CSPR 2024' }, + ], + }, +} as Meta; + +const Template: StoryFn = (args) => ( + <> + + + + + + +); + +export const Primary = Template.bind({}); diff --git a/src/lib/components/multiselect-dropdown/multiselect-dropdown.tsx b/src/lib/components/multiselect-dropdown/multiselect-dropdown.tsx new file mode 100644 index 00000000..af260c4b --- /dev/null +++ b/src/lib/components/multiselect-dropdown/multiselect-dropdown.tsx @@ -0,0 +1,386 @@ +import React, { useState, useEffect } from 'react'; +import styled from 'styled-components'; +import { useMultipleSelection, useCombobox } from 'downshift'; +import { useClickAndTouchAway } from '../../hooks/use-click-and-touch-away'; +import FlexRow from '../flex-row/flex-row'; +import FlexColumn from '../flex-column/flex-column'; +import BodyText from '../body-text/body-text'; +import { BaseProps } from '../../types'; +import SvgIcon from '../svg-icon/svg-icon'; +import Input from '../input/input'; +import { ArrowDownIcon, DeleteIcon, SearchIcon } from '../../icons-index'; + +const DropdownContainer = styled.div<{ disabled?: boolean }>( + ({ theme, disabled }) => ({ + outline: 'none', + + ...(disabled && { + opacity: '0.5', + pointerEvents: 'none', + }), + }), +); + +const MultiSelectContainer = styled(FlexRow)<{ isOpen: boolean }>( + ({ theme }) => ({ + borderRadius: theme.borderRadius.base, + padding: '8px', + background: theme.styleguideColors.fillSecondary, + ':hover, :active': { + svg: { + color: theme.styleguideColors.fillPrimaryRed, + }, + }, + }), +); + +const InputContainer = styled(FlexRow)(({ theme }) => ({ + width: '100%', +})); + +const StyledInput = styled(Input)(() => ({ + width: '100%', + border: 'none', + height: '24px', + '> div': { + padding: '0 8px', + }, +})); + +const DropdownIconWrapper = styled(FlexRow)(({ theme }) => ({ + paddingRight: '8px', + marginLeft: '8px', +})); + +const ArrowSvgIcon = styled(SvgIcon)(({ theme }) => ({ + path: { + fill: theme.styleguideColors.contentPrimary, + }, +})); + +const ClearSvgIcon = styled(SvgIcon)(({ theme }) => ({ + path: { + stroke: theme.styleguideColors.contentPrimary, + }, +})); + +const ChipItemContainer = styled.span(({ theme }) => ({ + borderRadius: theme.borderRadius.base, + cursor: 'pointer', + padding: '2px 8px', + background: theme.styleguideColors.fillTertiary, + color: theme.styleguideColors.contentPrimary, + wordBreak: 'break-word', +})); + +const ItemsContainer = styled.div<{ isOpen: boolean }>(({ theme, isOpen }) => ({ + display: isOpen ? 'inherit' : 'none', + marginTop: 4, + borderRadius: theme.borderRadius.base, + background: theme.styleguideColors.fillSecondary, + maxHeight: '250px', + overflowY: 'scroll', +})); + +const ItemsContainerEmpty = styled(FlexRow)(({ theme }) => ({ + padding: '32px 16px', + pointerEvents: 'none', + justifyContent: 'center', +})); + +const ItemContainer = styled(FlexRow)(({ theme }) => ({ + cursor: 'pointer', + minHeight: 36, + padding: '8px 16px', + wordBreak: 'break-word', + ':hover, :active': { + background: theme.styleguideColors.fillSecondaryBlueHover, + fontWeight: 600, + }, +})); + +const MultiSelectDeleteIcon = styled(SvgIcon)(({ theme }) => ({ + path: { + stroke: theme.styleguideColors.contentBlue, + }, + ':hover, :active': { + path: { + stroke: theme.styleguideColors.contentRed, + }, + }, +})); + +export type MultiSelectDropdownValue = { + label: string; + chipLabel?: string; + value: any; +}; + +export type MultiSelectDropdownEventValue = { + target: { + name?: string; + value: MultiSelectDropdownValue | null; + }; +}; + +export interface MultiSelectInputProps extends BaseProps { + value?: MultiSelectDropdownValue[]; + items: MultiSelectDropdownValue[]; + label?: string | JSX.Element; + placeholder?: string; + disabled?: boolean; + onAddItem?: (ev: MultiSelectDropdownEventValue) => void; + onSelectItem?: (ev: MultiSelectDropdownEventValue) => void; + onRemoveItem?: (ev: MultiSelectDropdownEventValue) => void; + onChangeInput?: (value: string) => void; +} + +const getChangeEvent = (value: any): MultiSelectDropdownEventValue => { + return { + target: { + name: undefined, + value, + }, + }; +}; + +export function MultiselectDropdown(props: MultiSelectInputProps) { + const { + items, + value, + label, + placeholder, + disabled = false, + onSelectItem, + onAddItem, + onRemoveItem, + onChangeInput, + } = props; + const [inputValue, setInputValue] = useState(''); + + const { + getSelectedItemProps, + getDropdownProps, + addSelectedItem, + removeSelectedItem, + selectedItems, + setSelectedItems, + reset, + } = useMultipleSelection({ + initialSelectedItems: value, + onSelectedItemsChange: (changes) => { + onSelectItem && onSelectItem(getChangeEvent(changes.selectedItems)); + }, + }); + + const inputValueItem = + inputValue?.length >= 3 + ? [ + { + id: inputValue, + label: inputValue, + value: inputValue, + chipLabel: inputValue, + }, + ] + : []; + + const itemsWithCustomInputValue = [...inputValueItem, ...items]; + + const { + isOpen, + getToggleButtonProps, + getLabelProps, + getMenuProps, + getInputProps, + getItemProps, + openMenu, + } = useCombobox({ + inputValue, + items: itemsWithCustomInputValue, + onStateChange: ({ inputValue, type, selectedItem: newSelectedItem }) => { + switch (type) { + case useCombobox.stateChangeTypes.InputChange: + setInputValue(inputValue || ''); + onChangeInput && onChangeInput(inputValue || ''); + break; + + case useCombobox.stateChangeTypes.InputKeyDownEnter: + case useCombobox.stateChangeTypes.ItemClick: + case useCombobox.stateChangeTypes.InputBlur: + const isAlreadySelected = selectedItems.some( + (i) => i.value === newSelectedItem?.value, + ); + + if (newSelectedItem) { + if (isAlreadySelected) { + setSelectedItems( + selectedItems.filter((i) => i.value !== newSelectedItem.value), + ); + onRemoveItem && onRemoveItem(getChangeEvent(newSelectedItem)); + } else { + addSelectedItem(newSelectedItem); + onAddItem && onAddItem(getChangeEvent(newSelectedItem)); + } + } + break; + case useCombobox.stateChangeTypes.FunctionCloseMenu: + handleClearInput(); + break; + default: + break; + } + }, + stateReducer: (state, actionAndChanges) => { + const { changes, type } = actionAndChanges; + switch (type) { + case useCombobox.stateChangeTypes.InputKeyDownEnter: + case useCombobox.stateChangeTypes.ItemClick: + return { + ...changes, + isOpen: state.isOpen, // keep the menu open after selection. + }; + default: + return changes; + } + }, + }); + + const { ref: outerClickRef } = useClickAndTouchAway({ + callback: () => { + if (isOpen) { + handleClearInput(); + } + }, + }); + + //Align resetting selected values if they were reset in parent + useEffect(() => { + if (!value || value.length < 1) { + reset(); + } + }, [value]); + + const handleClearInput = () => { + setInputValue(''); + onChangeInput && onChangeInput(''); + }; + + const handleClearAll = () => { + handleClearInput(); + onSelectItem && onSelectItem(getChangeEvent(null)); + reset(); + }; + + const showInput = isOpen || selectedItems.length === 0; + + return ( + + + {label && ( + + {label} + + )} +
+ + + {selectedItems.map((selectedItem, index) => ( + + + + {selectedItem?.chipLabel || selectedItem?.label} + { + event.preventDefault(); + event.stopPropagation(); + removeSelectedItem(selectedItem); + }} + size={14} + src={DeleteIcon} + /> + + + + ))} + {showInput ? ( + } + /> + ) : null} + + + {!!selectedItems.length && ( + + )} + + + + + {isOpen && + (!( + itemsWithCustomInputValue && itemsWithCustomInputValue.length + ) ? ( + + + No items found + + + ) : ( + itemsWithCustomInputValue.map( + (item: MultiSelectDropdownValue, index: number) => ( + + + {item.label} + + + ), + ) + ))} + +
+
+
+ ); +} + +export default MultiselectDropdown; diff --git a/src/lib/components/multiselect-input/multiselect-input.stories.tsx b/src/lib/components/multiselect-input/multiselect-input.stories.tsx index 7af8bca3..77ea872f 100644 --- a/src/lib/components/multiselect-input/multiselect-input.stories.tsx +++ b/src/lib/components/multiselect-input/multiselect-input.stories.tsx @@ -6,7 +6,8 @@ import MultiselectInput from './multiselect-input'; export default { component: MultiselectInput, - title: 'Components/Forms and inputs/Multiselect Input', + title: 'Components/Form/MultiselectInput', + excludeStories: ['Primary'], // tags: ['autodocs', '!dev'], args: { items: [ diff --git a/src/lib/components/multiselect-input/multiselect-input.tsx b/src/lib/components/multiselect-input/multiselect-input.tsx index adc50ff4..c19d5880 100644 --- a/src/lib/components/multiselect-input/multiselect-input.tsx +++ b/src/lib/components/multiselect-input/multiselect-input.tsx @@ -144,6 +144,7 @@ const getChangeEvent = (value: any): MultiSelectDropdownEventValue => { }; }; +/** @deprecated use the new MultiselectDropdown component instead. */ export function MultiSelectInput(props: MultiSelectInputProps) { const { items, diff --git a/src/lib/components/navigation/account/account.stories.tsx b/src/lib/components/navigation/account/account.stories.tsx index 0c4dc522..631832b5 100644 --- a/src/lib/components/navigation/account/account.stories.tsx +++ b/src/lib/components/navigation/account/account.stories.tsx @@ -7,6 +7,11 @@ export default { component: Account, title: 'Components/Navigation/Account', // tags: ['autodocs', '!dev'], + excludeStories: [ + 'AccountWithPublicKey', + 'AccountWithHash', + 'WithCustomAvatar', + ], args: {}, argTypes: { hash: { diff --git a/src/lib/components/navigation/cspr-products-menu/products-menu.stories.tsx b/src/lib/components/navigation/cspr-products-menu/products-menu.stories.tsx index 6d14cb9f..7b708e3a 100644 --- a/src/lib/components/navigation/cspr-products-menu/products-menu.stories.tsx +++ b/src/lib/components/navigation/cspr-products-menu/products-menu.stories.tsx @@ -13,7 +13,8 @@ import { export default { component: ProductsMenu, - title: 'Components/Navigation/Products Menu', + title: 'Components/Navigation/ProductsMenu', + excludeStories: ['Primary'], // tags: ['autodocs', '!dev'], args: { opened: true, diff --git a/src/lib/components/navigation/dropdown-menu/dropdown-menu.stories.tsx b/src/lib/components/navigation/dropdown-menu/dropdown-menu.stories.tsx index 4233d959..a7a5e238 100644 --- a/src/lib/components/navigation/dropdown-menu/dropdown-menu.stories.tsx +++ b/src/lib/components/navigation/dropdown-menu/dropdown-menu.stories.tsx @@ -28,7 +28,7 @@ const StyledFlexColumn = styled(FlexColumn)(({ theme }) => ({ export default { component: DropdownMenu, - title: 'Components/Navigation/Menu List', + title: 'Components/Navigation/DropdownMenu', // tags: ['autodocs', '!dev'], args: { opened: true, diff --git a/src/lib/components/navigation/main-menu/main-menu.stories.tsx b/src/lib/components/navigation/main-menu/main-menu.stories.tsx index 074b5fdb..e8467346 100644 --- a/src/lib/components/navigation/main-menu/main-menu.stories.tsx +++ b/src/lib/components/navigation/main-menu/main-menu.stories.tsx @@ -17,7 +17,7 @@ const Container = styled.div(({ theme }) => export default { component: MainMenuItem, - title: 'Components/Navigation/Main Menu', + title: 'Components/Navigation/MainMenu', // tags: ['autodocs', '!dev'], args: {}, argTypes: {}, diff --git a/src/lib/components/navigation/navigation-banner/navigation-banner.stories.tsx b/src/lib/components/navigation/navigation-banner/navigation-banner.stories.tsx index 218cfe22..95082e72 100644 --- a/src/lib/components/navigation/navigation-banner/navigation-banner.stories.tsx +++ b/src/lib/components/navigation/navigation-banner/navigation-banner.stories.tsx @@ -15,6 +15,7 @@ const StyledSvgIcon = styled(SvgIcon)(() => ({ export default { component: NavigationBanner, title: 'Components/Navigation/NavigationBanner', + excludeStories: ['Primary', 'BannerWithJSXNode', 'BannerWithLongText'], // tags: ['autodocs', '!dev'], args: { message: 'Call me maybe!', @@ -22,10 +23,6 @@ export default { }, } as Meta; -const Template: StoryFn = (args) => ( - -); - export const BannerWithJSXNode = () => ( ( /> ); +const Template: StoryFn = (args) => ( + +); + export const Primary = Template.bind({}); diff --git a/src/lib/components/page-tile-header/page-tile-header.stories.tsx b/src/lib/components/page-tile-header/page-tile-header.stories.tsx index 6ae52a79..978e1526 100644 --- a/src/lib/components/page-tile-header/page-tile-header.stories.tsx +++ b/src/lib/components/page-tile-header/page-tile-header.stories.tsx @@ -8,7 +8,7 @@ import PageTile from '../page-tile/page-tile'; export default { component: PageTileHeader, - title: 'Components/Layout and structure/PageTile Header', + title: 'Components/Layout/PageTileHeader', // tags: ['autodocs', '!dev'], } as Meta; diff --git a/src/lib/components/page-tile-tabs-header/page-tile-tabs-header.stories.tsx b/src/lib/components/page-tile-tabs-header/page-tile-tabs-header.stories.tsx index 2243c924..0ce3d1ea 100644 --- a/src/lib/components/page-tile-tabs-header/page-tile-tabs-header.stories.tsx +++ b/src/lib/components/page-tile-tabs-header/page-tile-tabs-header.stories.tsx @@ -9,7 +9,8 @@ import TabMenuItem from '../tab-menu-item/tab-menu-item'; export default { component: PageTileTabsHeader, - title: 'Components/Layout and structure/PageTileTabsHeader', + title: 'Components/Layout/PageTileTabsHeader', + excludeStories: ['Primary'], // tags: ['autodocs', '!dev'], } as Meta; @@ -28,6 +29,12 @@ const Template: StoryFn = () => ( {}}> Tab 3 + {}}> + Tab 4 + + {}}> + Tab 5 + diff --git a/src/lib/components/page-tile-tabs-header/page-tile-tabs-header.tsx b/src/lib/components/page-tile-tabs-header/page-tile-tabs-header.tsx index fda744a7..7d5e71e8 100644 --- a/src/lib/components/page-tile-tabs-header/page-tile-tabs-header.tsx +++ b/src/lib/components/page-tile-tabs-header/page-tile-tabs-header.tsx @@ -1,6 +1,6 @@ import React from 'react'; import styled from 'styled-components'; -import {BaseProps} from "../../types"; +import { BaseProps } from '../../types'; export interface Props extends BaseProps { tabsCount: number; @@ -14,11 +14,12 @@ const StyledWrapper = styled.div<{ childrenCount: number }>( justifyContent: childrenCount > 2 ? ['left', 'center'] : ['center'], padding: 16, overflowX: 'auto', - }) + }), ); +/** @deprecated use TabMenuContainer instead */ export const PageTileTabsHeader = ({ tabsCount, children }: Props) => { return {children}; }; -export default PageTileTabsHeader +export default PageTileTabsHeader; diff --git a/src/lib/components/page-tile/page-tile.stories.tsx b/src/lib/components/page-tile/page-tile.stories.tsx index 3f0168e9..d7d0ce98 100644 --- a/src/lib/components/page-tile/page-tile.stories.tsx +++ b/src/lib/components/page-tile/page-tile.stories.tsx @@ -7,7 +7,7 @@ import BodyText from '../body-text/body-text'; export default { component: PageTile, - title: 'Components/Layout and structure/Page Tile', + title: 'Components/Layout/PageTile', // tags: ['autodocs', '!dev'], args: { withPadding: true, diff --git a/src/lib/components/paginated-table/paginated-table.stories.tsx b/src/lib/components/paginated-table/paginated-table.stories.tsx new file mode 100644 index 00000000..b22834dd --- /dev/null +++ b/src/lib/components/paginated-table/paginated-table.stories.tsx @@ -0,0 +1,176 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { PaginatedTable, PaginatedTableProps } from './paginated-table'; +import { Meta, StoryFn } from '@storybook/react'; +import HeaderText from '../header-text/header-text'; +import TableDataHeader from '../table-data-header/table-data-header'; +import TableRow from '../table-row/table-row'; +import TableData from '../table-data/table-data'; +import BodyText from '../body-text/body-text'; +import { PrecisionCase } from '../../utils/currency'; +import CSPR from '../cspr/cspr'; +import PageTile from '../page-tile/page-tile'; +import FlexRow from '../flex-row/flex-row'; + +export default { + component: PaginatedTable, + title: 'Components/Display/PaginatedTable', + args: { + renderHeader: () => ( + + Table with pagination + + ), + renderDataHeaders: () => ( + + Rank + Balance{' '} + Owner + + ), + renderPaginatedData: (data: any[]) => ( + <> + {data.map((data) => ( + + + {data.rank} + + + + + + + + {data.owner} + + + ))} + + ), + }, +} as Meta; + +const getRandomBalance = () => { + const min = 100000000000; + const max = 10000000000000; + return Math.floor(Math.random() * (max - min + 1)) + min; +}; + +const MOCKED_OWNERS = [ + 'Alice', + 'Bob', + 'Charlie', + 'Diana', + 'Ethan', + 'Fiona', + 'Gabe', + 'Hana', + 'Ivan', + 'Jules', + 'Kira', + 'Liam', + 'Mona', + 'Noah', + 'Olga', + 'Pavel', + 'Quinn', + 'Ravi', + 'Sara', + 'Tara', + 'Uma', + 'Vik', + 'Walt', + 'Xena', + 'Yara', + 'Zane', +]; + +const MOCK_DATA = Array.from({ length: 87 }, (_, i) => { + const rank = i + 1; + const owner = MOCKED_OWNERS[i % MOCKED_OWNERS.length]; + const csprName = `${owner.toLowerCase()}.cspr`; + const motes = getRandomBalance(); + return { rank, owner: csprName, motes }; +}); + +const emulateGetTableDataRequest = (url: string) => { + const u = new URL(url, 'https://example.local'); + const page = Math.max(parseInt(u.searchParams.get('page') || '1', 10), 1); + const pageSize = Math.max( + parseInt(u.searchParams.get('page_size') || '10', 10), + 1, + ); + + const items_count = MOCK_DATA.length; + const page_count = Math.max(1, Math.ceil(items_count / pageSize)); + + const start = (page - 1) * pageSize; + const end = start + pageSize; + const data = MOCK_DATA.slice(start, end); + + return new Promise((resolve) => { + setTimeout(() => { + resolve({ data, page_count, items_count }); + }, 400); + }); +}; + +const Template: StoryFn = ( + args: PaginatedTableProps, +) => { + const [data, setData] = useState(null); + const [pagination, setPagination] = useState({ + currentPage: 1, + pageSize: 10, + }); + + const requestPath = useMemo( + () => + `/api/table?page=${pagination.currentPage}&page_size=${pagination.pageSize}`, + [pagination.currentPage, pagination.pageSize], + ); + + useEffect(() => { + (async () => { + const res = await emulateGetTableDataRequest(requestPath); + setData(res); + })(); + }, [requestPath]); + + const handleCurrentPage = (page: number) => { + setPagination((prev) => ({ + ...prev, + currentPage: page, + })); + }; + const handlePerPage = (pageSize: number) => { + setPagination((prev) => ({ + ...prev, + pageSize: pageSize, + })); + }; + return ( + + + + Emulated api request: {requestPath} + + + args.renderPaginatedData(data?.data)} + itemCount={data?.items_count} + pageCount={data?.page_count} + currentPage={pagination.currentPage} + perPage={pagination.pageSize} + setCurrentPage={handleCurrentPage} + setPerPage={handlePerPage} + /> + + ); +}; + +export const Primary = Template.bind({}); diff --git a/src/lib/components/paginated-table/paginated-table.tsx b/src/lib/components/paginated-table/paginated-table.tsx new file mode 100644 index 00000000..27d51a0d --- /dev/null +++ b/src/lib/components/paginated-table/paginated-table.tsx @@ -0,0 +1,101 @@ +import React, { Children } from 'react'; + +import { Table } from '../table/table.tsx'; +import { Pagination } from '../pagination/pagination'; +import { TableRowType } from '../table-row/table-row'; +import { TableLoader } from './table-loader'; +import { TableError } from './table-error'; + +export enum OrderDirection { + ASC = 'ASC', + DESC = 'DESC', +} + +export interface ErrorResult { + code: string; + message: string; + description?: string | React.ReactElement; +} + +export interface SortingProps { + orderBy?: string | undefined; + orderDirection?: OrderDirection; + setOrder?: (orderBy: string | undefined, direction: OrderDirection) => void; + reverseSortingDirection?: boolean; +} + +export type RenderProps = { sortingProps: SortingProps }; + +export type PaginatedTableProps = { + data: null | Entity[]; + loading?: boolean; + error?: ErrorResult | null; + renderDataHeaders: (renderProps: RenderProps) => React.ReactElement; + renderPaginatedData: ( + paginatedData: Entity[], + renderProps?: RenderProps, + ) => React.ReactElement | React.ReactElement[]; + tableRowType?: TableRowType; + pageCount: number; + currentPage: number; + pageSize?: number; + itemCount?: number; + setPerPage?: (limit: number) => void; + setCurrentPage?: (page: number) => void; + hideRowsPerPage?: boolean; + totalRowsLabel?: string; +}; + +export const PaginatedTable = ({ + data, + loading, + error, + renderDataHeaders, + renderPaginatedData, + tableRowType = TableRowType.TextWithAvatar, + ...props +}: PaginatedTableProps) => { + const renderPaginationRow = () => !error && ; + + return ( + renderPaginationRow()} + renderDataHeaders={() => + renderDataHeaders({ + sortingProps: null!, + }) + } + renderData={() => + (data == null && !error) || loading ? ( + + ) : error ? ( + + ) : data ? ( + renderPaginatedData(data, { + sortingProps: {}!, + }) + ) : ( + <> + ) + } + renderFooter={() => renderPaginationRow()} + {...props} + /> + ); +}; + +export default PaginatedTable; diff --git a/src/lib/components/table/table-error.tsx b/src/lib/components/paginated-table/table-error.tsx similarity index 100% rename from src/lib/components/table/table-error.tsx rename to src/lib/components/paginated-table/table-error.tsx diff --git a/src/lib/components/table/table-loader.tsx b/src/lib/components/paginated-table/table-loader.tsx similarity index 100% rename from src/lib/components/table/table-loader.tsx rename to src/lib/components/paginated-table/table-loader.tsx diff --git a/src/lib/components/pagination/pagination.stories.tsx b/src/lib/components/pagination/pagination.stories.tsx index 1ec5c39d..12f737ff 100644 --- a/src/lib/components/pagination/pagination.stories.tsx +++ b/src/lib/components/pagination/pagination.stories.tsx @@ -1,11 +1,11 @@ import React, { useState } from 'react'; import { Meta, StoryFn } from '@storybook/react'; import { Pagination } from './pagination'; -import PageTile from "../page-tile/page-tile"; +import PageTile from '../page-tile/page-tile'; export default { component: Pagination, - title: 'Components/Table/Pagination', + title: 'Components/Display/Pagination', args: { itemCount: 50, pageCount: 5, @@ -13,35 +13,35 @@ export default { } as Meta; const Template: StoryFn = (args) => { - const [pagination, setPagination] = useState({ - currentPage: 1, - pageSize: 10, - }); + const [pagination, setPagination] = useState({ + currentPage: 1, + pageSize: 10, + }); - const handleCurrentPage = (page: number) => { - setPagination((prev) => ({ - ...prev, - currentPage: page, - })); - } - const handlePerPage = (pageSize: number) => { - setPagination((prev) => ({ - ...prev, - pageSize: pageSize, - })); - } + const handleCurrentPage = (page: number) => { + setPagination((prev) => ({ + ...prev, + currentPage: page, + })); + }; + const handlePerPage = (pageSize: number) => { + setPagination((prev) => ({ + ...prev, + pageSize: pageSize, + })); + }; return ( - - - + + + ); -} +}; export const Primary = Template.bind({}); diff --git a/src/lib/components/progress-line/progress-line.stories.tsx b/src/lib/components/progress-line/progress-line.stories.tsx index 1224a03c..cd5ea4b8 100644 --- a/src/lib/components/progress-line/progress-line.stories.tsx +++ b/src/lib/components/progress-line/progress-line.stories.tsx @@ -8,7 +8,7 @@ import BodyText from '../body-text/body-text'; export default { component: ProgressLine, - title: 'Components/Messaging/Progress Line', + title: 'Components/Display/ProgressLine', // tags: ['autodocs', '!dev'], args: { steps: ['one', 'two', 'three', 'four'], diff --git a/src/lib/components/radio-button/radio-button.stories.tsx b/src/lib/components/radio-button/radio-button.stories.tsx index ba338ef2..85c25594 100644 --- a/src/lib/components/radio-button/radio-button.stories.tsx +++ b/src/lib/components/radio-button/radio-button.stories.tsx @@ -7,7 +7,7 @@ import FlexColumn from '../flex-column/flex-column'; // TODO - check logic of RadioButton export default { component: RadioButton, - title: 'Components/Forms and inputs/RadioButton', + title: 'Components/Form/RadioButton', // tags: ['autodocs', '!dev'], args: { value: 'casper', diff --git a/src/lib/components/subtitle-text/subtitle-text.stories.tsx b/src/lib/components/subtitle-text/subtitle-text.stories.tsx index 56e9c822..a9e98b25 100644 --- a/src/lib/components/subtitle-text/subtitle-text.stories.tsx +++ b/src/lib/components/subtitle-text/subtitle-text.stories.tsx @@ -8,7 +8,7 @@ import SubtitleText from './subtitle-text'; export default { component: SubtitleText, - title: 'Components/Primitives/Subtitle Text', + title: 'Components/Display/SubtitleText', // tags: ['autodocs', '!dev'], args: { size: 1, diff --git a/src/lib/components/svg-icon/svg-icon.stories.tsx b/src/lib/components/svg-icon/svg-icon.stories.tsx index 489c3a94..9f6f135f 100644 --- a/src/lib/components/svg-icon/svg-icon.stories.tsx +++ b/src/lib/components/svg-icon/svg-icon.stories.tsx @@ -1,13 +1,13 @@ import React from 'react'; import { Meta, StoryFn } from '@storybook/react'; import SvgIcon from '../svg-icon/svg-icon'; -import { FacebookIcon, Twitter_xIcon } from '../../icons-index'; +import { FacebookIcon } from '../../icons-index'; import SvgIconSocial from './svg-icon-social'; import FlexRow from '../flex-row/flex-row'; export default { component: SvgIcon, - title: 'Components/Image and icons/SvgIcon', + title: 'Components/Display/SvgIcon', // tags: ['autodocs', '!dev'], args: { src: FacebookIcon }, argTypes: { src: {} }, diff --git a/src/lib/components/tab-menu-container/tab-menu-container.stories.tsx b/src/lib/components/tab-menu-container/tab-menu-container.stories.tsx new file mode 100644 index 00000000..95a80cf2 --- /dev/null +++ b/src/lib/components/tab-menu-container/tab-menu-container.stories.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; +import TabMenuContainer from './tab-menu-container'; +import FlexRow from '../flex-row/flex-row'; +import FlexColumn from '../flex-column/flex-column'; +import PageTile from '../page-tile/page-tile'; +import TabMenu from '../tab-menu/tab-menu'; +import TabMenuItem from '../tab-menu-item/tab-menu-item'; + +export default { + component: TabMenuContainer, + title: 'Components/Layout/TabMenuContainer', + // tags: ['autodocs', '!dev'], +} as Meta; + +const Template: StoryFn = () => ( + + + + + + {}}> + Tab 1 + + {}}> + Tab 2 + + {}}> + Tab 3 + + {}}> + Tab 4 + + {}}> + Tab 5 + + + + + + +); + +export const Primary = Template.bind({}); diff --git a/src/lib/components/tab-menu-container/tab-menu-container.tsx b/src/lib/components/tab-menu-container/tab-menu-container.tsx new file mode 100644 index 00000000..eabc7a63 --- /dev/null +++ b/src/lib/components/tab-menu-container/tab-menu-container.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import styled from 'styled-components'; +import { BaseProps } from '../../types'; + +export interface TabMenuContainerProps extends BaseProps { + tabsCount: number; +} + +const StyledWrapper = styled.div<{ childrenCount: number }>( + ({ theme, childrenCount }) => + theme.withMedia({ + display: 'flex', + flexGrow: 1, + justifyContent: childrenCount > 2 ? ['left', 'center'] : ['center'], + padding: 16, + overflowX: 'auto', + }), +); + +export const TabMenuContainer = ({ + tabsCount, + children, +}: TabMenuContainerProps) => { + return {children}; +}; + +export default TabMenuContainer; diff --git a/src/lib/components/tab-menu/tab-menu.stories.tsx b/src/lib/components/tab-menu/tab-menu.stories.tsx index 291b3c46..5cd9c0f8 100644 --- a/src/lib/components/tab-menu/tab-menu.stories.tsx +++ b/src/lib/components/tab-menu/tab-menu.stories.tsx @@ -4,14 +4,10 @@ import FlexRow from '../flex-row/flex-row'; import FlexColumn from '../flex-column/flex-column'; import TabMenu from '../tab-menu/tab-menu'; import TabMenuItem from '../tab-menu-item/tab-menu-item'; -import BodyText from '../body-text/body-text'; -import TabContent from '../tab-content/tab-content'; -import PageTile from '../page-tile/page-tile'; -import PageTileTabsHeader from '../page-tile-tabs-header/page-tile-tabs-header'; export default { component: TabMenu, - title: 'Components/Layout and structure/Tab Menu', + title: 'Components/Layout/TabMenu', // tags: ['autodocs', '!dev'], args: { active: true, @@ -29,24 +25,13 @@ export default { } as Meta; const Template: StoryFn = (args) => ( - - - - - - - Tab 1 - - Tab 2 - Tab 3 - - - - Tab1 Content - - - - + + + Tab 1 + + Tab 2 + Tab 3 + ); export const Primary = Template.bind({}); diff --git a/src/lib/components/table-data-header/table-data-header.stories.tsx b/src/lib/components/table-data-header/table-data-header.stories.tsx index 7667fcaa..88b654ff 100644 --- a/src/lib/components/table-data-header/table-data-header.stories.tsx +++ b/src/lib/components/table-data-header/table-data-header.stories.tsx @@ -1,12 +1,10 @@ import React from 'react'; import { Meta, StoryFn } from '@storybook/react'; -import TableDataHeader, { - TableDataHeaderProps, -} from './table-data-header'; +import TableDataHeader, { TableDataHeaderProps } from './table-data-header'; export default { component: TableDataHeader, - title: 'Components/Table/Table Data Header', + title: 'Components/Display/TableDataHeader', } as Meta; const Template: StoryFn = ( diff --git a/src/lib/components/table/table.stories.tsx b/src/lib/components/table/table.stories.tsx index 0ff6a942..31afd1c0 100644 --- a/src/lib/components/table/table.stories.tsx +++ b/src/lib/components/table/table.stories.tsx @@ -1,25 +1,24 @@ -import React, { useEffect, useMemo, useState } from 'react'; +import React from 'react'; import { Table, TableProps } from './table'; import { Meta, StoryFn } from '@storybook/react'; -import HeaderText from '../header-text/header-text'; import TableDataHeader from '../table-data-header/table-data-header'; import TableRow from '../table-row/table-row'; import TableData from '../table-data/table-data'; import BodyText from '../body-text/body-text'; import { PrecisionCase } from '../../utils/currency'; -import Cspr from '../cspr/cspr'; +import CSPR from '../cspr/cspr'; import PageTile from '../page-tile/page-tile'; -import FlexRow from "../flex-row/flex-row"; + +const mockedData = [ + { rank: 1, motes: '50000000000000', owner: 'konrad.cspr' }, + { rank: 2, motes: '482900000000000', owner: 'victoria.cspr' }, + { rank: 3, motes: '1000000', owner: 'ab.cspr' }, +]; export default { component: Table, - title: 'Components/Table/Table with pagination', + title: 'Components/Display/Table', args: { - renderHeader: () => ( - - Table with pagination - - ), renderDataHeaders: () => ( Rank @@ -27,16 +26,16 @@ export default { Owner ), - renderPaginatedData: (data) => ( + renderData: () => ( <> - {data.map((data) => ( + {mockedData.map((data) => ( {data.rank} - @@ -52,91 +51,13 @@ export default { }, } as Meta; -const getRandomBalance = () => { - const min = 100000000000; - const max = 10000000000000; - return Math.floor(Math.random() * (max - min + 1)) + min; -} - -const MOCKED_OWNERS = [ - "Alice","Bob","Charlie","Diana","Ethan","Fiona","Gabe","Hana","Ivan","Jules", - "Kira","Liam","Mona","Noah","Olga","Pavel","Quinn","Ravi","Sara","Tara", - "Uma","Vik","Walt","Xena","Yara","Zane" -]; - -const MOCK_DATA = Array.from({ length: 87 }, (_, i) => { - const rank = i + 1; - const owner = MOCKED_OWNERS[i % MOCKED_OWNERS.length]; - const csprName = `${owner.toLowerCase()}.cspr` - const motes = getRandomBalance(); - return { rank, owner: csprName, motes }; -}); - -const emulateGetTableDataRequest = (url: string) => { - const u = new URL(url, "https://example.local"); - const page = Math.max(parseInt(u.searchParams.get("page") || "1", 10), 1); - const pageSize = Math.max(parseInt(u.searchParams.get("page_size") || "10", 10), 1); - - const items_count = MOCK_DATA.length; - const page_count = Math.max(1, Math.ceil(items_count / pageSize)); - - const start = (page - 1) * pageSize; - const end = start + pageSize; - const data = MOCK_DATA.slice(start, end); - - return new Promise((resolve) => { - setTimeout(() => { - resolve({ data, page_count, items_count }); - }, 400); - }); -} - const Template: StoryFn = (args: TableProps) => { - const [data, setData] = useState(null) - const [pagination, setPagination] = useState({ - currentPage: 1, - pageSize: 10, - }); - - const requestPath = useMemo( - () => `/api/table?page=${pagination.currentPage}&page_size=${pagination.pageSize}`, - [pagination.currentPage, pagination.pageSize] - ); - - useEffect(() => { - (async () => { - const res = await emulateGetTableDataRequest(requestPath); - setData(res); - })(); - }, [requestPath]); - - const handleCurrentPage = (page: number) => { - setPagination((prev) => ({ - ...prev, - currentPage: page, - })); - } - const handlePerPage = (pageSize: number) => { - setPagination((prev) => ({ - ...prev, - pageSize: pageSize, - })); - } return ( - - Emulated api request: {requestPath} -
args.renderPaginatedData(data?.data)} - itemCount={data?.items_count} - pageCount={data?.page_count} - currentPage={pagination.currentPage} - perPage={pagination.pageSize} - setCurrentPage={handleCurrentPage} - setPerPage={handlePerPage} + renderData={args.renderData} + renderFooter={args.renderFooter} /> ); diff --git a/src/lib/components/table/table.tsx b/src/lib/components/table/table.tsx index 2d6382fa..cb3c49aa 100644 --- a/src/lib/components/table/table.tsx +++ b/src/lib/components/table/table.tsx @@ -1,104 +1,70 @@ -import React, { Children } from 'react'; +import React, { ReactNode } from 'react'; +import styled from 'styled-components'; +import TableHead from '../table-head/table-head'; +import TableBody from '../table-body/table-body'; +import BodyText from '../body-text/body-text'; -import { BaseTable } from '../base-table/base-table'; -import { Pagination } from '../pagination/pagination'; -import { TableRowType } from '../table-row/table-row'; -import { TableLoader } from './table-loader'; -import { TableError } from './table-error'; - -export enum OrderDirection { - ASC = 'ASC', - DESC = 'DESC', +export interface TableProps { + renderHeader?: () => ReactNode; + renderDataHeaders?: () => ReactNode; + renderData?: () => ReactNode; + renderFooter?: () => ReactNode; + noData?: boolean; + noDataMessage?: string; + paddingBottom?: number; } -export interface ErrorResult { - code: string; - message: string; - description?: string | React.ReactElement; -} +export const TableContainer = styled.div<{ paddingBottom?: number }>( + ({ theme, paddingBottom }) => ({ + overflowX: 'auto', + ...(paddingBottom && { paddingBottom }), + }), +); -export interface SortingProps { - orderBy?: string | undefined; - orderDirection?: OrderDirection; - setOrder?: (orderBy: string | undefined, direction: OrderDirection) => void; - reverseSortingDirection?: boolean; -} +const StyledTable = styled.table(({ theme }) => ({ + width: '100%', + position: 'relative', + borderCollapse: 'collapse', +})); -export type RenderProps = { sortingProps: SortingProps }; +const NoDataContainer = styled.div(({ theme }) => ({ + position: 'absolute', + top: 0, + width: '100%', + height: '100%', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', +})); -export type TableProps = { - data: null | Entity[]; - loading?: boolean; - error?: ErrorResult | null; - renderDataHeaders: (renderProps: RenderProps) => React.ReactElement; - renderPaginatedData: ( - paginatedData: Entity[], - renderProps?: RenderProps, - ) => React.ReactElement | React.ReactElement[]; - tableRowType?: TableRowType; - pageCount: number; - currentPage: number; - pageSize?: number; - itemCount?: number; - setPerPage?: (limit: number) => void; - setCurrentPage?: (page: number) => void; - hideRowsPerPage?: boolean; - totalRowsLabel?: string; -}; - -export const Table = ({ - data, - loading, - error, - renderDataHeaders, - renderPaginatedData, - tableRowType = TableRowType.TextWithAvatar, - ...props -}: TableProps) => { - const renderPaginationRow = () => - !error && ( - - ); +export function Table(props: TableProps) { + const { + renderHeader, + renderDataHeaders, + renderData, + renderFooter, + noData, + noDataMessage, + paddingBottom, + } = props; return ( - renderPaginationRow()} - renderDataHeaders={() => - renderDataHeaders({ - sortingProps: null!, - }) - } - renderData={() => - (data == null && !error) || loading ? ( - - ) : error ? ( - - ) : data ? ( - renderPaginatedData(data, { - sortingProps: {}!, - }) - ) : ( - <> - ) - } - renderFooter={() => renderPaginationRow()} - {...props} - /> + <> + {renderHeader && renderHeader()} + + + {renderDataHeaders && {renderDataHeaders()}} + {renderData && {renderData()}} + + + {renderFooter && renderFooter()} + {noDataMessage && noData && ( + + {noDataMessage} + + )} + ); -}; +} export default Table; diff --git a/src/lib/components/text-row/text-row.stories.tsx b/src/lib/components/text-row/text-row.stories.tsx index fe312d38..4e4998e4 100644 --- a/src/lib/components/text-row/text-row.stories.tsx +++ b/src/lib/components/text-row/text-row.stories.tsx @@ -9,7 +9,8 @@ import { InfoIcon } from '../../icons-index'; export default { component: TextRow, - title: 'Components/Forms and inputs/Text Row', + title: 'Components/Form/TextRow', + excludeStories: ['Primary'], // tags: ['autodocs', '!dev'], args: { label: 'text row', diff --git a/src/lib/components/text/text.stories.tsx b/src/lib/components/text/text.stories.tsx index 3f9b1438..21c275f8 100644 --- a/src/lib/components/text/text.stories.tsx +++ b/src/lib/components/text/text.stories.tsx @@ -12,7 +12,7 @@ import { StoryFn } from '@storybook/react'; export default { component: Text, - title: 'Components/Primitives/Text', + title: 'Components/Display/Text', // tags: ['autodocs', '!dev'], args: { loading: false, diff --git a/src/lib/components/textarea/textarea.stories.tsx b/src/lib/components/textarea/textarea.stories.tsx index 0e91038c..a8928e2e 100644 --- a/src/lib/components/textarea/textarea.stories.tsx +++ b/src/lib/components/textarea/textarea.stories.tsx @@ -7,7 +7,7 @@ import { HeartIcon } from '../../icons-index'; export default { component: Textarea, - title: 'Components/Forms and inputs/Textarea', + title: 'Components/Form/Textarea', // tags: ['autodocs', '!dev'], args: { disabled: false, diff --git a/src/lib/components/token/token.stories.tsx b/src/lib/components/token/token.stories.tsx new file mode 100644 index 00000000..a1847ac1 --- /dev/null +++ b/src/lib/components/token/token.stories.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; +import Token from './token'; +import FlexRow from '../flex-row/flex-row'; +import FlexColumn from '../flex-column/flex-column'; + +export default { + component: Token, + title: 'Components/Display/Token', + // tags: ['autodocs', '!dev'], + args: { + amount: '50000123456789', + decimals: 9, + precision: 5, + ticker: 'BOIN', + }, + argTypes: { + amount: { + control: 'text', + description: 'Amount in motes to be displayed', + table: { + type: { summary: 'string' }, + defaultValue: { summary: '50000123456789' }, + }, + }, + decimals: { + control: 'number', + }, + precision: { + control: 'number', + }, + ticker: { + control: 'select', + options: ['BOIN', 'CLICK3', 'CSPR'], + }, + }, +} as Meta; + +const Template: StoryFn = (args) => ( + + + + + +); + +export const Primary = Template.bind({}); diff --git a/src/lib/components/token/token.tsx b/src/lib/components/token/token.tsx new file mode 100644 index 00000000..f559ea73 --- /dev/null +++ b/src/lib/components/token/token.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { formatNumber } from '../../utils/formatters'; +import { + currencyPrecisionByCase, + motesToCEP18Token, +} from '../../utils/currency'; + +export interface TokenProps { + amount?: string | null; + precision: number; + decimals: number; + ticker: string; + hideCurrency?: boolean; +} + +export function Token({ + amount, + precision, + decimals, + ticker, + hideCurrency, +}: TokenProps) { + if (amount == null) { + return <>{'N/A'}; + } + + const tokenAmount = motesToCEP18Token(amount, decimals); + const formattedTokenAmount = formatNumber(tokenAmount, { precision }); + const formattedText = formattedTokenAmount + ' ' + ticker; + + return <>{hideCurrency ? formattedTokenAmount : formattedText}; +} + +export default Token; diff --git a/src/lib/components/tooltip/tooltip.stories.tsx b/src/lib/components/tooltip/tooltip.stories.tsx index ee31bcb8..8bb9f551 100644 --- a/src/lib/components/tooltip/tooltip.stories.tsx +++ b/src/lib/components/tooltip/tooltip.stories.tsx @@ -8,7 +8,7 @@ import CaptionText from '../caption-text/caption-text'; export default { component: Tooltip, - title: 'Components/Overlays and layering/Tooltip', + title: 'Components/Display/Tooltip', // tags: ['autodocs', '!dev'], args: { title: diff --git a/src/lib/components/truncate-box/truncate-box.stories.tsx b/src/lib/components/truncate-box/truncate-box.stories.tsx index b7454ee4..f30ca593 100644 --- a/src/lib/components/truncate-box/truncate-box.stories.tsx +++ b/src/lib/components/truncate-box/truncate-box.stories.tsx @@ -7,7 +7,7 @@ import BodyText from '../body-text/body-text'; export default { component: TruncateBox, - title: 'Components/Forms and inputs/Truncate Box', + title: 'Components/Display/TruncateBox', // tags: ['autodocs', '!dev'], args: { size: 1, diff --git a/src/lib/components/user-input-window/user-input-window.stories.tsx b/src/lib/components/user-input-window/user-input-window.stories.tsx index 6d2b8456..68c59181 100644 --- a/src/lib/components/user-input-window/user-input-window.stories.tsx +++ b/src/lib/components/user-input-window/user-input-window.stories.tsx @@ -12,6 +12,7 @@ import { HeaderMenuIcon, LockImageIcon, WarningIcon } from '../../icons-index'; export default { component: UserInputWindow, title: 'Components/Overlays and layering/User Input Window', + excludeStories: ['Primary'], // tags: ['autodocs', '!dev'], parameters: { layout: 'fullscreen' }, argTypes: { diff --git a/src/lib/index.ts b/src/lib/index.ts index 64eaf6c1..818ca5e0 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -4,6 +4,7 @@ export * from './components/body-text/body-text'; export * from './components/button/button'; export * from './components/badge/badge'; export * from './components/copy-hash/copy-hash'; +export * from './components/copy/copy'; export * from './components/caption-text/caption-text'; export * from './components/checkbox/checkbox'; export * from './components/circular-indicator/circular-indicator'; @@ -34,11 +35,12 @@ export * from './components/table-body/table-body'; export * from './components/table-data/table-data'; export * from './components/table-head/table-head'; export * from './components/table-row/table-row'; -export * from './components/base-table/base-table'; -export * from './components/table-data-header/table-data-header'; export * from './components/table/table'; -export * from './components/table/table-error'; -export * from './components/table/table-loader'; +export * from './components/table-data-header/table-data-header'; +export * from './components/paginated-table/paginated-table'; +export * from './components/paginated-table/table-error'; +export * from './components/paginated-table/table-loader'; +export * from './components/pagination/pagination'; export * from './components/textarea/textarea'; export * from './components/truncate-box/truncate-box'; export * from './components/text/text'; @@ -63,6 +65,7 @@ export * from './components/cep18-token/cep18-token'; export * from './components/cspr/cspr'; export * from './components/user-input-window/user-input-window'; export * from './components/multiline-text-row/multiline-text-row'; +export * from './components/multiselect-dropdown/multiselect-dropdown'; export * from './components/warning-message/warning-message'; export * from './components/modal-content-header/modal-content-header'; export * from './components/dropdown-with-search/searchable-dropdown'; diff --git a/src/lib/utils/formatters.stories.tsx b/src/lib/utils/formatters.stories.tsx index feb5e15c..55523d41 100644 --- a/src/lib/utils/formatters.stories.tsx +++ b/src/lib/utils/formatters.stories.tsx @@ -13,7 +13,7 @@ import { } from './formatters'; export default { - title: 'Components/Utils/Formatters', + title: 'Components/Format/Formatters', // tags: ['autodocs', '!dev'], args: {}, argTypes: {}, diff --git a/src/static/favicon.ico b/src/static/favicon.ico index 19e44bbe..e9bed07a 100644 Binary files a/src/static/favicon.ico and b/src/static/favicon.ico differ diff --git a/src/storybook-components.tsx b/src/storybook-components.tsx index e0ad0549..5e6f2a87 100644 --- a/src/storybook-components.tsx +++ b/src/storybook-components.tsx @@ -1,38 +1,4 @@ import styled from 'styled-components'; -import FlexRow from './lib/components/flex-row/flex-row'; -import FlexColumn from './lib/components/flex-column/flex-column'; -import CsprDesignLogo from './static/cspr-design-logo.svg'; -import SvgIcon from './lib/components/svg-icon/svg-icon'; - -// @ts-ignore -const StyledCard = styled.div(() => ({ - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - width: '100px', - height: '100%', - minWidth: '200px', - minHeight: '200px', - overflow: 'hidden', - borderRadius: '12px', - backgroundColor: '#F2F3F5', - boxShadow: '0px 2px 4px rgba(143, 144, 152, 0.45)', -})); - -const StyledContainer = styled.div(({}) => ({ - display: 'flex', - flexDirection: 'row', - justifyContent: 'center', - alignItems: 'center', - padding: '16px', -})); - -const StyledCardText = styled.div(() => ({ - color: '#0B120E', - lineHeight: '24px', - fontWeight: 600, - fontFamily: 'Inter', -})); export const StyledHeaderWrapper = styled.span(({}) => ({ '& h1': { @@ -49,34 +15,3 @@ export const StyledWrapper = styled.div(({}) => ({ alignItems: 'center', color: '#fff !important', })); - -interface MenuBlockProps { - items: Array<{ label: string; link: string }>; -} - -export const MenuBlocks = ({ items }: MenuBlockProps) => { - return ( - - - {items.map((item) => { - return ( - - - - - - - {item.label} - - - - ); - })} - - - ); -};