added responsive features

This commit is contained in:
David Sun
2019-03-19 17:55:41 -04:00
parent 3ed2c732bd
commit 519c375a42
8 changed files with 323 additions and 130 deletions

View File

@@ -30,7 +30,7 @@ interface BorderProps {
isBottom?: boolean;
}
export const ANNOUNCEMENT_BANNER_HEIGHT = '12rem';
export const ANNOUNCEMENT_BANNER_HEIGHT = '14rem';
export const AnnouncementBanner: React.StatelessComponent<Props> = (props: Props) => {
const { heading, subline, mainCta, secondaryCta } = props;
@@ -43,9 +43,9 @@ export const AnnouncementBanner: React.StatelessComponent<Props> = (props: Props
<CustomHeading>{heading}</CustomHeading>
{subline && (
<Paragraph color={colors.white} isMuted={0.5} isNoMargin={true}>
<CustomParagraph color={colors.white} isMuted={0.5} isNoMargin={true}>
{subline}
</Paragraph>
</CustomParagraph>
)}
</Column>
<ColumnCta>
@@ -72,15 +72,17 @@ export const AnnouncementBanner: React.StatelessComponent<Props> = (props: Props
)}
{secondaryCta && (
<Button
color={colors.white}
href={secondaryCta.href}
onClick={secondaryCta.onClick}
target={secondaryCta.shouldOpenInNewTab ? '_blank' : ''}
isTransparent={true}
>
{secondaryCta.text}
</Button>
<SecondaryButtonWrapper>
<Button
color={colors.white}
href={secondaryCta.href}
onClick={secondaryCta.onClick}
target={secondaryCta.shouldOpenInNewTab ? '_blank' : ''}
isTransparent={true}
>
{secondaryCta.text}
</Button>
</SecondaryButtonWrapper>
)}
</ButtonWrap>
</ColumnCta>
@@ -93,6 +95,13 @@ interface CustomSectionProps extends SectionProps {
dismissed: boolean;
}
const SecondaryButtonWrapper = styled.div`
display: inline-block;
@media (max-width: 56rem) {
display: none;
}
`;
const BannerContentWrapper = styled.div`
max-width: 1200px;
display: flex;
@@ -101,6 +110,15 @@ const BannerContentWrapper = styled.div`
align-items: center;
justify-content: space-between;
height: 100%;
@media (max-width: 56rem) {
flex-direction: column;
}
`;
const CustomParagraph = styled(Paragraph)`
@media (max-width: 56rem) {
display: none;
}
`;
const CustomSection = styled(Section)<CustomSectionProps>`
@@ -151,22 +169,22 @@ const CustomHeading = styled.h2`
const ButtonWrap = styled.div`
display: inline-block;
@media (min-width: 768px) {
* + * {
margin-left: 15px;
}
& > button,
a {
margin: 0 12px;
}
& *:first-child {
margin-left: 0;
}
& *:last-child {
margin-right: 0;
}
@media (max-width: 768px) {
a,
button {
display: block;
width: 220px;
}
* + * {
margin-top: 15px;
display: flex;
flex-direction: column-reverse;
& > button,
a {
margin: 0;
}
}
`;
@@ -185,7 +203,8 @@ const Border = styled.div<BorderProps>`
top: ${props => !props.isBottom && 0};
bottom: ${props => props.isBottom && 0};
transform: translate(-112px);
z-index: 0;
pointer-events: none;
@media (max-width: 768px) {
width: calc(100% + 82px);
height: 40px;

View File

@@ -93,7 +93,7 @@ const SectionBase = styled.section<SectionProps>`
width: ${props => !props.isFullWidth && 'calc(100% - 60px)'};
max-width: 1500px;
margin: 0 auto;
padding: ${props => (!!props.padding && props.padding) || (props.isPadded && '120px 0')};
padding: ${props => props.isPadded && '120px 0'};
background-color: ${props => props.theme[`${props.bgColor}BgColor`] || props.bgColor};
position: relative;
overflow: ${props => !props.isFullWidth && 'hidden'};

View File

@@ -56,8 +56,4 @@ const InputWrapper = styled.div<InputProps>`
position: relative;
width: ${props => props.width || '100%'};
border-bottom: 1px solid #d5d5d5;
@media (max-width: 768px) {
width: 100%;
margin-bottom: 30px;
}
`;

View File

@@ -10,7 +10,14 @@ import { Section } from 'ts/components/newLayout';
import { SiteWrap } from 'ts/components/siteWrap';
import { Heading } from 'ts/components/text';
import { Input as SearchInput } from 'ts/components/ui/search_textfield';
import { BY_NAME_ORDERINGS, EDITORIAL, FILTERS, ORDERINGS, PROJECTS } from 'ts/pages/explore/explore_content';
import {
AVAILABLE_ASSET_DATAS,
BY_NAME_ORDERINGS,
EDITORIAL,
FILTERS,
ORDERINGS,
PROJECTS,
} from 'ts/pages/explore/explore_content';
import { ExploreSettingsDropdown } from 'ts/pages/explore/explore_dropdown';
import { ExploreGrid } from 'ts/pages/explore/explore_grid';
import { EXPLORE_STATE_DIALOGS, ExploreGridDialogTile } from 'ts/pages/explore/explore_grid_state_tile';
@@ -70,7 +77,7 @@ export class Explore extends React.Component<ExploreProps> {
<SiteWrap theme="light">
<DocumentTitle {...documentConstants.EXPLORE} />
<ExploreHero query={this.state.query} onSearch={this._setNewQuery} />
<Section padding={'0 0 60px 0'} maxWidth={'1150px'}>
<Section isPadded={false} padding={'0 0 60px 0'} maxWidth={'1150px'}>
<ExploreToolBar
onFilterClick={this._setFilter}
filters={this.state.filters}
@@ -115,7 +122,6 @@ export class Explore extends React.Component<ExploreProps> {
private readonly _onOrdering = async (newValue: string): Promise<void> => {
this.setState({ tilesOrdering: newValue });
// tslint:disable-next-line:no-floating-promises
const newTiles = await this._generateTilesWithModifier(this.state.tiles, ExploreTilesModifiers.Ordering, {
tilesOrdering: newValue as ExploreTilesOrdering,
});
@@ -127,7 +133,6 @@ export class Explore extends React.Component<ExploreProps> {
};
private readonly _onAnalytics = (project: ExploreProject, action: ExploreAnalyticAction): void => {
// Do Something
switch (action) {
case ExploreAnalyticAction.InstantClick:
analytics.track('Explore - Instant - Clicked', { name: project.name });
@@ -174,7 +179,6 @@ export class Explore extends React.Component<ExploreProps> {
};
private readonly _changeSearchResults = async (query: string): Promise<void> => {
// tslint:disable-next-line:no-floating-promises
const searchedTiles = await this._generateTilesWithModifier(this.state.tiles, ExploreTilesModifiers.Search, {
query,
filter: this.state.filters.find(f => f.active),
@@ -196,7 +200,6 @@ export class Explore extends React.Component<ExploreProps> {
if (_.filter(updatedFilters, f => f.active).length === 0) {
await this._setFilter('all');
} else {
// tslint:disable-next-line:no-floating-promises
const newTiles = await this._generateTilesWithModifier(
this.state.tiles,
_.isEmpty(this.state.query) ? ExploreTilesModifiers.Filter : ExploreTilesModifiers.Search,
@@ -284,14 +287,17 @@ export class Explore extends React.Component<ExploreProps> {
const tiles = rawProjects.map((e: ExploreProject) => {
const exploreProject = _.assign({}, e);
if (!!exploreProject.instant) {
exploreProject.instant = _.assign({}, exploreProject.instant, {
availableAssetDatas: AVAILABLE_ASSET_DATAS,
});
exploreProject.onInstantClick = this._launchInstantAsync.bind(this, exploreProject.instant);
}
exploreProject.onAnalytics = this._onAnalytics.bind(this, exploreProject);
return {
name: e.name,
exploreProject,
visibility: ExploreTileVisibility.Visible,
width: ExploreTileWidth.OneThird,
onAnalytics: this._onAnalytics.bind(this, exploreProject),
};
});
const orderedTiles = await this._generateTilesWithModifier(tiles, ExploreTilesModifiers.Ordering, {
@@ -307,6 +313,23 @@ const ExploreHeroContentWrapper = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
padding: 100px 0;
@media (max-width: 36rem) {
display: block;
padding: 50px 0;
}
`;
const ExploreSearchInputWrapper = styled.div`
width: 22rem;
@media (max-width: 52rem) {
width: 16rem;
}
@media (max-width: 36rem) {
margin-top: 10px;
padding-left: 5px;
width: 100%;
}
`;
interface ExploreHeroProps {
@@ -319,12 +342,14 @@ const ExploreHero = (props: ExploreHeroProps) => {
props.onSearch(e.target.value);
};
return (
<Section maxWidth={'1150px'} padding={'50px 0 50px 0'}>
<Section maxWidth={'1150px'} isPadded={false}>
<ExploreHeroContentWrapper>
<Heading isNoMargin={true} size="large">
Explore 0x
</Heading>
<SearchInput value={props.query} onChange={onChange} width={'22rem'} placeholder="Search..." />
<ExploreSearchInputWrapper>
<SearchInput value={props.query} onChange={onChange} placeholder="Search..." />
</ExploreSearchInputWrapper>
</ExploreHeroContentWrapper>
</Section>
);
@@ -333,11 +358,17 @@ const ExploreHero = (props: ExploreHeroProps) => {
const ExploreToolBarWrapper = styled.div`
display: flex;
justify-content: space-between;
@media (max-width: 36rem) {
display: block;
}
`;
const ExploreToolBarContentWrapper = styled.div`
display: flex;
padding-bottom: 2rem;
@media (max-width: 36rem) {
display: none;
}
& > * {
margin: 0 0.3rem;
}

View File

@@ -126,3 +126,13 @@ export const BY_NAME_ORDERINGS: { [s: string]: string[] } = {
[ExploreTilesOrdering.RecentlyAdded]: ['veil', 'boxswap', 'emoon', 'paradex', 'radar_relay', 'openrelay'],
[ExploreTilesOrdering.Alphabetical]: ['veil', 'boxswap', 'emoon', 'paradex', 'radar_relay', 'openrelay'],
};
export const AVAILABLE_ASSET_DATAS: string[] = [
'0xf47261b000000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359', // DAI
'0xf47261b0000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC
'0xf47261b00000000000000000000000000d8775f648430679a709e98d2b0cb6250d2887ef', // BAT
'0xf47261b000000000000000000000000005f4a42e251f2d52b8ed15e9fedaacfcef1fad27', // ZIL
'0xf47261b00000000000000000000000000f5d2fb29fb7d3cfee444a200298f468908cc942', // MANA
'0xf47261b00000000000000000000000000abdace70d3790235af448c88547603b945604ea', // DNT
'0xf47261b000000000000000000000000041e5560054824ea6b0732e656e3ad64e20e94e45', // CVC
];

View File

@@ -1,14 +1,13 @@
import * as React from 'react';
import styled from 'styled-components';
import { Icon } from 'ts/components/icon';
import { Heading } from 'ts/components/text';
import { Switch } from 'ts/components/ui/switch';
import { ExploreTagButton } from 'ts/pages/explore/explore_tag_button';
import { colors } from 'ts/style/colors';
import { ExploreTilesOrdering, ExploreTilesOrderingMetadata } from 'ts/types';
import { ExploreFilterMetadata, ExploreTilesOrdering, ExploreTilesOrderingMetadata } from 'ts/types';
const OrderingListWrapper = styled.ul`
export const OrderingListWrapper = styled.ul`
list-style-type: none;
`;
@@ -16,7 +15,7 @@ interface OrderingListItemProps {
active?: boolean;
}
const OrderingListItem = styled.li<OrderingListItemProps>`
export const OrderingListItem = styled.li<OrderingListItemProps>`
margin-bottom: 12px;
cursor: pointer;
color: ${props => (props.active ? colors.brandLight : colors.grey)};
@@ -26,13 +25,17 @@ const OrderingListItem = styled.li<OrderingListItemProps>`
}
`;
const ExploreSettingsDropdownButton = ({}) => {
interface ExploreSettingsDropdownButtonProps {
title?: string;
}
export const ExploreSettingsDropdownButton = (props: ExploreSettingsDropdownButtonProps) => {
return (
<ExploreTagButton disableHover={true}>
<SettingsIconWrapper>
<Icon color={colors.grey} name="settings" size={16} />
</SettingsIconWrapper>
Sort
{props.title || 'Sort'}
</ExploreTagButton>
);
};
@@ -45,17 +48,17 @@ const SettingsIconWrapper = styled.div`
}
`;
const SettingsWrapper = styled.div`
export const SettingsWrapper = styled.div`
position: relative;
@media (min-width: 800px) {
&:hover > div {
display: block;
visibility: visible;
opacity: 1;
transform: translate3d(0, 0, 0);
transition: opacity 0.35s, transform 0.35s, visibility 0s;
}
@media (max-width: 36rem) {
display: none;
}
&:hover > div {
display: block;
visibility: visible;
opacity: 1;
transform: translate3d(0, 0, 0);
transition: opacity 0.35s, transform 0.35s, visibility 0s;
}
`;
@@ -63,7 +66,7 @@ interface DropdownWrapInterface {
width?: number;
}
const DropdownWrap = styled.div<DropdownWrapInterface>`
export const DropdownWrap = styled.div<DropdownWrapInterface>`
width: ${props => props.width || 280}px;
margin-top: calc(16px - 2rem);
padding: 16px 24px;
@@ -120,67 +123,147 @@ export interface ExploreSettingsDropdownProps {
onOrdering: (newValue: string) => void;
onEditorial?: (newValue: boolean) => void;
editorial?: boolean;
filters: ExploreFilterMetadata[];
onFilterClick(filterName: string, active: boolean): void;
}
export class ExploreSettingsDropdown extends React.Component<ExploreSettingsDropdownProps> {
public render(): React.ReactNode {
return (
<SettingsWrapper>
<ExploreSettingsDropdownButton />
<DropdownWrap>
<DropdownContentWrapper>
{!!this.props.onEditorial &&
<div>
<Switch
isChecked={this.props.editorial}
onToggle={this.props.onEditorial}
label="Editorial"
/>
<Heading asElement="h4" size={14} color="inherit" marginBottom="0" isMuted={0.35}>
Editorial content reflects the views of the 0x core team.
</Heading>
</div>}
<OrderingWrapper>
{/* <Heading asElement="h4" size={14} color="inherit" marginBottom="16px" isMuted={0.35}>
Ordering
</Heading> */}
<OrderingListWrapper>
{this.props.orderings.map(o => {
const onClick = () => this.props.onOrdering(o.ordering);
return (
<OrderingListItem
onClick={onClick}
active={this.props.activeOrdering === o.ordering}
key={o.ordering}
>
{o.label}
</OrderingListItem>
);
})}
</OrderingListWrapper>
</OrderingWrapper>
</DropdownContentWrapper>
</DropdownWrap>
</SettingsWrapper>
<>
<ExploreSettingsFullDropdown {...this.props} />
<ExploreMobileSettingsDropdown {...this.props} />
</>
);
}
}
const DropdownContentWrapper = styled.div``;
const ExploreSettingsFullDropdown = (props: ExploreSettingsDropdownProps) => {
return (
<SettingsWrapper>
<ExploreSettingsDropdownButton />
<DropdownWrap>
<DropdownContentWrapper>
{!!props.onEditorial && (
<div>
<Switch isChecked={props.editorial} onToggle={props.onEditorial} label="Editorial" />
<Heading asElement="h4" size={14} color="inherit" marginBottom="0" isMuted={0.35}>
Editorial content reflects the views of the 0x core team.
</Heading>
</div>
)}
<OrderingWrapper>
<OrderingListWrapper>
{props.orderings.map(o => {
const onClick = () => props.onOrdering(o.ordering);
return (
<OrderingListItem
onClick={onClick}
active={props.activeOrdering === o.ordering}
key={o.ordering}
>
{o.label}
</OrderingListItem>
);
})}
</OrderingListWrapper>
</OrderingWrapper>
</DropdownContentWrapper>
</DropdownWrap>
</SettingsWrapper>
);
};
const OrderingWrapper = styled.div`
export const DropdownContentWrapper = styled.div``;
export const OrderingWrapper = styled.div`
margin-top: 10px;
position: relative;
// padding-top: 20px;
// margin-bottom: 20px;
// &:before {
// content: '';
// width: 100%;
// height: 1px;
// background-color: ${props => props.theme.dropdownColor};
// opacity: 0.15;
// position: absolute;
// top: 0;
// left: 0;
// }
`;
const MobileSettingsWrapper = styled(SettingsWrapper)`
display: none;
@media (max-width: 36rem) {
display: block;
& > button {
width: 100%;
}
padding-bottom: 1rem;
}
`;
const MobileDropdownWrap = styled(DropdownWrap)`
width: 100%;
margin-top: 0;
left: 0;
&:after,
&:before {
left: 50%;
}
`;
interface ExploreMobileSettingsDropdownProps extends ExploreSettingsDropdownProps {
filters: ExploreFilterMetadata[];
onFilterClick(filterName: string, active: boolean): void;
}
export const ExploreMobileSettingsDropdown = (props: ExploreMobileSettingsDropdownProps) => {
return (
<MobileSettingsWrapper>
<ExploreSettingsDropdownButton title="Filter + Sort" />
<MobileDropdownWrap>
<DropdownContentWrapper>
<OrderingWrapper>
<Heading asElement="h4" size={14} color="inherit" marginBottom="16px" isMuted={0.35}>
Filter
</Heading>
<OrderingListWrapper>
{props.filters.map(f => {
const onClick = () => props.onFilterClick(f.name, !f.active);
return (
<OrderingListItem onClick={onClick} active={f.active} key={f.name}>
{f.label}
</OrderingListItem>
);
})}
</OrderingListWrapper>
</OrderingWrapper>
<BottomOrderingWrapper>
<Heading asElement="h4" size={14} color="inherit" marginBottom="16px" isMuted={0.35}>
Sort
</Heading>
<OrderingListWrapper>
{props.orderings.map(o => {
const onClick = () => props.onOrdering(o.ordering);
return (
<OrderingListItem
onClick={onClick}
active={props.activeOrdering === o.ordering}
key={o.ordering}
>
{o.label}
</OrderingListItem>
);
})}
</OrderingListWrapper>
</BottomOrderingWrapper>
</DropdownContentWrapper>
</MobileDropdownWrap>
</MobileSettingsWrapper>
);
};
const BottomOrderingWrapper = styled(OrderingWrapper)`
margin-top: 20px;
padding-top: 20px;
&:before {
content: '';
width: 100%;
height: 1px;
background-color: ${props => props.theme.dropdownColor};
opacity: 0.15;
position: absolute;
top: 0;
left: 0;
}
`;

View File

@@ -3,17 +3,44 @@ import * as React from 'react';
import styled from 'styled-components';
import { ExploreGridTile } from 'ts/pages/explore/explore_grid_tile';
import { ExploreTile, ExploreTileVisibility, ExploreTileWidth } from 'ts/types';
import { ExploreTile, ExploreTileGridWidth, ExploreTileVisibility, ExploreTileWidth } from 'ts/types';
const EXPLORE_TILE_COL_WIDTH: { [ExploreTileWidth: string]: { [ExploreTileGridWidth: number]: number } } = {
[ExploreTileWidth.OneThird]: {
[ExploreTileGridWidth.ThreeColumn]: 2,
[ExploreTileGridWidth.TwoColumn]: 2,
[ExploreTileGridWidth.OneColumn]: 2,
},
[ExploreTileWidth.FullWidth]: {
[ExploreTileGridWidth.ThreeColumn]: 6,
[ExploreTileGridWidth.TwoColumn]: 4,
[ExploreTileGridWidth.OneColumn]: 2,
},
[ExploreTileWidth.Half]: {
[ExploreTileGridWidth.ThreeColumn]: 3,
[ExploreTileGridWidth.TwoColumn]: 4,
[ExploreTileGridWidth.OneColumn]: 2,
},
[ExploreTileWidth.TwoThirds]: {
[ExploreTileGridWidth.ThreeColumn]: 4,
[ExploreTileGridWidth.TwoColumn]: 4,
[ExploreTileGridWidth.OneColumn]: 2,
},
};
export interface ExptoreGridProps {
tiles: ExploreTile[];
}
interface RicherExploreGridListTile extends ExploreTile {
interface ExploreGridTilePosition {
gridStart: number;
gridEnd: number;
}
interface RicherExploreGridListTile extends ExploreTile {
tilePositions: { [ExploreTileGridWidth: number]: ExploreGridTilePosition };
}
export class ExploreGrid extends React.Component<ExptoreGridProps> {
public render(): React.ReactNode {
return (
@@ -21,13 +48,13 @@ export class ExploreGrid extends React.Component<ExptoreGridProps> {
{this._prepareTiles().map(t => {
if (!!t.exploreProject) {
return (
<ExploreGridTileWrapper key={t.name} gridStart={t.gridStart} gridEnd={t.gridEnd}>
<ExploreGridTileWrapper key={t.name} tilePositions={t.tilePositions}>
<ExploreGridTile {...t.exploreProject} />
</ExploreGridTileWrapper>
);
} else {
return (
<ExploreGridTileWrapper key={t.name} gridStart={t.gridStart} gridEnd={t.gridEnd}>
<ExploreGridTileWrapper key={t.name} tilePositions={t.tilePositions}>
{!!t.component && t.component}
</ExploreGridTileWrapper>
);
@@ -42,18 +69,32 @@ export class ExploreGrid extends React.Component<ExptoreGridProps> {
return this._generateGridValues(visibleTiles);
};
private readonly _generateGridValues = (tiles: ExploreTile[]): RicherExploreGridListTile[] => {
private readonly _generateGridPositions = (
tiles: RicherExploreGridListTile[],
width: ExploreTileGridWidth,
): RicherExploreGridListTile[] => {
let gridEndCounter = 1;
const richerTiles = tiles.map(t => {
if (gridEndCounter + t.width > ExploreTileWidth.FullWidth + 1) {
const newTiles = tiles.map(t => {
if (gridEndCounter + EXPLORE_TILE_COL_WIDTH[t.width][width] > width + 1) {
gridEndCounter = 1;
}
const gridStart = gridEndCounter;
const gridEnd = gridEndCounter + t.width;
const gridEnd = gridEndCounter + EXPLORE_TILE_COL_WIDTH[t.width][width];
gridEndCounter = gridEnd;
const newTile = _.assign({ gridStart, gridEnd }, t);
return newTile as RicherExploreGridListTile;
const newTilePositions = _.assign({}, t.tilePositions);
newTilePositions[width] = { gridStart, gridEnd };
return _.assign({}, t, { tilePositions: newTilePositions }) as RicherExploreGridListTile;
});
return newTiles;
};
private readonly _generateGridValues = (tiles: ExploreTile[]): RicherExploreGridListTile[] => {
let richerTiles = tiles.map(t => {
return _.assign({ tilePositions: {} }, t) as RicherExploreGridListTile;
});
richerTiles = this._generateGridPositions(richerTiles, ExploreTileGridWidth.ThreeColumn);
richerTiles = this._generateGridPositions(richerTiles, ExploreTileGridWidth.TwoColumn);
richerTiles = this._generateGridPositions(richerTiles, ExploreTileGridWidth.OneColumn);
return richerTiles;
};
}
@@ -61,27 +102,34 @@ export class ExploreGrid extends React.Component<ExptoreGridProps> {
interface ExploreGridListProps {}
interface ExploreGridTileWrapperProps {
gridStart: number;
gridEnd: number;
tilePositions: { [ExploreTileGridWidth: number]: ExploreGridTilePosition };
}
const ExploreGridTileWrapper = styled.div<ExploreGridTileWrapperProps>`
grid-column-start: ${props => props.gridStart};
grid-column-end: ${props => props.gridEnd};
grid-column-start: ${props => props.tilePositions[ExploreTileGridWidth.ThreeColumn].gridStart};
grid-column-end: ${props => props.tilePositions[ExploreTileGridWidth.ThreeColumn].gridEnd};
@media (max-width: 56rem) {
grid-column-start: ${props => props.tilePositions[ExploreTileGridWidth.TwoColumn].gridStart};
grid-column-end: ${props => props.tilePositions[ExploreTileGridWidth.TwoColumn].gridEnd};
}
@media (max-width: 36rem) {
grid-column-start: ${props => props.tilePositions[ExploreTileGridWidth.OneColumn].gridStart};
grid-column-end: ${props => props.tilePositions[ExploreTileGridWidth.OneColumn].gridEnd};
}
`;
const ExploreGridList = styled.div<ExploreGridListProps>`
display: grid;
grid-template-columns: repeat(${ExploreTileWidth.FullWidth}, 1fr);
grid-template-columns: repeat(${ExploreTileGridWidth.ThreeColumn}, 1fr);
grid-column-gap: 1.5rem;
grid-row-gap: 1.5rem;
& > * {
align-self: stretch;
}
@media (max-width: 56rem) {
grid-template-columns: repeat(2, 1fr);
grid-template-columns: repeat(${ExploreTileGridWidth.TwoColumn}, 1fr);
}
@media (max-width: 36rem) {
grid-template-columns: repeat(1, 1fr);
grid-template-columns: repeat(${ExploreTileGridWidth.OneColumn}, 1fr);
}
`;

View File

@@ -306,10 +306,16 @@ export enum ExploreTileVisibility {
}
export enum ExploreTileWidth {
OneThird = 2,
FullWidth = 6,
Half = 3,
TwoThirds = 4,
OneThird = 'ONE_THIRD',
FullWidth = 'FULL_WIDTH',
Half = 'HALF',
TwoThirds = 'TWO_THIRDS',
}
export enum ExploreTileGridWidth {
ThreeColumn = 6,
TwoColumn = 4,
OneColumn = 2,
}
export interface ExploreTile {