chore: prettier

This commit is contained in:
41666 2020-10-10 04:33:54 -04:00
parent ccf89d8480
commit 70fa51d4a1
67 changed files with 1811 additions and 1838 deletions

View file

@ -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"
] ]
} }

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,2 +1 @@
name: Terraform name: Terraform

14
.gitignore vendored
View file

@ -5,16 +5,6 @@ bazel-testlogs
node_modules node_modules
.env .env
docker-compose.yaml docker-compose.yaml
#Added by cargo
/target /target
*.log
storybook-static
#Added by cargo
#
#already existing elements were commented out
#/target
*.log

1
.prettierignore Normal file
View file

@ -0,0 +1 @@
bazel-*

View file

9
.prettierrc.js Normal file
View file

@ -0,0 +1,9 @@
module.exports = {
printWidth: 90,
useTabs: false,
tabWidth: 4,
singleQuote: true,
trailingComma: 'es5',
bracketSpacing: true,
semi: true,
};

View file

@ -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;
}, },
}; };

View file

@ -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,
}); });

View file

@ -1,4 +1,3 @@
export const parameters = { export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" }, actions: { argTypesRegex: '^on[A-Z].*' },
} };

View file

@ -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,
}); });

20
.vscode/settings.json vendored
View file

@ -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
} }
} }

View file

@ -1,29 +1,29 @@
# Roleypoly # Roleypoly
https://roleypoly.com https://roleypoly.com
Tame your Discord roles. Tame your Discord roles.
### Need Help with Roleypoly? ### Need Help with Roleypoly?
📚 [Please read through our community documentation.](https://github.com/roleypoly/community-docs) 📚 [Please read through our community documentation.](https://github.com/roleypoly/community-docs)
😕 [Still confused? Talk to us on Discord!](https://discord.gg/PWQUVsd) 😕 [Still confused? Talk to us on Discord!](https://discord.gg/PWQUVsd)
## Developing ## Developing
Roleypoly is a distributed system built with Go, React, Terraform, and Bazel. Roleypoly is a distributed system built with Go, React, Terraform, and Bazel.
This repo is currently being re-architected into a monorepo, so most processes might not be documented. This repo is currently being re-architected into a monorepo, so most processes might not be documented.
### Quickstart ### Quickstart
This repo can be quickly setup with [VSCode Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) or [GitHub Codespaces](https://github.com/codespaces). This will setup a fully featured Docker container for developing VSCode, including extensions. This repo can be quickly setup with [VSCode Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) or [GitHub Codespaces](https://github.com/codespaces). This will setup a fully featured Docker container for developing VSCode, including extensions.
If you'd like to not use either of those, it can be imported into your Docker host with `bazel run //src/dev-container`, or pulled from either `roleypoly/dev-container:main` or `docker.pkg.github.com/roleypoly/roleypoly/dev-container:main`. This use case is not actively investigated, but with tinkering, will work. Feel free to document this process and open a PR :) If you'd like to not use either of those, it can be imported into your Docker host with `bazel run //src/dev-container`, or pulled from either `roleypoly/dev-container:main` or `docker.pkg.github.com/roleypoly/roleypoly/dev-container:main`. This use case is not actively investigated, but with tinkering, will work. Feel free to document this process and open a PR :)
### Things to Know ### Things to Know
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`.

View file

@ -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"
}
} }

View file

@ -1,17 +1,17 @@
# DB # DB
Roleypoly's DB schemas, connectors, and other useful database admin tools. Roleypoly's DB schemas, connectors, and other useful database admin tools.
## Tools ## Tools
### ent ### ent
ent schema and the files it generates. ent schema and the files it generates.
Edit nothing outside of the `schemas` folder, as all others are generated. 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.

View file

@ -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>
); );

View file

@ -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%;
`; `;

View file

@ -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

View file

@ -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 />;

View file

@ -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);

View file

@ -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');

View file

@ -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])}
`; `;

View file

@ -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] }}>&nbsp;</td>
<tr key={i}> <td style={{ backgroundColor: ratio.color2[1] }}>&nbsp;</td>
<td style={{ backgroundColor: ratio.color1[1] }}>&nbsp;</td> <td style={getWCAGStyle(+ratio.ratio)}>{ratio.ratio}</td>
<td style={{ backgroundColor: ratio.color2[1] }}>&nbsp;</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);

View file

@ -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);
}; };

View file

@ -1,2 +1,2 @@
export * from "./colors"; export * from './colors';
export * as utils from "./withColors"; export * as utils from './withColors';

View file

@ -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 />;

View file

@ -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 />;
}; };

View file

@ -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>
); );
}; };

View file

@ -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>
);
}; };

View file

@ -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> 4312.
4312. 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>
); );

View file

@ -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}
`; `;

View file

@ -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>
); );

View file

@ -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%;
`)} `)}
`; `;

View file

@ -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>
); );

View file

@ -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>
); );

View file

@ -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>
); );
}; };

View file

@ -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;
`; `;

View file

@ -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')}
/> />
)} )}
</> </>
); );
}; };

View file

@ -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>
); );

View file

@ -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;
`; `;

View file

@ -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.`;
} }
}; };

View file

@ -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
</> </>
); );

View file

@ -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;
`; `;

View file

@ -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>
); );

View file

@ -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>
); );

View 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>;
};

View file

@ -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>;
});

View file

@ -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``;

View file

@ -7,6 +7,7 @@ export type TabViewProps = {
}; };
type TabProps = { type TabProps = {
title: string;
children: () => React.ReactNode; children: () => React.ReactNode;
}; };

View file

@ -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>
); );

View file

@ -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>
); );
}; };

View file

@ -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} />;
}; };

View file

@ -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}</>;
}; };

View file

@ -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> 4312.
4312. 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>
); );

View file

@ -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}
`; `;

View file

@ -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`

View file

@ -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

View file

@ -1 +1 @@
console.log("hello world"); console.log('hello world');

View file

@ -1,6 +1,6 @@
{ {
"deployment_env": { "deployment_env": {
"production": {}, "production": {},
"staging": {} "staging": {}
} }
} }

View file

@ -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/*": ["*"]
}
} }
}
} }

View file

@ -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"
} }
} }
] ]
} }

View file

@ -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"