feat(design-system): port molecules

This commit is contained in:
41666 2020-10-14 17:07:28 -04:00
parent ea2683da00
commit 7be4f0d1e7
70 changed files with 538 additions and 487 deletions

View file

@ -1,4 +1,5 @@
load("//:hack/react.bzl", "react_library")
load("//:hack/jest.bzl", "jest_test")
package(default_visibility = ["//visibility:public"])
@ -14,3 +15,7 @@ react_library(
"@types/styled-components",
],
)
jest_test(
src = ":tab-view",
)

View file

@ -4,7 +4,7 @@ load("//:hack/jest.bzl", "jest_test")
package(default_visibility = ["//visibility:public"])
react_library(
name = "timings",
name = "typist",
deps = [
"react",
"@types/react",
@ -12,5 +12,5 @@ react_library(
)
jest_test(
src = ":timings",
src = ":typist",
)

View 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",
],
)

View file

@ -0,0 +1,8 @@
import * as React from 'react';
import { DemoDiscord } from './DemoDiscord';
export default {
title: 'Molecules/Role Demos',
};
export const Discord = () => <DemoDiscord />;

View file

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

View file

@ -1,5 +1,6 @@
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`
background-color: ${palette.discord100};

View file

@ -8,8 +8,8 @@ import {
Line,
InputTextAlignment,
} from './DemoDiscord.styled';
import { demoData } from 'hack/fixtures/demoData';
import { Typist } from 'atoms/typist';
import { demoData } from 'roleypoly/src/design-system/shared-types/demoData';
import { Typist } from 'roleypoly/src/design-system/atoms/typist';
export const DemoDiscord = () => {
const time = new Date();

View 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",
],
)

View file

@ -0,0 +1,8 @@
import * as React from 'react';
import { DemoPicker } from './DemoPicker';
export default {
title: 'Molecules/Role Demos',
};
export const Picker = () => <DemoPicker />;

View file

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

View file

@ -1,8 +1,8 @@
import * as React from 'react';
import { Role } from 'atoms/role';
import { Role as RPCRole } from '@roleypoly/rpc/shared';
import { Role } from 'roleypoly/src/design-system/atoms/role';
import { Role as RPCRole } from 'roleypoly/src/design-system/shared-types';
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`
display: flex;
@ -21,7 +21,7 @@ const RoleWrap = styled.div`
export const DemoPicker = () => {
const [selectedStates, setSelectedStates] = React.useState<
{
[key in RPCRole.AsObject['id']]: boolean;
[key in RPCRole['id']]: boolean;
}
>(demoData.reduce((acc, role) => ({ ...acc, [role.id]: false }), {}));

View 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",
],
)

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

View file

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

View file

@ -1,6 +1,7 @@
import styled from 'styled-components';
import { palette } from 'atoms/colors';
import { transitions } from 'atoms/timings';
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
import { palette } from 'roleypoly/src/design-system/atoms/colors';
import { transitions } from 'roleypoly/src/design-system/atoms/timings';
export const FooterWrapper = styled.div`
display: flex;

View file

@ -1,6 +1,6 @@
import * as React from 'react';
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 { Flags } from './Flags';

View 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",
],
)

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

View file

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

View file

@ -1,6 +1,7 @@
import styled from 'styled-components';
import { transitions } from 'atoms/timings';
import { palette } from 'atoms/colors';
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
import { transitions } from 'roleypoly/src/design-system/atoms/timings';
import { palette } from 'roleypoly/src/design-system/atoms/colors';
export const GuildNavItem = styled.a`
display: flex;

View file

@ -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 * 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 = {
guildEnumeration: GuildEnumeration.AsObject;
guildEnumeration: GuildEnumeration;
};
const tooltipId = 'guildnav';
const Badges = (props: { guild: PresentableGuild.AsObject }) => {
const Badges = (props: { guild: PresentableGuild }) => {
return React.useMemo(() => {
if (!props.guild.member) {
return null;
@ -29,7 +33,7 @@ const Badges = (props: { guild: PresentableGuild.AsObject }) => {
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)) {
return <GoStar data-tip="Administrator" data-for={tooltipId} />;
@ -45,13 +49,7 @@ const Badges = (props: { guild: PresentableGuild.AsObject }) => {
export const GuildNav = (props: Props) => (
<div>
{sortBy(
props.guildEnumeration.guildsList.map((g) => ({
...g,
nameLower: g.guild?.name.toLowerCase(),
})),
'nameLower'
).map(({ nameLower, ...guild }) => (
{sortBy(props.guildEnumeration.guildsList, 'id').map((guild) => (
<Link href={`/s/${guild.id}`} passHref>
<GuildNavItem>
<NavSlug guild={guild.guild || null} key={guild.id} />

View file

@ -1,2 +0,0 @@
import { makeFactory } from '../.storybook/storyHelper';
export const moleculeStories = makeFactory('Molecules');

View 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",
],
)

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

View file

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

View file

@ -1,4 +1,5 @@
import styled from 'styled-components';
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
export const SlugContainer = styled.div`
display: flex;

View file

@ -1,11 +1,11 @@
import * as React from 'react';
import { Guild } from '@roleypoly/rpc/shared';
import { Avatar, utils } from 'atoms/avatar';
import { Guild } from 'roleypoly/src/design-system/shared-types';
import { Avatar, utils } from 'roleypoly/src/design-system/atoms/avatar';
import { SlugContainer, SlugName } from './NavSlug.styled';
import { GoOrganization } from 'react-icons/go';
type Props = {
guild: Guild.AsObject | null;
guild: Guild | null;
};
export const NavSlug = (props: Props) => (

View 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",
],
)

View file

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

View file

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

View file

@ -1,4 +1,5 @@
import styled from 'styled-components';
import * as _ from 'styled-components'; // tslint:disable-line:no-duplicate-imports
export const Head = styled.div`
margin: 7px 5px;

View file

@ -1,18 +1,21 @@
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 { 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 = {
title: string;
roles: RPCRole.AsObject[];
category: RPCCategory.AsObject;
roles: RPCRole[];
category: RPCCategory;
selectedRoles: string[];
onChange: (role: RPCRole.AsObject) => (newState: boolean) => void;
onChange: (role: RPCRole) => (newState: boolean) => void;
type: 'single' | 'multi';
} & (
| {
@ -53,7 +56,7 @@ export const PickerCategory = (props: CategoryProps) => (
role={role}
selected={props.selectedRoles.includes(role.id)}
onClick={props.onChange(role)}
disabled={role.safety !== RPCRole.RoleSafety.SAFE}
disabled={role.safety !== RoleSafety.SAFE}
tooltipId={props.category.id}
/>
</Container>

View 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",
],
)

View file

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

View file

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

View file

@ -1,12 +1,12 @@
import * as React from 'react';
import { Avatar, utils as avatarUtils } from 'atoms/avatar';
import { Guild } from '@roleypoly/rpc/shared';
import { AccentTitle } from 'atoms/typography';
import { Space } from 'atoms/space';
import { Avatar, utils as avatarUtils } from 'roleypoly/src/design-system/atoms/avatar';
import { Guild } from 'roleypoly/src/design-system/shared-types';
import { AccentTitle } from 'roleypoly/src/design-system/atoms/typography';
import { Space } from 'roleypoly/src/design-system/atoms/space';
import styled from 'styled-components';
type GreetingProps = {
guildSlug: Guild.AsObject;
guildSlug: Guild;
};
const Center = styled.div`
@ -14,6 +14,7 @@ const Center = styled.div`
justify-content: center;
align-items: center;
flex-direction: column;
text-align: center;
`;
export const PreauthGreeting = (props: GreetingProps) => (

View 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",
],
)

View file

@ -1,12 +1,12 @@
jest.unmock('atoms/text-input');
jest.unmock('roleypoly/src/design-system/atoms/text-input');
jest.unmock('./PreauthSecretCode');
import { Button } from 'atoms/button';
import { TextInputWithIcon } from 'atoms/text-input';
import { Button } from 'roleypoly/src/design-system/atoms/button';
import { TextInputWithIcon } from 'roleypoly/src/design-system/atoms/text-input';
import { shallow } from 'enzyme';
import * as React from 'react';
import { PreauthSecretCode } from './PreauthSecretCode';
import { FaderOpacity } from 'atoms/fader';
import { FaderOpacity } from 'roleypoly/src/design-system/atoms/fader';
const value = 'unfathomable fishy sticks';
const onSubmit = jest.fn();

View file

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

View file

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

View file

@ -1,9 +1,9 @@
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 { FaderOpacity } from 'atoms/fader';
import { Button } from 'atoms/button';
import { Space } from 'atoms/space';
import { FaderOpacity } from 'roleypoly/src/design-system/atoms/fader';
import { Button } from 'roleypoly/src/design-system/atoms/button';
import { Space } from 'roleypoly/src/design-system/atoms/space';
type PreauthProps = {
onSubmit: (code: string) => void;

View 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",
],
)

View file

@ -1,4 +1,4 @@
import { Button } from 'atoms/button';
import { Button } from 'roleypoly/src/design-system/atoms/button';
import { shallow } from 'enzyme';
import * as React from 'react';
import { ResetSubmit } from './ResetSubmit';

View file

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

View file

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

View file

