diff --git a/.github/workflows/nym-wallet-storybook.yml b/.github/workflows/nym-wallet-storybook.yml
new file mode 100644
index 0000000000..b7930ed200
--- /dev/null
+++ b/.github/workflows/nym-wallet-storybook.yml
@@ -0,0 +1,55 @@
+name: Nym Wallet Storybook
+
+on:
+ push:
+ paths:
+ - 'nym-wallet/**'
+
+jobs:
+ build:
+ runs-on: custom-runner-linux
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install rsync
+ run: sudo apt-get install rsync
+ - uses: rlespinasse/github-slug-action@v3.x
+ - uses: actions/setup-node@v2
+ with:
+ node-version: '16'
+ - name: Setup yarn
+ run: npm install -g yarn
+ - name: Build dependencies
+ run: yarn && yarn build
+ - name: Build storybook
+ run: yarn storybook:build
+ working-directory: ./nym-wallet
+ - name: Deploy branch to CI www (storybook)
+ continue-on-error: true
+ uses: easingthemes/ssh-deploy@main
+ env:
+ SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
+ ARGS: "-rltgoDzvO --delete"
+ SOURCE: "nym-wallet/storybook-static/"
+ REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
+ REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
+ TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/wallet-${{ env.GITHUB_REF_SLUG }}
+ EXCLUDE: "/dist/, /node_modules/"
+ - name: Keybase - Node Install
+ run: npm install
+ working-directory: .github/workflows/support-files
+ - name: Keybase - Send Notification
+ env:
+ NYM_NOTIFICATION_KIND: nym-wallet
+ NYM_PROJECT_NAME: "nym-wallet"
+ NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
+ NYM_CI_WWW_LOCATION: "wallet-${{ env.GITHUB_REF_SLUG }}"
+ GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
+ GIT_BRANCH: "${GITHUB_REF##*/}"
+ KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
+ KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
+ KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
+ KEYBASE_NYM_CHANNEL: "ci-nym-wallet"
+ IS_SUCCESS: "${{ job.status == 'success' }}"
+ uses: docker://keybaseio/client:stable-node
+ with:
+ args: .github/workflows/support-files/notifications/entry_point.sh
diff --git a/.github/workflows/support-files/notifications/send_message.js b/.github/workflows/support-files/notifications/send_message.js
index fa95444192..eacd5af1ed 100644
--- a/.github/workflows/support-files/notifications/send_message.js
+++ b/.github/workflows/support-files/notifications/send_message.js
@@ -3,7 +3,7 @@ require('dotenv').config();
const Bot = require('keybase-bot');
let context = {
- kinds: ['ts-packages', 'network-explorer', 'nightly'],
+ kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly'],
};
/**
diff --git a/.github/workflows/support-files/nym-wallet/index.js b/.github/workflows/support-files/nym-wallet/index.js
new file mode 100644
index 0000000000..be74285c12
--- /dev/null
+++ b/.github/workflows/support-files/nym-wallet/index.js
@@ -0,0 +1,29 @@
+const Handlebars = require('handlebars');
+const fs = require('fs');
+const path = require('path');
+
+async function addToContextAndValidate(context) {
+ if (!context.env.NYM_CI_WWW_LOCATION) {
+ throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set');
+ }
+ if (!context.env.NYM_CI_WWW_BASE) {
+ throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set');
+ }
+}
+
+async function getMessageBody(context) {
+ const source = fs
+ .readFileSync(
+ context.env.IS_SUCCESS === 'true'
+ ? path.resolve(__dirname, 'templates', 'success')
+ : path.resolve(__dirname, 'templates', 'failure'),
+ )
+ .toString();
+ const template = Handlebars.compile(source);
+ return template(context);
+}
+
+module.exports = {
+ addToContextAndValidate,
+ getMessageBody,
+};
diff --git a/.github/workflows/support-files/nym-wallet/templates/failure b/.github/workflows/support-files/nym-wallet/templates/failure
new file mode 100644
index 0000000000..adc2896ace
--- /dev/null
+++ b/.github/workflows/support-files/nym-wallet/templates/failure
@@ -0,0 +1,11 @@
+🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
+> :rocket: {{ env.NYM_PROJECT_NAME }}
+> 🔴 **FAILURE** :cry:
+> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
+> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
+> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
+
+Commit message:
+```
+{{ env.GIT_COMMIT_MESSAGE }}
+```
diff --git a/.github/workflows/support-files/nym-wallet/templates/success b/.github/workflows/support-files/nym-wallet/templates/success
new file mode 100644
index 0000000000..826f75e977
--- /dev/null
+++ b/.github/workflows/support-files/nym-wallet/templates/success
@@ -0,0 +1,15 @@
+🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
+> :rocket: {{ env.NYM_PROJECT_NAME }}
+> ✅ **SUCCESS**
+
+> ➡️➡️➡️➡️➡️ **View output:**
+> `storybook`: https://{{ env.NYM_CI_WWW_LOCATION }}.{{ env.NYM_CI_WWW_BASE }}
+
+> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
+> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
+> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
+
+Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}:
+```
+{{ env.GIT_COMMIT_MESSAGE }}
+```
diff --git a/nym-wallet/.storybook/main.js b/nym-wallet/.storybook/main.js
new file mode 100644
index 0000000000..db6de0998f
--- /dev/null
+++ b/nym-wallet/.storybook/main.js
@@ -0,0 +1,57 @@
+/* eslint-disable no-param-reassign */
+const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
+const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
+
+module.exports = {
+ stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
+ addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-interactions'],
+ framework: '@storybook/react',
+ core: {
+ builder: 'webpack5',
+ },
+ // webpackFinal: async (config, { configType }) => {
+ // // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
+ // // You can change the configuration based on that.
+ // // 'PRODUCTION' is used when building the static version of storybook.
+ webpackFinal: async (config) => {
+ config.module.rules.forEach((rule) => {
+ // look for SVG import rule and replace
+ // NOTE: the rule before modification is /\.(svg|ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/
+ if (rule.test?.toString().includes('svg')) {
+ rule.test = /\.(ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/;
+ }
+ });
+
+ // handle asset loading with this
+ config.module.rules.unshift({
+ test: /\.svg(\?.*)?$/i,
+ issuer: /\.[jt]sx?$/,
+ use: ['@svgr/webpack'],
+ });
+
+ config.resolve.extensions = ['.tsx', '.ts', '.js'];
+ config.resolve.plugins = [new TsconfigPathsPlugin()];
+
+ config.plugins.push(new ForkTsCheckerWebpackPlugin({
+ typescript: {
+ mode: 'write-references',
+ diagnosticOptions: {
+ semantic: true,
+ syntactic: true,
+ },
+ },
+ }));
+
+ if (!config.resolve.alias) {
+ config.resolve.alias = {};
+ }
+
+ config.resolve.alias['@tauri-apps/api'] = `${__dirname}/mocks/tauri`;
+
+ // Return the altered config
+ return config;
+ },
+ features: {
+ emotionAlias: false,
+ },
+};
diff --git a/nym-wallet/.storybook/mocks/tauri/index.js b/nym-wallet/.storybook/mocks/tauri/index.js
new file mode 100644
index 0000000000..1288b5215f
--- /dev/null
+++ b/nym-wallet/.storybook/mocks/tauri/index.js
@@ -0,0 +1,13 @@
+/**
+ * This is a mock for Tauri's API package (@tauri-apps/api), to prevent stories from being excluded, because they either use
+ * or import dependencies that use Tauri.
+ */
+
+module.exports = {
+ invoke: (operation) => {
+ console.error(`Tauri cannot be used in Storybook. The operation requested was "${operation}". You can add mock responses to "nym_wallet/.storybook/mocks/tauri.js" if you need. The default response is "void".`);
+ return new Promise((resolve, reject) => {
+ reject(new Error(`Tauri operation ${operation} not available in storybook.`));
+ });
+ },
+}
\ No newline at end of file
diff --git a/nym-wallet/.storybook/mocks/tauri/window.js b/nym-wallet/.storybook/mocks/tauri/window.js
new file mode 100644
index 0000000000..9f0afeeebd
--- /dev/null
+++ b/nym-wallet/.storybook/mocks/tauri/window.js
@@ -0,0 +1,10 @@
+/**
+ * This is a mock for Tauri's API package (@tauri-apps/api/window), to prevent stories from being excluded, because they either use
+ * or import dependencies that use Tauri.
+ */
+
+module.exports = {
+ appWindow: {
+ maximize: () => undefined,
+ }
+}
diff --git a/nym-wallet/.storybook/preview.js b/nym-wallet/.storybook/preview.js
new file mode 100644
index 0000000000..73ab87b2dd
--- /dev/null
+++ b/nym-wallet/.storybook/preview.js
@@ -0,0 +1,19 @@
+import { NymWalletThemeWithMode } from '../src/theme/NymWalletTheme';
+
+export const parameters = {
+ actions: { argTypesRegex: "^on[A-Z].*" },
+ controls: {
+ matchers: {
+ color: /(background|color)$/i,
+ date: /Date$/,
+ },
+ },
+}
+
+const withThemeProvider = (Story, context) => (
+
+
+
+);
+
+export const decorators = [withThemeProvider];
diff --git a/nym-wallet/package.json b/nym-wallet/package.json
index 1e83032807..299b34b39f 100644
--- a/nym-wallet/package.json
+++ b/nym-wallet/package.json
@@ -10,11 +10,15 @@
"tauri:dev": "yarn tauri dev",
"tauri:build": "yarn tauri build",
"tsc": "tsc --noEmit true",
+ "tsc:watch": "tsc --noEmit true --watch",
"dev": "yarn run webpack:dev & yarn run tauri:dev",
"prebuild": "yarn --cwd .. build",
"build": "run-s webpack:prod tauri:build",
"lint": "eslint src",
- "lint:fix": "eslint src --fix"
+ "lint:fix": "eslint src --fix",
+ "prestorybook": "yarn --cwd .. build",
+ "storybook": "start-storybook -p 6006",
+ "storybook:build": "build-storybook"
},
"dependencies": {
"@babel/preset-typescript": "^7.15.0",
@@ -47,6 +51,12 @@
"@babel/preset-react": "^7.14.5",
"@nymproject/eslint-config-react-typescript": "^1.0.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
+ "@storybook/addon-actions": "^6.4.19",
+ "@storybook/addon-essentials": "^6.4.19",
+ "@storybook/addon-interactions": "^6.4.19",
+ "@storybook/addon-links": "^6.4.19",
+ "@storybook/react": "^6.4.19",
+ "@storybook/testing-library": "^0.0.9",
"@svgr/webpack": "^6.1.1",
"@tauri-apps/cli": "^1.0.0-rc.5",
"@testing-library/jest-dom": "^5.14.1",
diff --git a/nym-wallet/src/stories/Introduction.stories.mdx b/nym-wallet/src/stories/Introduction.stories.mdx
new file mode 100644
index 0000000000..c22001164e
--- /dev/null
+++ b/nym-wallet/src/stories/Introduction.stories.mdx
@@ -0,0 +1,7 @@
+import { Meta } from '@storybook/addon-docs';
+
+
+
+# Nym Wallet Storybook
+
+This is the Storybook for the Nym Wallet.
diff --git a/nym-wallet/src/theme/NymWalletTheme.tsx b/nym-wallet/src/theme/NymWalletTheme.tsx
new file mode 100644
index 0000000000..0b7ee87f90
--- /dev/null
+++ b/nym-wallet/src/theme/NymWalletTheme.tsx
@@ -0,0 +1,15 @@
+import React from 'react';
+import { CssBaseline, PaletteMode } from '@mui/material';
+import { createTheme, ThemeProvider } from '@mui/material/styles';
+import { getDesignTokens } from './theme';
+import '@assets/fonts/fonts.css';
+
+export const NymWalletThemeWithMode: React.FC<{ mode: PaletteMode }> = ({ mode, children }) => {
+ const theme = React.useMemo(() => createTheme(getDesignTokens(mode)), [mode]);
+ return (
+
+
+ {children}
+
+ );
+};
diff --git a/package.json b/package.json
index 27039fe423..da52f34d1e 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,8 @@
"explorer"
],
"scripts": {
- "build": "lerna run --scope @nymproject/mui-theme --scope @nymproject/react build --stream",
+ "build": "run-s build:packages",
+ "build:packages": "lerna run --scope @nymproject/mui-theme --scope @nymproject/react --stream build",
"build:react-example": "lerna run --scope @nymproject/react-webpack-with-theme-example build --stream",
"build:playground": "lerna run --scope @nymproject/react storybook:build --stream",
"build:ci": "yarn build && run-p build:react-example build:playground && yarn build:ci:collect-artifacts",