mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-04-24 19:39:11 +00:00
feat(design-system): port molecules
This commit is contained in:
parent
35e4c94e56
commit
b3c384421b
41 changed files with 447 additions and 187 deletions
|
@ -13,6 +13,7 @@ DEFAULT_DEPS = [
|
|||
"@npm//jest-environment-enzyme",
|
||||
"@npm//jsdom",
|
||||
"@npm//jest",
|
||||
"@npm//@types/jest",
|
||||
"@npm//jest-enzyme",
|
||||
"@npm//jest-styled-components",
|
||||
"@npm//enzyme-to-json",
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"lint:prettier": "cross-env prettier -c '**/*.{ts,tsx,css,yml,yaml,md,json,js,jsx,sh,gitignore,mdx}'",
|
||||
"lint:stylelint": "cross-env stylelint '**/*.{ts,tsx}'",
|
||||
"now-build": "run-s storybook:build",
|
||||
"storybook": "start-storybook -p 6006",
|
||||
"storybook": "start-storybook -p 6006 --no-dll",
|
||||
"storybook:build": "build-storybook",
|
||||
"test": "jest"
|
||||
},
|
||||
|
@ -29,6 +29,7 @@
|
|||
"google-protobuf": "^3.13.0",
|
||||
"next": "^9.5.5",
|
||||
"react": "^17.0.1",
|
||||
"react-custom-scrollbars": "^4.2.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-icons": "^3.11.0",
|
||||
"react-tooltip": "^4.2.10",
|
||||
|
@ -51,6 +52,7 @@
|
|||
"@types/minimist": "^1.2.0",
|
||||
"@types/node": "^14.14.2",
|
||||
"@types/react": "^16.9.53",
|
||||
"@types/react-custom-scrollbars": "^4.0.7",
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"@types/styled-components": "^5.1.4",
|
||||
"@typescript-eslint/eslint-plugin": "^4.5.0",
|
||||
|
@ -87,4 +89,4 @@
|
|||
"tsconfig-paths-webpack-plugin": "^3.3.0",
|
||||
"typescript": "^4.0.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
16
src/design-system/molecules/error-banner/BUILD.bazel
Normal file
16
src/design-system/molecules/error-banner/BUILD.bazel
Normal file
|
@ -0,0 +1,16 @@
|
|||
load("//hack/bazel/js:react.bzl", "react_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
react_library(
|
||||
name = "error-banner",
|
||||
deps = [
|
||||
"react",
|
||||
"styled-components",
|
||||
"//src/design-system/atoms/breakpoints",
|
||||
"//src/design-system/atoms/colors",
|
||||
"//src/design-system/atoms/typography",
|
||||
"@types/react",
|
||||
"@types/styled-components",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,26 @@
|
|||
import * as React from 'react';
|
||||
import { ErrorBanner } from './ErrorBanner';
|
||||
|
||||
export default {
|
||||
title: 'Molecules/Error Banner',
|
||||
argTypes: {
|
||||
english: { control: 'text' },
|
||||
japanese: { control: 'text' },
|
||||
friendlyCode: { control: 'text' },
|
||||
},
|
||||
args: {
|
||||
english: 'Oh no! I lost it!',
|
||||
japanese: 'ちょっとにんげんだよ',
|
||||
friendlyCode: '404',
|
||||
},
|
||||
};
|
||||
|
||||
export const ErrorBanner_ = ({ english, japanese, friendlyCode }) => (
|
||||
<ErrorBanner
|
||||
message={{
|
||||
english,
|
||||
japanese,
|
||||
friendlyCode,
|
||||
}}
|
||||
/>
|
||||
);
|
|
@ -1,6 +1,7 @@
|
|||
import { onSmallScreen } from 'roleypoly/src/design-system/atoms/breakpoints';
|
||||
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||
import { text300, text500, text700 } from 'roleypoly/src/design-system/atoms/typography';
|
||||
import * as _ from 'styled-components'; // eslint-disable-line no-duplicate-imports
|
||||
import styled, { css } from 'styled-components';
|
||||
|
||||
export const ErrorWrapper = styled.div`
|
|
@ -6,7 +6,12 @@ import {
|
|||
ErrorText,
|
||||
ErrorTextLower,
|
||||
} from './ErrorBanner.styled';
|
||||
import { ErrorMessage } from 'templates/errors/errorStrings';
|
||||
|
||||
export type ErrorMessage = {
|
||||
english: string;
|
||||
japanese?: string;
|
||||
friendlyCode?: string;
|
||||
};
|
||||
|
||||
type ErrorBannerProps = {
|
||||
message: Required<ErrorMessage>;
|
|
@ -0,0 +1,14 @@
|
|||
import * as React from 'react';
|
||||
import { HelpStoryWrapper } from './storyDecorator';
|
||||
|
||||
export default {
|
||||
title: 'Molecules/Help Page',
|
||||
decorators: [HelpStoryWrapper],
|
||||
};
|
||||
|
||||
export const Base = () => (
|
||||
<>
|
||||
<h1>What is the world but vibrations?</h1>
|
||||
<p>Vibrations that synchronize and tie it together, running free forever.</p>
|
||||
</>
|
||||
);
|
|
@ -1,5 +1,6 @@
|
|||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import * as _ from 'styled-components'; // eslint-disable-line no-duplicate-imports
|
||||
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||
|
||||
export type HelpPageProps = {
|
|
@ -0,0 +1,9 @@
|
|||
import * as React from 'react';
|
||||
import { HelpPageBase } from './HelpPageBase';
|
||||
import { Content } from 'roleypoly/src/design-system/organisms/app-shell/AppShell.styled';
|
||||
|
||||
export const HelpStoryWrapper = (storyFn: any): React.ReactNode => (
|
||||
<Content>
|
||||
<HelpPageBase>{storyFn()}</HelpPageBase>
|
||||
</Content>
|
||||
);
|
|
@ -1,18 +1,20 @@
|
|||
import * as React from 'react';
|
||||
import { organismStories } from 'roleypoly/src/design-system/organisms/organisms.story';
|
||||
import { AppShell } from './AppShell';
|
||||
import { rpUser, guildEnum } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||
|
||||
const story = organismStories('App Shell', module);
|
||||
export default {
|
||||
title: 'Organisms/App Shell',
|
||||
component: AppShell,
|
||||
};
|
||||
|
||||
story.add('Guest', () => (
|
||||
export const Guest = () => (
|
||||
<AppShell showFooter user={null}>
|
||||
<h1>Hello World</h1>
|
||||
</AppShell>
|
||||
));
|
||||
);
|
||||
|
||||
story.add('Logged In', () => (
|
||||
export const LoggedIn = () => (
|
||||
<AppShell user={rpUser} guildEnumeration={guildEnum}>
|
||||
<h1>Hello World</h1>
|
||||
</AppShell>
|
||||
));
|
||||
);
|
|
@ -1,5 +1,6 @@
|
|||
import styled, { createGlobalStyle } from 'styled-components';
|
||||
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||
import * as _ from 'styled-components'; // eslint-disable-line no-duplicate-imports
|
||||
|
||||
export const Content = styled.div<{ small?: boolean }>`
|
||||
margin: 0 auto;
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
import * as React from 'react';
|
||||
import * as Masthead from 'roleypoly/src/design-system/organisms/masthead';
|
||||
import { RoleypolyUser } from '@roleypoly/rpc/shared';
|
||||
import {
|
||||
RoleypolyUser,
|
||||
GuildEnumeration,
|
||||
} from 'roleypoly/src/design-system/shared-types';
|
||||
import { Footer } from 'roleypoly/src/design-system/molecules/footer';
|
||||
import { Content, GlobalStyles } from './AppShell.styled';
|
||||
import { GlobalStyleColors } from 'roleypoly/src/design-system/atoms/colors';
|
||||
import { GuildEnumeration } from '@roleypoly/rpc/platform';
|
||||
import { Scrollbars } from 'react-custom-scrollbars';
|
||||
|
||||
type AppShellProps = {
|
||||
children: React.ReactNode;
|
||||
user: RoleypolyUser.AsObject | null;
|
||||
user: RoleypolyUser | null;
|
||||
showFooter?: boolean;
|
||||
small?: boolean;
|
||||
activeGuildId?: string | null;
|
||||
guildEnumeration?: GuildEnumeration.AsObject;
|
||||
guildEnumeration?: GuildEnumeration;
|
||||
};
|
||||
|
||||
export const AppShell = (props: AppShellProps) => (
|
||||
|
|
19
src/design-system/organisms/app-shell/BUILD.bazel
Normal file
19
src/design-system/organisms/app-shell/BUILD.bazel
Normal file
|
@ -0,0 +1,19 @@
|
|||
load("//hack/bazel/js:react.bzl", "react_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
react_library(
|
||||
name = "app-shell",
|
||||
deps = [
|
||||
"react",
|
||||
"react-custom-scrollbars",
|
||||
"styled-components",
|
||||
"//src/design-system/atoms/colors",
|
||||
"//src/design-system/molecules/footer",
|
||||
"//src/design-system/organisms/masthead",
|
||||
"//src/design-system/shared-types",
|
||||
"@types/react",
|
||||
"@types/react-custom-scrollbars",
|
||||
"@types/styled-components",
|
||||
],
|
||||
)
|
|
@ -1,16 +0,0 @@
|
|||
import * as React from 'react';
|
||||
import { organismStories } from 'roleypoly/src/design-system/organisms/organisms.story';
|
||||
import { ErrorBanner } from './ErrorBanner';
|
||||
import { text } from '@storybook/addon-knobs';
|
||||
|
||||
const story = organismStories('Error Banner', module);
|
||||
|
||||
story.add('Error Banner', () => (
|
||||
<ErrorBanner
|
||||
message={{
|
||||
english: text('English', 'Primary Text'),
|
||||
japanese: text('Japanese (Subtext)', 'Subtext'),
|
||||
friendlyCode: text('Friendly Code', 'Oops!'),
|
||||
}}
|
||||
/>
|
||||
));
|
|
@ -1,19 +0,0 @@
|
|||
import * as React from 'react';
|
||||
import { organismStories } from 'roleypoly/src/design-system/organisms/organisms.story';
|
||||
import { HelpPageBase } from './HelpPageBase';
|
||||
import { Content } from 'roleypoly/src/design-system/organisms/app-shell/AppShell.styled';
|
||||
|
||||
const baseStory = organismStories('Help Pages', module);
|
||||
|
||||
export const HelpStoryWrapper = (props: { children: React.ReactNode }) => (
|
||||
<Content>
|
||||
<HelpPageBase>{props.children}</HelpPageBase>
|
||||
</Content>
|
||||
);
|
||||
|
||||
baseStory.add('Base', () => (
|
||||
<HelpStoryWrapper>
|
||||
<h1>What is the world but vibrations?</h1>
|
||||
<p>Vibrations that synchronize and tie it together, running free forever.</p>
|
||||
</HelpStoryWrapper>
|
||||
));
|
20
src/design-system/organisms/help-why-no-roles/BUILD.bazel
Normal file
20
src/design-system/organisms/help-why-no-roles/BUILD.bazel
Normal file
|
@ -0,0 +1,20 @@
|
|||
load("//hack/bazel/js:react.bzl", "react_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
react_library(
|
||||
name = "help-why-no-roles",
|
||||
deps = [
|
||||
"chroma-js",
|
||||
"react",
|
||||
"react-icons",
|
||||
"styled-components",
|
||||
"//src/design-system/atoms/colors",
|
||||
"//src/design-system/atoms/halfsies",
|
||||
"//src/design-system/atoms/sparkle",
|
||||
"//src/design-system/shared-types",
|
||||
"@types/chroma-js",
|
||||
"@types/react",
|
||||
"@types/styled-components",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,10 @@
|
|||
import { WhyNoRoles } from './WhyNoRoles';
|
||||
import * as React from 'react';
|
||||
import { HelpStoryWrapper } from '../../molecules/help-page-base/storyDecorator';
|
||||
|
||||
export default {
|
||||
title: 'Organisms/Help Pages',
|
||||
decorators: [HelpStoryWrapper],
|
||||
};
|
||||
|
||||
export const WhyNoRoles_ = () => <WhyNoRoles />;
|
|
@ -1,10 +0,0 @@
|
|||
import { WhyNoRoles } from './WhyNoRoles';
|
||||
import * as React from 'react';
|
||||
import { organismStories } from 'roleypoly/src/design-system/organisms/organisms.story';
|
||||
import { HelpStoryWrapper } from 'roleypoly/src/design-system/organisms/help-page-base/HelpPageBase.story';
|
||||
|
||||
organismStories('Help Pages/Pages', module).add('Why No Roles', () => (
|
||||
<HelpStoryWrapper>
|
||||
<WhyNoRoles />
|
||||
</HelpStoryWrapper>
|
||||
));
|
|
@ -1,6 +1,7 @@
|
|||
import styled, { css } from 'styled-components';
|
||||
import { palette, numberToChroma } from 'roleypoly/src/design-system/atoms/colors';
|
||||
import { Role } from '@roleypoly/rpc/shared';
|
||||
import { Role } from 'roleypoly/src/design-system/shared-types';
|
||||
import * as _ from 'styled-components'; // eslint-disable-line no-duplicate-imports
|
||||
|
||||
export const DiscordBase = styled.div`
|
||||
background-color: ${palette.discord100};
|
||||
|
@ -18,7 +19,7 @@ const hover = (roleColor: string) => css`
|
|||
`;
|
||||
|
||||
export const DiscordRole = styled.div<{
|
||||
discordRole: Role.AsObject;
|
||||
discordRole: Role;
|
||||
isRoleypoly: boolean;
|
||||
}>`
|
||||
padding: 6px 10px;
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import chroma from 'chroma-js';
|
||||
import * as React from 'react';
|
||||
import { FaCheck, FaTimes } from 'react-icons/fa';
|
||||
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||
import {
|
||||
HalfsiesContainer,
|
||||
HalfsiesItem,
|
||||
} from 'roleypoly/src/design-system/atoms/halfsies';
|
||||
import { FaCheck, FaTimes } from 'react-icons/fa';
|
||||
import { DiscordBase, DiscordRole } from './WhyNoRoles.styled';
|
||||
import { demoData } from 'roleypoly/src/design-system/shared-types/demoData';
|
||||
import { Role } from '@roleypoly/rpc/shared';
|
||||
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||
import chroma from 'chroma-js';
|
||||
import { SparkleOverlay } from 'roleypoly/src/design-system/atoms/sparkle';
|
||||
import { Role } from 'roleypoly/src/design-system/shared-types';
|
||||
import { demoData } from 'roleypoly/src/design-system/shared-types/demoData';
|
||||
import { DiscordBase, DiscordRole } from './WhyNoRoles.styled';
|
||||
|
||||
const adminRoles: Role.AsObject[] = [
|
||||
const adminRoles: Role[] = [
|
||||
{
|
||||
id: 'roley2',
|
||||
name: 'Admin',
|
||||
|
@ -32,7 +32,7 @@ const adminRoles: Role.AsObject[] = [
|
|||
},
|
||||
];
|
||||
|
||||
const roleypolyRole: Role.AsObject = {
|
||||
const roleypolyRole: Role = {
|
||||
id: 'roley',
|
||||
name: 'Roleypoly',
|
||||
permissions: 0,
|
||||
|
@ -58,7 +58,7 @@ const MaybeWithOverlay = (props: { children: React.ReactNode; withOverlay: boole
|
|||
}
|
||||
};
|
||||
|
||||
const Example = (props: { roles: Role.AsObject[]; isGood: boolean }) => (
|
||||
const Example = (props: { roles: Role[]; isGood: boolean }) => (
|
||||
<div>
|
||||
<DiscordBase>
|
||||
{props.roles.map((r) => (
|
||||
|
|
21
src/design-system/organisms/landing/BUILD.bazel
Normal file
21
src/design-system/organisms/landing/BUILD.bazel
Normal file
|
@ -0,0 +1,21 @@
|
|||
load("//hack/bazel/js:react.bzl", "react_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
react_library(
|
||||
name = "landing",
|
||||
deps = [
|
||||
"react",
|
||||
"react-icons",
|
||||
"styled-components",
|
||||
"//src/design-system/atoms/breakpoints",
|
||||
"//src/design-system/atoms/colors",
|
||||
"//src/design-system/atoms/halfsies",
|
||||
"//src/design-system/atoms/space",
|
||||
"//src/design-system/atoms/typography",
|
||||
"//src/design-system/molecules/demo-discord",
|
||||
"//src/design-system/molecules/demo-picker",
|
||||
"@types/react",
|
||||
"@types/styled-components",
|
||||
],
|
||||
)
|
8
src/design-system/organisms/landing/Landing.stories.tsx
Normal file
8
src/design-system/organisms/landing/Landing.stories.tsx
Normal file
|
@ -0,0 +1,8 @@
|
|||
import * as React from 'react';
|
||||
import { Landing } from './Landing';
|
||||
|
||||
export default {
|
||||
title: 'Organisms/Landing',
|
||||
};
|
||||
|
||||
export const Landing_ = () => <Landing />;
|
|
@ -1,7 +0,0 @@
|
|||
import * as React from 'react';
|
||||
import { organismStories } from 'roleypoly/src/design-system/organisms/organisms.story';
|
||||
import { Landing } from './Landing';
|
||||
|
||||
const story = organismStories('Landing', module);
|
||||
|
||||
story.add('Landing', () => <Landing />);
|
|
@ -1,6 +1,7 @@
|
|||
import { onTablet } from 'roleypoly/src/design-system/atoms/breakpoints';
|
||||
import { text400 } from 'roleypoly/src/design-system/atoms/typography';
|
||||
import styled, { css } from 'styled-components';
|
||||
import * as _ from 'styled-components'; // eslint-disable-line no-duplicate-imports
|
||||
|
||||
export const HeroText = styled.div`
|
||||
${onTablet(css`
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
import { GuildEnumeration } from '@roleypoly/rpc/platform';
|
||||
import { RoleypolyUser } from '@roleypoly/rpc/shared';
|
||||
import Link from 'next/link';
|
||||
import * as React from 'react';
|
||||
import { GoOrganization } from 'react-icons/go';
|
||||
import {
|
||||
RoleypolyUser,
|
||||
GuildEnumeration,
|
||||
} from 'roleypoly/src/design-system/shared-types';
|
||||
import { Logomark } from 'roleypoly/src/design-system/atoms/branding';
|
||||
import { Popover } from 'roleypoly/src/design-system/atoms/popover';
|
||||
import { guildEnum } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||
import { GuildNav } from 'roleypoly/src/design-system/molecules/guild-nav';
|
||||
import { NavSlug } from 'roleypoly/src/design-system/molecules/nav-slug';
|
||||
import { UserAvatarGroup } from 'roleypoly/src/design-system/molecules/user-avatar-group';
|
||||
import { UserPopover } from 'roleypoly/src/design-system/molecules/user-popover';
|
||||
import Link from 'next/link';
|
||||
import * as React from 'react';
|
||||
import { GoOrganization } from 'react-icons/go';
|
||||
import { guildEnum } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||
import {
|
||||
GuildPopoverHead,
|
||||
InteractionBase,
|
||||
|
@ -21,9 +23,9 @@ import {
|
|||
} from './Masthead.styled';
|
||||
|
||||
type Props = {
|
||||
user: RoleypolyUser.AsObject;
|
||||
user: RoleypolyUser;
|
||||
activeGuildId: string | null;
|
||||
guildEnumeration: GuildEnumeration.AsObject;
|
||||
guildEnumeration: GuildEnumeration;
|
||||
};
|
||||
|
||||
export const Authed = (props: Props) => {
|
||||
|
|
26
src/design-system/organisms/masthead/BUILD.bazel
Normal file
26
src/design-system/organisms/masthead/BUILD.bazel
Normal file
|
@ -0,0 +1,26 @@
|
|||
load("//hack/bazel/js:react.bzl", "react_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
react_library(
|
||||
name = "masthead",
|
||||
deps = [
|
||||
"next",
|
||||
"react",
|
||||
"react-icons",
|
||||
"styled-components",
|
||||
"//src/design-system/atoms/branding",
|
||||
"//src/design-system/atoms/breakpoints",
|
||||
"//src/design-system/atoms/button",
|
||||
"//src/design-system/atoms/colors",
|
||||
"//src/design-system/atoms/popover",
|
||||
"//src/design-system/atoms/timings",
|
||||
"//src/design-system/molecules/guild-nav",
|
||||
"//src/design-system/molecules/nav-slug",
|
||||
"//src/design-system/molecules/user-avatar-group",
|
||||
"//src/design-system/molecules/user-popover",
|
||||
"//src/design-system/shared-types",
|
||||
"@types/react",
|
||||
"@types/styled-components",
|
||||
],
|
||||
)
|
|
@ -3,19 +3,20 @@ import {
|
|||
guild,
|
||||
guildEnum,
|
||||
} from 'roleypoly/src/design-system/shared-types/storyData';
|
||||
import { organismStories } from 'roleypoly/src/design-system/organisms/organisms.story';
|
||||
import * as React from 'react';
|
||||
import { Authed } from './Authed';
|
||||
import { Guest } from './Guest';
|
||||
|
||||
const rootStory = organismStories('Masthead', module);
|
||||
const userStory = organismStories('Masthead/User', module);
|
||||
export default {
|
||||
title: 'Organisms/Masthead',
|
||||
};
|
||||
|
||||
userStory.add('Has Guilds', () => (
|
||||
export const HasGuilds = () => (
|
||||
<Authed guildEnumeration={guildEnum} activeGuildId={guild.id} user={rpUser} />
|
||||
));
|
||||
userStory.add('No Guilds (New User)', () => (
|
||||
<Authed guildEnumeration={{ guildsList: [] }} activeGuildId={null} user={rpUser} />
|
||||
));
|
||||
);
|
||||
|
||||
rootStory.add('Guest', () => <Guest />);
|
||||
export const NoGuilds = () => (
|
||||
<Authed guildEnumeration={{ guildsList: [] }} activeGuildId={null} user={rpUser} />
|
||||
);
|
||||
|
||||
export const Guest_ = () => <Guest />;
|
|
@ -2,6 +2,7 @@ import { onSmallScreen } from 'roleypoly/src/design-system/atoms/breakpoints';
|
|||
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||
import { transitions } from 'roleypoly/src/design-system/atoms/timings';
|
||||
import styled, { css } from 'styled-components';
|
||||
import * as _ from 'styled-components'; // eslint-disable-line no-duplicate-imports
|
||||
|
||||
export const MastheadBase = styled.div`
|
||||
position: fixed;
|
||||
|
|
19
src/design-system/organisms/preauth/BUILD.bazel
Normal file
19
src/design-system/organisms/preauth/BUILD.bazel
Normal file
|
@ -0,0 +1,19 @@
|
|||
load("//hack/bazel/js:react.bzl", "react_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
react_library(
|
||||
name = "role-picker",
|
||||
deps = [
|
||||
"react",
|
||||
"react-icons",
|
||||
"styled-components",
|
||||
"//src/design-system/atoms/button",
|
||||
"//src/design-system/atoms/space",
|
||||
"//src/design-system/molecules/preauth-greeting",
|
||||
"//src/design-system/molecules/preauth-secret-code",
|
||||
"//src/design-system/shared-types",
|
||||
"@types/react",
|
||||
"@types/styled-components",
|
||||
],
|
||||
)
|
|
@ -1,32 +1,33 @@
|
|||
import * as React from 'react';
|
||||
import { Preauth } from './Preauth';
|
||||
import { organismStories } from 'roleypoly/src/design-system/organisms/organisms.story';
|
||||
import { guild } from 'roleypoly/src/design-system/shared-types/storyData';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import styled from 'styled-components';
|
||||
import { Preauth } from './Preauth';
|
||||
|
||||
const story = organismStories('Preauth', module);
|
||||
export default {
|
||||
title: 'Organisms/Preauth',
|
||||
component: Preauth,
|
||||
};
|
||||
|
||||
const Center = styled.div`
|
||||
margin: 0 auto;
|
||||
`;
|
||||
|
||||
story.add('No Slug', () => {
|
||||
export const NoSlug = ({ onSendSecretCode }) => {
|
||||
return (
|
||||
<Center>
|
||||
<Preauth botName="roleypoly#3266" onSendSecretCode={action('secret code!')} />
|
||||
<Preauth botName="roleypoly#3266" onSendSecretCode={onSendSecretCode} />
|
||||
</Center>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
story.add('With Slug', () => {
|
||||
export const WithSlug = ({ onSendSecretCode }) => {
|
||||
return (
|
||||
<Center>
|
||||
<Preauth
|
||||
botName="roleypoly#3266"
|
||||
guildSlug={guild}
|
||||
onSendSecretCode={action('secret code!')}
|
||||
onSendSecretCode={onSendSecretCode}
|
||||
/>
|
||||
</Center>
|
||||
);
|
||||
});
|
||||
};
|
|
@ -1,14 +1,15 @@
|
|||
import { Guild } from '@roleypoly/rpc/shared';
|
||||
import * as React from 'react';
|
||||
import { FaDiscord } from 'react-icons/fa';
|
||||
import { Button } from 'roleypoly/src/design-system/atoms/button';
|
||||
import { Space } from 'roleypoly/src/design-system/atoms/space';
|
||||
import { PreauthGreeting } from 'roleypoly/src/design-system/molecules/preauth-greeting';
|
||||
import { PreauthSecretCode } from 'roleypoly/src/design-system/molecules/preauth-secret-code';
|
||||
import * as React from 'react';
|
||||
import { FaDiscord } from 'react-icons/fa';
|
||||
import { Guild } from 'roleypoly/src/design-system/shared-types';
|
||||
import styled from 'styled-components';
|
||||
import * as _ from 'styled-components'; // eslint-disable-line no-duplicate-imports
|
||||
|
||||
export type PreauthProps = {
|
||||
guildSlug?: Guild.AsObject;
|
||||
guildSlug?: Guild;
|
||||
onSendSecretCode: (code: string) => void;
|
||||
botName?: string;
|
||||
};
|
||||
|
|
1
src/design-system/organisms/preauth/index.ts
Normal file
1
src/design-system/organisms/preauth/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './Preauth';
|
33
src/design-system/organisms/role-picker/BUILD.bazel
Normal file
33
src/design-system/organisms/role-picker/BUILD.bazel
Normal file
|
@ -0,0 +1,33 @@
|
|||
load("//hack/bazel/js:react.bzl", "react_library")
|
||||
load("//hack/bazel/js:jest.bzl", "jest_test")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
react_library(
|
||||
name = "role-picker",
|
||||
deps = [
|
||||
"react",
|
||||
"react-icons",
|
||||
"styled-components",
|
||||
"//src/common/utils",
|
||||
"//src/design-system/atoms/colors",
|
||||
"//src/design-system/atoms/fader",
|
||||
"//src/design-system/atoms/space",
|
||||
"//src/design-system/molecules/picker-category",
|
||||
"//src/design-system/molecules/reset-submit",
|
||||
"//src/design-system/molecules/server-masthead",
|
||||
"//src/design-system/shared-types",
|
||||
"@types/react",
|
||||
"@types/styled-components",
|
||||
],
|
||||
)
|
||||
|
||||
jest_test(
|
||||
src = ":role-picker",
|
||||
deps = [
|
||||
"//src/design-system/atoms/role",
|
||||
"//src/design-system/molecules/picker-category",
|
||||
"//src/design-system/molecules/reset-submit",
|
||||
"//src/design-system/shared-types",
|
||||
],
|
||||
)
|
|
@ -1,10 +1,13 @@
|
|||
jest.unmock('atoms/role')
|
||||
.unmock('atoms/button')
|
||||
.unmock('molecules/picker-category')
|
||||
.unmock('organisms/role-picker');
|
||||
jest.unmock('roleypoly/src/design-system/atoms/role')
|
||||
.unmock('roleypoly/src/design-system/atoms/button')
|
||||
.unmock('roleypoly/src/design-system/molecules/picker-category')
|
||||
.unmock('roleypoly/src/design-system/organisms/role-picker');
|
||||
|
||||
import { Role } from 'roleypoly/src/design-system/atoms/role';
|
||||
import { shallow } from 'enzyme';
|
||||
import * as React from 'react';
|
||||
import { Role } from 'roleypoly/src/design-system/atoms/role';
|
||||
import { PickerCategory } from 'roleypoly/src/design-system/molecules/picker-category';
|
||||
import { ResetSubmit } from 'roleypoly/src/design-system/molecules/reset-submit';
|
||||
import {
|
||||
guild,
|
||||
guildData,
|
||||
|
@ -12,9 +15,6 @@ import {
|
|||
member,
|
||||
mockCategorySingle,
|
||||
} from 'roleypoly/src/design-system/shared-types/storyData';
|
||||
import { ResetSubmit } from 'roleypoly/src/design-system/molecules/reset-submit';
|
||||
import { PickerCategory } from 'roleypoly/src/design-system/molecules/picker-category';
|
||||
import * as React from 'react';
|
||||
import { RolePicker, RolePickerProps } from './RolePicker';
|
||||
|
||||
it('unselects the rest of a category in single mode', () => {
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import * as React from 'react';
|
||||
import {
|
||||
guild,
|
||||
guildData,
|
||||
guildRoles,
|
||||
member,
|
||||
} from 'roleypoly/src/design-system/shared-types/storyData';
|
||||
import { RolePicker, RolePickerProps } from './RolePicker';
|
||||
import * as _ from 'styled-components'; // eslint-disable-line no-duplicate-imports
|
||||
|
||||
const props: Partial<RolePickerProps> = {
|
||||
guildData: guildData,
|
||||
member: member,
|
||||
guild: guild,
|
||||
roles: guildRoles,
|
||||
editable: false,
|
||||
};
|
||||
|
||||
const noMessageArgs: Partial<RolePickerProps> = {
|
||||
...props,
|
||||
guildData: {
|
||||
...guildData,
|
||||
message: '',
|
||||
},
|
||||
};
|
||||
|
||||
const noCategoriesArgs: Partial<RolePickerProps> = {
|
||||
...props,
|
||||
guildData: {
|
||||
...guildData,
|
||||
categoriesList: [],
|
||||
},
|
||||
};
|
||||
|
||||
const emptyArgs = {
|
||||
...props,
|
||||
guildData: {
|
||||
...guildData,
|
||||
categoriesList: [],
|
||||
message: '',
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
title: 'Organisms/Role Picker',
|
||||
args: props,
|
||||
component: RolePicker,
|
||||
};
|
||||
|
||||
export const Full = (args) => <RolePicker {...args} />;
|
||||
export const EditableFull = (args) => <RolePicker {...args} />;
|
||||
EditableFull.args = {
|
||||
editable: true,
|
||||
};
|
||||
export const NoMessage = (args) => <RolePicker {...args} />;
|
||||
NoMessage.args = noMessageArgs;
|
||||
export const NoCategories = (args) => <RolePicker {...args} />;
|
||||
NoCategories.args = noCategoriesArgs;
|
||||
export const Empty = (args) => <RolePicker {...args} />;
|
||||
Empty.args = emptyArgs;
|
|
@ -1,50 +0,0 @@
|
|||
import * as React from 'react';
|
||||
import { RolePicker, RolePickerProps } from './RolePicker';
|
||||
import { organismStories } from 'roleypoly/src/design-system/organisms/organisms.story';
|
||||
import {
|
||||
guildData,
|
||||
member,
|
||||
guildRoles,
|
||||
guild,
|
||||
} from 'roleypoly/src/design-system/shared-types/storyData';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
const storyPublic = organismStories('Role Picker/Public', module);
|
||||
const storyEditable = organismStories('Role Picker/Editable', module);
|
||||
|
||||
const props: RolePickerProps = {
|
||||
guildData: guildData,
|
||||
member: member,
|
||||
guild: guild,
|
||||
roles: guildRoles,
|
||||
onSubmit: action('onSubmit'),
|
||||
editable: false,
|
||||
};
|
||||
|
||||
const storyBuilder = (
|
||||
story: typeof storyPublic,
|
||||
mixinProps: Partial<RolePickerProps>
|
||||
) => {
|
||||
story.add('Full', () => <RolePicker {...{ ...props, ...mixinProps }} />);
|
||||
story.add('No Message', () => (
|
||||
<RolePicker
|
||||
{...{
|
||||
...props,
|
||||
guildData: { ...props.guildData, message: '' },
|
||||
...mixinProps,
|
||||
}}
|
||||
/>
|
||||
));
|
||||
story.add('No Categories', () => (
|
||||
<RolePicker
|
||||
{...{
|
||||
...props,
|
||||
guildData: { ...props.guildData, message: '', categoriesList: [] },
|
||||
...mixinProps,
|
||||
}}
|
||||
/>
|
||||
));
|
||||
};
|
||||
|
||||
storyBuilder(storyPublic, {});
|
||||
storyBuilder(storyEditable, { editable: true });
|
|
@ -1,4 +1,5 @@
|
|||
import styled from 'styled-components';
|
||||
import * as _ from 'styled-components'; // eslint-disable-line no-duplicate-imports
|
||||
import { palette } from 'roleypoly/src/design-system/atoms/colors';
|
||||
|
||||
export const Container = styled.div``;
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
import { Member } from '@roleypoly/rpc/discord';
|
||||
import { Category, GuildData } from '@roleypoly/rpc/platform';
|
||||
import { Guild, GuildRoles, Role } from '@roleypoly/rpc/shared';
|
||||
import { FaderOpacity } from 'roleypoly/src/design-system/atoms/fader';
|
||||
import { Space } from 'roleypoly/src/design-system/atoms/space';
|
||||
import { ResetSubmit } from 'roleypoly/src/design-system/molecules/reset-submit';
|
||||
import { ServerMasthead } from 'roleypoly/src/design-system/molecules/server-masthead';
|
||||
import { PickerCategory } from 'roleypoly/src/design-system/molecules/picker-category';
|
||||
import * as React from 'react';
|
||||
import { GoInfo } from 'react-icons/go';
|
||||
import { FaderOpacity } from 'roleypoly/src/design-system/atoms/fader';
|
||||
import { Space } from 'roleypoly/src/design-system/atoms/space';
|
||||
import { PickerCategory } from 'roleypoly/src/design-system/molecules/picker-category';
|
||||
import { ResetSubmit } from 'roleypoly/src/design-system/molecules/reset-submit';
|
||||
import { ServerMasthead } from 'roleypoly/src/design-system/molecules/server-masthead';
|
||||
import {
|
||||
Category,
|
||||
Guild,
|
||||
GuildData,
|
||||
GuildRoles,
|
||||
Member,
|
||||
Role,
|
||||
CategoryType,
|
||||
} from 'roleypoly/src/design-system/shared-types';
|
||||
import { ReactifyNewlines } from 'roleypoly/src/common/utils/ReactifyNewlines';
|
||||
import {
|
||||
CategoryContainer,
|
||||
Container,
|
||||
|
@ -15,13 +22,12 @@ import {
|
|||
InfoIcon,
|
||||
MessageBox,
|
||||
} from './RolePicker.styled';
|
||||
import { ReactifyNewlines } from 'utils/ReactifyNewlines';
|
||||
|
||||
export type RolePickerProps = {
|
||||
guild: Guild.AsObject;
|
||||
guildData: GuildData.AsObject;
|
||||
member: Member.AsObject;
|
||||
roles: GuildRoles.AsObject;
|
||||
guild: Guild;
|
||||
guildData: GuildData;
|
||||
member: Member;
|
||||
roles: GuildRoles;
|
||||
onSubmit: (selectedRoles: string[]) => void;
|
||||
editable: boolean;
|
||||
};
|
||||
|
@ -40,10 +46,8 @@ export const RolePicker = (props: RolePickerProps) => {
|
|||
props.member.rolesList
|
||||
);
|
||||
|
||||
const handleChange = (category: Category.AsObject) => (role: Role.AsObject) => (
|
||||
newState: boolean
|
||||
) => {
|
||||
if (category.type === Category.CategoryType.SINGLE) {
|
||||
const handleChange = (category: Category) => (role: Role) => (newState: boolean) => {
|
||||
if (category.type === CategoryType.SINGLE) {
|
||||
updateSelectedRoles(
|
||||
newState === true
|
||||
? [
|
||||
|
@ -94,14 +98,12 @@ export const RolePicker = (props: RolePickerProps) => {
|
|||
(r) => r.id === role
|
||||
)
|
||||
)
|
||||
.filter(
|
||||
(r) => r !== undefined
|
||||
) as Role.AsObject[]
|
||||
.filter((r) => r !== undefined) as Role[]
|
||||
}
|
||||
onChange={handleChange(category)}
|
||||
wikiMode={false}
|
||||
type={
|
||||
category.type === Category.CategoryType.SINGLE
|
||||
category.type === CategoryType.SINGLE
|
||||
? 'single'
|
||||
: 'multi'
|
||||
}
|
||||
|
|
56
yarn.lock
56
yarn.lock
|
@ -2876,6 +2876,13 @@
|
|||
"@types/react" "*"
|
||||
"@types/reactcss" "*"
|
||||
|
||||
"@types/react-custom-scrollbars@^4.0.7":
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-custom-scrollbars/-/react-custom-scrollbars-4.0.7.tgz#b1312ec749fcf4a01fee7466508501e072ede7ea"
|
||||
integrity sha512-4QPZdwd+wmzWq9TyNSA/4MZFYvlQn1GlEFFkpFx8VSs13gR/L+hQne0vFnbzwlQmGG7OksthkoVpYxWJjzz95w==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-dom@^16.9.8":
|
||||
version "16.9.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.8.tgz#fe4c1e11dfc67155733dfa6aa65108b4971cb423"
|
||||
|
@ -3318,6 +3325,11 @@ acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0:
|
|||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||
|
||||
add-px-to-style@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/add-px-to-style/-/add-px-to-style-1.0.0.tgz#d0c135441fa8014a8137904531096f67f28f263a"
|
||||
integrity sha1-0ME1RB+oAUqBN5BFMQlvZ/KPJjo=
|
||||
|
||||
address@1.1.2, address@^1.0.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
|
||||
|
@ -5744,6 +5756,15 @@ dom-converter@^0.2:
|
|||
dependencies:
|
||||
utila "~0.4"
|
||||
|
||||
dom-css@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-css/-/dom-css-2.1.0.tgz#fdbc2d5a015d0a3e1872e11472bbd0e7b9e6a202"
|
||||
integrity sha1-/bwtWgFdCj4YcuEUcrvQ57nmogI=
|
||||
dependencies:
|
||||
add-px-to-style "1.0.0"
|
||||
prefix-style "2.0.1"
|
||||
to-camel-case "1.0.0"
|
||||
|
||||
dom-serializer@0, dom-serializer@^0.2.1:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
|
||||
|
@ -10944,6 +10965,11 @@ postcss@^7.0.0, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.2
|
|||
source-map "^0.6.1"
|
||||
supports-color "^6.1.0"
|
||||
|
||||
prefix-style@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/prefix-style/-/prefix-style-2.0.1.tgz#66bba9a870cfda308a5dc20e85e9120932c95a06"
|
||||
integrity sha1-ZrupqHDP2jCKXcIOhekSCTLJWgY=
|
||||
|
||||
prelude-ls@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||
|
@ -11229,7 +11255,7 @@ quick-lru@^4.0.1:
|
|||
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f"
|
||||
integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
|
||||
|
||||
raf@^3.4.1:
|
||||
raf@^3.1.0, raf@^3.4.1:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
|
||||
integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==
|
||||
|
@ -11304,6 +11330,15 @@ react-color@^2.17.0:
|
|||
reactcss "^1.2.0"
|
||||
tinycolor2 "^1.4.1"
|
||||
|
||||
react-custom-scrollbars@^4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-custom-scrollbars/-/react-custom-scrollbars-4.2.1.tgz#830fd9502927e97e8a78c2086813899b2a8b66db"
|
||||
integrity sha1-gw/ZUCkn6X6KeMIIaBOJmyqLZts=
|
||||
dependencies:
|
||||
dom-css "^2.0.0"
|
||||
prop-types "^15.5.10"
|
||||
raf "^3.1.0"
|
||||
|
||||
react-dev-utils@^10.0.0:
|
||||
version "10.2.1"
|
||||
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19"
|
||||
|
@ -13334,11 +13369,23 @@ to-arraybuffer@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
|
||||
integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
|
||||
|
||||
to-camel-case@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-camel-case/-/to-camel-case-1.0.0.tgz#1a56054b2f9d696298ce66a60897322b6f423e46"
|
||||
integrity sha1-GlYFSy+daWKYzmamCJcyK29CPkY=
|
||||
dependencies:
|
||||
to-space-case "^1.0.0"
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
|
||||
|
||||
to-no-case@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/to-no-case/-/to-no-case-1.0.2.tgz#c722907164ef6b178132c8e69930212d1b4aa16a"
|
||||
integrity sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=
|
||||
|
||||
to-object-path@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
|
||||
|
@ -13371,6 +13418,13 @@ to-regex@^3.0.1, to-regex@^3.0.2:
|
|||
regex-not "^1.0.2"
|
||||
safe-regex "^1.1.0"
|
||||
|
||||
to-space-case@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-space-case/-/to-space-case-1.0.0.tgz#b052daafb1b2b29dc770cea0163e5ec0ebc9fc17"
|
||||
integrity sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=
|
||||
dependencies:
|
||||
to-no-case "^1.0.0"
|
||||
|
||||
toggle-selection@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
|
||||
|
|
Loading…
Add table
Reference in a new issue