mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-04-25 03:49:11 +00:00
chore: prettier
This commit is contained in:
parent
ccf89d8480
commit
70fa51d4a1
67 changed files with 1811 additions and 1838 deletions
|
@ -1,20 +1,20 @@
|
||||||
{
|
{
|
||||||
"name": "Roleypoly (Bazel, Go, Node)",
|
"name": "Roleypoly (Bazel, Go, Node)",
|
||||||
// Docker Hub because easier to go fast
|
// Docker Hub because easier to go fast
|
||||||
"image": "roleypoly/dev-container:main",
|
"image": "roleypoly/dev-container:main",
|
||||||
"settings": {
|
"settings": {
|
||||||
"terminal.integrated.shell.linux": "/bin/bash"
|
"terminal.integrated.shell.linux": "/bin/bash"
|
||||||
},
|
},
|
||||||
"extensions": [
|
"extensions": [
|
||||||
"bazelbuild.vscode-bazel",
|
"bazelbuild.vscode-bazel",
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"golang.go",
|
"golang.go",
|
||||||
"hashicorp.terraform",
|
"hashicorp.terraform",
|
||||||
"firsttris.vscode-jest-runner",
|
"firsttris.vscode-jest-runner",
|
||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"zxh404.vscode-proto3",
|
"zxh404.vscode-proto3",
|
||||||
"jpoissonnier.vscode-styled-components",
|
"jpoissonnier.vscode-styled-components",
|
||||||
"eg2.vscode-npm-script",
|
"eg2.vscode-npm-script",
|
||||||
"christian-kohler.npm-intellisense"
|
"christian-kohler.npm-intellisense"
|
||||||
]
|
]
|
||||||
}
|
}
|
32
.github/dependabot.yml
vendored
32
.github/dependabot.yml
vendored
|
@ -1,24 +1,24 @@
|
||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: 'npm'
|
||||||
directory: "/"
|
directory: '/'
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: 'github-actions'
|
||||||
directory: "/"
|
directory: '/'
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
|
||||||
- package-ecosystem: "docker"
|
- package-ecosystem: 'docker'
|
||||||
directory: "/.devcontainer"
|
directory: '/.devcontainer'
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
|
||||||
- package-ecosystem: "gomod"
|
- package-ecosystem: 'gomod'
|
||||||
directory: "/"
|
directory: '/'
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
# - package-ecosystem: "terraform"
|
# - package-ecosystem: "terraform"
|
||||||
# directory: "/terraform/platform/bootstrap"
|
# directory: "/terraform/platform/bootstrap"
|
||||||
# schedule:
|
# schedule:
|
||||||
|
|
94
.github/workflows/build.yml
vendored
94
.github/workflows/build.yml
vendored
|
@ -3,57 +3,57 @@ name: Bazel Build
|
||||||
on: push
|
on: push
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
bazel_build:
|
bazel_build:
|
||||||
name: Bazel Build
|
name: Bazel Build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@master
|
||||||
|
|
||||||
- name: Mount bazel cache
|
- name: Mount bazel cache
|
||||||
uses: actions/cache@v2.1.1
|
uses: actions/cache@v2.1.1
|
||||||
with:
|
with:
|
||||||
path: "/home/runner/.cache/bazel"
|
path: '/home/runner/.cache/bazel'
|
||||||
key: bazel
|
key: bazel
|
||||||
|
|
||||||
- name: Install bazelisk
|
- name: Install bazelisk
|
||||||
run: |
|
run: |
|
||||||
curl -LO "https://github.com/bazelbuild/bazelisk/releases/download/v1.1.0/bazelisk-linux-amd64"
|
curl -LO "https://github.com/bazelbuild/bazelisk/releases/download/v1.1.0/bazelisk-linux-amd64"
|
||||||
mkdir -p "${GITHUB_WORKSPACE}/bin/"
|
mkdir -p "${GITHUB_WORKSPACE}/bin/"
|
||||||
mv bazelisk-linux-amd64 "${GITHUB_WORKSPACE}/bin/bazel"
|
mv bazelisk-linux-amd64 "${GITHUB_WORKSPACE}/bin/bazel"
|
||||||
chmod +x "${GITHUB_WORKSPACE}/bin/bazel"
|
chmod +x "${GITHUB_WORKSPACE}/bin/bazel"
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: |
|
run: |
|
||||||
"${GITHUB_WORKSPACE}/bin/bazel" test \
|
"${GITHUB_WORKSPACE}/bin/bazel" test \
|
||||||
--stamp \
|
--stamp \
|
||||||
--workspace_status_command hack/workspace_status.sh \
|
--workspace_status_command hack/workspace_status.sh \
|
||||||
//src/...
|
//src/...
|
||||||
|
|
||||||
- name: Docker Login
|
- name: Docker Login
|
||||||
run: |
|
run: |
|
||||||
echo ${{github.token}} | docker login -u ${{github.actor}} --password-stdin docker.pkg.github.com
|
echo ${{github.token}} | docker login -u ${{github.actor}} --password-stdin docker.pkg.github.com
|
||||||
|
|
||||||
- name: Publish Artifacts
|
- name: Publish Artifacts
|
||||||
run: |
|
run: |
|
||||||
"${GITHUB_WORKSPACE}/bin/bazel" query //src/... |\
|
"${GITHUB_WORKSPACE}/bin/bazel" query //src/... |\
|
||||||
grep +publish |\
|
grep +publish |\
|
||||||
xargs -l1 "${GITHUB_WORKSPACE}/bin/bazel" run \
|
xargs -l1 "${GITHUB_WORKSPACE}/bin/bazel" run \
|
||||||
--stamp \
|
--stamp \
|
||||||
--workspace_status_command hack/workspace_status.sh
|
--workspace_status_command hack/workspace_status.sh
|
||||||
|
|
||||||
- name: Write Artifact Manifest
|
- name: Write Artifact Manifest
|
||||||
run: |
|
run: |
|
||||||
artifacts=$(${GITHUB_WORKSPACE}/bin/bazel query //src/... | grep +publish)
|
artifacts=$(${GITHUB_WORKSPACE}/bin/bazel query //src/... | grep +publish)
|
||||||
publishedServices=${artifacts//$'//src/'/}
|
publishedServices=${artifacts//$'//src/'/}
|
||||||
publishedServices=${publishedServices//$':+publish'/}
|
publishedServices=${publishedServices//$':+publish'/}
|
||||||
manifestJSON='{"services": {}}'
|
manifestJSON='{"services": {}}'
|
||||||
for svc in $publishedServices; do
|
for svc in $publishedServices; do
|
||||||
manifestJSON=$(echo $manifestJSON | jq ".services+={\"$svc\":\"$(cat bazel-bin/src/$svc/+publish.digest)\"}")
|
manifestJSON=$(echo $manifestJSON | jq ".services+={\"$svc\":\"$(cat bazel-bin/src/$svc/+publish.digest)\"}")
|
||||||
done
|
done
|
||||||
echo $manifestJSON > manifest.json
|
echo $manifestJSON > manifest.json
|
||||||
|
|
||||||
- name: Upload Artifact Manifest
|
- name: Upload Artifact Manifest
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: manifest.json
|
name: manifest.json
|
||||||
path: manifest.json
|
path: manifest.json
|
||||||
|
|
108
.github/workflows/codeql-analysis.yml
vendored
108
.github/workflows/codeql-analysis.yml
vendored
|
@ -1,67 +1,67 @@
|
||||||
name: "CodeQL"
|
name: 'CodeQL'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
pull_request:
|
pull_request:
|
||||||
# The branches below must be a subset of the branches above
|
# The branches below must be a subset of the branches above
|
||||||
branches: [main]
|
branches: [main]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 1 * * 2"
|
- cron: '0 1 * * 2'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
analyze:
|
analyze:
|
||||||
name: Analyze
|
name: Analyze
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
# Override automatic language detection by changing the below list
|
# Override automatic language detection by changing the below list
|
||||||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
||||||
language: ["go", "javascript"]
|
language: ['go', 'javascript']
|
||||||
# Learn more...
|
# Learn more...
|
||||||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
# We must fetch at least the immediate parents so that if this is
|
# We must fetch at least the immediate parents so that if this is
|
||||||
# a pull request then we can checkout the head.
|
# a pull request then we can checkout the head.
|
||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
|
|
||||||
# If this run was triggered by a pull request event, then checkout
|
# If this run was triggered by a pull request event, then checkout
|
||||||
# the head of the pull request instead of the merge commit.
|
# the head of the pull request instead of the merge commit.
|
||||||
- run: git checkout HEAD^2
|
- run: git checkout HEAD^2
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v1
|
uses: github/codeql-action/init@v1
|
||||||
with:
|
with:
|
||||||
queries: +security-and-quality
|
queries: +security-and-quality
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
# By default, queries listed here will override any specified in a config file.
|
# By default, queries listed here will override any specified in a config file.
|
||||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v1
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
# and modify them (or add more) to build your code if your project
|
# and modify them (or add more) to build your code if your project
|
||||||
# uses a compiled language
|
# uses a compiled language
|
||||||
|
|
||||||
#- run: |
|
#- run: |
|
||||||
# make bootstrap
|
# make bootstrap
|
||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v1
|
uses: github/codeql-action/analyze@v1
|
||||||
|
|
70
.github/workflows/dev-container.yml
vendored
70
.github/workflows/dev-container.yml
vendored
|
@ -1,43 +1,43 @@
|
||||||
name: Build Dev Container
|
name: Build Dev Container
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- .devcontainer/*
|
- .devcontainer/*
|
||||||
- src/dev-container/*
|
- src/dev-container/*
|
||||||
- .github/workflows/dev-container.yml
|
- .github/workflows/dev-container.yml
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 12 * * 2" # 12 noon every tuesday
|
- cron: '0 12 * * 2' # 12 noon every tuesday
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
dev_container_build:
|
dev_container_build:
|
||||||
name: Bazel Build (Dev Container)
|
name: Bazel Build (Dev Container)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@master
|
||||||
- name: Mount bazel cache
|
- name: Mount bazel cache
|
||||||
uses: actions/cache@v2.1.1
|
uses: actions/cache@v2.1.1
|
||||||
with:
|
with:
|
||||||
path: "/home/runner/.cache/bazel"
|
path: '/home/runner/.cache/bazel'
|
||||||
key: bazel_dev_container
|
key: bazel_dev_container
|
||||||
|
|
||||||
- name: Install bazelisk
|
- name: Install bazelisk
|
||||||
run: |
|
run: |
|
||||||
curl -LO "https://github.com/bazelbuild/bazelisk/releases/download/v1.1.0/bazelisk-linux-amd64"
|
curl -LO "https://github.com/bazelbuild/bazelisk/releases/download/v1.1.0/bazelisk-linux-amd64"
|
||||||
mkdir -p "${GITHUB_WORKSPACE}/bin/"
|
mkdir -p "${GITHUB_WORKSPACE}/bin/"
|
||||||
mv bazelisk-linux-amd64 "${GITHUB_WORKSPACE}/bin/bazel"
|
mv bazelisk-linux-amd64 "${GITHUB_WORKSPACE}/bin/bazel"
|
||||||
chmod +x "${GITHUB_WORKSPACE}/bin/bazel"
|
chmod +x "${GITHUB_WORKSPACE}/bin/bazel"
|
||||||
|
|
||||||
- name: Build & Publish Dev Container
|
- name: Build & Publish Dev Container
|
||||||
run: |
|
run: |
|
||||||
echo ${{github.token}} | docker login -u ${{github.actor}} --password-stdin docker.pkg.github.com
|
echo ${{github.token}} | docker login -u ${{github.actor}} --password-stdin docker.pkg.github.com
|
||||||
"${GITHUB_WORKSPACE}/bin/bazel" run \
|
"${GITHUB_WORKSPACE}/bin/bazel" run \
|
||||||
--stamp \
|
--stamp \
|
||||||
--workspace_status_command hack/workspace_status.sh \
|
--workspace_status_command hack/workspace_status.sh \
|
||||||
//src/dev-container:publish-dev-container
|
//src/dev-container:publish-dev-container
|
||||||
|
|
||||||
echo ${{secrets.DOCKER_PASSWORD}} | docker login -u ${{secrets.DOCKER_USERNAME}} --password-stdin
|
echo ${{secrets.DOCKER_PASSWORD}} | docker login -u ${{secrets.DOCKER_USERNAME}} --password-stdin
|
||||||
"${GITHUB_WORKSPACE}/bin/bazel" run \
|
"${GITHUB_WORKSPACE}/bin/bazel" run \
|
||||||
--stamp \
|
--stamp \
|
||||||
--workspace_status_command hack/workspace_status.sh \
|
--workspace_status_command hack/workspace_status.sh \
|
||||||
//src/dev-container:publish-dev-container-dockerhub
|
//src/dev-container:publish-dev-container-dockerhub
|
||||||
|
|
34
.github/workflows/release.yml
vendored
34
.github/workflows/release.yml
vendored
|
@ -3,22 +3,22 @@ name: Release Workflow
|
||||||
on: workflow_dispatch
|
on: workflow_dispatch
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
commit_release_tag:
|
commit_release_tag:
|
||||||
name: Commit Roleypoly Release Tag
|
name: Commit Roleypoly Release Tag
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@master
|
||||||
with:
|
with:
|
||||||
ssh-key: ${{ secrets.DEPLOY_KEY }}
|
ssh-key: ${{ secrets.DEPLOY_KEY }}
|
||||||
|
|
||||||
- name: Push changes
|
- name: Push changes
|
||||||
id: push
|
id: push
|
||||||
run: |
|
run: |
|
||||||
TAG=$(date +v%Y%m%d-%H%M%S)
|
TAG=$(date +v%Y%m%d-%H%M%S)
|
||||||
git config --local user.email "gh-automation@roleypoly.com"
|
git config --local user.email "gh-automation@roleypoly.com"
|
||||||
git config --local user.name "Roleypoly Release Automation"
|
git config --local user.name "Roleypoly Release Automation"
|
||||||
git tag $TAG
|
git tag $TAG
|
||||||
git push origin $TAG
|
git push origin $TAG
|
||||||
echo "::set-output release_tag=${TAG}"
|
echo "::set-output release_tag=${TAG}"
|
||||||
|
|
||||||
- name: Retag images
|
- name: Retag images
|
||||||
|
|
1
.github/workflows/terraform.yml
vendored
1
.github/workflows/terraform.yml
vendored
|
@ -1,2 +1 @@
|
||||||
name: Terraform
|
name: Terraform
|
||||||
|
|
||||||
|
|
12
.gitignore
vendored
12
.gitignore
vendored
|
@ -5,16 +5,6 @@ bazel-testlogs
|
||||||
node_modules
|
node_modules
|
||||||
.env
|
.env
|
||||||
docker-compose.yaml
|
docker-compose.yaml
|
||||||
|
|
||||||
#Added by cargo
|
|
||||||
|
|
||||||
/target
|
/target
|
||||||
|
|
||||||
|
|
||||||
#Added by cargo
|
|
||||||
#
|
|
||||||
#already existing elements were commented out
|
|
||||||
|
|
||||||
#/target
|
|
||||||
|
|
||||||
*.log
|
*.log
|
||||||
|
storybook-static
|
1
.prettierignore
Normal file
1
.prettierignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
bazel-*
|
9
.prettierrc.js
Normal file
9
.prettierrc.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
module.exports = {
|
||||||
|
printWidth: 90,
|
||||||
|
useTabs: false,
|
||||||
|
tabWidth: 4,
|
||||||
|
singleQuote: true,
|
||||||
|
trailingComma: 'es5',
|
||||||
|
bracketSpacing: true,
|
||||||
|
semi: true,
|
||||||
|
};
|
|
@ -1,16 +1,16 @@
|
||||||
const path = require("path");
|
const path = require('path');
|
||||||
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
|
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
|
||||||
addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
|
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
|
||||||
webpackFinal: async (config, { configType }) => {
|
webpackFinal: async (config, { configType }) => {
|
||||||
config.resolve.plugins = [
|
config.resolve.plugins = [
|
||||||
new TsconfigPathsPlugin({
|
new TsconfigPathsPlugin({
|
||||||
configFile: path.resolve(__dirname, "../tsconfig.json"),
|
configFile: path.resolve(__dirname, '../tsconfig.json'),
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { addons } from "@storybook/addons";
|
import { addons } from '@storybook/addons';
|
||||||
import { roleypolyTheme } from "./theme";
|
import { roleypolyTheme } from './theme';
|
||||||
|
|
||||||
addons.setConfig({
|
addons.setConfig({
|
||||||
theme: roleypolyTheme,
|
theme: roleypolyTheme,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
export const parameters = {
|
export const parameters = {
|
||||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
actions: { argTypesRegex: '^on[A-Z].*' },
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
import { create } from "@storybook/theming";
|
import { create } from '@storybook/theming';
|
||||||
import { palette } from "../src/design-system/atoms/colors";
|
import { palette } from '../src/design-system/atoms/colors';
|
||||||
|
|
||||||
export const roleypolyTheme = create({
|
export const roleypolyTheme = create({
|
||||||
base: "dark",
|
base: 'dark',
|
||||||
|
|
||||||
colorPrimary: palette.green400,
|
colorPrimary: palette.green400,
|
||||||
colorSecondary: palette.taupe200,
|
colorSecondary: palette.taupe200,
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
appBg: palette.taupe300,
|
appBg: palette.taupe300,
|
||||||
appContentBg: palette.taupe300,
|
appContentBg: palette.taupe300,
|
||||||
appBorderColor: palette.taupe100,
|
appBorderColor: palette.taupe100,
|
||||||
appBorderRadius: 0,
|
appBorderRadius: 0,
|
||||||
|
|
||||||
// Typography
|
// Typography
|
||||||
fontBase: "system-ui, sans-serif",
|
fontBase: 'system-ui, sans-serif',
|
||||||
fontCode: "monospace",
|
fontCode: 'monospace',
|
||||||
|
|
||||||
// Text colors
|
// Text colors
|
||||||
textColor: palette.grey600,
|
textColor: palette.grey600,
|
||||||
textInverseColor: palette.grey100,
|
textInverseColor: palette.grey100,
|
||||||
|
|
||||||
// Toolbar default and active colors
|
// Toolbar default and active colors
|
||||||
barTextColor: palette.taupe500,
|
barTextColor: palette.taupe500,
|
||||||
barSelectedColor: palette.taupe600,
|
barSelectedColor: palette.taupe600,
|
||||||
barBg: palette.taupe100,
|
barBg: palette.taupe100,
|
||||||
|
|
||||||
// Form colors
|
// Form colors
|
||||||
inputBg: "rgba(0,0,0,0.24)",
|
inputBg: 'rgba(0,0,0,0.24)',
|
||||||
inputBorder: palette.taupe100,
|
inputBorder: palette.taupe100,
|
||||||
inputTextColor: palette.grey600,
|
inputTextColor: palette.grey600,
|
||||||
inputBorderRadius: 0,
|
inputBorderRadius: 0,
|
||||||
});
|
});
|
||||||
|
|
16
.vscode/settings.json
vendored
16
.vscode/settings.json
vendored
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
"go.inferGopath": false,
|
"go.inferGopath": false,
|
||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2,
|
||||||
"editor.insertSpaces": true,
|
"editor.insertSpaces": true,
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"bazel.buildifierFixOnFormat": true,
|
"bazel.buildifierFixOnFormat": true,
|
||||||
"[starlark]": {
|
"[starlark]": {
|
||||||
"editor.tabSize": 4
|
"editor.tabSize": 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,5 +25,5 @@ If you'd like to not use either of those, it can be imported into your Docker ho
|
||||||
|
|
||||||
Bazel can make some tasks far harder normal. Ideally, these are automated over.
|
Bazel can make some tasks far harder normal. Ideally, these are automated over.
|
||||||
|
|
||||||
- **Updating `go.mod`?**
|
- **Updating `go.mod`?**
|
||||||
- Run `hack/gazelle.sh` to regenerate `deps.bzl`.
|
- Run `hack/gazelle.sh` to regenerate `deps.bzl`.
|
||||||
|
|
101
package.json
101
package.json
|
@ -1,52 +1,53 @@
|
||||||
{
|
{
|
||||||
"name": "roleypoly",
|
"name": "roleypoly",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "https://roleypoly.com",
|
"description": "https://roleypoly.com",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"storybook": "start-storybook -p 6006",
|
"storybook": "start-storybook -p 6006",
|
||||||
"build-storybook": "build-storybook",
|
"build-storybook": "build-storybook",
|
||||||
"now-build": "build-storybook"
|
"now-build": "build-storybook",
|
||||||
},
|
"lint:prettier": "cross-env prettier -c '**/*.{ts,tsx,css,yml,yaml,md,json,js,jsx}'"
|
||||||
"repository": {
|
},
|
||||||
"type": "git",
|
"repository": {
|
||||||
"url": "git+https://github.com/roleypoly/roleypoly.git"
|
"type": "git",
|
||||||
},
|
"url": "git+https://github.com/roleypoly/roleypoly.git"
|
||||||
"author": "Katalina Okano <git@kat.cafe>",
|
},
|
||||||
"license": "MIT",
|
"author": "Katalina Okano <git@kat.cafe>",
|
||||||
"bugs": {
|
"license": "MIT",
|
||||||
"url": "https://github.com/roleypoly/roleypoly/issues"
|
"bugs": {
|
||||||
},
|
"url": "https://github.com/roleypoly/roleypoly/issues"
|
||||||
"homepage": "https://github.com/roleypoly/roleypoly#readme",
|
},
|
||||||
"dependencies": {
|
"homepage": "https://github.com/roleypoly/roleypoly#readme",
|
||||||
"@roleypoly/rpc": "^1.9.3",
|
"dependencies": {
|
||||||
"chroma-js": "2.1.0",
|
"@roleypoly/rpc": "^1.9.3",
|
||||||
"next": "^9.5.4",
|
"chroma-js": "2.1.0",
|
||||||
"react": "16.13.1",
|
"next": "^9.5.5",
|
||||||
"react-dom": "16.13.1",
|
"react": "16.13.1",
|
||||||
"react-icons": "^3.11.0",
|
"react-dom": "16.13.1",
|
||||||
"styled-components": "^5.2.0"
|
"react-icons": "^3.11.0",
|
||||||
},
|
"styled-components": "^5.2.0"
|
||||||
"devDependencies": {
|
},
|
||||||
"@babel/core": "^7.11.6",
|
"devDependencies": {
|
||||||
"@bazel/typescript": "^2.2.1",
|
"@babel/core": "^7.11.6",
|
||||||
"@storybook/addon-actions": "^6.0.26",
|
"@bazel/typescript": "^2.2.1",
|
||||||
"@storybook/addon-essentials": "^6.0.26",
|
"@storybook/addon-actions": "^6.0.26",
|
||||||
"@storybook/addon-links": "^6.0.26",
|
"@storybook/addon-essentials": "^6.0.26",
|
||||||
"@storybook/addons": "^6.0.26",
|
"@storybook/addon-links": "^6.0.26",
|
||||||
"@storybook/react": "^6.0.26",
|
"@storybook/addons": "^6.0.26",
|
||||||
"@storybook/theming": "^6.0.26",
|
"@storybook/react": "^6.0.26",
|
||||||
"@types/chroma-js": "2.1.0",
|
"@storybook/theming": "^6.0.26",
|
||||||
"@types/google-protobuf": "3.7.3",
|
"@types/chroma-js": "2.1.0",
|
||||||
"@types/styled-components": "5.1.3",
|
"@types/google-protobuf": "3.7.3",
|
||||||
"babel-loader": "^8.1.0",
|
"@types/styled-components": "5.1.4",
|
||||||
"prettier": "^2.1.2",
|
"babel-loader": "^8.1.0",
|
||||||
"react-is": "^16.13.1",
|
"prettier": "^2.1.2",
|
||||||
"tsconfig-paths-webpack-plugin": "^3.3.0",
|
"react-is": "^16.13.1",
|
||||||
"tslint": "6.1.3",
|
"tsconfig-paths-webpack-plugin": "^3.3.0",
|
||||||
"tslint-config-prettier": "^1.18.0",
|
"tslint": "6.1.3",
|
||||||
"tslint-config-standard": "^9.0.0",
|
"tslint-config-prettier": "^1.18.0",
|
||||||
"tslint-plugin-prettier": "^2.3.0",
|
"tslint-config-standard": "^9.0.0",
|
||||||
"typescript": "^4.0.3"
|
"tslint-plugin-prettier": "^2.3.0",
|
||||||
}
|
"typescript": "^4.0.3"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,6 @@ Edit nothing outside of the `schemas` folder, as all others are generated.
|
||||||
|
|
||||||
When done editing, do `go generate ./ent` to update generation.
|
When done editing, do `go generate ./ent` to update generation.
|
||||||
|
|
||||||
*Failing to generate files will make CI fail.*
|
_Failing to generate files will make CI fail._
|
||||||
|
|
||||||
All schemas must be backwards compatible with previous versions of this library, and be compatible with **CockroachDB**-based Postgres.
|
All schemas must be backwards compatible with previous versions of this library, and be compatible with **CockroachDB**-based Postgres.
|
|
@ -1,30 +1,30 @@
|
||||||
import { text } from "@storybook/addon-knobs";
|
import { text } from '@storybook/addon-knobs';
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { Avatar } from "./Avatar";
|
import { Avatar } from './Avatar';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Avatar",
|
title: 'Atoms/Avatar',
|
||||||
component: Avatar,
|
component: Avatar,
|
||||||
argTypes: {
|
argTypes: {
|
||||||
initials: { control: "text" },
|
initials: { control: 'text' },
|
||||||
},
|
},
|
||||||
args: {
|
args: {
|
||||||
initials: "KR",
|
initials: 'KR',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WithInitials = ({ initials, ...rest }) => (
|
export const WithInitials = ({ initials, ...rest }) => (
|
||||||
<Avatar src="https://i.imgur.com/epMSRQH.png" size={48} {...rest}>
|
<Avatar src="https://i.imgur.com/epMSRQH.png" size={48} {...rest}>
|
||||||
{initials}
|
{initials}
|
||||||
</Avatar>
|
</Avatar>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const WithText = ({ initials, ...rest }) => (
|
export const WithText = ({ initials, ...rest }) => (
|
||||||
<Avatar size={48} {...rest}>
|
<Avatar size={48} {...rest}>
|
||||||
{initials}
|
{initials}
|
||||||
</Avatar>
|
</Avatar>
|
||||||
);
|
);
|
||||||
export const Empty = (args) => <Avatar size={48} {...args}></Avatar>;
|
export const Empty = (args) => <Avatar size={48} {...args}></Avatar>;
|
||||||
export const DeliberatelyEmpty = (args) => (
|
export const DeliberatelyEmpty = (args) => (
|
||||||
<Avatar size={48} deliberatelyEmpty={true} {...args}></Avatar>
|
<Avatar size={48} deliberatelyEmpty={true} {...args}></Avatar>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,46 +1,45 @@
|
||||||
import { AvatarProps } from "./Avatar";
|
import { AvatarProps } from './Avatar';
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from 'styled-components';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
import { palette } from "roleypoly/src/design-system/atoms/colors";
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
|
|
||||||
type ContainerProps = Pick<AvatarProps, "size"> &
|
type ContainerProps = Pick<AvatarProps, 'size'> & Pick<AvatarProps, 'deliberatelyEmpty'>;
|
||||||
Pick<AvatarProps, "deliberatelyEmpty">;
|
|
||||||
export const Container = styled.div<ContainerProps>`
|
export const Container = styled.div<ContainerProps>`
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: ${(props: ContainerProps) => props.size || 48}px;
|
width: ${(props: ContainerProps) => props.size || 48}px;
|
||||||
height: ${(props: ContainerProps) => props.size || 48}px;
|
height: ${(props: ContainerProps) => props.size || 48}px;
|
||||||
min-width: ${(props: ContainerProps) => props.size || 48}px;
|
min-width: ${(props: ContainerProps) => props.size || 48}px;
|
||||||
min-height: ${(props: ContainerProps) => props.size || 48}px;
|
min-height: ${(props: ContainerProps) => props.size || 48}px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: ${palette.grey100};
|
color: ${palette.grey100};
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: ${palette.grey500};
|
background-color: ${palette.grey500};
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-size: ${(props: ContainerProps) => props.size};
|
font-size: ${(props: ContainerProps) => props.size};
|
||||||
${(props) =>
|
${(props) =>
|
||||||
props.deliberatelyEmpty &&
|
props.deliberatelyEmpty &&
|
||||||
css`
|
css`
|
||||||
border: 4px solid rgba(0, 0, 0, 0.25);
|
border: 4px solid rgba(0, 0, 0, 0.25);
|
||||||
background-color: ${palette.taupe400};
|
background-color: ${palette.taupe400};
|
||||||
color: ${palette.taupe600};
|
color: ${palette.taupe600};
|
||||||
`}
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type ImageProps = Pick<AvatarProps, "src">;
|
type ImageProps = Pick<AvatarProps, 'src'>;
|
||||||
export const Image = styled.div<ImageProps>`
|
export const Image = styled.div<ImageProps>`
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 50% 50%;
|
background-position: 50% 50%;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,27 +1,24 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import {
|
import { Logomark as BrandingLogomark, Logotype as BrandingLogotype } from './Branding';
|
||||||
Logomark as BrandingLogomark,
|
import styled from 'styled-components';
|
||||||
Logotype as BrandingLogotype,
|
|
||||||
} from "./Branding";
|
|
||||||
import styled from "styled-components";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Branding",
|
title: 'Atoms/Branding',
|
||||||
};
|
};
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
background-color: black;
|
background-color: black;
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Logomark = () => (
|
export const Logomark = () => (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<BrandingLogomark />
|
<BrandingLogomark />
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Logotype = () => (
|
export const Logotype = () => (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<BrandingLogotype />
|
<BrandingLogotype />
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,11 +1,11 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { BreakpointDebugTool } from "./DebugTool";
|
import { BreakpointDebugTool } from './DebugTool';
|
||||||
import { BreakpointsProvider } from "./BreakpointProvider";
|
import { BreakpointsProvider } from './BreakpointProvider';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Breakpoints",
|
title: 'Atoms/Breakpoints',
|
||||||
decorators: [(story) => <BreakpointsProvider>{story()}</BreakpointsProvider>],
|
decorators: [(story) => <BreakpointsProvider>{story()}</BreakpointsProvider>],
|
||||||
component: BreakpointDebugTool,
|
component: BreakpointDebugTool,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DebugTool = () => <BreakpointDebugTool />;
|
export const DebugTool = () => <BreakpointDebugTool />;
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { withContext } from "roleypoly/src/common/utils/withContext";
|
import { withContext } from 'roleypoly/src/common/utils/withContext';
|
||||||
|
|
||||||
export type ScreenSize = {
|
export type ScreenSize = {
|
||||||
onSmallScreen: boolean;
|
onSmallScreen: boolean;
|
||||||
onTablet: boolean;
|
onTablet: boolean;
|
||||||
onDesktop: boolean;
|
onDesktop: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BreakpointProps = {
|
export type BreakpointProps = {
|
||||||
screenSize: ScreenSize;
|
screenSize: ScreenSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultScreenSize: BreakpointProps = {
|
const defaultScreenSize: BreakpointProps = {
|
||||||
screenSize: {
|
screenSize: {
|
||||||
onSmallScreen: true,
|
onSmallScreen: true,
|
||||||
onDesktop: false,
|
onDesktop: false,
|
||||||
onTablet: false,
|
onTablet: false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BreakpointContext = React.createContext(defaultScreenSize);
|
export const BreakpointContext = React.createContext(defaultScreenSize);
|
||||||
|
@ -24,4 +24,4 @@ export const BreakpointContext = React.createContext(defaultScreenSize);
|
||||||
export const useBreakpointContext = () => React.useContext(BreakpointContext);
|
export const useBreakpointContext = () => React.useContext(BreakpointContext);
|
||||||
|
|
||||||
export const withBreakpoints = <T>(Component: React.ComponentType<T>) =>
|
export const withBreakpoints = <T>(Component: React.ComponentType<T>) =>
|
||||||
withContext(BreakpointContext, Component as any);
|
withContext(BreakpointContext, Component as any);
|
||||||
|
|
|
@ -1,83 +1,83 @@
|
||||||
// TODO: port to new story
|
// TODO: port to new story
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { atomStories } from "atoms/atoms.story";
|
import { atomStories } from 'atoms/atoms.story';
|
||||||
import { Button, ButtonProps } from "./Button";
|
import { Button, ButtonProps } from './Button';
|
||||||
import { text as textKnob } from "@storybook/addon-knobs";
|
import { text as textKnob } from '@storybook/addon-knobs';
|
||||||
import { FaDiscord } from "react-icons/fa";
|
import { FaDiscord } from 'react-icons/fa';
|
||||||
import { styled } from "@storybook/theming";
|
import { styled } from '@storybook/theming';
|
||||||
|
|
||||||
const largeStory = atomStories("Button/Large", module);
|
const largeStory = atomStories('Button/Large', module);
|
||||||
const smallStory = atomStories("Button/Small", module);
|
const smallStory = atomStories('Button/Small', module);
|
||||||
|
|
||||||
const colorModes: NonNullable<ButtonProps["color"]>[] = [
|
const colorModes: NonNullable<ButtonProps['color']>[] = [
|
||||||
"primary",
|
'primary',
|
||||||
"secondary",
|
'secondary',
|
||||||
"discord",
|
'discord',
|
||||||
"muted",
|
'muted',
|
||||||
];
|
];
|
||||||
|
|
||||||
const Margin = styled.div`
|
const Margin = styled.div`
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const storyTemplate = (props: Omit<ButtonProps, "children">) => () => {
|
const storyTemplate = (props: Omit<ButtonProps, 'children'>) => () => {
|
||||||
const text = textKnob("Button content", "Example Button");
|
const text = textKnob('Button content', 'Example Button');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{colorModes.map((color, i) => (
|
{colorModes.map((color, i) => (
|
||||||
<Margin key={i}>
|
<Margin key={i}>
|
||||||
<Button {...props} color={color}>
|
<Button {...props} color={color}>
|
||||||
{text}
|
{text}
|
||||||
</Button>
|
</Button>
|
||||||
<div style={{ marginLeft: "1em" }}>
|
<div style={{ marginLeft: '1em' }}>
|
||||||
{color[0].toUpperCase()}
|
{color[0].toUpperCase()}
|
||||||
{color.slice(1)}
|
{color.slice(1)}
|
||||||
</div>
|
</div>
|
||||||
</Margin>
|
</Margin>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const storyBuilder = (
|
const storyBuilder = (
|
||||||
story: typeof largeStory,
|
story: typeof largeStory,
|
||||||
size: NonNullable<ButtonProps["size"]>
|
size: NonNullable<ButtonProps['size']>
|
||||||
) => {
|
) => {
|
||||||
story.add(
|
story.add(
|
||||||
"Normal",
|
'Normal',
|
||||||
storyTemplate({
|
storyTemplate({
|
||||||
size,
|
size,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
story.add(
|
story.add(
|
||||||
"Icon",
|
'Icon',
|
||||||
storyTemplate({
|
storyTemplate({
|
||||||
size,
|
size,
|
||||||
icon: (
|
icon: (
|
||||||
<div style={{ position: "relative", top: 3 }}>
|
<div style={{ position: 'relative', top: 3 }}>
|
||||||
<FaDiscord />
|
<FaDiscord />
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
story.add(
|
story.add(
|
||||||
"Loading",
|
'Loading',
|
||||||
storyTemplate({
|
storyTemplate({
|
||||||
size,
|
size,
|
||||||
icon: (
|
icon: (
|
||||||
<div style={{ position: "relative", top: 3 }}>
|
<div style={{ position: 'relative', top: 3 }}>
|
||||||
<FaDiscord />
|
<FaDiscord />
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
loading: true,
|
loading: true,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
storyBuilder(largeStory, "large");
|
storyBuilder(largeStory, 'large');
|
||||||
storyBuilder(smallStory, "small");
|
storyBuilder(smallStory, 'small');
|
||||||
|
|
|
@ -1,106 +1,106 @@
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from 'styled-components';
|
||||||
import { text400, text300 } from "roleypoly/src/design-system/atoms/typography";
|
import { text400, text300 } from 'roleypoly/src/design-system/atoms/typography';
|
||||||
import { fontCSS } from "roleypoly/src/design-system/atoms/fonts";
|
import { fontCSS } from 'roleypoly/src/design-system/atoms/fonts';
|
||||||
import { palette } from "roleypoly/src/design-system/atoms/colors";
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
export const IconContainer = styled.div`
|
export const IconContainer = styled.div`
|
||||||
margin-right: 0.6rem;
|
margin-right: 0.6rem;
|
||||||
font-size: 1.75em;
|
font-size: 1.75em;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const base = css`
|
const base = css`
|
||||||
${fontCSS}
|
${fontCSS}
|
||||||
appearance: none;
|
appearance: none;
|
||||||
display: block;
|
display: block;
|
||||||
background-color: ${palette.taupe300};
|
background-color: ${palette.taupe300};
|
||||||
color: ${palette.grey500};
|
color: ${palette.grey500};
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border: 2px solid rgba(0, 0, 0, 0.55);
|
border: 2px solid rgba(0, 0, 0, 0.55);
|
||||||
transition: all 0.15s ease-in-out;
|
|
||||||
outline: 0;
|
|
||||||
position: relative;
|
|
||||||
user-select: none;
|
|
||||||
cursor: pointer;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
background-color: #000;
|
|
||||||
opacity: 0;
|
|
||||||
transition: all 0.15s ease-in-out;
|
transition: all 0.15s ease-in-out;
|
||||||
}
|
outline: 0;
|
||||||
|
position: relative;
|
||||||
|
user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
:hover {
|
|
||||||
transform: translateY(-1px);
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
:active {
|
|
||||||
transform: translateY(1px);
|
|
||||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.25);
|
|
||||||
::after {
|
::after {
|
||||||
opacity: 0.1;
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: #000;
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.15s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
:active {
|
||||||
|
transform: translateY(1px);
|
||||||
|
box-shadow: 0 0 2px rgba(0, 0, 0, 0.25);
|
||||||
|
::after {
|
||||||
|
opacity: 0.1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const colors = {
|
const colors = {
|
||||||
primary: css`
|
primary: css`
|
||||||
background-color: ${palette.green400};
|
background-color: ${palette.green400};
|
||||||
color: ${palette.taupe100};
|
color: ${palette.taupe100};
|
||||||
`,
|
`,
|
||||||
secondary: css``,
|
secondary: css``,
|
||||||
discord: css`
|
discord: css`
|
||||||
background-color: ${palette.discord400};
|
background-color: ${palette.discord400};
|
||||||
border: 2px solid ${palette.discord200};
|
border: 2px solid ${palette.discord200};
|
||||||
`,
|
`,
|
||||||
muted: css`
|
muted: css`
|
||||||
border: 2px solid rgba(0, 0, 0, 0.15);
|
border: 2px solid rgba(0, 0, 0, 0.15);
|
||||||
background: none;
|
background: none;
|
||||||
:hover {
|
:hover {
|
||||||
background-color: ${palette.taupe200};
|
background-color: ${palette.taupe200};
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
|
|
||||||
const sizes = {
|
const sizes = {
|
||||||
small: css`
|
small: css`
|
||||||
${text300}
|
${text300}
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
`,
|
`,
|
||||||
large: css`
|
large: css`
|
||||||
${text400}
|
${text400}
|
||||||
padding: 12px 32px;
|
padding: 12px 32px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
|
|
||||||
const modifiers = {
|
const modifiers = {
|
||||||
withIcon: css`
|
withIcon: css`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
`,
|
`,
|
||||||
withLoading: css`
|
withLoading: css`
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
`,
|
`,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ButtonComposerOptions = {
|
export type ButtonComposerOptions = {
|
||||||
size: keyof typeof sizes;
|
size: keyof typeof sizes;
|
||||||
color: keyof typeof colors;
|
color: keyof typeof colors;
|
||||||
modifiers?: Array<keyof typeof modifiers>;
|
modifiers?: Array<keyof typeof modifiers>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Button = styled.button<ButtonComposerOptions>`
|
export const Button = styled.button<ButtonComposerOptions>`
|
||||||
${base}
|
${base}
|
||||||
${(props) => props.size in sizes && sizes[props.size]}
|
${(props) => props.size in sizes && sizes[props.size]}
|
||||||
${(props) => props.color in colors && colors[props.color]}
|
${(props) => props.color in colors && colors[props.color]}
|
||||||
${(props) => props.modifiers?.map((m) => modifiers[m])}
|
${(props) => props.modifiers?.map((m) => modifiers[m])}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,164 +1,162 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { palette } from "./colors";
|
import { palette } from './colors';
|
||||||
import styled from "styled-components";
|
import styled from 'styled-components';
|
||||||
import chroma from "chroma-js";
|
import chroma from 'chroma-js';
|
||||||
import { AmbientSmall } from "roleypoly/src/design-system/atoms/typography";
|
import { AmbientSmall } from 'roleypoly/src/design-system/atoms/typography';
|
||||||
|
|
||||||
type RatioList = {
|
type RatioList = {
|
||||||
color1: string[];
|
color1: string[];
|
||||||
color2: string[];
|
color2: string[];
|
||||||
ratio: string;
|
ratio: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Colors",
|
title: 'Atoms/Colors',
|
||||||
};
|
};
|
||||||
|
|
||||||
const Swatch = styled.div`
|
const Swatch = styled.div`
|
||||||
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
|
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
|
||||||
width: 250px;
|
width: 250px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid #fff;
|
border: 1px solid #fff;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const SwatchColor = styled.div`
|
const SwatchColor = styled.div`
|
||||||
height: 72px;
|
height: 72px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Label = styled.div`
|
const Label = styled.div`
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
color: ${palette.taupe100};
|
color: ${palette.taupe100};
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Colors = () => {
|
export const Colors = () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{Object.entries(palette).map(([name, color], i) => (
|
{Object.entries(palette).map(([name, color], i) => (
|
||||||
<Swatch key={i}>
|
<Swatch key={i}>
|
||||||
<SwatchColor style={{ backgroundColor: color }} />
|
<SwatchColor style={{ backgroundColor: color }} />
|
||||||
<Label>
|
<Label>
|
||||||
<p>{name}</p>
|
<p>{name}</p>
|
||||||
<p>
|
<p>
|
||||||
<code>var(--{name})</code>
|
<code>var(--{name})</code>
|
||||||
</p>
|
</p>
|
||||||
</Label>
|
</Label>
|
||||||
</Swatch>
|
</Swatch>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ContrastRatios = () => {
|
export const ContrastRatios = () => {
|
||||||
const allRatios = getAllRatios(palette);
|
const allRatios = getAllRatios(palette);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<b>WCAG Contrast Calculations.</b>
|
<b>WCAG Contrast Calculations.</b>
|
||||||
<br />
|
<br />
|
||||||
Marked in <span style={getWCAGStyle(7.1)}>Green</span> is 7.0+ or AAA.
|
Marked in <span style={getWCAGStyle(7.1)}>Green</span> is 7.0+ or AAA.
|
||||||
Acceptable for Text.
|
Acceptable for Text.
|
||||||
<br />
|
<br />
|
||||||
Marked in <span style={getWCAGStyle(4.6)}>Orange</span> is 4.5+ or AA.
|
Marked in <span style={getWCAGStyle(4.6)}>Orange</span> is 4.5+ or AA.
|
||||||
Acceptable for UI.
|
Acceptable for UI.
|
||||||
<br />
|
<br />
|
||||||
All below 4.5 is unacceptable.
|
All below 4.5 is unacceptable.
|
||||||
<br />
|
<br />
|
||||||
<AmbientSmall>
|
<AmbientSmall>WCAG Contrast testing disabled for this page.</AmbientSmall>
|
||||||
WCAG Contrast testing disabled for this page.
|
</p>
|
||||||
</AmbientSmall>
|
<ContrastTable>
|
||||||
</p>
|
<thead>
|
||||||
<ContrastTable>
|
<tr>
|
||||||
<thead>
|
<th colSpan={2}>Swatch</th>
|
||||||
<tr>
|
<th>Ratio</th>
|
||||||
<th colSpan={2}>Swatch</th>
|
<th>Color 1</th>
|
||||||
<th>Ratio</th>
|
<th>Color 2</th>
|
||||||
<th>Color 1</th>
|
</tr>
|
||||||
<th>Color 2</th>
|
</thead>
|
||||||
</tr>
|
<tbody>
|
||||||
</thead>
|
{allRatios.map((ratio, i) => (
|
||||||
<tbody>
|
<tr key={i}>
|
||||||
{allRatios.map((ratio, i) => (
|
<td style={{ backgroundColor: ratio.color1[1] }}> </td>
|
||||||
<tr key={i}>
|
<td style={{ backgroundColor: ratio.color2[1] }}> </td>
|
||||||
<td style={{ backgroundColor: ratio.color1[1] }}> </td>
|
<td style={getWCAGStyle(+ratio.ratio)}>{ratio.ratio}</td>
|
||||||
<td style={{ backgroundColor: ratio.color2[1] }}> </td>
|
<td>{ratio.color1[0]}</td>
|
||||||
<td style={getWCAGStyle(+ratio.ratio)}>{ratio.ratio}</td>
|
<td>{ratio.color2[0]}</td>
|
||||||
<td>{ratio.color1[0]}</td>
|
<td
|
||||||
<td>{ratio.color2[0]}</td>
|
style={{
|
||||||
<td
|
color: ratio.color1[1],
|
||||||
style={{
|
backgroundColor: ratio.color2[1],
|
||||||
color: ratio.color1[1],
|
paddingRight: '0.1em',
|
||||||
backgroundColor: ratio.color2[1],
|
}}
|
||||||
paddingRight: "0.1em",
|
>
|
||||||
}}
|
oh my god my
|
||||||
>
|
</td>
|
||||||
oh my god my
|
<td
|
||||||
</td>
|
style={{
|
||||||
<td
|
color: ratio.color2[1],
|
||||||
style={{
|
backgroundColor: ratio.color1[1],
|
||||||
color: ratio.color2[1],
|
paddingLeft: '0.1em',
|
||||||
backgroundColor: ratio.color1[1],
|
}}
|
||||||
paddingLeft: "0.1em",
|
>
|
||||||
}}
|
shin how dare you
|
||||||
>
|
</td>
|
||||||
shin how dare you
|
</tr>
|
||||||
</td>
|
))}
|
||||||
</tr>
|
</tbody>
|
||||||
))}
|
</ContrastTable>
|
||||||
</tbody>
|
</div>
|
||||||
</ContrastTable>
|
);
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const ContrastTable = styled.table`
|
const ContrastTable = styled.table`
|
||||||
td,
|
td,
|
||||||
th {
|
th {
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const getWCAGStyle = (ratio: number): React.CSSProperties => {
|
const getWCAGStyle = (ratio: number): React.CSSProperties => {
|
||||||
if (ratio >= 7) {
|
if (ratio >= 7) {
|
||||||
return { color: "green", fontWeight: "bold" };
|
return { color: 'green', fontWeight: 'bold' };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ratio >= 4.5) {
|
if (ratio >= 4.5) {
|
||||||
return { color: "orange", fontWeight: "bold" };
|
return { color: 'orange', fontWeight: 'bold' };
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAllRatios = (input: typeof palette) =>
|
const getAllRatios = (input: typeof palette) =>
|
||||||
Object.entries(input)
|
Object.entries(input)
|
||||||
.filter(([name]) => !name.startsWith("discord"))
|
.filter(([name]) => !name.startsWith('discord'))
|
||||||
.reduce((acc, [name, color]) => {
|
.reduce((acc, [name, color]) => {
|
||||||
return [
|
return [
|
||||||
...acc,
|
...acc,
|
||||||
...Object.entries(palette)
|
...Object.entries(palette)
|
||||||
.filter(([name]) => !name.startsWith("discord"))
|
.filter(([name]) => !name.startsWith('discord'))
|
||||||
.map(([matchName, matchColor]) => ({
|
.map(([matchName, matchColor]) => ({
|
||||||
color1: [name, color],
|
color1: [name, color],
|
||||||
color2: [matchName, matchColor],
|
color2: [matchName, matchColor],
|
||||||
ratio: chroma.contrast(color, matchColor).toFixed(2),
|
ratio: chroma.contrast(color, matchColor).toFixed(2),
|
||||||
})),
|
})),
|
||||||
];
|
];
|
||||||
}, [] as RatioList[])
|
}, [] as RatioList[])
|
||||||
.filter(({ ratio }) => +ratio !== 1)
|
.filter(({ ratio }) => +ratio !== 1)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (+a.ratio > +b.ratio) {
|
if (+a.ratio > +b.ratio) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
})
|
})
|
||||||
.filter((_, i) => i % 2 === 0);
|
.filter((_, i) => i % 2 === 0);
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
import { css, createGlobalStyle } from "styled-components";
|
import { css, createGlobalStyle } from 'styled-components';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
import chroma from "chroma-js";
|
import chroma from 'chroma-js';
|
||||||
|
|
||||||
export const palette = {
|
export const palette = {
|
||||||
taupe100: "#332D2D",
|
taupe100: '#332D2D',
|
||||||
taupe200: "#453E3D",
|
taupe200: '#453E3D',
|
||||||
taupe300: "#5D5352",
|
taupe300: '#5D5352',
|
||||||
taupe400: "#756867",
|
taupe400: '#756867',
|
||||||
taupe500: "#AB9B9A",
|
taupe500: '#AB9B9A',
|
||||||
taupe600: "#EBD6D4",
|
taupe600: '#EBD6D4',
|
||||||
|
|
||||||
discord100: "#23272A",
|
discord100: '#23272A',
|
||||||
discord200: "#2C2F33",
|
discord200: '#2C2F33',
|
||||||
discord400: "#7289DA",
|
discord400: '#7289DA',
|
||||||
discord500: "#99AAB5",
|
discord500: '#99AAB5',
|
||||||
|
|
||||||
green400: "#46B646",
|
green400: '#46B646',
|
||||||
|
|
||||||
red400: "#E95353",
|
red400: '#E95353',
|
||||||
|
|
||||||
gold400: "#EFCF24",
|
gold400: '#EFCF24',
|
||||||
|
|
||||||
grey100: "#1C1010",
|
grey100: '#1C1010',
|
||||||
grey500: "#DBD9D9",
|
grey500: '#DBD9D9',
|
||||||
grey600: "#F2EFEF",
|
grey600: '#F2EFEF',
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPaletteCSS = () =>
|
const getPaletteCSS = () =>
|
||||||
Object.entries(palette).reduce(
|
Object.entries(palette).reduce(
|
||||||
(acc, [key, color]) => ({ ...acc, [`--${key}`]: color }),
|
(acc, [key, color]) => ({ ...acc, [`--${key}`]: color }),
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const colorVars = css(getPaletteCSS());
|
export const colorVars = css(getPaletteCSS());
|
||||||
|
|
||||||
|
@ -41,5 +41,5 @@ export const GlobalStyleColors = createGlobalStyle`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const numberToChroma = (colorInt: number) => {
|
export const numberToChroma = (colorInt: number) => {
|
||||||
return chroma(colorInt);
|
return chroma(colorInt);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
export * from "./colors";
|
export * from './colors';
|
||||||
export * as utils from "./withColors";
|
export * as utils from './withColors';
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { DotOverlay } from "./DotOverlay";
|
import { DotOverlay } from './DotOverlay';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Dot Overlay",
|
title: 'Atoms/Dot Overlay',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Dark = () => <DotOverlay />;
|
export const Dark = () => <DotOverlay />;
|
||||||
|
|
|
@ -1,39 +1,39 @@
|
||||||
import styled from "styled-components";
|
import styled from 'styled-components';
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
const dotOverlayBase = styled.div`
|
const dotOverlayBase = styled.div`
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: -10;
|
z-index: -10;
|
||||||
background-size: 27px 27px;
|
background-size: 27px 27px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const DotOverlayDark = styled(dotOverlayBase)`
|
const DotOverlayDark = styled(dotOverlayBase)`
|
||||||
background-image: radial-gradient(
|
background-image: radial-gradient(
|
||||||
circle,
|
circle,
|
||||||
#332d2d,
|
#332d2d,
|
||||||
#332d2d 1px,
|
#332d2d 1px,
|
||||||
transparent 1px,
|
transparent 1px,
|
||||||
transparent
|
transparent
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const DotOverlayLight = styled(dotOverlayBase)`
|
const DotOverlayLight = styled(dotOverlayBase)`
|
||||||
background-image: radial-gradient(
|
background-image: radial-gradient(
|
||||||
circle,
|
circle,
|
||||||
#dbd9d9,
|
#dbd9d9,
|
||||||
#dbd9d9 1px,
|
#dbd9d9 1px,
|
||||||
transparent 1px,
|
transparent 1px,
|
||||||
transparent
|
transparent
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const DotOverlay = ({ light }: { light?: boolean }) => {
|
export const DotOverlay = ({ light }: { light?: boolean }) => {
|
||||||
return light ? <DotOverlayLight /> : <DotOverlayDark />;
|
return light ? <DotOverlayLight /> : <DotOverlayDark />;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { FaderOpacity, FaderSlide } from "./Fader";
|
import { FaderOpacity, FaderSlide } from './Fader';
|
||||||
import { Button } from "roleypoly/src/design-system/atoms/button";
|
import { Button } from 'roleypoly/src/design-system/atoms/button';
|
||||||
import { action } from "@storybook/addon-actions";
|
import { action } from '@storybook/addon-actions';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Fader",
|
title: 'Atoms/Fader',
|
||||||
component: FaderSlide,
|
component: FaderSlide,
|
||||||
args: {
|
args: {
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Opacity = (args) => {
|
export const Opacity = (args) => {
|
||||||
return (
|
return (
|
||||||
<FaderOpacity {...args}>
|
<FaderOpacity {...args}>
|
||||||
<Button onClick={action("onClick")}>Click me!</Button>
|
<Button onClick={action('onClick')}>Click me!</Button>
|
||||||
</FaderOpacity>
|
</FaderOpacity>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Slide = (args) => {
|
export const Slide = (args) => {
|
||||||
return (
|
return (
|
||||||
<FaderSlide {...args}>
|
<FaderSlide {...args}>
|
||||||
<Button onClick={action("onClick")}>Click me!</Button>
|
<Button onClick={action('onClick')}>Click me!</Button>
|
||||||
</FaderSlide>
|
</FaderSlide>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,38 +1,36 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import styled from "styled-components";
|
import styled from 'styled-components';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
export type FaderProps = {
|
export type FaderProps = {
|
||||||
isVisible: boolean;
|
isVisible: boolean;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FaderOpacityStyled = styled.div<Pick<FaderProps, "isVisible">>`
|
const FaderOpacityStyled = styled.div<Pick<FaderProps, 'isVisible'>>`
|
||||||
opacity: ${(props) => (props.isVisible ? 1 : 0)};
|
opacity: ${(props) => (props.isVisible ? 1 : 0)};
|
||||||
pointer-events: ${(props) => (props.isVisible ? "unset" : "none")};
|
pointer-events: ${(props) => (props.isVisible ? 'unset' : 'none')};
|
||||||
transition: opacity 0.35s ease-in-out;
|
transition: opacity 0.35s ease-in-out;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const FaderOpacity = (props: FaderProps) => {
|
export const FaderOpacity = (props: FaderProps) => {
|
||||||
return (
|
return (
|
||||||
<FaderOpacityStyled isVisible={props.isVisible}>
|
<FaderOpacityStyled isVisible={props.isVisible}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</FaderOpacityStyled>
|
</FaderOpacityStyled>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const FaderSlideStyled = styled.div<Pick<FaderProps, "isVisible">>`
|
const FaderSlideStyled = styled.div<Pick<FaderProps, 'isVisible'>>`
|
||||||
max-height: ${(props) => (props.isVisible ? "4em" : "0")};
|
max-height: ${(props) => (props.isVisible ? '4em' : '0')};
|
||||||
pointer-events: ${(props) => (props.isVisible ? "unset" : "none")};
|
pointer-events: ${(props) => (props.isVisible ? 'unset' : 'none')};
|
||||||
transition: max-height 0.35s ease-in-out;
|
transition: max-height 0.35s ease-in-out;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transform: translateZ(0);
|
transform: translateZ(0);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const FaderSlide = (props: FaderProps) => {
|
export const FaderSlide = (props: FaderProps) => {
|
||||||
return (
|
return (
|
||||||
<FaderSlideStyled isVisible={props.isVisible}>
|
<FaderSlideStyled isVisible={props.isVisible}>{props.children}</FaderSlideStyled>
|
||||||
{props.children}
|
);
|
||||||
</FaderSlideStyled>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,66 +1,62 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { UseFontStyled } from "./fonts";
|
import { UseFontStyled } from './fonts';
|
||||||
import styled from "styled-components";
|
import styled from 'styled-components';
|
||||||
import {
|
import {
|
||||||
MediumTitle,
|
MediumTitle,
|
||||||
Text as TextBlock,
|
Text as TextBlock,
|
||||||
} from "roleypoly/src/design-system/atoms/typography";
|
} from 'roleypoly/src/design-system/atoms/typography';
|
||||||
|
|
||||||
const resetFont = (storyFn: () => React.ReactNode) => (
|
const resetFont = (storyFn: () => React.ReactNode) => <FontReset>{storyFn()}</FontReset>;
|
||||||
<FontReset>{storyFn()}</FontReset>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Fonts",
|
title: 'Atoms/Fonts',
|
||||||
decorators: [resetFont],
|
decorators: [resetFont],
|
||||||
};
|
};
|
||||||
|
|
||||||
const FontReset = styled.div`
|
const FontReset = styled.div`
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const CorrectlyFontedH2 = (props: { children: React.ReactNode }) => (
|
const CorrectlyFontedH2 = (props: { children: React.ReactNode }) => (
|
||||||
<UseFontStyled>
|
<UseFontStyled>
|
||||||
<MediumTitle>{props.children}</MediumTitle>
|
<MediumTitle>{props.children}</MediumTitle>
|
||||||
</UseFontStyled>
|
</UseFontStyled>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Text = () => (
|
const Text = () => (
|
||||||
<>
|
<>
|
||||||
<p>
|
<p>
|
||||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Et facilis alias
|
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Et facilis alias
|
||||||
placeat cumque sapiente ad delectus omnis quae. Reiciendis quibusdam
|
placeat cumque sapiente ad delectus omnis quae. Reiciendis quibusdam deserunt
|
||||||
deserunt repellat. Exercitationem modi incidunt autem nemo tempore eaque
|
repellat. Exercitationem modi incidunt autem nemo tempore eaque soluta.
|
||||||
soluta.
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
帯カノ需混モイ一録43旧百12共ドレ能生ホクユ禁度ヨ材図クほはそ護関ラト郵張エノヨ議件クめざ県読れみとぶ論税クょンど慎転リつぎみ松期ほへド.
|
||||||
帯カノ需混モイ一録43旧百12共ドレ能生ホクユ禁度ヨ材図クほはそ護関ラト郵張エノヨ議件クめざ県読れみとぶ論税クょンど慎転リつぎみ松期ほへド.
|
縦投記ふで覧速っだせあ過先課フ演無ぎぱべ習併相ーす気6元ゆる領気希ぎ投代ラ我関レ森郎由系堂ず.
|
||||||
縦投記ふで覧速っだせあ過先課フ演無ぎぱべ習併相ーす気6元ゆる領気希ぎ投代ラ我関レ森郎由系堂ず.
|
読ケリ夜指ーっトせ認平引ウシ間花ヱクム年6台ぐ山婦ラスエ子著コア掲中ロ像属戸メソユ職諏ルど詐児題たに書希ク幕値長ラそめド.
|
||||||
読ケリ夜指ーっトせ認平引ウシ間花ヱクム年6台ぐ山婦ラスエ子著コア掲中ロ像属戸メソユ職諏ルど詐児題たに書希ク幕値長ラそめド.
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
🔸🐕🔺💱🎊👽🐛 👨📼🕦📞 👱👆🍗👚🌈 🔝🔟🍉🔰🍲🏁🕗 🎡🐉🍲📻🔢🔄 💟💲🍻💜💩🔼
|
||||||
🔸🐕🔺💱🎊👽🐛 👨📼🕦📞 👱👆🍗👚🌈 🔝🔟🍉🔰🍲🏁🕗 🎡🐉🍲📻🔢🔄
|
🎱🌸📛👫🌻 🗽🕜🐥👕🍈. 🐒🍚🔓📱🏦 🎦🌑🔛💙👣🔚 🔆🗻🌿🎳📲🍯 🌞💟🎌🍌 🔪📯🐎💮
|
||||||
💟💲🍻💜💩🔼 🎱🌸📛👫🌻 🗽🕜🐥👕🍈. 🐒🍚🔓📱🏦 🎦🌑🔛💙👣🔚 🔆🗻🌿🎳📲🍯
|
👌👭🎋🏉🏰 📓🕃🎂💉🔩 🐟🌇👺🌊🌒 📪👅🍂🍁 🌖🐮🔽🌒📊. 🔤🍍🌸📷🎴 💏🍌📎👥👉👒
|
||||||
🌞💟🎌🍌 🔪📯🐎💮 👌👭🎋🏉🏰 📓🕃🎂💉🔩 🐟🌇👺🌊🌒 📪👅🍂🍁 🌖🐮🔽🌒📊.
|
👝💜🔶🍣 💨🗼👈💉💉💰 🍐🕖🌰👝🕓🏊🐕 🏀📅📼📒 🐕🌈👋
|
||||||
🔤🍍🌸📷🎴 💏🍌📎👥👉👒 👝💜🔶🍣 💨🗼👈💉💉💰 🍐🕖🌰👝🕓🏊🐕 🏀📅📼📒
|
</p>
|
||||||
🐕🌈👋
|
</>
|
||||||
</p>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Fonts = () => (
|
export const Fonts = () => (
|
||||||
<TextBlock>
|
<TextBlock>
|
||||||
<section>
|
<section>
|
||||||
<CorrectlyFontedH2>Unstyled Default</CorrectlyFontedH2>
|
<CorrectlyFontedH2>Unstyled Default</CorrectlyFontedH2>
|
||||||
<Text />
|
<Text />
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<CorrectlyFontedH2>
|
<CorrectlyFontedH2>
|
||||||
Main (Source Han Sans Japanese, Source Sans)
|
Main (Source Han Sans Japanese, Source Sans)
|
||||||
</CorrectlyFontedH2>
|
</CorrectlyFontedH2>
|
||||||
<UseFontStyled>
|
<UseFontStyled>
|
||||||
<Text />
|
<Text />
|
||||||
</UseFontStyled>
|
</UseFontStyled>
|
||||||
</section>
|
</section>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import Head from "next/head";
|
import Head from 'next/head';
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from 'styled-components';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
export const InjectTypekitFont = () => {
|
export const InjectTypekitFont = () => {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
(window as any).Typekit.load();
|
(window as any).Typekit.load();
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<Head>
|
<Head>
|
||||||
<link
|
<link
|
||||||
key="typekit-css-preload"
|
key="typekit-css-preload"
|
||||||
rel="preload"
|
rel="preload"
|
||||||
href="https://use.typekit.net/bck0pci.js"
|
href="https://use.typekit.net/bck0pci.js"
|
||||||
as="script"
|
as="script"
|
||||||
/>
|
/>
|
||||||
<script key="typekit-js" src="https://use.typekit.net/bck0pci.js" />
|
<script key="typekit-js" src="https://use.typekit.net/bck0pci.js" />
|
||||||
</Head>
|
</Head>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fontCSS = css`
|
export const fontCSS = css`
|
||||||
font-family: "source-han-sans-japanese", "Source Sans Pro", sans-serif,
|
font-family: 'source-han-sans-japanese', 'Source Sans Pro', sans-serif,
|
||||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
|
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol' !important;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const UseFontStyled = styled.div`
|
export const UseFontStyled = styled.div`
|
||||||
${fontCSS}
|
${fontCSS}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { HalfsiesContainer, HalfsiesItem } from "./Halfsies";
|
import { HalfsiesContainer, HalfsiesItem } from './Halfsies';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Halfsies",
|
title: 'Atoms/Halfsies',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Container = () => (
|
export const Container = () => (
|
||||||
<HalfsiesContainer>
|
<HalfsiesContainer>
|
||||||
<HalfsiesItem>Lefty doo</HalfsiesItem>
|
<HalfsiesItem>Lefty doo</HalfsiesItem>
|
||||||
<HalfsiesItem>Righty doo</HalfsiesItem>
|
<HalfsiesItem>Righty doo</HalfsiesItem>
|
||||||
</HalfsiesContainer>
|
</HalfsiesContainer>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from 'styled-components';
|
||||||
import { onTablet } from "roleypoly/src/design-system/atoms/breakpoints";
|
import { onTablet } from 'roleypoly/src/design-system/atoms/breakpoints';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
export const HalfsiesContainer = styled.div`
|
export const HalfsiesContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const HalfsiesItem = styled.div`
|
export const HalfsiesItem = styled.div`
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
flex: 1 1 100%;
|
flex: 1 1 100%;
|
||||||
${onTablet(css`
|
${onTablet(css`
|
||||||
flex: 1 2 50%;
|
flex: 1 2 50%;
|
||||||
`)}
|
`)}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,74 +1,70 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { Hero as HeroComponent } from "./Hero";
|
import { Hero as HeroComponent } from './Hero';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Hero",
|
title: 'Atoms/Hero',
|
||||||
component: HeroComponent,
|
component: HeroComponent,
|
||||||
args: {
|
args: {
|
||||||
topSpacing: 75,
|
topSpacing: 75,
|
||||||
bottomSpacing: 25,
|
bottomSpacing: 25,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Hero = ({ topSpacing, bottomSpacing }) => {
|
export const Hero = ({ topSpacing, bottomSpacing }) => {
|
||||||
return (
|
return (
|
||||||
<StoryWrapper topSpacing={topSpacing} bottomSpacing={bottomSpacing}>
|
<StoryWrapper topSpacing={topSpacing} bottomSpacing={bottomSpacing}>
|
||||||
<HeroComponent topSpacing={topSpacing} bottomSpacing={bottomSpacing}>
|
<HeroComponent topSpacing={topSpacing} bottomSpacing={bottomSpacing}>
|
||||||
<h1>This is it.</h1>
|
<h1>This is it.</h1>
|
||||||
</HeroComponent>
|
</HeroComponent>
|
||||||
</StoryWrapper>
|
</StoryWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
type WrapperProps = {
|
type WrapperProps = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
topSpacing: number;
|
topSpacing: number;
|
||||||
bottomSpacing: number;
|
bottomSpacing: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StoryWrapper = ({
|
const StoryWrapper = ({ topSpacing, bottomSpacing, ...props }: WrapperProps) => (
|
||||||
topSpacing,
|
<div>
|
||||||
bottomSpacing,
|
<div
|
||||||
...props
|
style={{
|
||||||
}: WrapperProps) => (
|
position: 'absolute',
|
||||||
<div>
|
top: 0,
|
||||||
<div
|
bottom: 0,
|
||||||
style={{
|
left: 0,
|
||||||
position: "absolute",
|
right: 0,
|
||||||
top: 0,
|
height: '100vh',
|
||||||
bottom: 0,
|
}}
|
||||||
left: 0,
|
>
|
||||||
right: 0,
|
<div
|
||||||
height: "100vh",
|
style={{
|
||||||
}}
|
height: topSpacing,
|
||||||
>
|
backgroundColor: 'rgba(255,0,0,0.25)',
|
||||||
<div
|
top: 0,
|
||||||
style={{
|
left: 0,
|
||||||
height: topSpacing,
|
right: 0,
|
||||||
backgroundColor: "rgba(255,0,0,0.25)",
|
position: 'absolute',
|
||||||
top: 0,
|
overflow: 'hidden',
|
||||||
left: 0,
|
}}
|
||||||
right: 0,
|
>
|
||||||
position: "absolute",
|
topSpacing
|
||||||
overflow: "hidden",
|
</div>
|
||||||
}}
|
<div
|
||||||
>
|
style={{
|
||||||
topSpacing
|
height: bottomSpacing,
|
||||||
</div>
|
backgroundColor: 'rgba(0,0,255,0.25)',
|
||||||
<div
|
bottom: 0,
|
||||||
style={{
|
left: 0,
|
||||||
height: bottomSpacing,
|
right: 0,
|
||||||
backgroundColor: "rgba(0,0,255,0.25)",
|
position: 'absolute',
|
||||||
bottom: 0,
|
overflow: 'hidden',
|
||||||
left: 0,
|
}}
|
||||||
right: 0,
|
>
|
||||||
position: "absolute",
|
bottomSpacing
|
||||||
overflow: "hidden",
|
</div>
|
||||||
}}
|
</div>
|
||||||
>
|
{props.children}
|
||||||
bottomSpacing
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{props.children}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,33 +1,31 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import styled from "styled-components";
|
import styled from 'styled-components';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
type HeroContainerProps = {
|
type HeroContainerProps = {
|
||||||
topSpacing: number;
|
topSpacing: number;
|
||||||
bottomSpacing: number;
|
bottomSpacing: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type HeroProps = Partial<HeroContainerProps> & {
|
type HeroProps = Partial<HeroContainerProps> & {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
const HeroContainer = styled.div<HeroContainerProps>`
|
const HeroContainer = styled.div<HeroContainerProps>`
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
min-height: calc(
|
min-height: calc(100vh - ${(props) => props.topSpacing + props.bottomSpacing}px);
|
||||||
100vh - ${(props) => props.topSpacing + props.bottomSpacing}px
|
margin-top: ${(props) => props.topSpacing}px;
|
||||||
);
|
|
||||||
margin-top: ${(props) => props.topSpacing}px;
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Hero = (props: HeroProps) => (
|
export const Hero = (props: HeroProps) => (
|
||||||
<HeroContainer
|
<HeroContainer
|
||||||
topSpacing={props.topSpacing || 0}
|
topSpacing={props.topSpacing || 0}
|
||||||
bottomSpacing={props.bottomSpacing || 0}
|
bottomSpacing={props.bottomSpacing || 0}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</HeroContainer>
|
</HeroContainer>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { Button } from "roleypoly/src/design-system/atoms/button";
|
import { Button } from 'roleypoly/src/design-system/atoms/button';
|
||||||
import { Popover as PopoverComponent } from "./Popover";
|
import { Popover as PopoverComponent } from './Popover';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Popover",
|
title: 'Atoms/Popover',
|
||||||
argTypes: {
|
argTypes: {
|
||||||
canDefocus: { control: "boolean" },
|
canDefocus: { control: 'boolean' },
|
||||||
},
|
},
|
||||||
args: {
|
args: {
|
||||||
canDefocus: true,
|
canDefocus: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Popover = ({ canDefocus }) => {
|
export const Popover = ({ canDefocus }) => {
|
||||||
const [isOpen, setIsOpen] = React.useState(false);
|
const [isOpen, setIsOpen] = React.useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: 50 }}>
|
<div style={{ padding: 50 }}>
|
||||||
<Button size="small" onClick={() => setIsOpen(!isOpen)}>
|
<Button size="small" onClick={() => setIsOpen(!isOpen)}>
|
||||||
{!isOpen ? "Open" : "Close"} me!
|
{!isOpen ? 'Open' : 'Close'} me!
|
||||||
</Button>
|
</Button>
|
||||||
<PopoverComponent
|
<PopoverComponent
|
||||||
position="top right"
|
position="top right"
|
||||||
active={isOpen}
|
active={isOpen}
|
||||||
onExit={() => setIsOpen(false)}
|
onExit={() => setIsOpen(false)}
|
||||||
canDefocus={canDefocus}
|
canDefocus={canDefocus}
|
||||||
headContent={<>Hello c:</>}
|
headContent={<>Hello c:</>}
|
||||||
>
|
>
|
||||||
stuff
|
stuff
|
||||||
</PopoverComponent>
|
</PopoverComponent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,91 +1,88 @@
|
||||||
import {
|
import { onSmallScreen, onTablet } from 'roleypoly/src/design-system/atoms/breakpoints';
|
||||||
onSmallScreen,
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
onTablet,
|
import { transitions } from 'roleypoly/src/design-system/atoms/timings';
|
||||||
} from "roleypoly/src/design-system/atoms/breakpoints";
|
import styled, { css } from 'styled-components';
|
||||||
import { palette } from "roleypoly/src/design-system/atoms/colors";
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
import { transitions } from "roleypoly/src/design-system/atoms/timings";
|
|
||||||
import styled, { css } from "styled-components";
|
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
|
||||||
|
|
||||||
type PopoverStyledProps = {
|
type PopoverStyledProps = {
|
||||||
active: boolean;
|
active: boolean;
|
||||||
preferredWidth?: number;
|
preferredWidth?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PopoverBase = styled.div<PopoverStyledProps>`
|
export const PopoverBase = styled.div<PopoverStyledProps>`
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: absolute;
|
|
||||||
background-color: ${palette.taupe100};
|
|
||||||
padding: 5px;
|
|
||||||
border: 2px solid rgba(0, 0, 0, 0.15);
|
|
||||||
border-radius: 3px;
|
|
||||||
z-index: 10;
|
|
||||||
transition: opacity ${transitions.out2in}s ease-in,
|
|
||||||
transform ${transitions.out2in}s ease-in;
|
|
||||||
min-width: ${(props) => props.preferredWidth || 320}px;
|
|
||||||
max-width: 100vw;
|
|
||||||
${(props) =>
|
|
||||||
!props.active &&
|
|
||||||
css`
|
|
||||||
transform: translateY(-2vh);
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
`}
|
|
||||||
${onSmallScreen(css`
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
background-color: ${palette.taupe100};
|
||||||
left: 0;
|
padding: 5px;
|
||||||
bottom: 0;
|
border: 2px solid rgba(0, 0, 0, 0.15);
|
||||||
right: 0;
|
border-radius: 3px;
|
||||||
min-width: unset;
|
z-index: 10;
|
||||||
width: 100vw;
|
transition: opacity ${transitions.out2in}s ease-in,
|
||||||
height: 100vh;
|
transform ${transitions.out2in}s ease-in;
|
||||||
`)};
|
min-width: ${(props) => props.preferredWidth || 320}px;
|
||||||
|
max-width: 100vw;
|
||||||
|
${(props) =>
|
||||||
|
!props.active &&
|
||||||
|
css`
|
||||||
|
transform: translateY(-2vh);
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
`}
|
||||||
|
${onSmallScreen(css`
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
min-width: unset;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
`)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const DefocusHandler = styled.div<PopoverStyledProps>`
|
export const DefocusHandler = styled.div<PopoverStyledProps>`
|
||||||
background-color: rgba(0, 0, 0, 0.01);
|
background-color: rgba(0, 0, 0, 0.01);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
${(props) =>
|
${(props) =>
|
||||||
!props.active &&
|
!props.active &&
|
||||||
css`
|
css`
|
||||||
display: none;
|
display: none;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
`}
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const PopoverHead = styled.div`
|
export const PopoverHead = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const PopoverHeadCloser = styled.div`
|
export const PopoverHeadCloser = styled.div`
|
||||||
flex: 0;
|
flex: 0;
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
border-radius: 2em;
|
border-radius: 2em;
|
||||||
min-width: 1.4em;
|
min-width: 1.4em;
|
||||||
height: 1.4em;
|
height: 1.4em;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
${onTablet(
|
${onTablet(
|
||||||
css`
|
css`
|
||||||
display: none;
|
display: none;
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: rgba(0, 0, 0, 0.1);
|
background: rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const PopoverContent = styled.div`
|
export const PopoverContent = styled.div`
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,42 +1,42 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import {
|
import {
|
||||||
PopoverBase,
|
PopoverBase,
|
||||||
DefocusHandler,
|
DefocusHandler,
|
||||||
PopoverHead,
|
PopoverHead,
|
||||||
PopoverHeadCloser,
|
PopoverHeadCloser,
|
||||||
PopoverContent,
|
PopoverContent,
|
||||||
} from "./Popover.styled";
|
} from './Popover.styled';
|
||||||
import { globalOnKeyUp } from "roleypoly/src/design-system/atoms/key-events";
|
import { globalOnKeyUp } from 'roleypoly/src/design-system/atoms/key-events';
|
||||||
import { IoMdClose } from "react-icons/io";
|
import { IoMdClose } from 'react-icons/io';
|
||||||
|
|
||||||
type PopoverProps = {
|
type PopoverProps = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
position: "top left" | "top right" | "bottom left" | "bottom right";
|
position: 'top left' | 'top right' | 'bottom left' | 'bottom right';
|
||||||
active: boolean;
|
active: boolean;
|
||||||
canDefocus?: boolean;
|
canDefocus?: boolean;
|
||||||
onExit?: (type: "escape" | "defocus" | "explicit") => void;
|
onExit?: (type: 'escape' | 'defocus' | 'explicit') => void;
|
||||||
headContent: React.ReactNode;
|
headContent: React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Popover = (props: PopoverProps) => {
|
export const Popover = (props: PopoverProps) => {
|
||||||
globalOnKeyUp(["Escape"], () => props.onExit?.("escape"), props.active);
|
globalOnKeyUp(['Escape'], () => props.onExit?.('escape'), props.active);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PopoverBase active={props.active}>
|
<PopoverBase active={props.active}>
|
||||||
<PopoverHead>
|
<PopoverHead>
|
||||||
<PopoverHeadCloser onClick={() => props.onExit?.("explicit")}>
|
<PopoverHeadCloser onClick={() => props.onExit?.('explicit')}>
|
||||||
<IoMdClose />
|
<IoMdClose />
|
||||||
</PopoverHeadCloser>
|
</PopoverHeadCloser>
|
||||||
<div>{props.headContent}</div>
|
<div>{props.headContent}</div>
|
||||||
</PopoverHead>
|
</PopoverHead>
|
||||||
<PopoverContent>{props.children}</PopoverContent>
|
<PopoverContent>{props.children}</PopoverContent>
|
||||||
</PopoverBase>
|
</PopoverBase>
|
||||||
{props.canDefocus && (
|
{props.canDefocus && (
|
||||||
<DefocusHandler
|
<DefocusHandler
|
||||||
active={props.active}
|
active={props.active}
|
||||||
onClick={() => props.onExit?.("defocus")}
|
onClick={() => props.onExit?.('defocus')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,79 +1,79 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { Role as RoleComponent } from "./Role";
|
import { Role as RoleComponent } from './Role';
|
||||||
import { roleCategory } from "roleypoly/hack/fixtures/storyData";
|
import { roleCategory } from 'roleypoly/hack/fixtures/storyData';
|
||||||
import { withColors } from "roleypoly/src/design-system/atoms/colors/withColors";
|
import { withColors } from 'roleypoly/src/design-system/atoms/colors/withColors';
|
||||||
import styled from "styled-components";
|
import styled from 'styled-components';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Role",
|
title: 'Atoms/Role',
|
||||||
component: RoleComponent,
|
component: RoleComponent,
|
||||||
decorators: [withColors],
|
decorators: [withColors],
|
||||||
};
|
};
|
||||||
|
|
||||||
const Demo = styled.div`
|
const Demo = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const RoleWithState = (props: any) => {
|
const RoleWithState = (props: any) => {
|
||||||
const [selected, updateSelected] = React.useState(false);
|
const [selected, updateSelected] = React.useState(false);
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: 5 }}>
|
<div style={{ padding: 5 }}>
|
||||||
<RoleComponent
|
<RoleComponent
|
||||||
{...props}
|
{...props}
|
||||||
selected={selected}
|
selected={selected}
|
||||||
onClick={(next) => updateSelected(next)}
|
onClick={(next) => updateSelected(next)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Role = () => (
|
export const Role = () => (
|
||||||
<Demo>
|
<Demo>
|
||||||
{roleCategory.map((c, idx) => (
|
{roleCategory.map((c, idx) => (
|
||||||
<RoleWithState key={idx} role={c} />
|
<RoleWithState key={idx} role={c} />
|
||||||
))}
|
))}
|
||||||
</Demo>
|
</Demo>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Selected = () => (
|
export const Selected = () => (
|
||||||
<Demo>
|
<Demo>
|
||||||
{roleCategory.map((c, idx) => (
|
{roleCategory.map((c, idx) => (
|
||||||
<RoleComponent key={idx} role={c} selected={true} />
|
<RoleComponent key={idx} role={c} selected={true} />
|
||||||
))}
|
))}
|
||||||
</Demo>
|
</Demo>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const Unselected = () => (
|
export const Unselected = () => (
|
||||||
<Demo>
|
<Demo>
|
||||||
{roleCategory.map((c, idx) => (
|
{roleCategory.map((c, idx) => (
|
||||||
<RoleComponent key={idx} role={c} selected={false} />
|
<RoleComponent key={idx} role={c} selected={false} />
|
||||||
))}
|
))}
|
||||||
</Demo>
|
</Demo>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const DisabledByPosition = () => (
|
export const DisabledByPosition = () => (
|
||||||
<Demo>
|
<Demo>
|
||||||
{roleCategory.map((c, idx) => (
|
{roleCategory.map((c, idx) => (
|
||||||
<RoleComponent
|
<RoleComponent
|
||||||
key={idx}
|
key={idx}
|
||||||
role={{ ...c, safety: 1 }}
|
role={{ ...c, safety: 1 }}
|
||||||
selected={false}
|
selected={false}
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Demo>
|
</Demo>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const DisabledByDanger = () => (
|
export const DisabledByDanger = () => (
|
||||||
<Demo>
|
<Demo>
|
||||||
{roleCategory.map((c, idx) => (
|
{roleCategory.map((c, idx) => (
|
||||||
<RoleComponent
|
<RoleComponent
|
||||||
key={idx}
|
key={idx}
|
||||||
role={{ ...c, safety: 2 }}
|
role={{ ...c, safety: 2 }}
|
||||||
selected={false}
|
selected={false}
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</Demo>
|
</Demo>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,84 +1,79 @@
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from 'styled-components';
|
||||||
import { transitions } from "roleypoly/src/design-system/atoms/timings";
|
import { transitions } from 'roleypoly/src/design-system/atoms/timings';
|
||||||
import { palette } from "roleypoly/src/design-system/atoms/colors";
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
export type StyledProps = {
|
export type StyledProps = {
|
||||||
selected: boolean;
|
selected: boolean;
|
||||||
defaultColor: boolean;
|
defaultColor: boolean;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Outer = styled.div<StyledProps>`
|
export const Outer = styled.div<StyledProps>`
|
||||||
border-radius: 24px;
|
border-radius: 24px;
|
||||||
background-color: ${(props) =>
|
background-color: ${(props) =>
|
||||||
props.selected && !props.defaultColor
|
props.selected && !props.defaultColor ? 'var(--role-color)' : palette.taupe100};
|
||||||
? "var(--role-color)"
|
color: ${(props) => (props.selected ? 'var(--role-contrast)' : palette.grey600)};
|
||||||
: palette.taupe100};
|
transition: color ${transitions.in2in}s ease-in-out,
|
||||||
color: ${(props) =>
|
background-color ${transitions.in2in}s ease-in-out,
|
||||||
props.selected ? "var(--role-contrast)" : palette.grey600};
|
transform ${transitions.actionable}s ease-in-out,
|
||||||
transition: color ${transitions.in2in}s ease-in-out,
|
box-shadow ${transitions.actionable}s ease-in-out;
|
||||||
background-color ${transitions.in2in}s ease-in-out,
|
display: flex;
|
||||||
transform ${transitions.actionable}s ease-in-out,
|
padding: 4px;
|
||||||
box-shadow ${transitions.actionable}s ease-in-out;
|
user-select: none;
|
||||||
display: flex;
|
overflow: hidden;
|
||||||
padding: 4px;
|
cursor: pointer;
|
||||||
user-select: none;
|
${(props) =>
|
||||||
overflow: hidden;
|
!props.disabled
|
||||||
cursor: pointer;
|
? css`
|
||||||
${(props) =>
|
&:hover {
|
||||||
!props.disabled
|
transform: translateY(-2px);
|
||||||
? css`
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
|
||||||
&:hover {
|
}
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
box-shadow: 0 0 0 transparent;
|
box-shadow: 0 0 0 transparent;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
: null};
|
: null};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Circle = styled.div<StyledProps>`
|
export const Circle = styled.div<StyledProps>`
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
border-radius: 25px;
|
border-radius: 25px;
|
||||||
background-color: ${(props) =>
|
background-color: ${(props) =>
|
||||||
props.defaultColor && !props.selected
|
props.defaultColor && !props.selected ? 'transparent' : 'var(--role-color)'};
|
||||||
? "transparent"
|
border: 1px solid
|
||||||
: "var(--role-color)"};
|
${(props) =>
|
||||||
border: 1px solid
|
props.defaultColor
|
||||||
${(props) =>
|
? 'var(--role-color)'
|
||||||
props.defaultColor
|
: props.selected
|
||||||
? "var(--role-color)"
|
? 'var(--role-accent)'
|
||||||
: props.selected
|
: 'transparent'};
|
||||||
? "var(--role-accent)"
|
display: flex;
|
||||||
: "transparent"};
|
justify-content: center;
|
||||||
display: flex;
|
align-items: center;
|
||||||
justify-content: center;
|
transition: border ${transitions.in2in}s ease-in-out,
|
||||||
align-items: center;
|
background-color ${transitions.in2in}s ease-in-out;
|
||||||
transition: border ${transitions.in2in}s ease-in-out,
|
flex-shrink: 0;
|
||||||
background-color ${transitions.in2in}s ease-in-out;
|
|
||||||
flex-shrink: 0;
|
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
fill-opacity: ${(props) => (props.selected || props.disabled ? 1 : 0)};
|
fill-opacity: ${(props) => (props.selected || props.disabled ? 1 : 0)};
|
||||||
transition: fill-opacity ${transitions.in2in}s ease-in-out;
|
transition: fill-opacity ${transitions.in2in}s ease-in-out;
|
||||||
fill: ${(props) =>
|
fill: ${(props) =>
|
||||||
props.disabled && props.defaultColor
|
props.disabled && props.defaultColor
|
||||||
? "var(--role-color)"
|
? 'var(--role-color)'
|
||||||
: "var(--role-contrast)"};
|
: 'var(--role-contrast)'};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Text = styled.div`
|
export const Text = styled.div`
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,80 +1,80 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { Role as RPCRole } from "@roleypoly/rpc/shared";
|
import { Role as RPCRole } from '@roleypoly/rpc/shared';
|
||||||
import * as styled from "./Role.styled";
|
import * as styled from './Role.styled';
|
||||||
import { FaCheck, FaTimes } from "react-icons/fa";
|
import { FaCheck, FaTimes } from 'react-icons/fa';
|
||||||
import { numberToChroma } from "roleypoly/src/design-system/atoms/colors";
|
import { numberToChroma } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
import chroma from "chroma-js";
|
import chroma from 'chroma-js';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
role: RPCRole.AsObject;
|
role: RPCRole.AsObject;
|
||||||
selected: boolean;
|
selected: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
onClick?: (newState: boolean) => void;
|
onClick?: (newState: boolean) => void;
|
||||||
tooltipId?: string;
|
tooltipId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Role = (props: Props) => {
|
export const Role = (props: Props) => {
|
||||||
const colorVars = {
|
const colorVars = {
|
||||||
"--role-color": "white",
|
'--role-color': 'white',
|
||||||
"--role-contrast": "hsl(0,0,0%)",
|
'--role-contrast': 'hsl(0,0,0%)',
|
||||||
"--role-accent": "hsl(0,0,70%)",
|
'--role-accent': 'hsl(0,0,70%)',
|
||||||
};
|
};
|
||||||
|
|
||||||
if (props.role.color !== 0) {
|
if (props.role.color !== 0) {
|
||||||
const baseColor = numberToChroma(props.role.color);
|
const baseColor = numberToChroma(props.role.color);
|
||||||
const contrastColorUp = baseColor.brighten(5);
|
const contrastColorUp = baseColor.brighten(5);
|
||||||
const contrastColorDown = baseColor.darken(5);
|
const contrastColorDown = baseColor.darken(5);
|
||||||
const ratio = chroma.contrast(contrastColorDown, baseColor);
|
const ratio = chroma.contrast(contrastColorDown, baseColor);
|
||||||
const contrastColor = ratio > 2 ? contrastColorDown : contrastColorUp;
|
const contrastColor = ratio > 2 ? contrastColorDown : contrastColorUp;
|
||||||
const accentColor = ratio > 2 ? baseColor.darken(2) : baseColor.brighten(2);
|
const accentColor = ratio > 2 ? baseColor.darken(2) : baseColor.brighten(2);
|
||||||
colorVars["--role-color"] = baseColor.css();
|
colorVars['--role-color'] = baseColor.css();
|
||||||
colorVars["--role-accent"] = accentColor.css();
|
colorVars['--role-accent'] = accentColor.css();
|
||||||
colorVars["--role-contrast"] = contrastColor.css();
|
colorVars['--role-contrast'] = contrastColor.css();
|
||||||
}
|
}
|
||||||
|
|
||||||
const styledProps: styled.StyledProps = {
|
const styledProps: styled.StyledProps = {
|
||||||
selected: props.selected,
|
selected: props.selected,
|
||||||
defaultColor: props.role.color === 0,
|
defaultColor: props.role.color === 0,
|
||||||
disabled: !!props.disabled,
|
disabled: !!props.disabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
const extra = !props.disabled
|
const extra = !props.disabled
|
||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
"data-tip": disabledReason(props.role),
|
'data-tip': disabledReason(props.role),
|
||||||
"data-for": props.tooltipId,
|
'data-for': props.tooltipId,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<styled.Outer
|
<styled.Outer
|
||||||
{...styledProps}
|
{...styledProps}
|
||||||
style={colorVars as any}
|
style={colorVars as any}
|
||||||
onClick={() => !props.disabled && props.onClick?.(!props.selected)}
|
onClick={() => !props.disabled && props.onClick?.(!props.selected)}
|
||||||
{...extra}
|
{...extra}
|
||||||
>
|
>
|
||||||
<styled.Circle {...styledProps}>
|
<styled.Circle {...styledProps}>
|
||||||
{!props.disabled ? <FaCheck /> : <FaTimes />}
|
{!props.disabled ? <FaCheck /> : <FaTimes />}
|
||||||
</styled.Circle>
|
</styled.Circle>
|
||||||
<styled.Text>{props.role.name}</styled.Text>
|
<styled.Text>{props.role.name}</styled.Text>
|
||||||
</styled.Outer>
|
</styled.Outer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const disabledReason = (role: RPCRole.AsObject) => {
|
const disabledReason = (role: RPCRole.AsObject) => {
|
||||||
switch (role.safety) {
|
switch (role.safety) {
|
||||||
case RPCRole.RoleSafety.HIGHERTHANBOT:
|
case RPCRole.RoleSafety.HIGHERTHANBOT:
|
||||||
return `This role is above Roleypoly's own role.`;
|
return `This role is above Roleypoly's own role.`;
|
||||||
case RPCRole.RoleSafety.DANGEROUSPERMISSIONS:
|
case RPCRole.RoleSafety.DANGEROUSPERMISSIONS:
|
||||||
const { permissions } = role;
|
const { permissions } = role;
|
||||||
let permissionHits: string[] = [];
|
let permissionHits: string[] = [];
|
||||||
|
|
||||||
(permissions & 0x00000008) === 0x00000008 &&
|
(permissions & 0x00000008) === 0x00000008 &&
|
||||||
permissionHits.push("Administrator");
|
permissionHits.push('Administrator');
|
||||||
(permissions & 0x10000000) === 0x10000000 &&
|
(permissions & 0x10000000) === 0x10000000 &&
|
||||||
permissionHits.push("Manage Roles");
|
permissionHits.push('Manage Roles');
|
||||||
|
|
||||||
return `This role has unsafe permissions: ${permissionHits.join(", ")}`;
|
return `This role has unsafe permissions: ${permissionHits.join(', ')}`;
|
||||||
default:
|
default:
|
||||||
return `This role is disabled.`;
|
return `This role is disabled.`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { Space as SpaceComponent } from "./Space";
|
import { Space as SpaceComponent } from './Space';
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms",
|
title: 'Atoms',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Space = () => (
|
export const Space = () => (
|
||||||
<>
|
<>
|
||||||
hello world
|
hello world
|
||||||
<SpaceComponent />
|
<SpaceComponent />
|
||||||
but im over here
|
but im over here
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import styled from "styled-components";
|
import styled from 'styled-components';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
export const Space = styled.div`
|
export const Space = styled.div`
|
||||||
height: 15px;
|
height: 15px;
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { SparkleOverlay } from "./Sparkle";
|
import { SparkleOverlay } from './Sparkle';
|
||||||
import { Button } from "roleypoly/src/design-system/atoms/button";
|
import { Button } from 'roleypoly/src/design-system/atoms/button';
|
||||||
import { Hero } from "roleypoly/src/design-system/atoms/hero";
|
import { Hero } from 'roleypoly/src/design-system/atoms/hero';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Sparkle",
|
title: 'Atoms/Sparkle',
|
||||||
component: SparkleOverlay,
|
component: SparkleOverlay,
|
||||||
args: {
|
args: {
|
||||||
size: -10,
|
size: -10,
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
repeatCount: 3,
|
repeatCount: 3,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ExampleButton = (args) => (
|
export const ExampleButton = (args) => (
|
||||||
<Hero>
|
<Hero>
|
||||||
<SparkleOverlay {...args}>
|
<SparkleOverlay {...args}>
|
||||||
<Button>Yo check this!</Button>
|
<Button>Yo check this!</Button>
|
||||||
</SparkleOverlay>
|
</SparkleOverlay>
|
||||||
</Hero>
|
</Hero>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,55 +1,52 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import styled from "styled-components";
|
import styled from 'styled-components';
|
||||||
import { palette } from "roleypoly/src/design-system/atoms/colors";
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
import { SparklePatternAlpha, SparklePatternBeta } from "./Shapes";
|
import { SparklePatternAlpha, SparklePatternBeta } from './Shapes';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
size?: number;
|
size?: number;
|
||||||
opacity?: number;
|
opacity?: number;
|
||||||
repeatCount?: number;
|
repeatCount?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SparkleContainer = styled.div`
|
const SparkleContainer = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type EffectProps = {
|
type EffectProps = {
|
||||||
effectSize: Props["size"];
|
effectSize: Props['size'];
|
||||||
effectOpacity: Props["opacity"];
|
effectOpacity: Props['opacity'];
|
||||||
};
|
};
|
||||||
|
|
||||||
const SparkleEffect = styled.div<EffectProps>`
|
const SparkleEffect = styled.div<EffectProps>`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: ${(props) => props.effectSize}px;
|
top: ${(props) => props.effectSize}px;
|
||||||
bottom: ${(props) => props.effectSize}px;
|
bottom: ${(props) => props.effectSize}px;
|
||||||
left: ${(props) => props.effectSize}px;
|
left: ${(props) => props.effectSize}px;
|
||||||
right: ${(props) => props.effectSize}px;
|
right: ${(props) => props.effectSize}px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
opacity: ${(props) => props.effectOpacity};
|
opacity: ${(props) => props.effectOpacity};
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const SparkleOverlay = (props: Props) => (
|
export const SparkleOverlay = (props: Props) => (
|
||||||
<SparkleContainer>
|
<SparkleContainer>
|
||||||
<SparkleEffect
|
<SparkleEffect effectSize={props.size || 0} effectOpacity={props.opacity || 1}>
|
||||||
effectSize={props.size || 0}
|
<SparklePatternAlpha
|
||||||
effectOpacity={props.opacity || 1}
|
repeatCount={props.repeatCount}
|
||||||
>
|
height="100%"
|
||||||
<SparklePatternAlpha
|
strokeColor={palette.gold400}
|
||||||
repeatCount={props.repeatCount}
|
/>
|
||||||
height="100%"
|
<SparklePatternBeta
|
||||||
strokeColor={palette.gold400}
|
repeatCount={props.repeatCount}
|
||||||
/>
|
height="100%"
|
||||||
<SparklePatternBeta
|
strokeColor={palette.gold400}
|
||||||
repeatCount={props.repeatCount}
|
/>
|
||||||
height="100%"
|
</SparkleEffect>
|
||||||
strokeColor={palette.gold400}
|
{props.children}
|
||||||
/>
|
</SparkleContainer>
|
||||||
</SparkleEffect>
|
|
||||||
{props.children}
|
|
||||||
</SparkleContainer>
|
|
||||||
);
|
);
|
||||||
|
|
24
src/design-system/atoms/tab-view/TabView.stories.tsx
Normal file
24
src/design-system/atoms/tab-view/TabView.stories.tsx
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { TabView, Tab } from './TabView';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Atoms/Tab View',
|
||||||
|
argTypes: {
|
||||||
|
tabCount: { control: 'range', min: 1, max: 100 },
|
||||||
|
},
|
||||||
|
args: {
|
||||||
|
tabCount: 10,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ManyTabs = ({ tabCount }) => {
|
||||||
|
const tabs = [...'0'.repeat(tabCount)].reduce(
|
||||||
|
(acc, _, idx) => ({
|
||||||
|
...acc,
|
||||||
|
[`Tab ${idx + 1}`]: <Tab>{() => <div>tab {idx + 1}</div>}</Tab>,
|
||||||
|
}),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
return <TabView>{tabs}</TabView>;
|
||||||
|
};
|
|
@ -1,37 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { atomStories } from 'atoms/atoms.story';
|
|
||||||
import { TabView, Tab } from './TabView';
|
|
||||||
import { number } from '@storybook/addon-knobs';
|
|
||||||
|
|
||||||
const story = atomStories('Tab View', module);
|
|
||||||
|
|
||||||
story.add('Multiple Tabs', () => (
|
|
||||||
<TabView>
|
|
||||||
{{
|
|
||||||
'Tab 1': <Tab>{() => <div>tab 1</div>}</Tab>,
|
|
||||||
'Tab 2': <Tab>{() => <div>tab 2</div>}</Tab>,
|
|
||||||
}}
|
|
||||||
</TabView>
|
|
||||||
));
|
|
||||||
|
|
||||||
story.add('Single Tab', () => (
|
|
||||||
<TabView>
|
|
||||||
{{
|
|
||||||
'Tab 1': <Tab>{() => <div>tab 1</div>}</Tab>,
|
|
||||||
}}
|
|
||||||
</TabView>
|
|
||||||
));
|
|
||||||
|
|
||||||
story.add('Many Tabs', () => {
|
|
||||||
const amount = number('Tab Count', 10);
|
|
||||||
|
|
||||||
const tabs = [...'0'.repeat(amount)].reduce(
|
|
||||||
(acc, _, idx) => ({
|
|
||||||
...acc,
|
|
||||||
[`Tab ${idx + 1}`]: <Tab>{() => <div>tab {idx + 1}</div>}</Tab>,
|
|
||||||
}),
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
return <TabView>{tabs}</TabView>;
|
|
||||||
});
|
|
|
@ -1,43 +1,43 @@
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from 'styled-components';
|
||||||
import { palette } from "roleypoly/src/design-system/atoms/colors";
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
import { transitions } from "roleypoly/src/design-system/atoms/timings";
|
import { transitions } from 'roleypoly/src/design-system/atoms/timings';
|
||||||
import { onTablet } from "roleypoly/src/design-system/atoms/breakpoints";
|
import { onTablet } from 'roleypoly/src/design-system/atoms/breakpoints';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
export const TabViewStyled = styled.div``;
|
export const TabViewStyled = styled.div``;
|
||||||
|
|
||||||
export const TabTitleRow = styled.div`
|
export const TabTitleRow = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
border-bottom: 1px solid ${palette.taupe100};
|
border-bottom: 1px solid ${palette.taupe100};
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const TabTitle = styled.div<{ selected: boolean }>`
|
export const TabTitle = styled.div<{ selected: boolean }>`
|
||||||
flex: 1;
|
flex: 1;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 0.7em 1em;
|
padding: 0.7em 1em;
|
||||||
border-bottom: 3px solid transparent;
|
border-bottom: 3px solid transparent;
|
||||||
transition: border-color ${transitions.in2out}s ease-in-out,
|
transition: border-color ${transitions.in2out}s ease-in-out,
|
||||||
color ${transitions.in2out}s ease-in-out;
|
color ${transitions.in2out}s ease-in-out;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: ${palette.taupe500};
|
color: ${palette.taupe500};
|
||||||
${(props) =>
|
${(props) =>
|
||||||
props.selected
|
props.selected
|
||||||
? css`
|
? css`
|
||||||
color: unset;
|
color: unset;
|
||||||
border-bottom-color: ${palette.taupe500};
|
border-bottom-color: ${palette.taupe500};
|
||||||
`
|
`
|
||||||
: css`
|
: css`
|
||||||
&:hover {
|
&:hover {
|
||||||
border-bottom-color: ${palette.taupe300};
|
border-bottom-color: ${palette.taupe300};
|
||||||
color: unset;
|
color: unset;
|
||||||
}
|
}
|
||||||
`};
|
`};
|
||||||
${onTablet(css`
|
${onTablet(css`
|
||||||
padding: 0.45em 1em;
|
padding: 0.45em 1em;
|
||||||
`)}
|
`)}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const TabContent = styled.div``;
|
export const TabContent = styled.div``;
|
||||||
|
|
|
@ -7,6 +7,7 @@ export type TabViewProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
type TabProps = {
|
type TabProps = {
|
||||||
|
title: string;
|
||||||
children: () => React.ReactNode;
|
children: () => React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { TextInput, TextInputWithIcon } from "./TextInput";
|
import { TextInput, TextInputWithIcon } from './TextInput';
|
||||||
import { SmallTitle } from "roleypoly/src/design-system/atoms/typography";
|
import { SmallTitle } from 'roleypoly/src/design-system/atoms/typography';
|
||||||
import { FiKey } from "react-icons/fi";
|
import { FiKey } from 'react-icons/fi';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Text Input",
|
title: 'Atoms/Text Input',
|
||||||
argTypes: {
|
argTypes: {
|
||||||
placeholder: { control: "text" },
|
placeholder: { control: 'text' },
|
||||||
},
|
},
|
||||||
args: {
|
args: {
|
||||||
placeholder: "Fill me in!",
|
placeholder: 'Fill me in!',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Common = (args) => (
|
export const Common = (args) => (
|
||||||
<div>
|
|
||||||
<SmallTitle>TextInput</SmallTitle>
|
|
||||||
<div>
|
<div>
|
||||||
<TextInput {...args} />
|
<SmallTitle>TextInput</SmallTitle>
|
||||||
|
<div>
|
||||||
|
<TextInput {...args} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<TextInput {...args} disabled />
|
||||||
|
</div>
|
||||||
|
<SmallTitle>TextInputWithIcon</SmallTitle>
|
||||||
|
<div>
|
||||||
|
<TextInputWithIcon icon={<FiKey />} {...args} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<TextInputWithIcon icon={<FiKey />} {...args} disabled />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<TextInputWithIcon icon={<FiKey />} {...args} type="password" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<TextInput {...args} disabled />
|
|
||||||
</div>
|
|
||||||
<SmallTitle>TextInputWithIcon</SmallTitle>
|
|
||||||
<div>
|
|
||||||
<TextInputWithIcon icon={<FiKey />} {...args} />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<TextInputWithIcon icon={<FiKey />} {...args} disabled />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<TextInputWithIcon icon={<FiKey />} {...args} type="password" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,83 +1,83 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import styled from "styled-components";
|
import styled from 'styled-components';
|
||||||
import { palette } from "roleypoly/src/design-system/atoms/colors";
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
|
|
||||||
const StyledTextInput = styled.input`
|
const StyledTextInput = styled.input`
|
||||||
appearance: none;
|
appearance: none;
|
||||||
border: 1px solid ${palette.taupe200};
|
border: 1px solid ${palette.taupe200};
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
line-height: 163%;
|
line-height: 163%;
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
background-color: ${palette.taupe300};
|
background-color: ${palette.taupe300};
|
||||||
color: ${palette.grey600};
|
color: ${palette.grey600};
|
||||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
max-width: 97vw;
|
max-width: 97vw;
|
||||||
|
|
||||||
:focus {
|
:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
border-color: ${palette.grey100};
|
border-color: ${palette.grey100};
|
||||||
box-shadow: 1px 0 3px rgba(0, 0, 0, 0.25);
|
box-shadow: 1px 0 3px rgba(0, 0, 0, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
[disabled],
|
[disabled],
|
||||||
:disabled {
|
:disabled {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
color: rgba(255, 255, 255, 0.75);
|
color: rgba(255, 255, 255, 0.75);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
:hover:not([disabled]) {
|
:hover:not([disabled]) {
|
||||||
border-color: ${palette.grey100};
|
border-color: ${palette.grey100};
|
||||||
}
|
}
|
||||||
|
|
||||||
::placeholder {
|
::placeholder {
|
||||||
color: ${palette.taupe500};
|
color: ${palette.taupe500};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type TextInputProps = React.InputHTMLAttributes<HTMLInputElement> & {
|
type TextInputProps = React.InputHTMLAttributes<HTMLInputElement> & {
|
||||||
_override?: React.Component;
|
_override?: React.Component;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TextInput = (props: TextInputProps) => {
|
export const TextInput = (props: TextInputProps) => {
|
||||||
const { ...rest } = props;
|
const { ...rest } = props;
|
||||||
return <StyledTextInput {...rest} />;
|
return <StyledTextInput {...rest} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledTextInputWithIcon = styled(StyledTextInput)`
|
const StyledTextInputWithIcon = styled(StyledTextInput)`
|
||||||
padding-left: 36px;
|
padding-left: 36px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const IconContainer = styled.div`
|
const IconContainer = styled.div`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 12px;
|
left: 12px;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const IconInputContainer = styled.div`
|
const IconInputContainer = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type TextInputWithIconProps = TextInputProps & {
|
type TextInputWithIconProps = TextInputProps & {
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TextInputWithIcon = (props: TextInputWithIconProps) => {
|
export const TextInputWithIcon = (props: TextInputWithIconProps) => {
|
||||||
const { icon, ...rest } = props;
|
const { icon, ...rest } = props;
|
||||||
return (
|
return (
|
||||||
<IconInputContainer>
|
<IconInputContainer>
|
||||||
<IconContainer>{icon}</IconContainer>
|
<IconContainer>{icon}</IconContainer>
|
||||||
<StyledTextInputWithIcon {...rest}></StyledTextInputWithIcon>
|
<StyledTextInputWithIcon {...rest}></StyledTextInputWithIcon>
|
||||||
</IconInputContainer>
|
</IconInputContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import { Typist } from "./Typist";
|
import { Typist } from './Typist';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Typist",
|
title: 'Atoms/Typist',
|
||||||
component: Typist,
|
component: Typist,
|
||||||
args: {
|
args: {
|
||||||
charTimeout: 75,
|
charTimeout: 75,
|
||||||
resetTimeout: 2000,
|
resetTimeout: 2000,
|
||||||
lines: ["hello world", "and again", "a third", "story time!"],
|
lines: ['hello world', 'and again', 'a third', 'story time!'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Looping = (args) => {
|
export const Looping = (args) => {
|
||||||
return <Typist {...args} />;
|
return <Typist {...args} />;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
|
|
||||||
type TypistProps = {
|
type TypistProps = {
|
||||||
resetTimeout: number;
|
resetTimeout: number;
|
||||||
charTimeout: number;
|
charTimeout: number;
|
||||||
lines: string[];
|
lines: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Typist = (props: TypistProps) => {
|
export const Typist = (props: TypistProps) => {
|
||||||
const [outputText, setOutputText] = React.useState("");
|
const [outputText, setOutputText] = React.useState('');
|
||||||
const [currentLine, setCurrentLine] = React.useState(0);
|
const [currentLine, setCurrentLine] = React.useState(0);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const fullLine = props.lines[currentLine];
|
const fullLine = props.lines[currentLine];
|
||||||
|
|
||||||
if (outputText === fullLine) {
|
if (outputText === fullLine) {
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
setOutputText("");
|
setOutputText('');
|
||||||
setCurrentLine((currentLine + 1) % props.lines.length);
|
setCurrentLine((currentLine + 1) % props.lines.length);
|
||||||
}, props.resetTimeout);
|
}, props.resetTimeout);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
setOutputText(fullLine.slice(0, outputText.length + 1));
|
setOutputText(fullLine.slice(0, outputText.length + 1));
|
||||||
}, props.charTimeout);
|
}, props.charTimeout);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
};
|
};
|
||||||
}, [currentLine, outputText]);
|
}, [currentLine, outputText]);
|
||||||
|
|
||||||
return <>{outputText}</>;
|
return <>{outputText}</>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,109 +1,109 @@
|
||||||
import * as React from "react";
|
import * as React from 'react';
|
||||||
import * as typography from "./typography";
|
import * as typography from './typography';
|
||||||
import styled from "styled-components";
|
import styled from 'styled-components';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Atoms/Typography",
|
title: 'Atoms/Typography',
|
||||||
};
|
};
|
||||||
|
|
||||||
const Text = () => (
|
const Text = () => (
|
||||||
<>
|
<>
|
||||||
<p>
|
<p>
|
||||||
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Et facilis alias
|
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Et facilis alias
|
||||||
placeat cumque sapiente ad delectus omnis quae. Reiciendis quibusdam
|
placeat cumque sapiente ad delectus omnis quae. Reiciendis quibusdam deserunt
|
||||||
deserunt repellat. Exercitationem modi incidunt autem nemo tempore eaque
|
repellat. Exercitationem modi incidunt autem nemo tempore eaque soluta.
|
||||||
soluta.
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
帯カノ需混モイ一録43旧百12共ドレ能生ホクユ禁度ヨ材図クほはそ護関ラト郵張エノヨ議件クめざ県読れみとぶ論税クょンど慎転リつぎみ松期ほへド.
|
||||||
帯カノ需混モイ一録43旧百12共ドレ能生ホクユ禁度ヨ材図クほはそ護関ラト郵張エノヨ議件クめざ県読れみとぶ論税クょンど慎転リつぎみ松期ほへド.
|
縦投記ふで覧速っだせあ過先課フ演無ぎぱべ習併相ーす気6元ゆる領気希ぎ投代ラ我関レ森郎由系堂ず.
|
||||||
縦投記ふで覧速っだせあ過先課フ演無ぎぱべ習併相ーす気6元ゆる領気希ぎ投代ラ我関レ森郎由系堂ず.
|
読ケリ夜指ーっトせ認平引ウシ間花ヱクム年6台ぐ山婦ラスエ子著コア掲中ロ像属戸メソユ職諏ルど詐児題たに書希ク幕値長ラそめド.
|
||||||
読ケリ夜指ーっトせ認平引ウシ間花ヱクム年6台ぐ山婦ラスエ子著コア掲中ロ像属戸メソユ職諏ルど詐児題たに書希ク幕値長ラそめド.
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
🔸🐕🔺💱🎊👽🐛 👨📼🕦📞 👱👆🍗👚🌈 🔝🔟🍉🔰🍲🏁🕗 🎡🐉🍲📻🔢🔄 💟💲🍻💜💩🔼
|
||||||
🔸🐕🔺💱🎊👽🐛 👨📼🕦📞 👱👆🍗👚🌈 🔝🔟🍉🔰🍲🏁🕗 🎡🐉🍲📻🔢🔄
|
🎱🌸📛👫🌻 🗽🕜🐥👕🍈. 🐒🍚🔓📱🏦 🎦🌑🔛💙👣🔚 🔆🗻🌿🎳📲🍯 🌞💟🎌🍌 🔪📯🐎💮
|
||||||
💟💲🍻💜💩🔼 🎱🌸📛👫🌻 🗽🕜🐥👕🍈. 🐒🍚🔓📱🏦 🎦🌑🔛💙👣🔚 🔆🗻🌿🎳📲🍯
|
👌👭🎋🏉🏰 📓🕃🎂💉🔩 🐟🌇👺🌊🌒 📪👅🍂🍁 🌖🐮🔽🌒📊. 🔤🍍🌸📷🎴 💏🍌📎👥👉👒
|
||||||
🌞💟🎌🍌 🔪📯🐎💮 👌👭🎋🏉🏰 📓🕃🎂💉🔩 🐟🌇👺🌊🌒 📪👅🍂🍁 🌖🐮🔽🌒📊.
|
👝💜🔶🍣 💨🗼👈💉💉💰 🍐🕖🌰👝🕓🏊🐕 🏀📅📼📒 🐕🌈👋
|
||||||
🔤🍍🌸📷🎴 💏🍌📎👥👉👒 👝💜🔶🍣 💨🗼👈💉💉💰 🍐🕖🌰👝🕓🏊🐕 🏀📅📼📒
|
</p>
|
||||||
🐕🌈👋
|
</>
|
||||||
</p>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const swatches: [string, string | undefined, string][] = [
|
const swatches: [string, string | undefined, string][] = [
|
||||||
["text900", "LargeTitle", "Used for large titles."],
|
['text900', 'LargeTitle', 'Used for large titles.'],
|
||||||
["text800", "MediumTitle", "Used for medium titles."],
|
['text800', 'MediumTitle', 'Used for medium titles.'],
|
||||||
["text700", "SmallTitle", "Used for small titles."],
|
['text700', 'SmallTitle', 'Used for small titles.'],
|
||||||
["text600", "AccentTitle", "Used for accenting titles."],
|
['text600', 'AccentTitle', 'Used for accenting titles.'],
|
||||||
["text500", "LargeText", "Used for general large font text blocks."],
|
['text500', 'LargeText', 'Used for general large font text blocks.'],
|
||||||
["text400", "Text", "Used for less important font text blocks."],
|
['text400', 'Text', 'Used for less important font text blocks.'],
|
||||||
["text300", undefined, "Used for smaller UI elements."],
|
['text300', undefined, 'Used for smaller UI elements.'],
|
||||||
["text200", "AmbientLarge", "Used for ambient text."],
|
['text200', 'AmbientLarge', 'Used for ambient text.'],
|
||||||
["text100", "AmbientSmall", "Used for ambient text."],
|
['text100', 'AmbientSmall', 'Used for ambient text.'],
|
||||||
];
|
];
|
||||||
|
|
||||||
const Section = styled.section`
|
const Section = styled.section`
|
||||||
margin: 3.26rem;
|
margin: 3.26rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const swatch = (mixin: typeof typography.text900) =>
|
const swatch = (mixin: typeof typography.text900) =>
|
||||||
styled.p`
|
styled.p`
|
||||||
${mixin}
|
${mixin}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Usage = styled.code`
|
const Usage = styled.code`
|
||||||
${typography.text300}
|
${typography.text300}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Description = styled.i`
|
const Description = styled.i`
|
||||||
${typography.text200}
|
${typography.text200}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Sizes = () => (
|
export const Sizes = () => (
|
||||||
<div>
|
<div>
|
||||||
{swatches.map(([mixin, componentName, usage], i) => {
|
{swatches.map(([mixin, componentName, usage], i) => {
|
||||||
const Component = swatch((typography as any)[mixin]);
|
const Component = swatch((typography as any)[mixin]);
|
||||||
return (
|
return (
|
||||||
<Section key={i}>
|
<Section key={i}>
|
||||||
<div>
|
<div>
|
||||||
<Component>The quick brown fox jumped over the lazy dog.</Component>
|
<Component>
|
||||||
</div>
|
The quick brown fox jumped over the lazy dog.
|
||||||
<div>
|
</Component>
|
||||||
<Usage>
|
</div>
|
||||||
<code>
|
<div>
|
||||||
@{mixin} {componentName && `<${componentName} />`}
|
<Usage>
|
||||||
</code>
|
<code>
|
||||||
</Usage>
|
@{mixin} {componentName && `<${componentName} />`}
|
||||||
</div>
|
</code>
|
||||||
<div>
|
</Usage>
|
||||||
<Description>{usage}</Description>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
</Section>
|
<Description>{usage}</Description>
|
||||||
);
|
</div>
|
||||||
})}
|
</Section>
|
||||||
</div>
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const SpacingHead = styled.p`
|
const SpacingHead = styled.p`
|
||||||
${typography.text700}
|
${typography.text700}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const SpacingSection = styled(Section)`
|
const SpacingSection = styled(Section)`
|
||||||
max-width: 50vw;
|
max-width: 50vw;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Spacing = () => (
|
export const Spacing = () => (
|
||||||
<div>
|
<div>
|
||||||
{swatches.map(([mixin], i) => {
|
{swatches.map(([mixin], i) => {
|
||||||
const Component = swatch((typography as any)[mixin]);
|
const Component = swatch((typography as any)[mixin]);
|
||||||
return (
|
return (
|
||||||
<SpacingSection key={i}>
|
<SpacingSection key={i}>
|
||||||
<SpacingHead>@{mixin}</SpacingHead>
|
<SpacingHead>@{mixin}</SpacingHead>
|
||||||
<Component>
|
<Component>
|
||||||
<Text />
|
<Text />
|
||||||
</Component>
|
</Component>
|
||||||
</SpacingSection>
|
</SpacingSection>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,88 +1,88 @@
|
||||||
import styled, { css } from "styled-components";
|
import styled, { css } from 'styled-components';
|
||||||
import * as _ from "styled-components"; // tslint:disable-line:no-duplicate-imports
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
const reset = css`
|
const reset = css`
|
||||||
margin: 0;
|
margin: 0;
|
||||||
line-height: 163%;
|
line-height: 163%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size-adjust: 0.75;
|
font-size-adjust: 0.75;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const text900 = css`
|
export const text900 = css`
|
||||||
${reset}
|
${reset}
|
||||||
font-size: 2.3rem;
|
font-size: 2.3rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const text800 = css`
|
export const text800 = css`
|
||||||
${reset}
|
${reset}
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const text700 = css`
|
export const text700 = css`
|
||||||
${reset}
|
${reset}
|
||||||
font-size: 1.7rem;
|
font-size: 1.7rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const text600 = css`
|
export const text600 = css`
|
||||||
${reset}
|
${reset}
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const text500 = css`
|
export const text500 = css`
|
||||||
${reset}
|
${reset}
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const text400 = css`
|
export const text400 = css`
|
||||||
${reset}
|
${reset}
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const text300 = css`
|
export const text300 = css`
|
||||||
${reset}
|
${reset}
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const text200 = css`
|
export const text200 = css`
|
||||||
${reset}
|
${reset}
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const text100 = css`
|
export const text100 = css`
|
||||||
${reset}
|
${reset}
|
||||||
font-size: 0.5rem;
|
font-size: 0.5rem;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const LargeTitle = styled.span`
|
export const LargeTitle = styled.span`
|
||||||
${text900}
|
${text900}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const MediumTitle = styled.span`
|
export const MediumTitle = styled.span`
|
||||||
${text800}
|
${text800}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const SmallTitle = styled.span`
|
export const SmallTitle = styled.span`
|
||||||
${text700}
|
${text700}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const AccentTitle = styled.span`
|
export const AccentTitle = styled.span`
|
||||||
${text600}
|
${text600}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const LargeText = styled.span`
|
export const LargeText = styled.span`
|
||||||
${text500}
|
${text500}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Text = styled.span`
|
export const Text = styled.span`
|
||||||
${text400}
|
${text400}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const AmbientLarge = styled.span`
|
export const AmbientLarge = styled.span`
|
||||||
${text200}
|
${text200}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const AmbientSmall = styled.span`
|
export const AmbientSmall = styled.span`
|
||||||
${text100}
|
${text100}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -4,9 +4,9 @@ This package houses the dev-container image.
|
||||||
|
|
||||||
It includes:
|
It includes:
|
||||||
|
|
||||||
- go (1.15.2)
|
- go (1.15.2)
|
||||||
- bazel (latest via bazelisk)
|
- bazel (latest via bazelisk)
|
||||||
- node (latest lts via nvm)
|
- node (latest lts via nvm)
|
||||||
|
|
||||||
As well as any other tooling within VSCode Dev Containers.
|
As well as any other tooling within VSCode Dev Containers.
|
||||||
|
|
||||||
|
@ -20,5 +20,5 @@ bazel run //srv/dev-container && docker run -it --rm bazel/src/dev-container:dev
|
||||||
|
|
||||||
To just use, this is published to two registries. There is no effective difference, except that GitHub's registry requires login, and Docker Hub does not.
|
To just use, this is published to two registries. There is no effective difference, except that GitHub's registry requires login, and Docker Hub does not.
|
||||||
|
|
||||||
- `docker pull roleypoly/dev-container:main`
|
- `docker pull roleypoly/dev-container:main`
|
||||||
- `docker pull docker.pkg.github.com/roleypoly/roleypoly/dev-container:main`
|
- `docker pull docker.pkg.github.com/roleypoly/roleypoly/dev-container:main`
|
||||||
|
|
|
@ -4,18 +4,18 @@ Service for handling Discord OAuth flow.
|
||||||
|
|
||||||
## Responsibilities
|
## Responsibilities
|
||||||
|
|
||||||
- Redirect users to relevant Discord OAuth page w/ state
|
- Redirect users to relevant Discord OAuth page w/ state
|
||||||
- Handle redirect from Discord OAuth flow and process the token
|
- Handle redirect from Discord OAuth flow and process the token
|
||||||
- Modify active session to include relevant data
|
- Modify active session to include relevant data
|
||||||
- v3: for parity, this is just user data
|
- v3: for parity, this is just user data
|
||||||
- _vNext: get guilds from oauth and cache_
|
- _vNext: get guilds from oauth and cache_
|
||||||
- _vNext: Source of truth for user guilds_
|
- _vNext: Source of truth for user guilds_
|
||||||
|
|
||||||
## Boundaries & Services
|
## Boundaries & Services
|
||||||
|
|
||||||
- **Inbound**
|
- **Inbound**
|
||||||
- HTTP: /discord-auth/\*
|
- HTTP: /discord-auth/\*
|
||||||
- gRPC: DiscordAuthService
|
- gRPC: DiscordAuthService
|
||||||
- **Outbound**
|
- **Outbound**
|
||||||
- Redis
|
- Redis
|
||||||
- gRPC: SessionService
|
- gRPC: SessionService
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
console.log("hello world");
|
console.log('hello world');
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"deployment_env": {
|
"deployment_env": {
|
||||||
"production": {},
|
"production": {},
|
||||||
"staging": {}
|
"staging": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,25 +1,25 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
"target": "es2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
||||||
"module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
"module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
||||||
"lib": [
|
"lib": [
|
||||||
"dom",
|
"dom",
|
||||||
"dom.iterable",
|
"dom.iterable",
|
||||||
"es2020",
|
"es2020",
|
||||||
"es2015.collection",
|
"es2015.collection",
|
||||||
"es2015.iterable",
|
"es2015.iterable",
|
||||||
"es2015.core"
|
"es2015.core"
|
||||||
],
|
],
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"isolatedModules": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"skipLibCheck": true,
|
||||||
"skipLibCheck": true,
|
"declaration": true,
|
||||||
"declaration": true,
|
"moduleResolution": "node",
|
||||||
"paths": {
|
"paths": {
|
||||||
"roleypoly/*": ["*"]
|
"roleypoly/*": ["*"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
20
vercel.json
20
vercel.json
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"builds": [
|
"builds": [
|
||||||
{
|
{
|
||||||
"src": "package.json",
|
"src": "package.json",
|
||||||
"use": "@vercel/static-build",
|
"use": "@vercel/static-build",
|
||||||
"config": {
|
"config": {
|
||||||
"distDir": "storybook-static"
|
"distDir": "storybook-static"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
77
yarn.lock
77
yarn.lock
|
@ -1240,6 +1240,26 @@
|
||||||
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
|
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
|
||||||
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
|
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
|
||||||
|
|
||||||
|
"@hapi/accept@5.0.1":
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-5.0.1.tgz#068553e867f0f63225a506ed74e899441af53e10"
|
||||||
|
integrity sha512-fMr4d7zLzsAXo28PRRQPXR1o2Wmu+6z+VY1UzDp0iFo13Twj8WePakwXBiqn3E1aAlTpSNzCXdnnQXFhst8h8Q==
|
||||||
|
dependencies:
|
||||||
|
"@hapi/boom" "9.x.x"
|
||||||
|
"@hapi/hoek" "9.x.x"
|
||||||
|
|
||||||
|
"@hapi/boom@9.x.x":
|
||||||
|
version "9.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.0.tgz#0d9517657a56ff1e0b42d0aca9da1b37706fec56"
|
||||||
|
integrity sha512-4nZmpp4tXbm162LaZT45P7F7sgiem8dwAh2vHWT6XX24dozNjGMg6BvKCRvtCUcmcXqeMIUqWN8Rc5X8yKuROQ==
|
||||||
|
dependencies:
|
||||||
|
"@hapi/hoek" "9.x.x"
|
||||||
|
|
||||||
|
"@hapi/hoek@9.x.x":
|
||||||
|
version "9.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.0.tgz#6c9eafc78c1529248f8f4d92b0799a712b6052c6"
|
||||||
|
integrity sha512-i9YbZPN3QgfighY/1X1Pu118VUz2Fmmhd6b2n0/O8YVgGGfw0FbUYoA97k7FkpGJ+pLCFEDLUmAPPV4D1kpeFw==
|
||||||
|
|
||||||
"@icons/material@^0.2.4":
|
"@icons/material@^0.2.4":
|
||||||
version "0.2.4"
|
version "0.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8"
|
resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8"
|
||||||
|
@ -1352,20 +1372,20 @@
|
||||||
call-me-maybe "^1.0.1"
|
call-me-maybe "^1.0.1"
|
||||||
glob-to-regexp "^0.3.0"
|
glob-to-regexp "^0.3.0"
|
||||||
|
|
||||||
"@next/env@9.5.4":
|
"@next/env@9.5.5":
|
||||||
version "9.5.4"
|
version "9.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-9.5.4.tgz#950f3370151a940ecac6e7e19cf125e6113e101e"
|
resolved "https://registry.yarnpkg.com/@next/env/-/env-9.5.5.tgz#db993649ec6e619e34a36de90dc2baa52fc5280f"
|
||||||
integrity sha512-uGnUO68/u9C8bqHj5obIvyGRDqe/jh1dFSLx03mJmlESjcCmV4umXYJOnt3XzU1VhVntSE+jUZtnS5bjYmmLfQ==
|
integrity sha512-N9wdjU6XoqLqNQWtrGiWtp1SUuJsYK1cNrZ24A6YD+4w5CNV5SkZX6aewKZCCLP5Y8UNfTij2FkJiSYUfBjX8g==
|
||||||
|
|
||||||
"@next/polyfill-module@9.5.4":
|
"@next/polyfill-module@9.5.5":
|
||||||
version "9.5.4"
|
version "9.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-9.5.4.tgz#35ea31ce5f6bbf0ac31aac483b60d4ba17a79861"
|
resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-9.5.5.tgz#d9c65679a66664ab4859078f58997113c9d01f10"
|
||||||
integrity sha512-GA2sW7gs33s7RGPFqkMiT9asYpaV/Hhw9+XM9/UlPrkNdTaxZWaPa2iHgmqJ7k6OHiOmy+CBLFrUBgzqKNhs3Q==
|
integrity sha512-itqYFeHo3yN4ccpHq2uNFC2UVQm12K6DxUVwYdui9MJiiueT0pSGb2laYEjf/G5+vVq7M2vb+DkjkOkPMBVfeg==
|
||||||
|
|
||||||
"@next/react-dev-overlay@9.5.4":
|
"@next/react-dev-overlay@9.5.5":
|
||||||
version "9.5.4"
|
version "9.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.5.4.tgz#7d88a710d23021020cca213bc77106df18950b2b"
|
resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-9.5.5.tgz#11b36813d75c43b7bd9d5e478bded1ed5391d03a"
|
||||||
integrity sha512-tYvNmOQ0inykSvcimkTiONMv4ZyFB2G2clsy9FKLLRZ2OA+Jiov6T7Pq6YpKbBwTLu/BQGVc7Qn4BZ5CDHR8ig==
|
integrity sha512-B1nDANxjXr2oyohv+tX0OXZTmJtO5qEWmisNPGnqQ2Z32IixfaAgyNYVuCVf20ap6EUz5elhgNUwRIFh/e26mQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/code-frame" "7.10.4"
|
"@babel/code-frame" "7.10.4"
|
||||||
ally.js "1.4.1"
|
ally.js "1.4.1"
|
||||||
|
@ -1378,10 +1398,10 @@
|
||||||
stacktrace-parser "0.1.10"
|
stacktrace-parser "0.1.10"
|
||||||
strip-ansi "6.0.0"
|
strip-ansi "6.0.0"
|
||||||
|
|
||||||
"@next/react-refresh-utils@9.5.4":
|
"@next/react-refresh-utils@9.5.5":
|
||||||
version "9.5.4"
|
version "9.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-9.5.4.tgz#3bfe067f0cfc717f079482d956211708c9e81126"
|
resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-9.5.5.tgz#fe559b5ca51c038cb7840e0d669a6d7ef01fe4eb"
|
||||||
integrity sha512-TPhEiYxK5YlEuzVuTzgZiDN7SDh4drvUAqsO9Yccd8WLcfYqOLRN2fCALremW5mNLAZQZW3iFgW8PW8Gckq4EQ==
|
integrity sha512-Gz5z0+ID+KAGto6Tkgv1a340damEw3HG6ANLKwNi5/QSHqQ3JUAVxMuhz3qnL54505I777evpzL89ofWEMIWKw==
|
||||||
|
|
||||||
"@nodelib/fs.stat@^1.1.2":
|
"@nodelib/fs.stat@^1.1.2":
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
|
@ -2338,10 +2358,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
|
resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9"
|
||||||
integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==
|
integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==
|
||||||
|
|
||||||
"@types/styled-components@5.1.3":
|
"@types/styled-components@5.1.4":
|
||||||
version "5.1.3"
|
version "5.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.3.tgz#6fab3d9c8f7d9a15cbb89d379d850c985002f363"
|
resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.4.tgz#11f167dbde268635c66adc89b5a5db2e69d75384"
|
||||||
integrity sha512-HGpirof3WOhiX17lb61Q/tpgqn48jxO8EfZkdJ8ueYqwLbK2AHQe/G08DasdA2IdKnmwOIP1s9X2bopxKXgjRw==
|
integrity sha512-78f5Zuy0v/LTQNOYfpH+CINHpchzMMmAt9amY2YNtSgsk1TmlKm8L2Wijss/mtTrsUAVTm2CdGB8VOM65vA8xg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/hoist-non-react-statics" "*"
|
"@types/hoist-non-react-statics" "*"
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
@ -7439,10 +7459,10 @@ next-tick@~1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
|
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
|
||||||
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
|
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
|
||||||
|
|
||||||
next@^9.5.4:
|
next@^9.5.5:
|
||||||
version "9.5.4"
|
version "9.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/next/-/next-9.5.4.tgz#3c6aa3fd38ff1711e956ea2b6833475e0262ec35"
|
resolved "https://registry.yarnpkg.com/next/-/next-9.5.5.tgz#37a37095e7c877ed6c94ba82e34ab9ed02b4eb33"
|
||||||
integrity sha512-dicsJSxiUFcRjeZ/rNMAO3HS5ttFFuRHhdAn5g7lHnWUZ3MnEX4ggBIihaoUr6qu2So9KoqUPXpS91MuSXUmBw==
|
integrity sha512-KF4MIdTYeI6YIGODNw27w9HGzCll4CXbUpkP6MNvyoHlpsunx8ybkQHm/hYa7lWMozmsn58LwaXJOhe4bSrI0g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@ampproject/toolbox-optimizer" "2.6.0"
|
"@ampproject/toolbox-optimizer" "2.6.0"
|
||||||
"@babel/code-frame" "7.10.4"
|
"@babel/code-frame" "7.10.4"
|
||||||
|
@ -7462,10 +7482,11 @@ next@^9.5.4:
|
||||||
"@babel/preset-typescript" "7.10.4"
|
"@babel/preset-typescript" "7.10.4"
|
||||||
"@babel/runtime" "7.11.2"
|
"@babel/runtime" "7.11.2"
|
||||||
"@babel/types" "7.11.5"
|
"@babel/types" "7.11.5"
|
||||||
"@next/env" "9.5.4"
|
"@hapi/accept" "5.0.1"
|
||||||
"@next/polyfill-module" "9.5.4"
|
"@next/env" "9.5.5"
|
||||||
"@next/react-dev-overlay" "9.5.4"
|
"@next/polyfill-module" "9.5.5"
|
||||||
"@next/react-refresh-utils" "9.5.4"
|
"@next/react-dev-overlay" "9.5.5"
|
||||||
|
"@next/react-refresh-utils" "9.5.5"
|
||||||
ast-types "0.13.2"
|
ast-types "0.13.2"
|
||||||
babel-plugin-transform-define "2.0.0"
|
babel-plugin-transform-define "2.0.0"
|
||||||
babel-plugin-transform-react-remove-prop-types "0.4.24"
|
babel-plugin-transform-react-remove-prop-types "0.4.24"
|
||||||
|
|
Loading…
Add table
Reference in a new issue