mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-06-16 09:39:09 +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
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'
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue