mirror of
https://github.com/wassname/talk.git
synced 2026-07-05 02:00:39 +08:00
Make design responsive
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
.root {
|
||||
}
|
||||
|
||||
.gutterBottom {
|
||||
margin-bottom: calc(1px * var(--spacing-unit));
|
||||
}
|
||||
|
||||
.topBar {
|
||||
margin-bottom: calc(0.5px * var(--spacing-unit));
|
||||
}
|
||||
@@ -1,32 +1,27 @@
|
||||
import cn from "classnames";
|
||||
import React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
|
||||
import { RelativeTime, Typography } from "talk-ui/components";
|
||||
import { Typography } from "talk-ui/components";
|
||||
|
||||
import * as styles from "./Comment.css";
|
||||
import CommentTimestamp from "./CommentTimestamp";
|
||||
import CommentTopBar from "./CommentTopBar";
|
||||
import Username from "./Username";
|
||||
|
||||
export interface CommentProps {
|
||||
className?: string;
|
||||
author: {
|
||||
username: string;
|
||||
} | null;
|
||||
body: string | null;
|
||||
createdAt: string;
|
||||
gutterBottom?: boolean;
|
||||
}
|
||||
|
||||
const Comment: StatelessComponent<CommentProps> = props => {
|
||||
const rootClassName = cn(styles.root, props.className, {
|
||||
[styles.gutterBottom]: props.gutterBottom,
|
||||
});
|
||||
return (
|
||||
<div className={rootClassName} role="article">
|
||||
<div className={styles.topBar}>
|
||||
<div role="article">
|
||||
<CommentTopBar>
|
||||
{props.author && <Username>{props.author.username}</Username>}
|
||||
<RelativeTime date={props.createdAt} />
|
||||
</div>
|
||||
<CommentTimestamp>{props.createdAt}</CommentTimestamp>
|
||||
</CommentTopBar>
|
||||
<Typography>{props.body}</Typography>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.root {
|
||||
composes: timestamp from "talk-ui/shared/typography.css";
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
|
||||
import { RelativeTime } from "talk-ui/components";
|
||||
|
||||
import * as styles from "./CommentTimestamp.css";
|
||||
|
||||
export interface CommentTimestampProps {
|
||||
children: string;
|
||||
}
|
||||
|
||||
const CommentTimestamp: StatelessComponent<CommentTimestampProps> = props => (
|
||||
<RelativeTime className={styles.root} date={props.children} />
|
||||
);
|
||||
|
||||
export default CommentTimestamp;
|
||||
@@ -0,0 +1,3 @@
|
||||
.root {
|
||||
margin-bottom: calc(0.5 * var(--spacing-unit));
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import cn from "classnames";
|
||||
import React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
|
||||
import { Flex, MatchMedia } from "talk-ui/components";
|
||||
|
||||
import * as styles from "./CommentTopBar.css";
|
||||
|
||||
export interface CommentTopBarProps {
|
||||
className?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const CommentTopBar: StatelessComponent<CommentTopBarProps> = props => {
|
||||
const rootClassName = cn(styles.root, props.className);
|
||||
return (
|
||||
<MatchMedia minWidth="xs">
|
||||
{matches => (
|
||||
<Flex
|
||||
className={rootClassName}
|
||||
alignItems="baseline"
|
||||
direction={matches ? "row" : "column"}
|
||||
itemGutter={matches ? true : "half"}
|
||||
>
|
||||
{props.children}
|
||||
</Flex>
|
||||
)}
|
||||
</MatchMedia>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommentTopBar;
|
||||
@@ -1,6 +1,6 @@
|
||||
.root {
|
||||
border-left: 3px solid;
|
||||
padding-left: calc(1px * var(--spacing-unit));
|
||||
padding-left: var(--spacing-unit);
|
||||
}
|
||||
|
||||
.level0 {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
height: 100px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: calc(1px * var(--spacing-unit));
|
||||
margin-bottom: var(--spacing-unit);
|
||||
}
|
||||
|
||||
.postButtonContainer {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Localized } from "fluent-react/compat";
|
||||
import * as React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
|
||||
import { Button } from "talk-ui/components";
|
||||
import { Button, Flex } from "talk-ui/components";
|
||||
|
||||
import CommentContainer from "../containers/CommentContainer";
|
||||
import Indent from "./Indent";
|
||||
@@ -18,9 +18,14 @@ export interface ReplyListProps {
|
||||
const ReplyList: StatelessComponent<ReplyListProps> = props => {
|
||||
return (
|
||||
<Indent>
|
||||
<div id={`talk-comments-replyList-log--${props.commentID}`} role="log">
|
||||
<Flex
|
||||
direction="column"
|
||||
id={`talk-comments-replyList-log--${props.commentID}`}
|
||||
role="log"
|
||||
itemGutter
|
||||
>
|
||||
{props.comments.map(comment => (
|
||||
<CommentContainer key={comment.id} data={comment} gutterBottom />
|
||||
<CommentContainer key={comment.id} data={comment} />
|
||||
))}
|
||||
{props.hasMore && (
|
||||
<Localized id="comments-replyList-showAll">
|
||||
@@ -37,7 +42,7 @@ const ReplyList: StatelessComponent<ReplyListProps> = props => {
|
||||
</Button>
|
||||
</Localized>
|
||||
)}
|
||||
</div>
|
||||
</Flex>
|
||||
</Indent>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Localized } from "fluent-react/compat";
|
||||
import * as React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
|
||||
import { Button } from "talk-ui/components";
|
||||
import { Button, Flex } from "talk-ui/components";
|
||||
|
||||
import CommentContainer from "../containers/CommentContainer";
|
||||
import PostCommentFormContainer from "../containers/PostCommentFormContainer";
|
||||
@@ -24,12 +24,18 @@ const Stream: StatelessComponent<StreamProps> = props => {
|
||||
<div className={styles.root}>
|
||||
<Logo gutterBottom />
|
||||
<PostCommentFormContainer assetID={props.assetID} />
|
||||
<div id="talk-comments-stream-log" role="log" aria-live="polite">
|
||||
<Flex
|
||||
direction="column"
|
||||
id="talk-comments-stream-log"
|
||||
role="log"
|
||||
aria-live="polite"
|
||||
itemGutter
|
||||
>
|
||||
{props.comments.map(comment => (
|
||||
<div key={comment.id}>
|
||||
<CommentContainer data={comment} gutterBottom />
|
||||
<Flex direction="column" key={comment.id} itemGutter>
|
||||
<CommentContainer data={comment} />
|
||||
<ReplyListContainer comment={comment} />
|
||||
</div>
|
||||
</Flex>
|
||||
))}
|
||||
{props.hasMore && (
|
||||
<Localized id="comments-stream-loadMore">
|
||||
@@ -46,7 +52,7 @@ const Stream: StatelessComponent<StreamProps> = props => {
|
||||
</Button>
|
||||
</Localized>
|
||||
)}
|
||||
</div>
|
||||
</Flex>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
.root {
|
||||
composes: heading4 from "talk-ui/shared/typography.css";
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,28 @@
|
||||
import React from "react";
|
||||
import { StatelessComponent } from "react";
|
||||
|
||||
import { MatchMedia, Typography } from "talk-ui/components";
|
||||
|
||||
import * as styles from "./Username.css";
|
||||
|
||||
export interface CommentProps {
|
||||
export interface UsernameProps {
|
||||
children: string;
|
||||
}
|
||||
|
||||
const Username: StatelessComponent<CommentProps> = props => {
|
||||
return <span className={styles.root}>{props.children}</span>;
|
||||
const Username: StatelessComponent<UsernameProps> = props => {
|
||||
return (
|
||||
<MatchMedia minWidth="xs">
|
||||
{matches => (
|
||||
<Typography
|
||||
variant={matches ? "heading2" : "heading3"}
|
||||
className={styles.root}
|
||||
component="span"
|
||||
>
|
||||
{props.children}
|
||||
</Typography>
|
||||
)}
|
||||
</MatchMedia>
|
||||
);
|
||||
};
|
||||
|
||||
export default Username;
|
||||
|
||||
@@ -22,7 +22,10 @@ export class ReplyListContainer extends React.Component<InnerProps> {
|
||||
};
|
||||
|
||||
public render() {
|
||||
if (this.props.comment.replies === null) {
|
||||
if (
|
||||
this.props.comment.replies === null ||
|
||||
this.props.comment.replies.edges.length === 0
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
const comments = this.props.comment.replies.edges.map(edge => edge.node);
|
||||
|
||||
@@ -2,6 +2,54 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.halfItemGutter {
|
||||
& > * {
|
||||
margin: 0 calc(0.5 * var(--spacing-unit)) 0 0;
|
||||
}
|
||||
&.directionRowReverse {
|
||||
& > * {
|
||||
margin: 0 0 0 calc(0.5 * var(--spacing-unit));
|
||||
}
|
||||
}
|
||||
&.directionColumn {
|
||||
& > * {
|
||||
margin: 0 0 calc(0.5 * var(--spacing-unit)) 0;
|
||||
}
|
||||
}
|
||||
&.directionColumnReverese {
|
||||
& > * {
|
||||
margin: calc(0.5 * var(--spacing-unit)) 0 0 0;
|
||||
}
|
||||
}
|
||||
& > *:last-child {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.itemGutter {
|
||||
& > * {
|
||||
margin: 0 var(--spacing-unit) 0 0;
|
||||
}
|
||||
&.directionRowReverse {
|
||||
& > * {
|
||||
margin: 0 0 0 var(--spacing-unit);
|
||||
}
|
||||
}
|
||||
&.directionColumn {
|
||||
& > * {
|
||||
margin: 0 0 var(--spacing-unit) 0;
|
||||
}
|
||||
}
|
||||
&.directionColumnReverese {
|
||||
& > * {
|
||||
margin: var(--spacing-unit) 0 0 0;
|
||||
}
|
||||
}
|
||||
& > *:last-child {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.justifyFlexStart {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import { pascalCase } from "talk-common/utils";
|
||||
import * as styles from "./Flex.css";
|
||||
|
||||
interface InnerProps {
|
||||
id?: string;
|
||||
role?: string;
|
||||
justifyContent?:
|
||||
| "flex-start"
|
||||
| "flex-end"
|
||||
@@ -16,12 +18,24 @@ interface InnerProps {
|
||||
| "space-evenly";
|
||||
alignItems?: "flex-start" | "flex-end" | "center" | "baseline" | "stretch";
|
||||
direction?: "row" | "column" | "row-reverse" | "column-reverse";
|
||||
itemGutter?: boolean | "half";
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const Flex: StatelessComponent<InnerProps> = props => {
|
||||
const { justifyContent, alignItems, direction, ...rest } = props;
|
||||
const {
|
||||
className,
|
||||
justifyContent,
|
||||
alignItems,
|
||||
direction,
|
||||
itemGutter,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const classObject: Record<string, boolean> = {};
|
||||
const classObject: Record<string, boolean> = {
|
||||
[styles.itemGutter]: itemGutter === true,
|
||||
[styles.halfItemGutter]: itemGutter === "half",
|
||||
};
|
||||
|
||||
if (justifyContent) {
|
||||
classObject[(styles as any)[`justify${pascalCase(justifyContent)}`]] = true;
|
||||
@@ -35,7 +49,7 @@ const Flex: StatelessComponent<InnerProps> = props => {
|
||||
classObject[(styles as any)[`direction${pascalCase(direction)}`]] = true;
|
||||
}
|
||||
|
||||
const classNames: string = cn(styles.root, classObject);
|
||||
const classNames: string = cn(styles.root, className, classObject);
|
||||
|
||||
return <div className={classNames} {...rest} />;
|
||||
};
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
composes: overline from "talk-ui/shared/typography.css";
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
composes: timestamp from "talk-ui/shared/typography.css";
|
||||
}
|
||||
|
||||
.alignLeft {
|
||||
text-align: left;
|
||||
}
|
||||
@@ -70,7 +74,7 @@
|
||||
}
|
||||
|
||||
.paragraph {
|
||||
margin-bottom: calc(1px * var(--spacing-unit));
|
||||
margin-bottom: var(--spacing-unit);
|
||||
}
|
||||
|
||||
.colorInherit {
|
||||
|
||||
@@ -16,7 +16,8 @@ type Variant =
|
||||
| "subtitle2"
|
||||
| "body1"
|
||||
| "body2"
|
||||
| "button";
|
||||
| "button"
|
||||
| "timestamp";
|
||||
|
||||
// Based on Typography Component of Material UI.
|
||||
// https://github.com/mui-org/material-ui/blob/303199d39b42a321d28347d8440d69166f872f27/packages/material-ui/src/Typography/Typography.js
|
||||
@@ -129,6 +130,7 @@ Typography.defaultProps = {
|
||||
subtitle2: "h3",
|
||||
body1: "p",
|
||||
body2: "aside",
|
||||
timestamp: "span",
|
||||
},
|
||||
noWrap: false,
|
||||
paragraph: false,
|
||||
|
||||
@@ -61,3 +61,12 @@
|
||||
|
||||
.overline {
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
color: var(--palette-text-secondary);
|
||||
font-family: "Source Sans Pro";
|
||||
font-weight: var(--font-weight-medium);
|
||||
font-size: 14px;
|
||||
line-height: calc(18em / 16);
|
||||
letter-spacing: calc(0.2em / 16);
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
*/
|
||||
|
||||
:root {
|
||||
--spacing-unit: var(--spacing-unit-small);
|
||||
--spacing-unit: calc(1px * var(--spacing-unit-small));
|
||||
}
|
||||
|
||||
@media (min-width: $breakpoints-xs) {
|
||||
:root {
|
||||
--spacing-unit: var(--spacing-unit-large);
|
||||
--spacing-unit: calc(1px * var(--spacing-unit-large));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user