diff --git a/package-lock.json b/package-lock.json index c504d8d7c..d853f3b07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15007,9 +15007,9 @@ "dev": true }, "matchmediaquery": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.2.1.tgz", - "integrity": "sha1-IjxwBXk94D5HzpKxMoWnLEStos8=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.3.0.tgz", + "integrity": "sha512-u0dlv+VENJ+3YepvwSPBieuvnA6DWfaYa/ctwysAR13y4XLJNyt7bEVKzNj/Nvjo+50d88Pj+xL9xaSo6JmX/w==", "dev": true, "requires": { "css-mediaquery": "^0.1.2" @@ -19590,13 +19590,13 @@ } }, "react-responsive": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-4.1.0.tgz", - "integrity": "sha512-ZuDraf0qsJlyiTwzeva+foHx83IP6SIhru9o7BvMwQ4ZHjRIL5WjdgVNNrKSRbmeWO9rEJoMpabei/5lJn8KaA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-5.0.0.tgz", + "integrity": "sha512-oEimZ0FTCC3/pjGDEBHOz06nWbBNDIbMGOdRYp6K9SBUmrqgNAX77hTiqvmRQeLyI97zz4F4kiaFRxFspDxE+w==", "dev": true, "requires": { "hyphenate-style-name": "^1.0.0", - "matchmediaquery": "^0.2.1", + "matchmediaquery": "^0.3.0", "prop-types": "^15.6.1" } }, diff --git a/package.json b/package.json index 5e5d7b210..7aae0f6cb 100644 --- a/package.json +++ b/package.json @@ -177,7 +177,7 @@ "react-final-form": "^3.6.4", "react-popper": "^1.0.0-beta.6", "react-relay": "github:coralproject/patched#react-relay", - "react-responsive": "^4.1.0", + "react-responsive": "^5.0.0", "react-test-renderer": "^16.4.1", "react-timeago": "^4.1.9", "react-with-state-props": "^2.0.4", diff --git a/src/core/client/embed/index.html b/src/core/client/embed/index.html index 10106ff8c..b579dab8f 100644 --- a/src/core/client/embed/index.html +++ b/src/core/client/embed/index.html @@ -16,7 +16,7 @@

Talk 5.0 – Embed Stream

