mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-06-16 17:49:09 +00:00
chore: fix storybook for realsies
This commit is contained in:
parent
1bbc61c82f
commit
3d867c1db0
18 changed files with 927 additions and 34 deletions
42
src/design-system/README.md
Normal file
42
src/design-system/README.md
Normal file
|
@ -0,0 +1,42 @@
|
|||
# Roleypoly Design System
|
||||
|
||||
Codename: **rapid**
|
||||
|
||||
The Roleypoly Design System (rapid) is an atomic design system to help rapidly and consistently build Roleypoly and related services. The color system in use is deliberately simple, and should be adhered to.
|
||||
|
||||
## Developing
|
||||
|
||||
**Please follow hermeticity considerations.**
|
||||
|
||||
This package cannot reference RPC types, as they do not exist in the outside world. Storybook is the core component of this, and Storybook doesn't know how to find RPC types at CI build time, as Bazel is also not present.
|
||||
|
||||
You need:
|
||||
|
||||
- `node` (lts or later)
|
||||
- `yarn` (v1.x)
|
||||
|
||||
Run:
|
||||
|
||||
- `yarn storybook` to get started.
|
||||
|
||||
## Atomic Design 101
|
||||
|
||||
Components are split into the following categories:
|
||||
|
||||
- **atoms**
|
||||
- smallest possible parts.
|
||||
- typically individual pieces, such as branding, layout macros, and style-wrapped native elements.
|
||||
- **molecules**
|
||||
- groups of atoms
|
||||
- typically these make up sections of major UI parts
|
||||
- **organisms**
|
||||
- groups of molecules
|
||||
- typically these are major UI parts
|
||||
- **templates**
|
||||
- groups of organisms
|
||||
- typically a full page, without data.
|
||||
- **pages**
|
||||
- _not covered by rapid_
|
||||
- routes data into templates.
|
||||
|
||||
This sort of layout works extremely well with Next.js, the UI toolkit within Roleypoly. You should also be able to develop most parts, up until pages, directly within Storybook.
|
|
@ -12,6 +12,7 @@ react_library(
|
|||
"styled-components",
|
||||
"//src/design-system/atoms/colors",
|
||||
"//src/design-system/atoms/timings",
|
||||
"//src/design-system/shared-types",
|
||||
"//src/rpc/shared",
|
||||
"@types/chroma-js",
|
||||
"@types/react",
|
||||
|
@ -21,5 +22,7 @@ react_library(
|
|||
|
||||
jest_test(
|
||||
src = ":role",
|
||||
deps = ["//hack/fixtures"],
|
||||
deps = [
|
||||
"//src/design-system/shared-types",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { shallow } from 'enzyme';
|
||||
import { roleCategory } from 'roleypoly/hack/fixtures/storyData';
|
||||
import { roleCategory } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||
import * as React from 'react';
|
||||
import { Role } from './Role';
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import * as React from 'react';
|
||||
import { Role as RoleComponent } from './Role';
|
||||
import { roleCategory } from 'roleypoly/hack/fixtures/storyData';
|
||||
import { roleCategory } from '../../shared-types/storyData';
|
||||
import { withColors } from 'roleypoly/src/design-system/atoms/colors/withColors';
|
||||
import styled from 'styled-components';
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import * as React from 'react';
|
||||
import { Role as RPCRole } from 'roleypoly/src/rpc/shared';
|
||||
import { Role as RPCRole, RoleSafety } from '../../shared-types';
|
||||
import * as styled from './Role.styled';
|
||||
import { FaCheck, FaTimes } from 'react-icons/fa';
|
||||
import { numberToChroma } from 'roleypoly/src/design-system/atoms/colors';
|
||||
import chroma from 'chroma-js';
|
||||
|
||||
type Props = {
|
||||
role: RPCRole.AsObject;
|
||||
role: RPCRole;
|
||||
selected: boolean;
|
||||
disabled?: boolean;
|
||||
onClick?: (newState: boolean) => void;
|
||||
|
@ -60,11 +60,11 @@ export const Role = (props: Props) => {
|
|||
);
|
||||
};
|
||||
|
||||
const disabledReason = (role: RPCRole.AsObject) => {
|
||||
const disabledReason = (role: RPCRole) => {
|
||||
switch (role.safety) {
|
||||
case RPCRole.RoleSafety.HIGHERTHANBOT:
|
||||
case RoleSafety.HIGHERTHANBOT:
|
||||
return `This role is above Roleypoly's own role.`;
|
||||
case RPCRole.RoleSafety.DANGEROUSPERMISSIONS:
|
||||
case RoleSafety.DANGEROUSPERMISSIONS:
|
||||
const { permissions } = role;
|
||||
let permissionHits: string[] = [];
|
||||
|
||||
|
|
5
src/design-system/shared-types/BUILD.bazel
Normal file
5
src/design-system/shared-types/BUILD.bazel
Normal file
|
@ -0,0 +1,5 @@
|
|||
load("//:hack/react.bzl", "react_library")
|
||||
|
||||
react_library(
|
||||
name = "shared-types",
|
||||
)
|
13
src/design-system/shared-types/Category.ts
Normal file
13
src/design-system/shared-types/Category.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
export enum CategoryType {
|
||||
SINGLE = 0,
|
||||
MULTI,
|
||||
}
|
||||
|
||||
export type Category = {
|
||||
id: string;
|
||||
name: string;
|
||||
rolesList: string[];
|
||||
hidden: boolean;
|
||||
type: CategoryType;
|
||||
position: number;
|
||||
};
|
34
src/design-system/shared-types/Guild.ts
Normal file
34
src/design-system/shared-types/Guild.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { Category } from './Category';
|
||||
import { Role } from './Role';
|
||||
import { Member } from './User';
|
||||
|
||||
export type Guild = {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
ownerid: string;
|
||||
membercount: number;
|
||||
splash: string;
|
||||
};
|
||||
|
||||
export type GuildRoles = {
|
||||
id: string;
|
||||
rolesList: Role[];
|
||||
};
|
||||
|
||||
export type GuildData = {
|
||||
id: string;
|
||||
message: string;
|
||||
categoriesList: Category[];
|
||||
entitlementsList: string[];
|
||||
};
|
||||
|
||||
export type GuildEnumeration = {
|
||||
guildsList: {
|
||||
id: string;
|
||||
guild: Guild;
|
||||
member: Member;
|
||||
data: GuildData;
|
||||
roles: GuildRoles;
|
||||
}[];
|
||||
};
|
15
src/design-system/shared-types/Role.ts
Normal file
15
src/design-system/shared-types/Role.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
export enum RoleSafety {
|
||||
SAFE = 0,
|
||||
HIGHERTHANBOT,
|
||||
DANGEROUSPERMISSIONS,
|
||||
}
|
||||
|
||||
export type Role = {
|
||||
id: string;
|
||||
name: string;
|
||||
color: number;
|
||||
permissions: number;
|
||||
managed: boolean;
|
||||
position: number;
|
||||
safety: RoleSafety;
|
||||
};
|
18
src/design-system/shared-types/User.ts
Normal file
18
src/design-system/shared-types/User.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
export type DiscordUser = {
|
||||
id: string;
|
||||
username: string;
|
||||
discriminator: string;
|
||||
avatar: string;
|
||||
bot: boolean;
|
||||
};
|
||||
|
||||
export type Member = {
|
||||
guildid: string;
|
||||
rolesList: string[];
|
||||
nick: string;
|
||||
user: DiscordUser;
|
||||
};
|
||||
|
||||
export type RoleypolyUser = {
|
||||
discorduser: DiscordUser;
|
||||
};
|
4
src/design-system/shared-types/index.ts
Normal file
4
src/design-system/shared-types/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
export * from './Role';
|
||||
export * from './Category';
|
||||
export * from './Guild';
|
||||
export * from './User';
|
241
src/design-system/shared-types/storyData.ts
Normal file
241
src/design-system/shared-types/storyData.ts
Normal file
|
@ -0,0 +1,241 @@
|
|||
import {
|
||||
Category,
|
||||
DiscordUser,
|
||||
Guild,
|
||||
GuildData,
|
||||
GuildEnumeration,
|
||||
GuildRoles,
|
||||
Member,
|
||||
Role,
|
||||
RoleSafety,
|
||||
RoleypolyUser,
|
||||
CategoryType,
|
||||
} from '.';
|
||||
|
||||
export const roleCategory: Role[] = [
|
||||
{
|
||||
id: 'aaa',
|
||||
permissions: 0,
|
||||
name: 'She/Her',
|
||||
color: 0xffc0cb,
|
||||
position: 1,
|
||||
managed: false,
|
||||
safety: RoleSafety.SAFE,
|
||||
},
|
||||
{
|
||||
id: 'bbb',
|
||||
permissions: 0,
|
||||
name: 'He/Him',
|
||||
color: 0xc0ebff,
|
||||
position: 2,
|
||||
managed: false,
|
||||
safety: RoleSafety.SAFE,
|
||||
},
|
||||
{
|
||||
id: 'ccc',
|
||||
permissions: 0,
|
||||
name: 'They/Them',
|
||||
color: 0xc0ffd5,
|
||||
position: 3,
|
||||
managed: false,
|
||||
safety: RoleSafety.SAFE,
|
||||
},
|
||||
{
|
||||
id: 'ddd',
|
||||
permissions: 0,
|
||||
name: 'Reee',
|
||||
color: 0xff0000,
|
||||
position: 4,
|
||||
managed: false,
|
||||
safety: RoleSafety.SAFE,
|
||||
},
|
||||
{
|
||||
id: 'eee',
|
||||
permissions: 0,
|
||||
name: 'black but actually bravely default',
|
||||
color: 0x000000,
|
||||
position: 5,
|
||||
managed: false,
|
||||
safety: RoleSafety.SAFE,
|
||||
},
|
||||
{
|
||||
id: 'fff',
|
||||
permissions: 0,
|
||||
name: 'b̻͌̆̽ͣ̃ͭ̊l͚̥͙̔ͨ̊aͥć͕k͎̟͍͕ͥ̋ͯ̓̈̉̋i͛̄̔͂̚̚҉̳͈͔̖̼̮ṣ̤̗̝͊̌͆h͈̭̰͔̥̯ͅ',
|
||||
color: 0x1,
|
||||
position: 6,
|
||||
managed: false,
|
||||
safety: RoleSafety.SAFE,
|
||||
},
|
||||
{
|
||||
id: 'unsafe1',
|
||||
permissions: 0,
|
||||
name: 'too high',
|
||||
color: 0xff0088,
|
||||
position: 7,
|
||||
managed: false,
|
||||
safety: RoleSafety.HIGHERTHANBOT,
|
||||
},
|
||||
{
|
||||
id: 'unsafe2',
|
||||
permissions: 0x00000008 | 0x10000000,
|
||||
name: 'too strong',
|
||||
color: 0x00ff88,
|
||||
position: 8,
|
||||
managed: false,
|
||||
safety: RoleSafety.DANGEROUSPERMISSIONS,
|
||||
},
|
||||
];
|
||||
|
||||
export const mockCategory: Category = {
|
||||
id: 'aaa',
|
||||
name: 'Mock',
|
||||
rolesList: roleCategory.map((x) => x.id),
|
||||
hidden: false,
|
||||
type: CategoryType.MULTI,
|
||||
position: 0,
|
||||
};
|
||||
|
||||
export const roleCategory2: Role[] = [
|
||||
{
|
||||
id: 'ddd2',
|
||||
permissions: 0,
|
||||
name: 'red',
|
||||
color: 0xff0000,
|
||||
position: 9,
|
||||
managed: false,
|
||||
safety: RoleSafety.SAFE,
|
||||
},
|
||||
{
|
||||
id: 'eee2',
|
||||
permissions: 0,
|
||||
name: 'green',
|
||||
color: 0x00ff00,
|
||||
position: 10,
|
||||
managed: false,
|
||||
safety: RoleSafety.SAFE,
|
||||
},
|
||||
];
|
||||
|
||||
export const mockCategorySingle: Category = {
|
||||
id: 'bbb',
|
||||
name: 'Mock Single 岡野',
|
||||
rolesList: roleCategory2.map((x) => x.id),
|
||||
hidden: false,
|
||||
type: CategoryType.SINGLE,
|
||||
position: 0,
|
||||
};
|
||||
|
||||
export const guildRoles: GuildRoles = {
|
||||
id: 'aaa',
|
||||
rolesList: [...roleCategory, ...roleCategory2],
|
||||
};
|
||||
|
||||
export const roleWikiData = {
|
||||
aaa: 'Typically used by feminine-identifying people',
|
||||
bbb: 'Typically used by masculine-identifying people',
|
||||
ccc: 'Typically used to refer to all people as a singular neutral.',
|
||||
};
|
||||
|
||||
export const guild: Guild = {
|
||||
name: 'emoji megaporium',
|
||||
id: 'aaa',
|
||||
icon:
|
||||
'https://cdn.discordapp.com/icons/421896162539470888/3372fd895ed913b55616c5e49cd50e60.png?size=256',
|
||||
ownerid: 'bbb',
|
||||
membercount: 23453,
|
||||
splash: '',
|
||||
};
|
||||
|
||||
export const guildMap: { [x: string]: Guild } = {
|
||||
'emoji megaporium': guild,
|
||||
Roleypoly: {
|
||||
name: 'Roleypoly',
|
||||
id: 'aaa',
|
||||
icon:
|
||||
'https://cdn.discordapp.com/icons/203493697696956418/ff08d36f5aee1ff48f8377b65d031ab0.png?size=256',
|
||||
ownerid: 'bbb',
|
||||
membercount: 23453,
|
||||
splash: '',
|
||||
},
|
||||
'chamber of secrets': {
|
||||
name: 'chamber of secrets',
|
||||
id: 'aaa',
|
||||
icon: '',
|
||||
ownerid: 'bbb',
|
||||
membercount: 23453,
|
||||
splash: '',
|
||||
},
|
||||
Eclipse: {
|
||||
name: 'Eclipse',
|
||||
id: 'aaa',
|
||||
icon:
|
||||
'https://cdn.discordapp.com/icons/408821059161423873/49dfdd8b2456e2977e80a8b577b19c0d.png?size=256',
|
||||
ownerid: 'bbb',
|
||||
membercount: 23453,
|
||||
splash: '',
|
||||
},
|
||||
};
|
||||
|
||||
export const guildData: GuildData = {
|
||||
id: 'aaa',
|
||||
message: 'henlo worl!!',
|
||||
categoriesList: [mockCategory, mockCategorySingle],
|
||||
entitlementsList: [],
|
||||
};
|
||||
|
||||
export const user: DiscordUser = {
|
||||
id: '123',
|
||||
username: 'okano cat',
|
||||
discriminator: '3266',
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/avatars/62601275618889728/b1292bb974557337702cb941fc038085.png',
|
||||
bot: false,
|
||||
};
|
||||
|
||||
export const member: Member = {
|
||||
guildid: 'aaa',
|
||||
rolesList: ['aaa', 'eee', 'unsafe2', 'ddd2'],
|
||||
nick: 'okano cat',
|
||||
user: user,
|
||||
};
|
||||
|
||||
export const rpUser: RoleypolyUser = {
|
||||
discorduser: user,
|
||||
};
|
||||
|
||||
export const guildEnum: GuildEnumeration = {
|
||||
guildsList: [
|
||||
{
|
||||
id: 'aaa',
|
||||
guild: guildMap['emoji megaporium'],
|
||||
member,
|
||||
data: guildData,
|
||||
roles: guildRoles,
|
||||
},
|
||||
{
|
||||
id: 'bbb',
|
||||
guild: guildMap['Roleypoly'],
|
||||
member: {
|
||||
...member,
|
||||
rolesList: ['unsafe2'],
|
||||
},
|
||||
data: guildData,
|
||||
roles: guildRoles,
|
||||
},
|
||||
{
|
||||
id: 'ccc',
|
||||
guild: guildMap['chamber of secrets'],
|
||||
member,
|
||||
data: guildData,
|
||||
roles: guildRoles,
|
||||
},
|
||||
{
|
||||
id: 'ddd',
|
||||
guild: guildMap['Eclipse'],
|
||||
member,
|
||||
data: guildData,
|
||||
roles: guildRoles,
|
||||
},
|
||||
],
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue