Merge pull request #112 from jedmund/rewrite-responsive-grid

Rewrite responsive grid
This commit is contained in:
Justin Edmund 2023-01-02 05:49:26 -08:00 committed by GitHub
commit 65986285bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 252 additions and 157 deletions

View file

@ -3,27 +3,36 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
margin: auto; margin: auto;
max-width: 761px; max-width: $grid-width;
@include breakpoint(tablet) { @include breakpoint(tablet) {
align-items: center; align-items: center;
} }
} }
#grid_characters { #Characters {
display: grid; display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr)); grid-template-columns: repeat(5, minmax(0, 1fr));
gap: $unit; gap: $unit-3x;
margin: 0; margin: 0;
padding: 0; padding: 0;
max-width: 761px; max-width: $grid-width;
isolation: isolate; isolation: isolate;
@include breakpoint(tablet) { @include breakpoint(tablet) {
gap: $unit-2x;
justify-content: space-between; justify-content: space-between;
width: 100%; width: 100%;
} }
// prettier-ignore
@media only screen
and (max-width: 500px)
and (max-height: 920px)
and (-webkit-min-device-pixel-ratio: 2) {
gap: $unit;
}
& > li:last-child { & > li:last-child {
margin: 0; margin: 0;
} }

View file

@ -361,7 +361,7 @@ const CharacterGrid = (props: Props) => {
resolveConflict={resolveConflict} resolveConflict={resolveConflict}
resetConflict={resetConflict} resetConflict={resetConflict}
/> />
<ul id="grid_characters"> <ul id="Characters">
{Array.from(Array(numCharacters)).map((x, i) => { {Array.from(Array(numCharacters)).map((x, i) => {
return ( return (
<li key={`grid_unit_${i}`}> <li key={`grid_unit_${i}`}>

View file

@ -76,4 +76,10 @@
} }
} }
} }
.CharacterName {
@include breakpoint(phone) {
font-size: $font-tiny;
}
}
} }

View file

@ -1,21 +1,35 @@
#ExtraSummons { .ExtraGrid.Summons {
background: var(--subaura-orange-bg); background: var(--subaura-orange-bg);
border-radius: 8px; border-radius: $input-corner;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: grid;
grid-template-columns: 2.32fr 2fr;
justify-content: center; justify-content: center;
margin: 20px auto; margin: 20px auto;
max-width: 727px; max-width: calc($grid-width + 20px);
padding: 16px 16px 16px 0; padding: $unit-3x $unit-3x $unit-3x 0;
position: relative; position: relative;
left: 9px; left: 9px;
@include breakpoint(phone) { @include breakpoint(tablet) {
left: auto; left: auto;
max-width: auto; max-width: $grid-width;
padding: $unit-2x;
width: 100%; width: 100%;
} }
@include breakpoint(phone) {
display: flex;
gap: $unit-2x;
padding: $unit-2x;
flex-direction: column;
#ExtraSummons {
max-width: 50vw;
margin: 0 auto;
}
}
& > span { & > span {
color: var(--subaura-orange-text); color: var(--subaura-orange-text);
display: flex; display: flex;
@ -23,17 +37,21 @@
justify-content: center; justify-content: center;
line-height: 1.2; line-height: 1.2;
font-weight: 500; font-weight: 500;
margin-right: 16px;
text-align: center; text-align: center;
width: 387px;
} }
#grid_summons { #ExtraSummons {
display: grid; display: grid;
grid-template-columns: auto auto; gap: $unit-3x;
grid-column-gap: $unit * 2; grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-rows: 1fr;
grid-row-gap: $unit * 3; @include breakpoint(tablet) {
gap: $unit-2x;
}
@include breakpoint(phone) {
gap: $unit;
}
& > li { & > li {
list-style: none; list-style: none;

View file

@ -21,9 +21,9 @@ const ExtraSummons = (props: Props) => {
const { t } = useTranslation('common') const { t } = useTranslation('common')
return ( return (
<div id="ExtraSummons"> <div className="ExtraGrid Summons">
<span>{t('summons.subaura')}</span> <span>{t('summons.subaura')}</span>
<ul id="grid_summons"> <ul id="ExtraSummons">
{Array.from(Array(numSummons)).map((x, i) => { {Array.from(Array(numSummons)).map((x, i) => {
return ( return (
<li key={`grid_unit_${i}`}> <li key={`grid_unit_${i}`}>

View file

@ -1,14 +1,15 @@
#ExtraGrid { .ExtraGrid.Weapons {
background: var(--extra-purple-bg); background: var(--extra-purple-bg);
border-radius: 8px; border-radius: $card-corner;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: grid;
grid-template-columns: 1.42fr 3fr;
justify-content: center; justify-content: center;
margin: 20px auto; margin: 20px auto;
max-width: 766px; max-width: calc($grid-width + 20px);
padding: 16px 16px 16px 0; padding: $unit-2x $unit-2x $unit-2x 0;
position: relative; position: relative;
left: 8px; left: $unit;
@include breakpoint(tablet) { @include breakpoint(tablet) {
left: auto; left: auto;
@ -16,6 +17,13 @@
width: 100%; width: 100%;
} }
@include breakpoint(phone) {
display: flex;
gap: $unit-2x;
padding: $unit-2x;
flex-direction: column;
}
& > span { & > span {
color: var(--extra-purple-text); color: var(--extra-purple-text);
display: flex; display: flex;
@ -24,17 +32,21 @@
justify-content: center; justify-content: center;
line-height: 1.2; line-height: 1.2;
font-weight: 500; font-weight: 500;
margin-right: 16px;
text-align: center; text-align: center;
} }
.grid_weapons { #ExtraWeapons {
display: flex; display: grid;
flex-direction: row; gap: $unit-3x;
flex-wrap: wrap; grid-template-columns: repeat(3, minmax(0, 1fr));
margin: 0;
padding: 0; @include breakpoint(tablet) {
max-width: 528px; gap: $unit-2x;
}
@include breakpoint(phone) {
gap: $unit;
}
} }
.WeaponUnit .WeaponImage { .WeaponUnit .WeaponImage {

View file

@ -21,9 +21,9 @@ const ExtraWeapons = (props: Props) => {
const { t } = useTranslation('common') const { t } = useTranslation('common')
return ( return (
<div id="ExtraGrid"> <div className="ExtraGrid Weapons">
<span>{t('extra_weapons')}</span> <span>{t('extra_weapons')}</span>
<ul className="grid_weapons"> <ul id="ExtraWeapons">
{Array.from(Array(numWeapons)).map((x, i) => { {Array.from(Array(numWeapons)).map((x, i) => {
return ( return (
<li key={`grid_unit_${i}`}> <li key={`grid_unit_${i}`}>

View file

@ -1,14 +1,20 @@
#Job { #Job {
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
margin-bottom: $unit * 3; margin-bottom: $unit-3x;
width: 100%;
@include breakpoint(tablet) { // prettier-ignore
align-items: center; @media only screen
flex-direction: column; and (max-width: 800px)
gap: $unit; and (max-height: 920px)
justify-content: center; and (-webkit-min-device-pixel-ratio: 2) {
max-width: 447px; align-items: center;
flex-direction: column;
gap: $unit;
justify-content: center;
width: 100%;
// max-width: 447px;
} }
select { select {
@ -60,8 +66,13 @@
width: $width; width: $width;
transition: box-shadow 0.15s ease-in-out; transition: box-shadow 0.15s ease-in-out;
@include breakpoint(tablet) { // prettier-ignore
margin-right: 0; @media only screen
and (max-width: 800px)
and (max-height: 920px)
and (-webkit-min-device-pixel-ratio: 2) {
margin-right: 0;
width: 100%;
} }
@include breakpoint(phone) { @include breakpoint(phone) {

View file

@ -1,7 +1,8 @@
.DetailsWrapper { .DetailsWrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-top: $unit-4x; margin: $unit-4x auto 0 auto;
max-width: $grid-width;
@include breakpoint(phone) { @include breakpoint(phone) {
padding: 0 $unit; padding: 0 $unit;

View file

@ -6,22 +6,30 @@
justify-content: center; justify-content: center;
margin: 0 auto; margin: 0 auto;
margin-bottom: $unit * 3; margin-bottom: $unit * 3;
max-width: 760px; max-width: $grid-width;
position: relative; position: relative;
@include breakpoint(phone) { // prettier-ignore
gap: $unit; @media only screen
margin-left: 0; and (max-width: 550px)
margin-right: 0; and (max-height: 920px)
padding: 0 $unit; and (-webkit-min-device-pixel-ratio: 2) {
max-width: auto; gap: $unit;
width: 100%; margin-left: 0;
margin-right: 0;
padding: 0 $unit;
max-width: auto;
width: 100%;
} }
.SegmentedControl { .SegmentedControl {
flex-grow: 1; flex-grow: 1;
@include breakpoint(phone) { // prettier-ignore
@media only screen
and (max-width: 550px)
and (max-height: 920px)
and (-webkit-min-device-pixel-ratio: 2) {
flex-grow: 1; flex-grow: 1;
width: 100%; width: 100%;
display: grid; display: grid;
@ -34,13 +42,18 @@
color: #888; color: #888;
display: flex; display: flex;
font-weight: $normal; font-weight: $normal;
gap: 8px; gap: $unit;
line-height: 34px; line-height: 34px;
height: 100%; height: 100%;
position: absolute; position: absolute;
right: 0px; right: 0px;
top: 1px;
@include breakpoint(phone) { // prettier-ignore
@media only screen
and (max-width: 550px)
and (max-height: 920px)
and (-webkit-min-device-pixel-ratio: 2) {
position: static; position: static;
.Text { .Text {

View file

@ -1,8 +1,18 @@
#SummonGrid { #SummonGrid {
display: grid; display: grid;
grid-template-columns: auto auto auto; grid-template-columns: repeat(2, minmax(0, 1fr)) 2fr;
grid-column-gap: $unit * 2; gap: $unit-3x;
justify-content: center; justify-content: center;
margin: 0 auto;
max-width: $grid-width;
@include breakpoint(tablet) {
gap: $unit-2x;
}
@include breakpoint(phone) {
gap: $unit;
}
& .Label { & .Label {
color: $grey-55; color: $grey-55;
@ -21,12 +31,19 @@
} }
} }
#grid_summons { #Summons {
display: grid; display: grid;
grid-template-columns: auto auto; grid-template-columns: repeat(2, minmax(0, 1fr));
grid-column-gap: $unit * 2; grid-template-rows: repeat(2, minmax(0, 1fr));
grid-template-rows: 1fr; gap: $unit-3x;
grid-row-gap: $unit * 3;
@include breakpoint(tablet) {
gap: $unit-2x;
}
@include breakpoint(phone) {
gap: $unit;
}
& > li { & > li {
list-style: none; list-style: none;

View file

@ -248,7 +248,7 @@ const SummonGrid = (props: Props) => {
const summonGridElement = ( const summonGridElement = (
<div id="LabeledGrid"> <div id="LabeledGrid">
<div className="Label">{t('summons.summons')}</div> <div className="Label">{t('summons.summons')}</div>
<ul id="grid_summons"> <ul id="Summons">
{Array.from(Array(numSummons)).map((x, i) => { {Array.from(Array(numSummons)).map((x, i) => {
return ( return (
<li key={`grid_unit_${i}`}> <li key={`grid_unit_${i}`}>

View file

@ -3,35 +3,18 @@
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
&.main .SummonImage,
&.friend .SummonImage {
aspect-ratio: 182 / 315;
width: 182px;
height: auto;
@include breakpoint(tablet) {
width: 20.3vw;
}
}
&.grid { &.grid {
// max-width: 148px; // max-width: 148px;
// min-height: 141px; // min-height: 141px;
min-height: 180px; min-height: 180px;
@include breakpoint(tablet) { @include breakpoint(tablet) {
min-height: 16.5vw; min-height: 15.9vw;
} }
.SummonImage { .SummonImage {
aspect-ratio: 148 / 111;
list-style-type: none; list-style-type: none;
width: 148px; width: 100%;
height: auto;
@include breakpoint(tablet) {
width: 20vw;
}
} }
} }
@ -77,6 +60,12 @@
} }
} }
.SummonName {
@include breakpoint(phone) {
font-size: $font-tiny;
}
}
&.filled h3 { &.filled h3 {
display: block; display: block;
} }
@ -103,5 +92,9 @@
position: relative; position: relative;
width: 100%; width: 100%;
z-index: 2; z-index: 2;
&.Placeholder {
opacity: 0;
}
} }
} }

View file

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useTranslation } from 'next-i18next' import { useTranslation } from 'next-i18next'
import classnames from 'classnames' import classNames from 'classnames'
import SearchModal from '~components/SearchModal' import SearchModal from '~components/SearchModal'
import SummonHovercard from '~components/SummonHovercard' import SummonHovercard from '~components/SummonHovercard'
@ -30,7 +30,7 @@ const SummonUnit = (props: Props) => {
const locale = const locale =
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en' router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
const classes = classnames({ const classes = classNames({
SummonUnit: true, SummonUnit: true,
main: props.unitType == 0, main: props.unitType == 0,
grid: props.unitType == 1, grid: props.unitType == 1,
@ -85,6 +85,12 @@ const SummonUnit = (props: Props) => {
setImageUrl(imgSrc) setImageUrl(imgSrc)
} }
function placeholderImageUrl() {
return props.unitType == 0 || props.unitType == 2
? '/images/placeholders/placeholder-summon-main.png'
: '/images/placeholders/placeholder-summon-grid.png'
}
function passUncapData(uncap: number) { function passUncapData(uncap: number) {
if (props.gridSummon) if (props.gridSummon)
props.updateUncap(props.gridSummon.id, props.position, uncap) props.updateUncap(props.gridSummon.id, props.position, uncap)
@ -92,7 +98,14 @@ const SummonUnit = (props: Props) => {
const image = ( const image = (
<div className="SummonImage"> <div className="SummonImage">
<img alt={summon?.name.en} className="grid_image" src={imageUrl} /> <img
alt={summon?.name.en}
className={classNames({
GridImage: true,
Placeholder: imageUrl === '',
})}
src={imageUrl !== '' ? imageUrl : placeholderImageUrl()}
/>
{props.editable ? ( {props.editable ? (
<span className="icon"> <span className="icon">
<PlusIcon /> <PlusIcon />

View file

@ -1,52 +1,51 @@
#MainGrid { #WeaponGrid {
align-items: center;
display: flex; display: flex;
flex-direction: column;
justify-content: center; justify-content: center;
@include breakpoint(phone) { #MainGrid {
display: grid; display: grid;
grid-template-columns: 1fr auto; gap: $unit-3x;
} grid-template-columns: 1.278fr 3fr;
justify-items: center;
.grid_weapons { grid-template-areas:
display: grid; 'mainhand grid'
grid-template-columns: 1fr 1fr 1fr; 'mainhand grid'
grid-template-rows: 1fr 1fr 1fr; 'mainhand grid';
margin: 0; max-width: $grid-width;
padding: 0;
max-width: 528px;
}
}
#MainGrid,
#ExtraGrid {
.grid_weapons > * {
margin-bottom: $unit-3x;
margin-right: $unit-3x;
@include breakpoint(tablet) { @include breakpoint(tablet) {
margin-bottom: $unit-2x; gap: $unit-2x;
margin-right: $unit-2x;
} }
@include breakpoint(phone) {
gap: $unit;
}
}
#Weapons {
display: grid; /* make the right-images container a grid */
grid-template-columns: repeat(
3,
minmax(0, 1fr)
); /* create 3 columns, each taking up 1 fraction */
grid-template-rows: repeat(
3,
1fr
); /* create 3 rows, each taking up 1 fraction */
gap: $unit-3x;
@include breakpoint(tablet) { @include breakpoint(tablet) {
margin-bottom: $unit; gap: $unit-2x;
margin-right: $unit;
} }
&:nth-last-child(-n + 3) { @include breakpoint(phone) {
margin-bottom: 0; gap: $unit;
} }
} }
.grid_weapons > *:nth-child(3n + 3) { li {
margin-right: 0;
}
.grid_weapons > li {
list-style: none; list-style: none;
} }
} }
#ExtraWeapons #grid_weapons > * {
margin-bottom: 0;
}

View file

@ -361,7 +361,7 @@ const WeaponGrid = (props: Props) => {
{incompatibleAlert()} {incompatibleAlert()}
<div id="MainGrid"> <div id="MainGrid">
{mainhandElement} {mainhandElement}
<ul className="grid_weapons">{weaponGridElement}</ul> <ul id="Weapons">{weaponGridElement}</ul>
</div> </div>
{(() => { {(() => {

View file

@ -1,9 +1,11 @@
.WeaponUnit { .WeaponUnit {
align-items: center;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 4px; gap: $unit-half;
min-height: 139px;
position: relative; position: relative;
width: 100%;
height: auto;
@include breakpoint(tablet) { @include breakpoint(tablet) {
min-height: auto; min-height: auto;
@ -25,25 +27,14 @@
} }
&.mainhand { &.mainhand {
margin-right: $unit-3x; display: flex;
max-width: 200px;
@include breakpoint(tablet) {
margin-right: $unit-2x;
}
@include breakpoint(phone) {
margin-right: $unit-2x;
margin-right: $unit;
}
&.editable .WeaponImage:hover { &.editable .WeaponImage:hover {
transform: $scale-tall; transform: $scale-tall;
} }
.WeaponImage { .WeaponImage {
aspect-ratio: 200 / 418; width: 100%;
width: 200px;
height: auto; height: auto;
.Awakening { .Awakening {
@ -62,20 +53,13 @@
height: auto; height: auto;
} }
} }
@include breakpoint(tablet) {
width: 25vw;
}
} }
} }
&.grid { &.grid {
max-width: 160px;
.WeaponImage { .WeaponImage {
aspect-ratio: 160 / 92;
list-style-type: none; list-style-type: none;
width: 160px; width: 100%;
height: auto; height: auto;
.Awakening { .Awakening {
@ -94,10 +78,6 @@
height: auto; height: auto;
} }
} }
@include breakpoint(tablet) {
width: 20vw;
}
} }
} }
@ -176,6 +156,10 @@
position: relative; position: relative;
width: 100%; width: 100%;
z-index: 2; z-index: 2;
&.Placeholder {
opacity: 0;
}
} }
.icon { .icon {
@ -189,4 +173,10 @@
} }
} }
} }
.WeaponName {
@include breakpoint(phone) {
font-size: $font-tiny;
}
}
} }

View file

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useTranslation } from 'next-i18next' import { useTranslation } from 'next-i18next'
import classnames from 'classnames' import classNames from 'classnames'
import SearchModal from '~components/SearchModal' import SearchModal from '~components/SearchModal'
import WeaponModal from '~components/WeaponModal' import WeaponModal from '~components/WeaponModal'
@ -36,7 +36,7 @@ const WeaponUnit = (props: Props) => {
const locale = const locale =
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en' router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
const classes = classnames({ const classes = classNames({
WeaponUnit: true, WeaponUnit: true,
mainhand: props.unitType == 0, mainhand: props.unitType == 0,
grid: props.unitType == 1, grid: props.unitType == 1,
@ -73,6 +73,12 @@ const WeaponUnit = (props: Props) => {
setImageUrl(imgSrc) setImageUrl(imgSrc)
} }
function placeholderImageUrl() {
return props.unitType == 0
? '/images/placeholders/placeholder-weapon-main.png'
: '/images/placeholders/placeholder-weapon-grid.png'
}
function awakeningImage() { function awakeningImage() {
if ( if (
props.gridWeapon && props.gridWeapon &&
@ -366,7 +372,14 @@ const WeaponUnit = (props: Props) => {
{ultimaImages()} {ultimaImages()}
</div> </div>
</div> </div>
<img alt={weapon?.name.en} className="grid_image" src={imageUrl} /> <img
alt={weapon?.name.en}
className={classNames({
GridImage: true,
Placeholder: imageUrl === '',
})}
src={imageUrl !== '' ? imageUrl : placeholderImageUrl()}
/>
{props.editable ? ( {props.editable ? (
<span className="icon"> <span className="icon">
<PlusIcon /> <PlusIcon />
@ -395,9 +408,7 @@ const WeaponUnit = (props: Props) => {
gridWeapon.id && gridWeapon.id &&
canBeModified(gridWeapon) ? ( canBeModified(gridWeapon) ? (
<WeaponModal gridWeapon={gridWeapon}> <WeaponModal gridWeapon={gridWeapon}>
<div> <Button accessoryIcon={<SettingsIcon />} />
<Button accessoryIcon={<SettingsIcon />} />
</div>
</WeaponModal> </WeaponModal>
) : ( ) : (
'' ''

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -13,6 +13,8 @@ $laptop: 1280px;
$tablet: 768px; $tablet: 768px;
$phone: 375px; $phone: 375px;
$grid-width: 720px;
// Legacy // Legacy
$medium-screen: 768px; $medium-screen: 768px;