@ -1,5 +1,6 @@
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`
display: flex;

View file

@ -1,5 +1,5 @@
import { onSmallScreen } from 'atoms/breakpoints';
import { Button } from 'atoms/button';
import { onSmallScreen } from 'roleypoly/src/design-system/atoms/breakpoints';
import { Button } from 'roleypoly/src/design-system/atoms/button';
import * as React from 'react';
import { MdRestore } from 'react-icons/md';
import styled from 'styled-components';

View 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",
],
)

View file

@ -3,7 +3,7 @@ jest.unmock('./ServerMasthead');
import * as React from 'react';
import { shallow } from 'enzyme';
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';
it('shows Edit Server when editable is true', () => {

View file

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

View file

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

View file

@ -1,6 +1,6 @@
import styled from 'styled-components';
import { palette } from 'atoms/colors';
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 Wrapper = styled.div`
display: flex;

View file

@ -1,14 +1,14 @@
import { Guild } from '@roleypoly/rpc/shared';
import { Avatar, utils } from 'atoms/avatar';
import { AccentTitle, AmbientLarge } from 'atoms/typography';
import { Guild } from 'roleypoly/src/design-system/shared-types';
import { Avatar, utils } from 'roleypoly/src/design-system/atoms/avatar';
import { AccentTitle, AmbientLarge } from 'roleypoly/src/design-system/atoms/typography';
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 { GoPencil } from 'react-icons/go';
import { Editable, Icon, Name, Wrapper } from './ServerMasthead.styled';
export type ServerMastheadProps = {
guild: Guild.AsObject;
guild: Guild;
editable: boolean;
};

View 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",
],
)

View file

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

View file

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

View file

@ -1,6 +1,6 @@
import styled, { css } from 'styled-components';
import { onSmallScreen } from 'atoms/breakpoints';
import { palette } from 'atoms/colors';
import { onSmallScreen } from 'roleypoly/src/design-system/atoms/breakpoints';
import { palette } from 'roleypoly/src/design-system/atoms/colors';
export const Collapse = styled.div<{ preventCollapse: boolean }>`
${(props) =>

View file

@ -1,10 +1,10 @@
import * as React from 'react';
import { DiscordUser } from '@roleypoly/rpc/shared';
import { utils, Avatar } from 'atoms/avatar';
import { DiscordUser } from 'roleypoly/src/design-system/shared-types';
import { utils, Avatar } from 'roleypoly/src/design-system/atoms/avatar';
import { Group, Collapse, Discriminator, GroupText } from './UserAvatarGroup.styled';
type Props = {
user: DiscordUser.AsObject;
user: DiscordUser;
preventCollapse?: boolean;
};

View 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",
],
)

View file

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

View file

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

View file

@ -1,6 +1,6 @@
import styled from 'styled-components';
import { palette } from 'atoms/colors';
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 Base = styled.div`
text-align: right;

View file

@ -1,12 +1,12 @@
import * as React from 'react';
import { DiscordUser } from '@roleypoly/rpc/shared';
import { UserAvatarGroup } from 'molecules/user-avatar-group';
import { DiscordUser } from 'roleypoly/src/design-system/shared-types';
import { UserAvatarGroup } from 'roleypoly/src/design-system/molecules/user-avatar-group';
import { Base, NavAction } from './UserPopover.styled';
import { GoGear, GoSignOut } from 'react-icons/go';
import Link from 'next/link';
type UserPopoverProps = {
user: DiscordUser.AsObject;
user: DiscordUser;
};
export const UserPopover = (props: UserPopoverProps) => (

View file

@ -23,12 +23,14 @@ export type GuildData = {
entitlementsList: string[];
};
export type GuildEnumeration = {
guildsList: {
id: string;
guild: Guild;
member: Member;
data: GuildData;
roles: GuildRoles;
}[];
export type PresentableGuild = {
id: string;
guild: Guild;
member: Member;
data: GuildData;
roles: GuildRoles;
};
export type GuildEnumeration = {
guildsList: PresentableGuild[];
};

View file

@ -0,0 +1,58 @@
import { Role } from '.';
export const demoData: Role[] = [
{
id: '557812805546541066',
name: 'a cute role ♡',
color: 0xd19494,
permissions: 0,
safety: 0,
managed: false,
position: 0,
},
{
id: '557812901717737472',
name: 'a vanity role ♡',
color: 0xd1d194,
permissions: 0,
safety: 0,
managed: false,
position: 0,
},
{
id: '557812915386843170',
name: 'a brave role ♡',
color: 0x94d194,
permissions: 0,
safety: 0,
managed: false,
position: 0,
},
{
id: '557824893241131029',
name: 'a proud role ♡',
color: 0x94d1d1,
permissions: 0,
safety: 0,
managed: false,
position: 0,
},
{
id: '557824994269200384',
name: 'a wonderful role ♡',
color: 0x9494d1,
permissions: 0,
safety: 0,
managed: false,
position: 0,
},
{
id: '557825026406088717',
name: 'a 日本語 role ♡',
color: 0xd194d1,
permissions: 0,
safety: 0,
managed: false,
position: 0,
},
];