Style fixes

* Fix missing navigation shadow
* Switch to grid organization at top level
* Force calc() sizes to guarantee elements occupy right size
This commit is contained in:
Thiago Chaves 2022-07-14 13:00:34 +03:00
parent c8ea641e0d
commit 72249d9105
7 changed files with 125 additions and 78 deletions

View File

@ -15,10 +15,14 @@ export function ExpressionCard({
}: ExpressionCardProps) { }: ExpressionCardProps) {
return ( return (
<article className="content-card"> <article className="content-card">
<h2 className="content-row text-title">{prompt}</h2> <h2 className="content-row text-title margin-small">{prompt}</h2>
<span className="content-row text-meta">{categories.join(", ")}</span> <span className="content-row text-meta margin-small">
{categories.join(", ")}
</span>
{show_description ? ( {show_description ? (
<div className="content-paragraph text-details">{description}</div> <div className="content-row text-details margin-paragraph">
{description}
</div>
) : null} ) : null}
</article> </article>
); );

View File

@ -11,9 +11,11 @@ export function ExpressionSetCard({
}: ExpressionSetCardProps) { }: ExpressionSetCardProps) {
return ( return (
<article className="content-card"> <article className="content-card">
<h2 className="content-row text-title">{name}</h2> <h2 className="content-row text-title margin-small">{name}</h2>
<span className="content-row text-meta">{word_count} word(s)</span> <span className="content-row text-meta margin-small">
<p className="content-paragraph text-details">{description}</p> {word_count} word(s)
</span>
<p className="content-row text-details margin-paragraph">{description}</p>
</article> </article>
); );
} }

View File