-
+
diff --git a/src/core/client/framework/lib/bootstrap/TalkContext.tsx b/src/core/client/framework/lib/bootstrap/TalkContext.tsx index f7987877c..7567f9412 100644 --- a/src/core/client/framework/lib/bootstrap/TalkContext.tsx +++ b/src/core/client/framework/lib/bootstrap/TalkContext.tsx @@ -2,6 +2,7 @@ import { LocalizationProvider } from "fluent-react/compat"; import { MessageContext } from "fluent/compat"; import { Child as PymChild } from "pym.js"; import React, { StatelessComponent } from "react"; +import { MediaQueryMatchers } from "react-responsive"; import { Formatter } from "react-timeago"; import { Environment } from "relay-runtime"; @@ -23,6 +24,9 @@ export interface TalkContext { /** Session storage */ sessionStorage: Storage; + + /** media query values for testing purposes */ + mediaQueryValues?: MediaQueryMatchers; /** * A way to listen for clicks that are e.g. outside of the @@ -54,6 +58,7 @@ export const TalkContextProvider: StatelessComponent<{ value={{ timeagoFormatter: value.timeagoFormatter, registerClickFarAway: value.registerClickFarAway, + mediaQueryValues: value.mediaQueryValues, }} > {children} diff --git a/src/core/client/stream/components/Comment/Comment.css b/src/core/client/stream/components/Comment/Comment.css index c4bf8c532..5c0f67095 100644 --- a/src/core/client/stream/components/Comment/Comment.css +++ b/src/core/client/stream/components/Comment/Comment.css @@ -1,3 +1,6 @@ +.root { + width: 100%; +} .footer { margin-top: var(--spacing-unit); } diff --git a/src/core/client/stream/components/Comment/Comment.tsx b/src/core/client/stream/components/Comment/Comment.tsx index 932cd7155..b47c8ac02 100644 --- a/src/core/client/stream/components/Comment/Comment.tsx +++ b/src/core/client/stream/components/Comment/Comment.tsx @@ -20,7 +20,7 @@ export interface CommentProps { const Comment: StatelessComponent = props => { return ( -
+
{props.author && props.author.username && {props.author.username}} diff --git a/src/core/client/stream/components/Comment/TopBar.tsx b/src/core/client/stream/components/Comment/TopBar.tsx index 2dfe6419d..a82dd0a28 100644 --- a/src/core/client/stream/components/Comment/TopBar.tsx +++ b/src/core/client/stream/components/Comment/TopBar.tsx @@ -14,7 +14,7 @@ export interface TopBarProps { const TopBar: StatelessComponent = props => { const rootClassName = cn(styles.root, props.className); return ( - + {matches => ( = props => { return ( - + {matches => ( diff --git a/src/core/client/stream/components/Comment/__snapshots__/TopBar.spec.tsx.snap b/src/core/client/stream/components/Comment/__snapshots__/TopBar.spec.tsx.snap index 6c5348d0b..2e6694137 100644 --- a/src/core/client/stream/components/Comment/__snapshots__/TopBar.spec.tsx.snap +++ b/src/core/client/stream/components/Comment/__snapshots__/TopBar.spec.tsx.snap @@ -1,9 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`renders correctly on big screens 1`] = ` -
+
Hello World @@ -13,9 +15,11 @@ exports[`renders correctly on big screens 1`] = ` `; exports[`renders correctly on small screens 1`] = ` -
+
Hello World diff --git a/src/core/client/stream/components/PermalinkButton/PermalinkButton.tsx b/src/core/client/stream/components/PermalinkButton/PermalinkButton.tsx index aedf477e5..ec1be799f 100644 --- a/src/core/client/stream/components/PermalinkButton/PermalinkButton.tsx +++ b/src/core/client/stream/components/PermalinkButton/PermalinkButton.tsx @@ -57,7 +57,7 @@ class Permalink extends React.Component { active={visible} size="small" > - + share diff --git a/src/core/client/stream/components/UserBoxUnauthenticated.tsx b/src/core/client/stream/components/UserBoxUnauthenticated.tsx index 37a22ee0f..9d838a510 100644 --- a/src/core/client/stream/components/UserBoxUnauthenticated.tsx +++ b/src/core/client/stream/components/UserBoxUnauthenticated.tsx @@ -3,6 +3,7 @@ import React, { StatelessComponent } from "react"; import { Button, Flex, Typography } from "talk-ui/components"; +import MatchMedia from "talk-ui/components/MatchMedia"; import * as styles from "./UserBoxUnauthenticated.css"; export interface UserBoxUnauthenticatedProps { @@ -15,18 +16,20 @@ const UserBoxUnauthenticated: StatelessComponent< > = props => { return ( - - - Join the conversation + + + + Join the conversation + + + + | - - - | - +
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
-
+
-
+
- - Join the conversation - - - | -
-
+
-
+
-
+
-
+
-
+
+
Show all Comments -
+
-
+
+
-
+
-
+
- - Join the conversation - - - | -
-
+
-
+
-
+
+
+
+
-
+
-
+
- - Join the conversation - - - | -
-
+
-
+
-
+
+
-
+
-
+
- - Join the conversation - - - | -
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
-
+
-
+
- - Join the conversation - - - | -
-
+
-
+
-
+
-
+
-
+
+
-
+
-
+
- - Join the conversation - - - | -
-
+
-
+
-
+
-
+
-
+
+
-
+
-
+
- - Join the conversation - - - | -
-
+
-
+
-
+
-
+
-
+
-
+
* { + margin: 0 calc(2 * var(--spacing-unit)) 0 0 !important; + } + &.directionRowReverse { + & > * { + margin: 0 0 0 calc(2 * var(--spacing-unit)) !important; + } + } + &.directionColumn { + & > * { + margin: 0 0 calc(2 * var(--spacing-unit)) 0 !important; + } + } + &.directionColumnReverese { + & > * { + margin: calc(2 * var(--spacing-unit)) 0 0 0 !important; + } + } + & > *:last-child { + margin: 0 !important; + } +} + .itemGutter { & > * { margin: 0 var(--spacing-unit) 0 0 !important; @@ -93,6 +122,23 @@ margin-left: calc(0.5 * var(--spacing-unit)) !important; } } + + &:not(.directionColumn).doubleItemGutter { + &:not(:empty) { + margin-top: calc(-2 * var(--spacing-unit)) !important; + } + & > * { + margin-top: calc(2 * var(--spacing-unit)) !important; + } + } + &.directionColumn.doubleItemGutter { + &:not(:empty) { + margin-left: calc(-2 * var(--spacing-unit)) !important; + } + &.doubleItemGutter > * { + margin-left: calc(2 * var(--spacing-unit)) !important; + } + } } .justifyFlexStart { diff --git a/src/core/client/ui/components/Flex/Flex.mdx b/src/core/client/ui/components/Flex/Flex.mdx index 84eeb8240..7ca59bb54 100644 --- a/src/core/client/ui/components/Flex/Flex.mdx +++ b/src/core/client/ui/components/Flex/Flex.mdx @@ -33,3 +33,29 @@ import Button from '../Button' + +## Item Gutter + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/core/client/ui/components/Flex/Flex.tsx b/src/core/client/ui/components/Flex/Flex.tsx index c29bd814c..bf66f9084 100644 --- a/src/core/client/ui/components/Flex/Flex.tsx +++ b/src/core/client/ui/components/Flex/Flex.tsx @@ -25,7 +25,7 @@ interface InnerProps { | "space-evenly"; alignItems?: "flex-start" | "flex-end" | "center" | "baseline" | "stretch"; direction?: "row" | "column" | "row-reverse" | "column-reverse"; - itemGutter?: boolean | "half"; + itemGutter?: boolean | "half" | "double"; className?: string; wrap?: boolean | "reverse"; @@ -43,6 +43,7 @@ const Flex: StatelessComponent = props => { itemGutter, wrap, forwardRef, + children, ...rest } = props; @@ -55,6 +56,7 @@ const Flex: StatelessComponent = props => { const classObject: Record = { [classes.itemGutter]: itemGutter === true, [classes.halfItemGutter]: itemGutter === "half", + [classes.doubleItemGutter]: itemGutter === "double", [classes.wrap]: wrap === true, [classes.wrapReverse]: wrap === "reverse", }; @@ -75,12 +77,13 @@ const Flex: StatelessComponent = props => { classObject[(classes as any)[`direction${pascalCase(direction)}`]] = true; } - const classNames: string = cn(classes.root, className, classObject); + const rootClassNames: string = cn(classes.root, className); + const flexClassNames: string = cn(classes.flex, classObject); // The first div is required to support nested `Flex` components with itemGutters. return ( -
-
+
+
{children}
); }; diff --git a/src/core/client/ui/components/Flex/__snapshots__/Flex.spec.tsx.snap b/src/core/client/ui/components/Flex/__snapshots__/Flex.spec.tsx.snap index b1f72d74b..d96f60ebd 100644 --- a/src/core/client/ui/components/Flex/__snapshots__/Flex.spec.tsx.snap +++ b/src/core/client/ui/components/Flex/__snapshots__/Flex.spec.tsx.snap @@ -1,9 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`renders correctly 1`] = ` -
+
Hello World @@ -13,9 +15,11 @@ exports[`renders correctly 1`] = ` `; exports[`renders with halfe item gutter 1`] = ` -
+
Hello World @@ -25,9 +29,11 @@ exports[`renders with halfe item gutter 1`] = ` `; exports[`renders with item gutter 1`] = ` -
+
Hello World @@ -37,9 +43,11 @@ exports[`renders with item gutter 1`] = ` `; exports[`renders with wrap 1`] = ` -
+
Hello World @@ -49,9 +57,11 @@ exports[`renders with wrap 1`] = ` `; exports[`renders with wrap reverse 1`] = ` -
+
Hello World diff --git a/src/core/client/ui/components/MatchMedia/MatchMedia.mdx b/src/core/client/ui/components/MatchMedia/MatchMedia.mdx index 3f3186bb6..b9a64a328 100644 --- a/src/core/client/ui/components/MatchMedia/MatchMedia.mdx +++ b/src/core/client/ui/components/MatchMedia/MatchMedia.mdx @@ -12,29 +12,29 @@ import MatchMedia from './MatchMedia' ## Basic usage - + I'm a very small screen - + I'm a small screen - + I'm a medium screen - + I'm a large screen - + I'm a very large screen - + I'm a super large screen ## Using render props - + {matches => {matches ? "I'm big" : "I'm small"}} diff --git a/src/core/client/ui/components/MatchMedia/MatchMedia.spec.tsx b/src/core/client/ui/components/MatchMedia/MatchMedia.spec.tsx index 6f53df511..1b4ded65e 100644 --- a/src/core/client/ui/components/MatchMedia/MatchMedia.spec.tsx +++ b/src/core/client/ui/components/MatchMedia/MatchMedia.spec.tsx @@ -9,8 +9,8 @@ import { default as MatchMediaWithContext, MatchMedia } from "./MatchMedia"; it("renders correctly", () => { const props: PropTypesOf = { - minWidth: "xs", - maxWidth: "sm", + lteWidth: "xs", + gteWidth: "sm", component: "div", screen: true, children:
Hello World
, @@ -19,6 +19,16 @@ it("renders correctly", () => { expect(wrapper).toMatchSnapshot(); }); +it("renders less than and great than correctly", () => { + const props: PropTypesOf = { + ltWidth: "xs", + gtWidth: "sm", + children:
Hello World
, + }; + const wrapper = shallow(); + expect(wrapper).toMatchSnapshot(); +}); + it("map new speech prop to older aural prop", () => { const props: PropTypesOf = { speech: true, @@ -37,7 +47,7 @@ it("should get mediaQueryValues from context", () => { }; const wrapper = mount( - + Hello World diff --git a/src/core/client/ui/components/MatchMedia/MatchMedia.tsx b/src/core/client/ui/components/MatchMedia/MatchMedia.tsx index 8df6cff34..677e558bc 100644 --- a/src/core/client/ui/components/MatchMedia/MatchMedia.tsx +++ b/src/core/client/ui/components/MatchMedia/MatchMedia.tsx @@ -10,8 +10,17 @@ import UIContext from "../UIContext"; type Breakpoints = keyof typeof theme.breakpoints; interface InnerProps { - minWidth?: Breakpoints; - maxWidth?: Breakpoints; + /** greater than or equal width. */ + gteWidth?: Breakpoints; + + /** greater than width. */ + gtWidth?: Breakpoints; + + /** less than equals width. */ + lteWidth?: Breakpoints; + + /** less than equals width. */ + ltWidth?: Breakpoints; children: ReactNode | ((matches: boolean) => React.ReactNode); className?: string; component?: @@ -27,13 +36,21 @@ interface InnerProps { } export const MatchMedia: StatelessComponent = props => { - const { speech, minWidth, maxWidth, ...rest } = props; + const { speech, gteWidth, gtWidth, lteWidth, ltWidth, ...rest } = props; const mapped = { // TODO: Temporarily map newer speech to older aural type until // react-responsive supports the speech prop. aural: speech, - minWidth: minWidth ? theme.breakpoints[minWidth] + 1 : undefined, - maxWidth: maxWidth ? theme.breakpoints[maxWidth] : undefined, + minWidth: gtWidth + ? theme.breakpoints[gtWidth] + 1 + : gteWidth + ? theme.breakpoints[gteWidth] + : undefined, + maxWidth: ltWidth + ? theme.breakpoints[ltWidth] - 1 + : lteWidth + ? theme.breakpoints[lteWidth] + : undefined, }; return ; }; diff --git a/src/core/client/ui/components/MatchMedia/__snapshots__/MatchMedia.spec.tsx.snap b/src/core/client/ui/components/MatchMedia/__snapshots__/MatchMedia.spec.tsx.snap index a128d4ba0..88670e33f 100644 --- a/src/core/client/ui/components/MatchMedia/__snapshots__/MatchMedia.spec.tsx.snap +++ b/src/core/client/ui/components/MatchMedia/__snapshots__/MatchMedia.spec.tsx.snap @@ -14,8 +14,8 @@ exports[`map new speech prop to older aural prop 1`] = ` exports[`renders correctly 1`] = ` @@ -24,3 +24,15 @@ exports[`renders correctly 1`] = `
`; + +exports[`renders less than and great than correctly 1`] = ` + +
+ Hello World +
+
+`;