mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-04-25 03:49:11 +00:00
feat(design-system): port molecules
This commit is contained in:
parent
ea2683da00
commit
7be4f0d1e7
70 changed files with 538 additions and 487 deletions
|
@ -1,12 +0,0 @@
|
||||||
load("//:hack/react.bzl", "react_library")
|
|
||||||
|
|
||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
react_library(
|
|
||||||
name = "fixtures",
|
|
||||||
deps = [
|
|
||||||
"//src/rpc/discord",
|
|
||||||
"//src/rpc/platform",
|
|
||||||
"//src/rpc/shared",
|
|
||||||
],
|
|
||||||
)
|
|
|
@ -1,237 +0,0 @@
|
||||||
import { Member } from 'roleypoly/src/rpc/discord';
|
|
||||||
import { Category, GuildData, GuildEnumeration } from 'roleypoly/src/rpc/platform';
|
|
||||||
import {
|
|
||||||
DiscordUser,
|
|
||||||
Guild,
|
|
||||||
GuildRoles,
|
|
||||||
Role,
|
|
||||||
RoleypolyUser,
|
|
||||||
} from 'roleypoly/src/rpc/shared';
|
|
||||||
|
|
||||||
export const roleCategory: Role.AsObject[] = [
|
|
||||||
{
|
|
||||||
id: 'aaa',
|
|
||||||
permissions: 0,
|
|
||||||
name: 'She/Her',
|
|
||||||
color: 0xffc0cb,
|
|
||||||
position: 1,
|
|
||||||
managed: false,
|
|
||||||
safety: Role.RoleSafety.SAFE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'bbb',
|
|
||||||
permissions: 0,
|
|
||||||
name: 'He/Him',
|
|
||||||
color: 0xc0ebff,
|
|
||||||
position: 2,
|
|
||||||
managed: false,
|
|
||||||
safety: Role.RoleSafety.SAFE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'ccc',
|
|
||||||
permissions: 0,
|
|
||||||
name: 'They/Them',
|
|
||||||
color: 0xc0ffd5,
|
|
||||||
position: 3,
|
|
||||||
managed: false,
|
|
||||||
safety: Role.RoleSafety.SAFE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'ddd',
|
|
||||||
permissions: 0,
|
|
||||||
name: 'Reee',
|
|
||||||
color: 0xff0000,
|
|
||||||
position: 4,
|
|
||||||
managed: false,
|
|
||||||
safety: Role.RoleSafety.SAFE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'eee',
|
|
||||||
permissions: 0,
|
|
||||||
name: 'black but actually bravely default',
|
|
||||||
color: 0x000000,
|
|
||||||
position: 5,
|
|
||||||
managed: false,
|
|
||||||
safety: Role.RoleSafety.SAFE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'fff',
|
|
||||||
permissions: 0,
|
|
||||||
name: 'b̻͌̆̽ͣ̃ͭ̊l͚̥͙̔ͨ̊aͥć͕k͎̟͍͕ͥ̋ͯ̓̈̉̋i͛̄̔͂̚̚҉̳͈͔̖̼̮ṣ̤̗̝͊̌͆h͈̭̰͔̥̯ͅ',
|
|
||||||
color: 0x1,
|
|
||||||
position: 6,
|
|
||||||
managed: false,
|
|
||||||
safety: Role.RoleSafety.SAFE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'unsafe1',
|
|
||||||
permissions: 0,
|
|
||||||
name: 'too high',
|
|
||||||
color: 0xff0088,
|
|
||||||
position: 7,
|
|
||||||
managed: false,
|
|
||||||
safety: Role.RoleSafety.HIGHERTHANBOT,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'unsafe2',
|
|
||||||
permissions: 0x00000008 | 0x10000000,
|
|
||||||
name: 'too strong',
|
|
||||||
color: 0x00ff88,
|
|
||||||
position: 8,
|
|
||||||
managed: false,
|
|
||||||
safety: Role.RoleSafety.DANGEROUSPERMISSIONS,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const mockCategory: Category.AsObject = {
|
|
||||||
id: 'aaa',
|
|
||||||
name: 'Mock',
|
|
||||||
rolesList: roleCategory.map((x) => x.id),
|
|
||||||
hidden: false,
|
|
||||||
type: Category.CategoryType.MULTI,
|
|
||||||
position: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const roleCategory2: Role.AsObject[] = [
|
|
||||||
{
|
|
||||||
id: 'ddd2',
|
|
||||||
permissions: 0,
|
|
||||||
name: 'red',
|
|
||||||
color: 0xff0000,
|
|
||||||
position: 9,
|
|
||||||
managed: false,
|
|
||||||
safety: Role.RoleSafety.SAFE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'eee2',
|
|
||||||
permissions: 0,
|
|
||||||
name: 'green',
|
|
||||||
color: 0x00ff00,
|
|
||||||
position: 10,
|
|
||||||
managed: false,
|
|
||||||
safety: Role.RoleSafety.SAFE,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const mockCategorySingle: Category.AsObject = {
|
|
||||||
id: 'bbb',
|
|
||||||
name: 'Mock Single 岡野',
|
|
||||||
rolesList: roleCategory2.map((x) => x.id),
|
|
||||||
hidden: false,
|
|
||||||
type: Category.CategoryType.SINGLE,
|
|
||||||
position: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const guildRoles: GuildRoles.AsObject = {
|
|
||||||
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.AsObject = {
|
|
||||||
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.AsObject } = {
|
|
||||||
'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.AsObject = {
|
|
||||||
id: 'aaa',
|
|
||||||
message: 'henlo worl!!',
|
|
||||||
categoriesList: [mockCategory, mockCategorySingle],
|
|
||||||
entitlementsList: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
export const user: DiscordUser.AsObject = {
|
|
||||||
id: '123',
|
|
||||||
username: 'okano cat',
|
|
||||||
discriminator: '3266',
|
|
||||||
avatar:
|
|
||||||
'https://cdn.discordapp.com/avatars/62601275618889728/b1292bb974557337702cb941fc038085.png',
|
|
||||||
bot: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const member: Member.AsObject = {
|
|
||||||
guildid: 'aaa',
|
|
||||||
rolesList: ['aaa', 'eee', 'unsafe2', 'ddd2'],
|
|
||||||
nick: 'okano cat',
|
|
||||||
user: user,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const rpUser: RoleypolyUser.AsObject = {
|
|
||||||
discorduser: user,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const guildEnum: GuildEnumeration.AsObject = {
|
|
||||||
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,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
|
@ -14,7 +14,7 @@ def render_deps(deps = []):
|
||||||
"@npm//@improbable-eng/grpc-web",
|
"@npm//@improbable-eng/grpc-web",
|
||||||
])
|
])
|
||||||
has_added_grpc_deps = True
|
has_added_grpc_deps = True
|
||||||
elif dep.startswith("//"):
|
elif dep.startswith("//") or dep.startswith("@npm//"):
|
||||||
output_deps.append(dep)
|
output_deps.append(dep)
|
||||||
else:
|
else:
|
||||||
output_deps.append("@npm//" + dep)
|
output_deps.append("@npm//" + dep)
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
"react": "16.13.1",
|
"react": "16.13.1",
|
||||||
"react-dom": "16.13.1",
|
"react-dom": "16.13.1",
|
||||||
"react-icons": "^3.11.0",
|
"react-icons": "^3.11.0",
|
||||||
|
"react-tooltip": "^4.2.10",
|
||||||
"styled-components": "^5.2.0"
|
"styled-components": "^5.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
load("//:hack/react.bzl", "react_library")
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
load("//:hack/jest.bzl", "jest_test")
|
||||||
|
|
||||||
package(default_visibility = ["//visibility:public"])
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
@ -14,3 +15,7 @@ react_library(
|
||||||
"@types/styled-components",
|
"@types/styled-components",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
jest_test(
|
||||||
|
src = ":tab-view",
|
||||||
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@ load("//:hack/jest.bzl", "jest_test")
|
||||||
package(default_visibility = ["//visibility:public"])
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
react_library(
|
react_library(
|
||||||
name = "timings",
|
name = "typist",
|
||||||
deps = [
|
deps = [
|
||||||
"react",
|
"react",
|
||||||
"@types/react",
|
"@types/react",
|
||||||
|
@ -12,5 +12,5 @@ react_library(
|
||||||
)
|
)
|
||||||
|
|
||||||
jest_test(
|
jest_test(
|
||||||
src = ":timings",
|
src = ":typist",
|
||||||
)
|
)
|
||||||
|
|
16
src/design-system/molecules/demo-discord/BUILD.bazel
Normal file
16
src/design-system/molecules/demo-discord/BUILD.bazel
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "demo-discord",
|
||||||
|
deps = [
|
||||||
|
"react",
|
||||||
|
"styled-components",
|
||||||
|
"//src/design-system/atoms/colors",
|
||||||
|
"//src/design-system/atoms/typist",
|
||||||
|
"//src/design-system/shared-types",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,8 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { DemoDiscord } from './DemoDiscord';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules/Role Demos',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Discord = () => <DemoDiscord />;
|
|
@ -1,7 +0,0 @@
|
||||||
import { moleculeStories } from 'molecules/molecules.story';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { DemoDiscord } from './DemoDiscord';
|
|
||||||
|
|
||||||
const story = moleculeStories('Landing Demos', module);
|
|
||||||
|
|
||||||
story.add('Discord', () => <DemoDiscord />);
|
|
|
@ -1,5 +1,6 @@
|
||||||
import styled, { keyframes } from 'styled-components';
|
import styled, { keyframes } from 'styled-components';
|
||||||
import { palette } from 'atoms/colors';
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
|
|
||||||
export const Base = styled.div`
|
export const Base = styled.div`
|
||||||
background-color: ${palette.discord100};
|
background-color: ${palette.discord100};
|
||||||
|
|
|
@ -8,8 +8,8 @@ import {
|
||||||
Line,
|
Line,
|
||||||
InputTextAlignment,
|
InputTextAlignment,
|
||||||
} from './DemoDiscord.styled';
|
} from './DemoDiscord.styled';
|
||||||
import { demoData } from 'hack/fixtures/demoData';
|
import { demoData } from 'roleypoly/src/design-system/shared-types/demoData';
|
||||||
import { Typist } from 'atoms/typist';
|
import { Typist } from 'roleypoly/src/design-system/atoms/typist';
|
||||||
|
|
||||||
export const DemoDiscord = () => {
|
export const DemoDiscord = () => {
|
||||||
const time = new Date();
|
const time = new Date();
|
||||||
|
|
15
src/design-system/molecules/demo-picker/BUILD.bazel
Normal file
15
src/design-system/molecules/demo-picker/BUILD.bazel
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "demo-picker",
|
||||||
|
deps = [
|
||||||
|
"react",
|
||||||
|
"styled-components",
|
||||||
|
"//src/design-system/atoms/role",
|
||||||
|
"//src/design-system/shared-types",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,8 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { DemoPicker } from './DemoPicker';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules/Role Demos',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Picker = () => <DemoPicker />;
|
|
@ -1,7 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { moleculeStories } from 'molecules/molecules.story';
|
|
||||||
import { DemoPicker } from './DemoPicker';
|
|
||||||
|
|
||||||
const story = moleculeStories('Landing Demos', module);
|
|
||||||
|
|
||||||
story.add('Picker', () => <DemoPicker />);
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Role } from 'atoms/role';
|
import { Role } from 'roleypoly/src/design-system/atoms/role';
|
||||||
import { Role as RPCRole } from '@roleypoly/rpc/shared';
|
import { Role as RPCRole } from 'roleypoly/src/design-system/shared-types';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { demoData } from 'hack/fixtures/demoData';
|
import { demoData } from 'roleypoly/src/design-system/shared-types/demoData';
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -21,7 +21,7 @@ const RoleWrap = styled.div`
|
||||||
export const DemoPicker = () => {
|
export const DemoPicker = () => {
|
||||||
const [selectedStates, setSelectedStates] = React.useState<
|
const [selectedStates, setSelectedStates] = React.useState<
|
||||||
{
|
{
|
||||||
[key in RPCRole.AsObject['id']]: boolean;
|
[key in RPCRole['id']]: boolean;
|
||||||
}
|
}
|
||||||
>(demoData.reduce((acc, role) => ({ ...acc, [role.id]: false }), {}));
|
>(demoData.reduce((acc, role) => ({ ...acc, [role.id]: false }), {}));
|
||||||
|
|
||||||
|
|
17
src/design-system/molecules/footer/BUILD.bazel
Normal file
17
src/design-system/molecules/footer/BUILD.bazel
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "footer",
|
||||||
|
deps = [
|
||||||
|
"react",
|
||||||
|
"react-icons",
|
||||||
|
"styled-components",
|
||||||
|
"//src/design-system/atoms/colors",
|
||||||
|
"//src/design-system/atoms/timings",
|
||||||
|
"//src/design-system/atoms/typography",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
9
src/design-system/molecules/footer/Footer.stories.tsx
Normal file
9
src/design-system/molecules/footer/Footer.stories.tsx
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Footer as FooterComponent } from './Footer';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules',
|
||||||
|
component: FooterComponent,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Footer = (args) => <FooterComponent {...args} />;
|
|
@ -1,7 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { moleculeStories } from 'molecules/molecules.story';
|
|
||||||
import { Footer } from './Footer';
|
|
||||||
|
|
||||||
const story = moleculeStories('Footer', module);
|
|
||||||
|
|
||||||
story.add('Basic', () => <Footer />);
|
|
|
@ -1,6 +1,7 @@
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { palette } from 'atoms/colors';
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
import { transitions } from 'atoms/timings';
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
|
import { transitions } from 'roleypoly/src/design-system/atoms/timings';
|
||||||
|
|
||||||
export const FooterWrapper = styled.div`
|
export const FooterWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { FooterWrapper, HoverColor } from './Footer.styled';
|
import { FooterWrapper, HoverColor } from './Footer.styled';
|
||||||
import { AmbientLarge } from 'atoms/typography';
|
import { AmbientLarge } from 'roleypoly/src/design-system/atoms/typography';
|
||||||
import { FaHeart } from 'react-icons/fa';
|
import { FaHeart } from 'react-icons/fa';
|
||||||
import { Flags } from './Flags';
|
import { Flags } from './Flags';
|
||||||
|
|
||||||
|
|
21
src/design-system/molecules/guild-nav/BUILD.bazel
Normal file
21
src/design-system/molecules/guild-nav/BUILD.bazel
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "guild-nav",
|
||||||
|
deps = [
|
||||||
|
"next",
|
||||||
|
"react",
|
||||||
|
"react-icons",
|
||||||
|
"react-tooltip",
|
||||||
|
"styled-components",
|
||||||
|
"//src/common/utils",
|
||||||
|
"//src/design-system/atoms/colors",
|
||||||
|
"//src/design-system/atoms/timings",
|
||||||
|
"//src/design-system/molecules/nav-slug",
|
||||||
|
"//src/design-system/shared-types",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
21
src/design-system/molecules/guild-nav/GuildNav.stories.tsx
Normal file
21
src/design-system/molecules/guild-nav/GuildNav.stories.tsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { GuildNav } from './GuildNav';
|
||||||
|
import { guildEnum } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||||
|
import { PopoverBase } from 'roleypoly/src/design-system/atoms/popover/Popover.styled';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules/Guild Nav',
|
||||||
|
component: GuildNav,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const HasGuilds = () => (
|
||||||
|
<PopoverBase active>
|
||||||
|
<GuildNav guildEnumeration={guildEnum} />
|
||||||
|
</PopoverBase>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const NoGuilds = () => (
|
||||||
|
<PopoverBase active>
|
||||||
|
<GuildNav guildEnumeration={{ guildsList: [] }} />
|
||||||
|
</PopoverBase>
|
||||||
|
);
|
|
@ -1,18 +0,0 @@
|
||||||
import { moleculeStories } from 'molecules/molecules.story';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { GuildNav } from './GuildNav';
|
|
||||||
import { guildEnum } from 'hack/fixtures/storyData';
|
|
||||||
import { PopoverBase } from 'atoms/popover/Popover.styled';
|
|
||||||
|
|
||||||
const story = moleculeStories('Guild Nav', module);
|
|
||||||
|
|
||||||
story.add('Has Guilds', () => (
|
|
||||||
<PopoverBase active>
|
|
||||||
<GuildNav guildEnumeration={guildEnum} />
|
|
||||||
</PopoverBase>
|
|
||||||
));
|
|
||||||
story.add('No Guilds', () => (
|
|
||||||
<PopoverBase active>
|
|
||||||
<GuildNav guildEnumeration={{ guildsList: [] }} />
|
|
||||||
</PopoverBase>
|
|
||||||
));
|
|
|
@ -1,6 +1,7 @@
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { transitions } from 'atoms/timings';
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
import { palette } from 'atoms/colors';
|
import { transitions } from 'roleypoly/src/design-system/atoms/timings';
|
||||||
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
|
|
||||||
export const GuildNavItem = styled.a`
|
export const GuildNavItem = styled.a`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,21 +1,25 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { NavSlug } from 'molecules/nav-slug';
|
|
||||||
import { sortBy } from 'utils/sortBy';
|
|
||||||
import { GuildEnumeration, PresentableGuild } from '@roleypoly/rpc/platform';
|
|
||||||
import { hasPermission, permissions } from 'utils/hasPermission';
|
|
||||||
import { GoZap, GoStar } from 'react-icons/go';
|
|
||||||
import { Role } from '@roleypoly/rpc/shared';
|
|
||||||
import { GuildNavItem } from './GuildNav.styled';
|
|
||||||
import ReactTooltip from 'react-tooltip';
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { GoStar, GoZap } from 'react-icons/go';
|
||||||
|
import ReactTooltip from 'react-tooltip';
|
||||||
|
import { hasPermission, permissions } from 'roleypoly/src/common/utils/hasPermission';
|
||||||
|
import { sortBy } from 'roleypoly/src/common/utils/sortBy';
|
||||||
|
import {
|
||||||
|
GuildEnumeration,
|
||||||
|
PresentableGuild,
|
||||||
|
Role,
|
||||||
|
Guild,
|
||||||
|
} from 'roleypoly/src/design-system/shared-types';
|
||||||
|
import { NavSlug } from 'roleypoly/src/design-system/molecules/nav-slug';
|
||||||
|
import { GuildNavItem } from './GuildNav.styled';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
guildEnumeration: GuildEnumeration.AsObject;
|
guildEnumeration: GuildEnumeration;
|
||||||
};
|
};
|
||||||
|
|
||||||
const tooltipId = 'guildnav';
|
const tooltipId = 'guildnav';
|
||||||
|
|
||||||
const Badges = (props: { guild: PresentableGuild.AsObject }) => {
|
const Badges = (props: { guild: PresentableGuild }) => {
|
||||||
return React.useMemo(() => {
|
return React.useMemo(() => {
|
||||||
if (!props.guild.member) {
|
if (!props.guild.member) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -29,7 +33,7 @@ const Badges = (props: { guild: PresentableGuild.AsObject }) => {
|
||||||
|
|
||||||
return props.guild.roles.rolesList.find((role) => role.id === id);
|
return props.guild.roles.rolesList.find((role) => role.id === id);
|
||||||
})
|
})
|
||||||
.filter((x) => !!x) as Role.AsObject[];
|
.filter((x) => !!x) as Role[];
|
||||||
|
|
||||||
if (hasPermission(roles, permissions.ADMINISTRATOR)) {
|
if (hasPermission(roles, permissions.ADMINISTRATOR)) {
|
||||||
return <GoStar data-tip="Administrator" data-for={tooltipId} />;
|
return <GoStar data-tip="Administrator" data-for={tooltipId} />;
|
||||||
|
@ -45,13 +49,7 @@ const Badges = (props: { guild: PresentableGuild.AsObject }) => {
|
||||||
|
|
||||||
export const GuildNav = (props: Props) => (
|
export const GuildNav = (props: Props) => (
|
||||||
<div>
|
<div>
|
||||||
{sortBy(
|
{sortBy(props.guildEnumeration.guildsList, 'id').map((guild) => (
|
||||||
props.guildEnumeration.guildsList.map((g) => ({
|
|
||||||
...g,
|
|
||||||
nameLower: g.guild?.name.toLowerCase(),
|
|
||||||
})),
|
|
||||||
'nameLower'
|
|
||||||
).map(({ nameLower, ...guild }) => (
|
|
||||||
<Link href={`/s/${guild.id}`} passHref>
|
<Link href={`/s/${guild.id}`} passHref>
|
||||||
<GuildNavItem>
|
<GuildNavItem>
|
||||||
<NavSlug guild={guild.guild || null} key={guild.id} />
|
<NavSlug guild={guild.guild || null} key={guild.id} />
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
import { makeFactory } from '../.storybook/storyHelper';
|
|
||||||
export const moleculeStories = makeFactory('Molecules');
|
|
16
src/design-system/molecules/nav-slug/BUILD.bazel
Normal file
16
src/design-system/molecules/nav-slug/BUILD.bazel
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "nav-slug",
|
||||||
|
deps = [
|
||||||
|
"react",
|
||||||
|
"react-icons",
|
||||||
|
"styled-components",
|
||||||
|
"//src/design-system/atoms/avatar",
|
||||||
|
"//src/design-system/shared-types",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
11
src/design-system/molecules/nav-slug/NavSlug.stories.tsx
Normal file
11
src/design-system/molecules/nav-slug/NavSlug.stories.tsx
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { NavSlug } from './NavSlug';
|
||||||
|
import { guild } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules/Server Slug',
|
||||||
|
component: NavSlug,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Empty = () => <NavSlug guild={null} />;
|
||||||
|
export const Example = () => <NavSlug guild={guild} />;
|
|
@ -1,9 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { moleculeStories } from 'molecules/molecules.story';
|
|
||||||
import { NavSlug } from './NavSlug';
|
|
||||||
import { guild } from 'hack/fixtures/storyData';
|
|
||||||
|
|
||||||
const story = moleculeStories('Server Slug', module);
|
|
||||||
|
|
||||||
story.add('Empty', () => <NavSlug guild={null} />);
|
|
||||||
story.add('Example', () => <NavSlug guild={guild} />);
|
|
|
@ -1,4 +1,5 @@
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
export const SlugContainer = styled.div`
|
export const SlugContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Guild } from '@roleypoly/rpc/shared';
|
import { Guild } from 'roleypoly/src/design-system/shared-types';
|
||||||
import { Avatar, utils } from 'atoms/avatar';
|
import { Avatar, utils } from 'roleypoly/src/design-system/atoms/avatar';
|
||||||
import { SlugContainer, SlugName } from './NavSlug.styled';
|
import { SlugContainer, SlugName } from './NavSlug.styled';
|
||||||
import { GoOrganization } from 'react-icons/go';
|
import { GoOrganization } from 'react-icons/go';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
guild: Guild.AsObject | null;
|
guild: Guild | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const NavSlug = (props: Props) => (
|
export const NavSlug = (props: Props) => (
|
||||||
|
|
17
src/design-system/molecules/picker-category/BUILD.bazel
Normal file
17
src/design-system/molecules/picker-category/BUILD.bazel
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "picker-category",
|
||||||
|
deps = [
|
||||||
|
"react",
|
||||||
|
"react-tooltip",
|
||||||
|
"styled-components",
|
||||||
|
"//src/design-system/atoms/role",
|
||||||
|
"//src/design-system/atoms/typography",
|
||||||
|
"//src/design-system/shared-types",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,38 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import {
|
||||||
|
roleWikiData,
|
||||||
|
roleCategory,
|
||||||
|
mockCategory,
|
||||||
|
} from 'roleypoly/src/design-system/shared-types/storyData';
|
||||||
|
import { PickerCategory } from './PickerCategory';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules/Picker Category',
|
||||||
|
component: PickerCategory,
|
||||||
|
args: {
|
||||||
|
title: 'Pronouns',
|
||||||
|
roles: roleCategory,
|
||||||
|
category: mockCategory,
|
||||||
|
selectedRoles: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Default = (args) => {
|
||||||
|
return <PickerCategory {...args} />;
|
||||||
|
};
|
||||||
|
export const Single = (args) => {
|
||||||
|
return <PickerCategory {...args} type="single" />;
|
||||||
|
};
|
||||||
|
Single.args = {
|
||||||
|
type: 'single',
|
||||||
|
};
|
||||||
|
export const Multi = (args) => {
|
||||||
|
return <PickerCategory {...args} type="single" />;
|
||||||
|
};
|
||||||
|
Multi.args = {
|
||||||
|
type: 'multi',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Wiki = (args) => {
|
||||||
|
return <PickerCategory {...args} wikiMode roleWikiData={roleWikiData} />;
|
||||||
|
};
|
|
@ -1,36 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { moleculeStories } from 'molecules/molecules.story';
|
|
||||||
import { PickerCategory, CategoryProps } from './PickerCategory';
|
|
||||||
import { action } from '@storybook/addon-actions';
|
|
||||||
import { text, optionsKnob } from '@storybook/addon-knobs';
|
|
||||||
import { roleCategory, roleWikiData, mockCategory } from 'hack/fixtures/storyData';
|
|
||||||
|
|
||||||
const stories = moleculeStories('Picker Category', module);
|
|
||||||
|
|
||||||
const data: (mode?: 'single') => CategoryProps = (mode?: 'single') => ({
|
|
||||||
title: text('Title', 'Pronouns'),
|
|
||||||
type: 'multi',
|
|
||||||
roles: roleCategory,
|
|
||||||
wikiMode: false,
|
|
||||||
category: mockCategory,
|
|
||||||
onChange: () => action('onChange'),
|
|
||||||
selectedRoles: optionsKnob<string[]>(
|
|
||||||
'Selected Roles',
|
|
||||||
roleCategory.reduce((acc, x) => ({ ...acc, [x.name]: x.id }), {}),
|
|
||||||
[roleCategory[0].id],
|
|
||||||
{ display: mode === 'single' ? 'select' : 'multi-select' }
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
stories.add('Multi', () => {
|
|
||||||
const d = data();
|
|
||||||
return <PickerCategory {...d} type="multi" />;
|
|
||||||
});
|
|
||||||
stories.add('Single', () => {
|
|
||||||
const d = data('single');
|
|
||||||
return <PickerCategory {...d} type="single" />;
|
|
||||||
});
|
|
||||||
stories.add('Wiki', () => {
|
|
||||||
const d = data();
|
|
||||||
return <PickerCategory {...d} wikiMode roleWikiData={roleWikiData} />;
|
|
||||||
});
|
|
|
@ -1,4 +1,5 @@
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
|
||||||
export const Head = styled.div`
|
export const Head = styled.div`
|
||||||
margin: 7px 5px;
|
margin: 7px 5px;
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Role as RPCRole } from '@roleypoly/rpc/shared';
|
|
||||||
import { Category as RPCCategory } from '@roleypoly/rpc/platform';
|
|
||||||
import { LargeText, AmbientLarge } from 'atoms/typography';
|
|
||||||
import { Role } from 'atoms/role';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
import ReactTooltip from 'react-tooltip';
|
import ReactTooltip from 'react-tooltip';
|
||||||
import { Head, HeadTitle, HeadSub } from './PickerCategory.styled';
|
import { Role } from 'roleypoly/src/design-system/atoms/role';
|
||||||
|
import { AmbientLarge, LargeText } from 'roleypoly/src/design-system/atoms/typography';
|
||||||
|
import {
|
||||||
|
Category as RPCCategory,
|
||||||
|
Role as RPCRole,
|
||||||
|
RoleSafety,
|
||||||
|
} from 'roleypoly/src/design-system/shared-types';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { Head, HeadSub, HeadTitle } from './PickerCategory.styled';
|
||||||
|
|
||||||
export type CategoryProps = {
|
export type CategoryProps = {
|
||||||
title: string;
|
title: string;
|
||||||
roles: RPCRole.AsObject[];
|
roles: RPCRole[];
|
||||||
category: RPCCategory.AsObject;
|
category: RPCCategory;
|
||||||
selectedRoles: string[];
|
selectedRoles: string[];
|
||||||
onChange: (role: RPCRole.AsObject) => (newState: boolean) => void;
|
onChange: (role: RPCRole) => (newState: boolean) => void;
|
||||||
type: 'single' | 'multi';
|
type: 'single' | 'multi';
|
||||||
} & (
|
} & (
|
||||||
| {
|
| {
|
||||||
|
@ -53,7 +56,7 @@ export const PickerCategory = (props: CategoryProps) => (
|
||||||
role={role}
|
role={role}
|
||||||
selected={props.selectedRoles.includes(role.id)}
|
selected={props.selectedRoles.includes(role.id)}
|
||||||
onClick={props.onChange(role)}
|
onClick={props.onChange(role)}
|
||||||
disabled={role.safety !== RPCRole.RoleSafety.SAFE}
|
disabled={role.safety !== RoleSafety.SAFE}
|
||||||
tooltipId={props.category.id}
|
tooltipId={props.category.id}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
17
src/design-system/molecules/preauth-greeting/BUILD.bazel
Normal file
17
src/design-system/molecules/preauth-greeting/BUILD.bazel
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "preauth-greeting",
|
||||||
|
deps = [
|
||||||
|
"react",
|
||||||
|
"styled-components",
|
||||||
|
"//src/design-system/atoms/avatar",
|
||||||
|
"//src/design-system/atoms/space",
|
||||||
|
"//src/design-system/atoms/typography",
|
||||||
|
"//src/design-system/shared-types",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,13 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { PreauthGreeting } from './PreauthGreeting';
|
||||||
|
import { guild } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules/Preauth/Greeting',
|
||||||
|
component: PreauthGreeting,
|
||||||
|
args: {
|
||||||
|
guildSlug: guild,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Greeting = (args) => <PreauthGreeting {...args} />;
|
|
@ -1,8 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { moleculeStories } from '../molecules.story';
|
|
||||||
import { PreauthGreeting } from './PreauthGreeting';
|
|
||||||
import { guild } from 'hack/fixtures/storyData';
|
|
||||||
|
|
||||||
const story = moleculeStories('Preauth', module);
|
|
||||||
|
|
||||||
story.add('Greeting', () => <PreauthGreeting guildSlug={guild} />);
|
|
|
@ -1,12 +1,12 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Avatar, utils as avatarUtils } from 'atoms/avatar';
|
import { Avatar, utils as avatarUtils } from 'roleypoly/src/design-system/atoms/avatar';
|
||||||
import { Guild } from '@roleypoly/rpc/shared';
|
import { Guild } from 'roleypoly/src/design-system/shared-types';
|
||||||
import { AccentTitle } from 'atoms/typography';
|
import { AccentTitle } from 'roleypoly/src/design-system/atoms/typography';
|
||||||
import { Space } from 'atoms/space';
|
import { Space } from 'roleypoly/src/design-system/atoms/space';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
type GreetingProps = {
|
type GreetingProps = {
|
||||||
guildSlug: Guild.AsObject;
|
guildSlug: Guild;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Center = styled.div`
|
const Center = styled.div`
|
||||||
|
@ -14,6 +14,7 @@ const Center = styled.div`
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const PreauthGreeting = (props: GreetingProps) => (
|
export const PreauthGreeting = (props: GreetingProps) => (
|
||||||
|
|
29
src/design-system/molecules/preauth-secret-code/BUILD.bazel
Normal file
29
src/design-system/molecules/preauth-secret-code/BUILD.bazel
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
load("//:hack/jest.bzl", "jest_test")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "preauth-secret-code",
|
||||||
|
deps = [
|
||||||
|
"react",
|
||||||
|
"react-icons",
|
||||||
|
"styled-components",
|
||||||
|
"//src/design-system/atoms/button",
|
||||||
|
"//src/design-system/atoms/fader",
|
||||||
|
"//src/design-system/atoms/space",
|
||||||
|
"//src/design-system/atoms/text-input",
|
||||||
|
"//src/design-system/shared-types",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
jest_test(
|
||||||
|
src = ":preauth-secret-code",
|
||||||
|
deps = [
|
||||||
|
"//src/design-system/atoms/button",
|
||||||
|
"//src/design-system/atoms/fader",
|
||||||
|
"//src/design-system/atoms/text-input",
|
||||||
|
],
|
||||||
|
)
|
|
@ -1,12 +1,12 @@
|
||||||
jest.unmock('atoms/text-input');
|
jest.unmock('roleypoly/src/design-system/atoms/text-input');
|
||||||
jest.unmock('./PreauthSecretCode');
|
jest.unmock('./PreauthSecretCode');
|
||||||
|
|
||||||
import { Button } from 'atoms/button';
|
import { Button } from 'roleypoly/src/design-system/atoms/button';
|
||||||
import { TextInputWithIcon } from 'atoms/text-input';
|
import { TextInputWithIcon } from 'roleypoly/src/design-system/atoms/text-input';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { PreauthSecretCode } from './PreauthSecretCode';
|
import { PreauthSecretCode } from './PreauthSecretCode';
|
||||||
import { FaderOpacity } from 'atoms/fader';
|
import { FaderOpacity } from 'roleypoly/src/design-system/atoms/fader';
|
||||||
|
|
||||||
const value = 'unfathomable fishy sticks';
|
const value = 'unfathomable fishy sticks';
|
||||||
const onSubmit = jest.fn();
|
const onSubmit = jest.fn();
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { PreauthSecretCode } from './PreauthSecretCode';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules/Preauth/Secret Code',
|
||||||
|
component: PreauthSecretCode,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SecretCode = (args) => <PreauthSecretCode {...args} />;
|
|
@ -1,8 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { moleculeStories } from '../molecules.story';
|
|
||||||
import { PreauthSecretCode } from './PreauthSecretCode';
|
|
||||||
import { action } from '@storybook/addon-actions';
|
|
||||||
|
|
||||||
const story = moleculeStories('Preauth', module);
|
|
||||||
|
|
||||||
story.add('Secret Code', () => <PreauthSecretCode onSubmit={action('onSubmit')} />);
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { TextInputWithIcon } from 'atoms/text-input';
|
import { TextInputWithIcon } from 'roleypoly/src/design-system/atoms/text-input';
|
||||||
import { FiKey } from 'react-icons/fi';
|
import { FiKey } from 'react-icons/fi';
|
||||||
import { FaderOpacity } from 'atoms/fader';
|
import { FaderOpacity } from 'roleypoly/src/design-system/atoms/fader';
|
||||||
import { Button } from 'atoms/button';
|
import { Button } from 'roleypoly/src/design-system/atoms/button';
|
||||||
import { Space } from 'atoms/space';
|
import { Space } from 'roleypoly/src/design-system/atoms/space';
|
||||||
|
|
||||||
type PreauthProps = {
|
type PreauthProps = {
|
||||||
onSubmit: (code: string) => void;
|
onSubmit: (code: string) => void;
|
||||||
|
|
24
src/design-system/molecules/reset-submit/BUILD.bazel
Normal file
24
src/design-system/molecules/reset-submit/BUILD.bazel
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
load("//:hack/jest.bzl", "jest_test")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "reset-submit",
|
||||||
|
deps = [
|
||||||
|
"react",
|
||||||
|
"react-icons",
|
||||||
|
"styled-components",
|
||||||
|
"//src/design-system/atoms/breakpoints",
|
||||||
|
"//src/design-system/atoms/button",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
jest_test(
|
||||||
|
src = ":reset-submit",
|
||||||
|
deps = [
|
||||||
|
"//src/design-system/atoms/button",
|
||||||
|
],
|
||||||
|
)
|
|
@ -1,4 +1,4 @@
|
||||||
import { Button } from 'atoms/button';
|
import { Button } from 'roleypoly/src/design-system/atoms/button';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { ResetSubmit } from './ResetSubmit';
|
import { ResetSubmit } from './ResetSubmit';
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { ResetSubmit } from './ResetSubmit';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules',
|
||||||
|
component: ResetSubmit,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ResetAndSubmit = (args) => <ResetSubmit {...args} />;
|
|
@ -1,9 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { moleculeStories } from 'molecules/molecules.story';
|
|
||||||
import { action } from '@storybook/addon-actions';
|
|
||||||
import { ResetSubmit } from './ResetSubmit';
|
|
||||||
const story = moleculeStories('Reset & Submit', module);
|
|
||||||
|
|
||||||
story.add('Reset & Submit', () => (
|
|
||||||
<ResetSubmit onSubmit={action('onSubmit')} onReset={action('onReset')} />
|
|
||||||
));
|
|
|
@ -1,5 +1,6 @@
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { onSmallScreen } from 'atoms/breakpoints';
|
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
|
||||||
|
import { onSmallScreen } from 'roleypoly/src/design-system/atoms/breakpoints';
|
||||||
|
|
||||||
export const Buttons = styled.div`
|
export const Buttons = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { onSmallScreen } from 'atoms/breakpoints';
|
import { onSmallScreen } from 'roleypoly/src/design-system/atoms/breakpoints';
|
||||||
import { Button } from 'atoms/button';
|
import { Button } from 'roleypoly/src/design-system/atoms/button';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { MdRestore } from 'react-icons/md';
|
import { MdRestore } from 'react-icons/md';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
28
src/design-system/molecules/server-masthead/BUILD.bazel
Normal file
28
src/design-system/molecules/server-masthead/BUILD.bazel
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
load("//:hack/jest.bzl", "jest_test")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "server-masthead",
|
||||||
|
deps = [
|
||||||
|
"next",
|
||||||
|
"react",
|
||||||
|
"react-icons",
|
||||||
|
"styled-components",
|
||||||
|
"//src/design-system/atoms/avatar",
|
||||||
|
"//src/design-system/atoms/colors",
|
||||||
|
"//src/design-system/atoms/timings",
|
||||||
|
"//src/design-system/atoms/typography",
|
||||||
|
"//src/design-system/shared-types",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
jest_test(
|
||||||
|
src = ":server-masthead",
|
||||||
|
deps = [
|
||||||
|
"//src/design-system/shared-types",
|
||||||
|
],
|
||||||
|
)
|
|
@ -3,7 +3,7 @@ jest.unmock('./ServerMasthead');
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import { ServerMasthead } from './ServerMasthead';
|
import { ServerMasthead } from './ServerMasthead';
|
||||||
import { guild } from 'hack/fixtures/storyData';
|
import { guild } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||||
import { Editable } from './ServerMasthead.styled';
|
import { Editable } from './ServerMasthead.styled';
|
||||||
|
|
||||||
it('shows Edit Server when editable is true', () => {
|
it('shows Edit Server when editable is true', () => {
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { ServerMasthead } from './ServerMasthead';
|
||||||
|
import { guild } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules/Server Masthead',
|
||||||
|
args: {
|
||||||
|
editable: false,
|
||||||
|
guild,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Default = (args) => <ServerMasthead {...args} />;
|
||||||
|
export const Editable = (args) => <ServerMasthead {...args} />;
|
||||||
|
Editable.args = {
|
||||||
|
editable: true,
|
||||||
|
};
|
|
@ -1,9 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { moleculeStories } from 'molecules/molecules.story';
|
|
||||||
import { ServerMasthead } from './ServerMasthead';
|
|
||||||
import { guild } from 'hack/fixtures/storyData';
|
|
||||||
|
|
||||||
const story = moleculeStories('Server Masthead', module);
|
|
||||||
|
|
||||||
story.add('Default', () => <ServerMasthead guild={guild} editable={false} />);
|
|
||||||
story.add('Editable', () => <ServerMasthead guild={guild} editable={true} />);
|
|
|
@ -1,6 +1,6 @@
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { palette } from 'atoms/colors';
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
import { transitions } from 'atoms/timings';
|
import { transitions } from 'roleypoly/src/design-system/atoms/timings';
|
||||||
|
|
||||||
export const Wrapper = styled.div`
|
export const Wrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { Guild } from '@roleypoly/rpc/shared';
|
import { Guild } from 'roleypoly/src/design-system/shared-types';
|
||||||
import { Avatar, utils } from 'atoms/avatar';
|
import { Avatar, utils } from 'roleypoly/src/design-system/atoms/avatar';
|
||||||
import { AccentTitle, AmbientLarge } from 'atoms/typography';
|
import { AccentTitle, AmbientLarge } from 'roleypoly/src/design-system/atoms/typography';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { guild } from 'hack/fixtures/storyData';
|
import { guild } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { GoPencil } from 'react-icons/go';
|
import { GoPencil } from 'react-icons/go';
|
||||||
import { Editable, Icon, Name, Wrapper } from './ServerMasthead.styled';
|
import { Editable, Icon, Name, Wrapper } from './ServerMasthead.styled';
|
||||||
|
|
||||||
export type ServerMastheadProps = {
|
export type ServerMastheadProps = {
|
||||||
guild: Guild.AsObject;
|
guild: Guild;
|
||||||
editable: boolean;
|
editable: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
17
src/design-system/molecules/user-avatar-group/BUILD.bazel
Normal file
17
src/design-system/molecules/user-avatar-group/BUILD.bazel
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "user-avatar-group",
|
||||||
|
deps = [
|
||||||
|
"react",
|
||||||
|
"styled-components",
|
||||||
|
"//src/design-system/atoms/avatar",
|
||||||
|
"//src/design-system/atoms/breakpoints",
|
||||||
|
"//src/design-system/atoms/colors",
|
||||||
|
"//src/design-system/shared-types",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,19 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { UserAvatarGroup } from './UserAvatarGroup';
|
||||||
|
import { user } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||||
|
import { Hero } from 'roleypoly/src/design-system/atoms/hero';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules/User Avatar Group',
|
||||||
|
component: UserAvatarGroup,
|
||||||
|
args: {
|
||||||
|
user,
|
||||||
|
preventCollapse: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Default = (args) => (
|
||||||
|
<Hero>
|
||||||
|
<UserAvatarGroup {...args} />
|
||||||
|
</Hero>
|
||||||
|
);
|
|
@ -1,13 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import { moleculeStories } from 'molecules/molecules.story';
|
|
||||||
import { UserAvatarGroup } from './UserAvatarGroup';
|
|
||||||
import { user } from 'hack/fixtures/storyData';
|
|
||||||
import { Hero } from 'atoms/hero';
|
|
||||||
|
|
||||||
const story = moleculeStories('User Avatar Group', module);
|
|
||||||
|
|
||||||
story.add('Default', () => (
|
|
||||||
<Hero>
|
|
||||||
<UserAvatarGroup user={user} />
|
|
||||||
</Hero>
|
|
||||||
));
|
|
|
@ -1,6 +1,6 @@
|
||||||
import styled, { css } from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
import { onSmallScreen } from 'atoms/breakpoints';
|
import { onSmallScreen } from 'roleypoly/src/design-system/atoms/breakpoints';
|
||||||
import { palette } from 'atoms/colors';
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
|
|
||||||
export const Collapse = styled.div<{ preventCollapse: boolean }>`
|
export const Collapse = styled.div<{ preventCollapse: boolean }>`
|
||||||
${(props) =>
|
${(props) =>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { DiscordUser } from '@roleypoly/rpc/shared';
|
import { DiscordUser } from 'roleypoly/src/design-system/shared-types';
|
||||||
import { utils, Avatar } from 'atoms/avatar';
|
import { utils, Avatar } from 'roleypoly/src/design-system/atoms/avatar';
|
||||||
import { Group, Collapse, Discriminator, GroupText } from './UserAvatarGroup.styled';
|
import { Group, Collapse, Discriminator, GroupText } from './UserAvatarGroup.styled';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
user: DiscordUser.AsObject;
|
user: DiscordUser;
|
||||||
preventCollapse?: boolean;
|
preventCollapse?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
20
src/design-system/molecules/user-popover/BUILD.bazel
Normal file
20
src/design-system/molecules/user-popover/BUILD.bazel
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
load("//:hack/react.bzl", "react_library")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
react_library(
|
||||||
|
name = "user-popover",
|
||||||
|
deps = [
|
||||||
|
"next",
|
||||||
|
"react",
|
||||||
|
"react-icons",
|
||||||
|
"styled-components",
|
||||||
|
"//src/design-system/atoms/breakpoints",
|
||||||
|
"//src/design-system/atoms/colors",
|
||||||
|
"//src/design-system/atoms/timings",
|
||||||
|
"//src/design-system/molecules/user-avatar-group",
|
||||||
|
"//src/design-system/shared-types",
|
||||||
|
"@types/react",
|
||||||
|
"@types/styled-components",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { user } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { UserPopover as UserPopoverComponent } from './UserPopover';
|
||||||
|
import { PopoverBase } from 'roleypoly/src/design-system/atoms/popover/Popover.styled';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Molecules/User Popover',
|
||||||
|
component: UserPopoverComponent,
|
||||||
|
args: {
|
||||||
|
user,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const UserPopover = (args) => (
|
||||||
|
<PopoverBase active>
|
||||||
|
<UserPopoverComponent {...args} />
|
||||||
|
</PopoverBase>
|
||||||
|
);
|
|
@ -1,13 +0,0 @@
|
||||||
import { user } from 'hack/fixtures/storyData';
|
|
||||||
import { moleculeStories } from 'molecules/molecules.story';
|
|
||||||
import * as React from 'react';
|
|
||||||
import { UserPopover } from './UserPopover';
|
|
||||||
import { PopoverBase } from 'atoms/popover/Popover.styled';
|
|
||||||
|
|
||||||
const story = moleculeStories('User Popover', module);
|
|
||||||
|
|
||||||
story.add('User Popover', () => (
|
|
||||||
<PopoverBase active>
|
|
||||||
<UserPopover user={user} />
|
|
||||||
</PopoverBase>
|
|
||||||
));
|
|
|
@ -1,6 +1,6 @@
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { palette } from 'atoms/colors';
|
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||||
import { transitions } from 'atoms/timings';
|
import { transitions } from 'roleypoly/src/design-system/atoms/timings';
|
||||||
|
|
||||||
export const Base = styled.div`
|
export const Base = styled.div`
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { DiscordUser } from '@roleypoly/rpc/shared';
|
import { DiscordUser } from 'roleypoly/src/design-system/shared-types';
|
||||||
import { UserAvatarGroup } from 'molecules/user-avatar-group';
|
import { UserAvatarGroup } from 'roleypoly/src/design-system/molecules/user-avatar-group';
|
||||||
import { Base, NavAction } from './UserPopover.styled';
|
import { Base, NavAction } from './UserPopover.styled';
|
||||||
import { GoGear, GoSignOut } from 'react-icons/go';
|
import { GoGear, GoSignOut } from 'react-icons/go';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
type UserPopoverProps = {
|
type UserPopoverProps = {
|
||||||
user: DiscordUser.AsObject;
|
user: DiscordUser;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const UserPopover = (props: UserPopoverProps) => (
|
export const UserPopover = (props: UserPopoverProps) => (
|
||||||
|
|
|
@ -23,12 +23,14 @@ export type GuildData = {
|
||||||
entitlementsList: string[];
|
entitlementsList: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type GuildEnumeration = {
|
export type PresentableGuild = {
|
||||||
guildsList: {
|
id: string;
|
||||||
id: string;
|
guild: Guild;
|
||||||
guild: Guild;
|
member: Member;
|
||||||
member: Member;
|
data: GuildData;
|
||||||
data: GuildData;
|
roles: GuildRoles;
|
||||||
roles: GuildRoles;
|
};
|
||||||
}[];
|
|
||||||
|
export type GuildEnumeration = {
|
||||||
|
guildsList: PresentableGuild[];
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Role } from 'roleypoly/src/rpc/shared';
|
import { Role } from '.';
|
||||||
|
|
||||||
export const demoData: Role.AsObject[] = [
|
export const demoData: Role[] = [
|
||||||
{
|
{
|
||||||
id: '557812805546541066',
|
id: '557812805546541066',
|
||||||
name: 'a cute role ♡',
|
name: 'a cute role ♡',
|
13
yarn.lock
13
yarn.lock
|
@ -10907,6 +10907,14 @@ react-textarea-autosize@^8.1.1:
|
||||||
use-composed-ref "^1.0.0"
|
use-composed-ref "^1.0.0"
|
||||||
use-latest "^1.0.0"
|
use-latest "^1.0.0"
|
||||||
|
|
||||||
|
react-tooltip@^4.2.10:
|
||||||
|
version "4.2.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-4.2.10.tgz#ed1a1acd388940c96f4b6309f4fd4dcce5e01bdc"
|
||||||
|
integrity sha512-D7ZLx6/QwpUl0SZRek3IZy/HWpsEEp0v3562tcT8IwZgu8IgV7hY5ZzniTkHyRcuL+IQnljpjj7A7zCgl2+T3w==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
uuid "^7.0.3"
|
||||||
|
|
||||||
react@16.13.1, react@^16.8.3:
|
react@16.13.1, react@^16.8.3:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
|
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
|
||||||
|
@ -13259,6 +13267,11 @@ uuid@^3.1.0, uuid@^3.3.2:
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||||
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||||
|
|
||||||
|
uuid@^7.0.3:
|
||||||
|
version "7.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b"
|
||||||
|
integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==
|
||||||
|
|
||||||
uuid@^8.0.0, uuid@^8.3.0:
|
uuid@^8.0.0, uuid@^8.3.0:
|
||||||
version "8.3.1"
|
version "8.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31"
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31"
|
||||||
|
|
Loading…
Add table
Reference in a new issue