@ -15,8 +15,8 @@ export function ExpressionSetInfo({
word_count, word_count,
}: ExpressionSetInfo) { }: ExpressionSetInfo) {
return ( return (
<section className="expression-set-info"> <section>
<h2 className="content-row"> <h2 className="content-row margin-small">
<span className="text-title grow">{name}</span> <span className="text-title grow">{name}</span>
<Link <Link
href={{ href={{
@ -27,7 +27,7 @@ export function ExpressionSetInfo({
}} }}
passHref passHref
> >
<a className="icon-button justify-end"> <a className="icon-button">
<Image <Image
src="/icons/settings.svg" src="/icons/settings.svg"
width="24" width="24"
@ -37,8 +37,10 @@ export function ExpressionSetInfo({
</a> </a>
</Link> </Link>
</h2> </h2>
<span className="content-row text-meta">{word_count} word(s)</span> <span className="content-row text-meta margin-small">
<p className="content-paragraph text-details">{description}</p> {word_count} word(s)
</span>
<p className="content-row text-details margin-paragraph">{description}</p>
</section> </section>
); );
} }

View File

@ -17,18 +17,20 @@ const ExpressionSetDetailsPage: NextPage = () => {
if (!expression_set) if (!expression_set)
return ( return (
<Page> <Page>
<p className="details">Expression set not found</p> <div className="page-with-padding scroll">
<p className="text-details">Expression set not found</p>
</div>
</Page> </Page>
); );
// Fallback for expression set empty // Fallback for expression set empty TODO fix style
const word_count = expression_to_expression_set.filter( const word_count = expression_to_expression_set.filter(
(item) => item.expression_set_id === expression_set.id (item) => item.expression_set_id === expression_set.id
).length; ).length;
if (!word_count) if (!word_count)
return ( return (
<Page> <Page>
<div className="expression-set-page"> <div className="page-with-padding scroll">
<ExpressionSetInfo <ExpressionSetInfo
id={expression_set.id} id={expression_set.id}
name={expression_set.name} name={expression_set.name}
@ -42,25 +44,28 @@ const ExpressionSetDetailsPage: NextPage = () => {
return ( return (
<Page> <Page>
<div className="expression-set-page"> <div className="page-with-bottom-navigation">
<ExpressionSetInfo <section className="padding-small scroll">
id={expression_set.id} <ExpressionSetInfo
name={expression_set.name} id={expression_set.id}
description={expression_set.description} name={expression_set.name}
word_count={word_count} description={expression_set.description}
/> word_count={word_count}
<p className="text-details grow">{/* TODO other details */}</p> />
<Link </section>
href={{ <section className="navigation-bottom">
pathname: "/expression-sets/practice", <Link
query: { "set-id": expression_set.id }, href={{
}} pathname: "/expression-sets/practice",
passHref query: { "set-id": expression_set.id },
> }}
<a className="navigation-item text-navigation"> passHref
<span>Practice this set</span> >
</a> <a className="navigation-item-bottom text-navigation grow">
</Link> <span>Practice this set</span>
</a>
</Link>
</section>
</div> </div>
</Page> </Page>
); );

View File

@ -9,7 +9,7 @@ const ExpressionSetListPage: NextPage = () => {
return ( return (
<Page> <Page>
<div className="content-list"> <div className="page-with-padding content-list scroll">
{expression_sets.map(({ id, name, description }) => ( {expression_sets.map(({ id, name, description }) => (
<Link <Link
key={id} key={id}

View File

@ -1,4 +1,5 @@
import type { NextPage } from "next"; import type { NextPage } from "next";
import Link from "next/link";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { ExpressionCard } from "../../components"; import { ExpressionCard } from "../../components";
import { Page } from "../../components/Page"; import { Page } from "../../components/Page";
@ -10,7 +11,7 @@ import {
} from "../../util/data-utils"; } from "../../util/data-utils";
const ExpressionSetListPage: NextPage = () => { const ExpressionSetListPage: NextPage = () => {
const { query } = useRouter(); const { query, pathname } = useRouter();
const { const {
expressions, expressions,
categories, categories,
@ -26,7 +27,7 @@ const ExpressionSetListPage: NextPage = () => {
if (!expression_set) if (!expression_set)
return ( return (
<Page> <Page>
<p className="details">Expression set not found</p> <p className="text-details">Expression set not found</p>
</Page> </Page>
); );
@ -40,7 +41,7 @@ const ExpressionSetListPage: NextPage = () => {
if (expression_candidates.length === 0) { if (expression_candidates.length === 0) {
return ( return (
<Page> <Page>
<p className="details">No expressions left in this set</p> <p className="text-details">No expressions left in this set</p>
</Page> </Page>
); );
} }
@ -54,18 +55,30 @@ const ExpressionSetListPage: NextPage = () => {
expression_to_category, expression_to_category,
}); });
console.log("Expressions", expressions);
console.log("Categories", expression_categories);
console.log("Expression", expression);
return ( return (
<Page> <Page>
<ExpressionCard <div className="page-with-bottom-navigation">
prompt={expression.prompt} <section className="padding-small scroll">
categories={expression_categories.map((category) => category.name)} <ExpressionCard
description={expression.description} prompt={expression.prompt}
show_description categories={expression_categories.map((category) => category.name)}
/> description={expression.description}
show_description
/>
</section>
<section className="navigation-bottom">
<Link href={{ pathname, query }} passHref>
<a className="navigation-item-bottom text-navigation grow">
<div>wrong</div>
</a>
</Link>
<Link href={{ pathname, query }} passHref>
<a className="navigation-item-bottom text-navigation grow">
<div>right</div>
</a>
</Link>
</section>
</div>
</Page> </Page>
); );
}; };

View File

@ -42,9 +42,11 @@
/* Page */ /* Page */
.page { .page {
display: flex; background-color: lavender;
flex-direction: column; display: grid;
grid-template-columns: 1fr;
grid-template-rows: 64px calc(100vh - 72px); /* Is there a keyword solution for this? */
grid-gap: 8px;
height: 100vh; height: 100vh;
margin: auto; margin: auto;
max-width: 800px; max-width: 800px;
@ -53,19 +55,8 @@
.page > main { .page > main {
background-color: lavender; background-color: lavender;
display: block; display: block;
flex: 1;
position: relative; position: relative;
/* Will it conflict with overlays? Move elsewhere? */
padding: 16px;
height: 100%; height: 100%;
overflow-y: auto;
}
.content-list {
display: grid;
grid-template-columns: 1fr;
grid-gap: 16px;
} }
/* Navigation */ /* Navigation */
@ -76,6 +67,12 @@
box-shadow: 0px 5px 5px -5px darkslategray; box-shadow: 0px 5px 5px -5px darkslategray;
} }
.navigation-bottom {
display: flex;
flex-direction: row;
box-shadow: 0px 5px 5px 5px darkslategray;
}
.navigation > .navigation-li { .navigation > .navigation-li {
flex: 1; flex: 1;
} }
@ -96,6 +93,18 @@
height: 64px; height: 64px;
} }
.navigation-item-bottom {
display: flex;
flex-shrink: 0;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: lavenderblush;
border: 1px solid darkslategray;
height: 80px;
}
.navigation-item:hover { .navigation-item:hover {
background-color: antiquewhite; background-color: antiquewhite;
} }
@ -119,21 +128,8 @@
border: 1px solid slategray; border: 1px solid slategray;
} }
/* tofix */
.details {
color: darkslategray;
font-size: 15px;
margin: 20px 0px;
overflow-y: auto;
}
/* Content organization */ /* Content organization */
.content-page {
padding: 16px;
}
.content-card { .content-card {
background-color: lavender; background-color: lavender;
border: 1px solid darkslategray; border: 1px solid darkslategray;
@ -145,17 +141,42 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
}
.content-list {
display: flex;
flex-direction: column;
height: 100%;
}
.content-list > * + * {
margin-top: 16px;
}
/* Margins and paddings */
.padding-small {
padding: 8px 16px;
}
.margin-small {
margin: 10px 0px; margin: 10px 0px;
} }
.content-paragraph { .margin-paragraph {
margin: 20px 0px 10px; margin: 20px 0px 10px;
} }
/* Expression set page */ /* Expression set page */
.expression-set-page { .page-with-padding {
display: flex; padding: 8px 16px 16px;
flex-direction: column; }
.page-with-bottom-navigation {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: calc(100% - 88px) 80px;
grid-gap: 8px;
height: 100%; height: 100%;
} }