Implement radix select
This commit is contained in:
parent
e155aa72dd
commit
c37f0754fb
14 changed files with 512 additions and 289 deletions
|
|
@ -3,7 +3,7 @@
|
|||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
padding: 0;
|
||||
margin: 0 0 $unit 0;
|
||||
margin: 0;
|
||||
|
||||
.Input {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
|
|
|||
|
|
@ -1,55 +1,55 @@
|
|||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { useSnapshot } from "valtio";
|
||||
import { getCookie } from "cookies-next";
|
||||
import clonedeep from "lodash.clonedeep";
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useSnapshot } from 'valtio'
|
||||
import { getCookie } from 'cookies-next'
|
||||
import clonedeep from 'lodash.clonedeep'
|
||||
|
||||
import PartySegmentedControl from "~components/PartySegmentedControl";
|
||||
import PartyDetails from "~components/PartyDetails";
|
||||
import WeaponGrid from "~components/WeaponGrid";
|
||||
import SummonGrid from "~components/SummonGrid";
|
||||
import CharacterGrid from "~components/CharacterGrid";
|
||||
import PartySegmentedControl from '~components/PartySegmentedControl'
|
||||
import PartyDetails from '~components/PartyDetails'
|
||||
import WeaponGrid from '~components/WeaponGrid'
|
||||
import SummonGrid from '~components/SummonGrid'
|
||||
import CharacterGrid from '~components/CharacterGrid'
|
||||
|
||||
import api from "~utils/api";
|
||||
import { appState, initialAppState } from "~utils/appState";
|
||||
import { GridType, TeamElement } from "~utils/enums";
|
||||
import api from '~utils/api'
|
||||
import { appState, initialAppState } from '~utils/appState'
|
||||
import { GridType, TeamElement } from '~utils/enums'
|
||||
|
||||
import "./index.scss";
|
||||
import './index.scss'
|
||||
|
||||
// Props
|
||||
interface Props {
|
||||
new?: boolean;
|
||||
team?: Party;
|
||||
raids: Raid[][];
|
||||
pushHistory?: (path: string) => void;
|
||||
new?: boolean
|
||||
team?: Party
|
||||
raids: Raid[][]
|
||||
pushHistory?: (path: string) => void
|
||||
}
|
||||
|
||||
const Party = (props: Props) => {
|
||||
// Cookies
|
||||
const cookie = getCookie("account");
|
||||
const cookie = getCookie('account')
|
||||
const accountData: AccountCookie = cookie
|
||||
? JSON.parse(cookie as string)
|
||||
: null;
|
||||
: null
|
||||
|
||||
const headers = useMemo(() => {
|
||||
return accountData
|
||||
? { headers: { Authorization: `Bearer ${accountData.token}` } }
|
||||
: {};
|
||||
}, [accountData]);
|
||||
: {}
|
||||
}, [accountData])
|
||||
|
||||
// Set up router
|
||||
const router = useRouter();
|
||||
const router = useRouter()
|
||||
|
||||
// Set up states
|
||||
const { party } = useSnapshot(appState);
|
||||
const [currentTab, setCurrentTab] = useState<GridType>(GridType.Weapon);
|
||||
const { party } = useSnapshot(appState)
|
||||
const [currentTab, setCurrentTab] = useState<GridType>(GridType.Weapon)
|
||||
|
||||
// Reset state on first load
|
||||
useEffect(() => {
|
||||
const resetState = clonedeep(initialAppState);
|
||||
appState.grid = resetState.grid;
|
||||
if (props.team) storeParty(props.team);
|
||||
}, []);
|
||||
const resetState = clonedeep(initialAppState)
|
||||
appState.grid = resetState.grid
|
||||
if (props.team) storeParty(props.team)
|
||||
}, [])
|
||||
|
||||
// Methods: Creating a new party
|
||||
async function createParty(extra: boolean = false) {
|
||||
|
|
@ -58,14 +58,14 @@ const Party = (props: Props) => {
|
|||
...(accountData && { user_id: accountData.userId }),
|
||||
extra: extra,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return await api.endpoints.parties.create(body, headers);
|
||||
return await api.endpoints.parties.create(body, headers)
|
||||
}
|
||||
|
||||
// Methods: Updating the party's details
|
||||
function checkboxChanged(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
appState.party.extra = event.target.checked;
|
||||
appState.party.extra = event.target.checked
|
||||
|
||||
if (party.id) {
|
||||
api.endpoints.parties.update(
|
||||
|
|
@ -74,7 +74,7 @@ const Party = (props: Props) => {
|
|||
party: { extra: event.target.checked },
|
||||
},
|
||||
headers
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -98,11 +98,11 @@ const Party = (props: Props) => {
|
|||
headers
|
||||
)
|
||||
.then(() => {
|
||||
appState.party.name = name;
|
||||
appState.party.description = description;
|
||||
appState.party.raid = raid;
|
||||
appState.party.updated_at = party.updated_at;
|
||||
});
|
||||
appState.party.name = name
|
||||
appState.party.description = description
|
||||
appState.party.raid = raid
|
||||
appState.party.updated_at = party.updated_at
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,95 +113,95 @@ const Party = (props: Props) => {
|
|||
.destroy({ id: appState.party.id, params: headers })
|
||||
.then(() => {
|
||||
// Push to route
|
||||
router.push("/");
|
||||
router.push('/')
|
||||
|
||||
// Clean state
|
||||
const resetState = clonedeep(initialAppState);
|
||||
const resetState = clonedeep(initialAppState)
|
||||
Object.keys(resetState).forEach((key) => {
|
||||
appState[key] = resetState[key];
|
||||
});
|
||||
appState[key] = resetState[key]
|
||||
})
|
||||
|
||||
// Set party to be editable
|
||||
appState.party.editable = true;
|
||||
appState.party.editable = true
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
console.error(error)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Methods: Storing party data
|
||||
const storeParty = function (party: Party) {
|
||||
// Store the important party and state-keeping values
|
||||
appState.party.name = party.name;
|
||||
appState.party.description = party.description;
|
||||
appState.party.raid = party.raid;
|
||||
appState.party.updated_at = party.updated_at;
|
||||
appState.party.job = party.job;
|
||||
appState.party.jobSkills = party.job_skills;
|
||||
appState.party.name = party.name
|
||||
appState.party.description = party.description
|
||||
appState.party.raid = party.raid
|
||||
appState.party.updated_at = party.updated_at
|
||||
appState.party.job = party.job
|
||||
appState.party.jobSkills = party.job_skills
|
||||
|
||||
appState.party.id = party.id;
|
||||
appState.party.extra = party.extra;
|
||||
appState.party.user = party.user;
|
||||
appState.party.favorited = party.favorited;
|
||||
appState.party.created_at = party.created_at;
|
||||
appState.party.updated_at = party.updated_at;
|
||||
appState.party.id = party.id
|
||||
appState.party.extra = party.extra
|
||||
appState.party.user = party.user
|
||||
appState.party.favorited = party.favorited
|
||||
appState.party.created_at = party.created_at
|
||||
appState.party.updated_at = party.updated_at
|
||||
|
||||
// Populate state
|
||||
storeCharacters(party.characters);
|
||||
storeWeapons(party.weapons);
|
||||
storeSummons(party.summons);
|
||||
};
|
||||
storeCharacters(party.characters)
|
||||
storeWeapons(party.weapons)
|
||||
storeSummons(party.summons)
|
||||
}
|
||||
|
||||
const storeCharacters = (list: Array<GridCharacter>) => {
|
||||
list.forEach((object: GridCharacter) => {
|
||||
if (object.position != null)
|
||||
appState.grid.characters[object.position] = object;
|
||||
});
|
||||
};
|
||||
appState.grid.characters[object.position] = object
|
||||
})
|
||||
}
|
||||
|
||||
const storeWeapons = (list: Array<GridWeapon>) => {
|
||||
list.forEach((gridObject: GridWeapon) => {
|
||||
if (gridObject.mainhand) {
|
||||
appState.grid.weapons.mainWeapon = gridObject;
|
||||
appState.party.element = gridObject.object.element;
|
||||
appState.grid.weapons.mainWeapon = gridObject
|
||||
appState.party.element = gridObject.object.element
|
||||
} else if (!gridObject.mainhand && gridObject.position != null) {
|
||||
appState.grid.weapons.allWeapons[gridObject.position] = gridObject;
|
||||
appState.grid.weapons.allWeapons[gridObject.position] = gridObject
|
||||
}
|
||||
});
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
const storeSummons = (list: Array<GridSummon>) => {
|
||||
list.forEach((gridObject: GridSummon) => {
|
||||
if (gridObject.main) appState.grid.summons.mainSummon = gridObject;
|
||||
if (gridObject.main) appState.grid.summons.mainSummon = gridObject
|
||||
else if (gridObject.friend)
|
||||
appState.grid.summons.friendSummon = gridObject;
|
||||
appState.grid.summons.friendSummon = gridObject
|
||||
else if (
|
||||
!gridObject.main &&
|
||||
!gridObject.friend &&
|
||||
gridObject.position != null
|
||||
)
|
||||
appState.grid.summons.allSummons[gridObject.position] = gridObject;
|
||||
});
|
||||
};
|
||||
appState.grid.summons.allSummons[gridObject.position] = gridObject
|
||||
})
|
||||
}
|
||||
|
||||
// Methods: Navigating with segmented control
|
||||
function segmentClicked(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
switch (event.target.value) {
|
||||
case "class":
|
||||
setCurrentTab(GridType.Class);
|
||||
break;
|
||||
case "characters":
|
||||
setCurrentTab(GridType.Character);
|
||||
break;
|
||||
case "weapons":
|
||||
setCurrentTab(GridType.Weapon);
|
||||
break;
|
||||
case "summons":
|
||||
setCurrentTab(GridType.Summon);
|
||||
break;
|
||||
case 'class':
|
||||
setCurrentTab(GridType.Class)
|
||||
break
|
||||
case 'characters':
|
||||
setCurrentTab(GridType.Character)
|
||||
break
|
||||
case 'weapons':
|
||||
setCurrentTab(GridType.Weapon)
|
||||
break
|
||||
case 'summons':
|
||||
setCurrentTab(GridType.Summon)
|
||||
break
|
||||
default:
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ const Party = (props: Props) => {
|
|||
onClick={segmentClicked}
|
||||
onCheckboxChange={checkboxChanged}
|
||||
/>
|
||||
);
|
||||
)
|
||||
|
||||
const weaponGrid = (
|
||||
<WeaponGrid
|
||||
|
|
@ -221,7 +221,7 @@ const Party = (props: Props) => {
|
|||
createParty={createParty}
|
||||
pushHistory={props.pushHistory}
|
||||
/>
|
||||
);
|
||||
)
|
||||
|
||||
const summonGrid = (
|
||||
<SummonGrid
|
||||
|
|
@ -230,7 +230,7 @@ const Party = (props: Props) => {
|
|||
createParty={createParty}
|
||||
pushHistory={props.pushHistory}
|
||||
/>
|
||||
);
|
||||
)
|
||||
|
||||
const characterGrid = (
|
||||
<CharacterGrid
|
||||
|
|
@ -239,21 +239,21 @@ const Party = (props: Props) => {
|
|||
createParty={createParty}
|
||||
pushHistory={props.pushHistory}
|
||||
/>
|
||||
);
|
||||
)
|
||||
|
||||
const currentGrid = () => {
|
||||
switch (currentTab) {
|
||||
case GridType.Character:
|
||||
return characterGrid;
|
||||
return characterGrid
|
||||
case GridType.Weapon:
|
||||
return weaponGrid;
|
||||
return weaponGrid
|
||||
case GridType.Summon:
|
||||
return summonGrid;
|
||||
return summonGrid
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<React.Fragment>
|
||||
{navigation}
|
||||
<section id="Party">{currentGrid()}</section>
|
||||
{
|
||||
|
|
@ -263,8 +263,8 @@ const Party = (props: Props) => {
|
|||
deleteCallback={deleteTeam}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default Party;
|
||||
export default Party
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
.PartyDetails {
|
||||
display: none; // This breaks transition, find a workaround
|
||||
opacity: 0;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 100px;
|
||||
margin: $unit-4x auto 0;
|
||||
max-width: $unit * 95;
|
||||
position: relative;
|
||||
|
||||
|
|
@ -13,9 +12,10 @@
|
|||
transition: opacity 0.2s ease-in-out, top 0.2s ease-in-out;
|
||||
|
||||
&.Visible {
|
||||
display: block;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $unit;
|
||||
height: auto;
|
||||
margin-bottom: 40vh;
|
||||
opacity: 1;
|
||||
top: 0;
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: $unit;
|
||||
margin-bottom: $unit-12x;
|
||||
|
||||
.left {
|
||||
flex-grow: 1;
|
||||
|
|
@ -108,7 +109,7 @@
|
|||
}
|
||||
|
||||
& > *:not(:last-child):after {
|
||||
content: " · ";
|
||||
content: ' · ';
|
||||
margin: 0 calc($unit / 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -146,7 +147,7 @@
|
|||
.EmptyDetails {
|
||||
display: none;
|
||||
justify-content: center;
|
||||
margin-bottom: $unit * 10;
|
||||
margin: $unit-4x 0 $unit-10x;
|
||||
|
||||
&.Visible {
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -1,81 +1,81 @@
|
|||
import React, { useState } from "react";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
import { useSnapshot } from "valtio";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import React, { useState } from 'react'
|
||||
import Head from 'next/head'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useSnapshot } from 'valtio'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
import Linkify from "react-linkify";
|
||||
import classNames from "classnames";
|
||||
import Linkify from 'react-linkify'
|
||||
import classNames from 'classnames'
|
||||
|
||||
import * as AlertDialog from "@radix-ui/react-alert-dialog";
|
||||
import CrossIcon from "~public/icons/Cross.svg";
|
||||
import * as AlertDialog from '@radix-ui/react-alert-dialog'
|
||||
import CrossIcon from '~public/icons/Cross.svg'
|
||||
|
||||
import Button from "~components/Button";
|
||||
import CharLimitedFieldset from "~components/CharLimitedFieldset";
|
||||
import RaidDropdown from "~components/RaidDropdown";
|
||||
import TextFieldset from "~components/TextFieldset";
|
||||
import Button from '~components/Button'
|
||||
import CharLimitedFieldset from '~components/CharLimitedFieldset'
|
||||
import RaidDropdown from '~components/RaidDropdown'
|
||||
import TextFieldset from '~components/TextFieldset'
|
||||
|
||||
import { accountState } from "~utils/accountState";
|
||||
import { appState } from "~utils/appState";
|
||||
import { accountState } from '~utils/accountState'
|
||||
import { appState } from '~utils/appState'
|
||||
|
||||
import "./index.scss";
|
||||
import Link from "next/link";
|
||||
import { formatTimeAgo } from "~utils/timeAgo";
|
||||
import './index.scss'
|
||||
import Link from 'next/link'
|
||||
import { formatTimeAgo } from '~utils/timeAgo'
|
||||
|
||||
const emptyRaid: Raid = {
|
||||
id: "",
|
||||
id: '',
|
||||
name: {
|
||||
en: "",
|
||||
ja: "",
|
||||
en: '',
|
||||
ja: '',
|
||||
},
|
||||
slug: "",
|
||||
slug: '',
|
||||
level: 0,
|
||||
group: 0,
|
||||
element: 0,
|
||||
};
|
||||
}
|
||||
|
||||
// Props
|
||||
interface Props {
|
||||
editable: boolean;
|
||||
updateCallback: (name?: string, description?: string, raid?: Raid) => void;
|
||||
editable: boolean
|
||||
updateCallback: (name?: string, description?: string, raid?: Raid) => void
|
||||
deleteCallback: (
|
||||
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
|
||||
) => void;
|
||||
) => void
|
||||
}
|
||||
|
||||
const PartyDetails = (props: Props) => {
|
||||
const { party, raids } = useSnapshot(appState);
|
||||
const { account } = useSnapshot(accountState);
|
||||
const { party, raids } = useSnapshot(appState)
|
||||
const { account } = useSnapshot(accountState)
|
||||
|
||||
const { t } = useTranslation("common");
|
||||
const router = useRouter();
|
||||
const locale = router.locale || "en";
|
||||
const { t } = useTranslation('common')
|
||||
const router = useRouter()
|
||||
const locale = router.locale || 'en'
|
||||
|
||||
const nameInput = React.createRef<HTMLInputElement>();
|
||||
const descriptionInput = React.createRef<HTMLTextAreaElement>();
|
||||
const raidSelect = React.createRef<HTMLSelectElement>();
|
||||
const nameInput = React.createRef<HTMLInputElement>()
|
||||
const descriptionInput = React.createRef<HTMLTextAreaElement>()
|
||||
const raidSelect = React.createRef<HTMLSelectElement>()
|
||||
|
||||
const readOnlyClasses = classNames({
|
||||
PartyDetails: true,
|
||||
ReadOnly: true,
|
||||
Visible: !party.detailsVisible,
|
||||
});
|
||||
})
|
||||
|
||||
const editableClasses = classNames({
|
||||
PartyDetails: true,
|
||||
Editable: true,
|
||||
Visible: party.detailsVisible,
|
||||
});
|
||||
})
|
||||
|
||||
const emptyClasses = classNames({
|
||||
EmptyDetails: true,
|
||||
Visible: !party.detailsVisible,
|
||||
});
|
||||
})
|
||||
|
||||
const userClass = classNames({
|
||||
user: true,
|
||||
empty: !party.user,
|
||||
});
|
||||
})
|
||||
|
||||
const linkClass = classNames({
|
||||
wind: party && party.element == 1,
|
||||
|
|
@ -84,42 +84,42 @@ const PartyDetails = (props: Props) => {
|
|||
earth: party && party.element == 4,
|
||||
dark: party && party.element == 5,
|
||||
light: party && party.element == 6,
|
||||
});
|
||||
})
|
||||
|
||||
const [errors, setErrors] = useState<{ [key: string]: string }>({
|
||||
name: "",
|
||||
description: "",
|
||||
});
|
||||
name: '',
|
||||
description: '',
|
||||
})
|
||||
|
||||
function handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
event.preventDefault();
|
||||
event.preventDefault()
|
||||
|
||||
const { name, value } = event.target;
|
||||
let newErrors = errors;
|
||||
const { name, value } = event.target
|
||||
let newErrors = errors
|
||||
|
||||
setErrors(newErrors);
|
||||
setErrors(newErrors)
|
||||
}
|
||||
|
||||
function handleTextAreaChange(event: React.ChangeEvent<HTMLTextAreaElement>) {
|
||||
event.preventDefault();
|
||||
event.preventDefault()
|
||||
|
||||
const { name, value } = event.target;
|
||||
let newErrors = errors;
|
||||
const { name, value } = event.target
|
||||
let newErrors = errors
|
||||
|
||||
setErrors(newErrors);
|
||||
setErrors(newErrors)
|
||||
}
|
||||
|
||||
function toggleDetails() {
|
||||
appState.party.detailsVisible = !appState.party.detailsVisible;
|
||||
appState.party.detailsVisible = !appState.party.detailsVisible
|
||||
}
|
||||
|
||||
function updateDetails(event: React.MouseEvent) {
|
||||
const nameValue = nameInput.current?.value;
|
||||
const descriptionValue = descriptionInput.current?.value;
|
||||
const raid = raids.find((raid) => raid.slug === raidSelect.current?.value);
|
||||
const nameValue = nameInput.current?.value
|
||||
const descriptionValue = descriptionInput.current?.value
|
||||
const raid = raids.find((raid) => raid.slug === raidSelect.current?.value)
|
||||
|
||||
props.updateCallback(nameValue, descriptionValue, raid);
|
||||
toggleDetails();
|
||||
props.updateCallback(nameValue, descriptionValue, raid)
|
||||
toggleDetails()
|
||||
}
|
||||
|
||||
const userImage = () => {
|
||||
|
|
@ -132,18 +132,18 @@ const PartyDetails = (props: Props) => {
|
|||
/profile/${party.user.picture.picture}@2x.png 2x`}
|
||||
src={`/profile/${party.user.picture.picture}.png`}
|
||||
/>
|
||||
);
|
||||
else return <div className="no-user" />;
|
||||
};
|
||||
)
|
||||
else return <div className="no-user" />
|
||||
}
|
||||
|
||||
const userBlock = () => {
|
||||
return (
|
||||
<div className={userClass}>
|
||||
{userImage()}
|
||||
{party.user ? party.user.username : t("no_user")}
|
||||
{party.user ? party.user.username : t('no_user')}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
const linkedUserBlock = (user: User) => {
|
||||
return (
|
||||
|
|
@ -152,8 +152,8 @@ const PartyDetails = (props: Props) => {
|
|||
<a className={linkClass}>{userBlock()}</a>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
const linkedRaidBlock = (raid: Raid) => {
|
||||
return (
|
||||
|
|
@ -162,8 +162,8 @@ const PartyDetails = (props: Props) => {
|
|||
<a className={`Raid ${linkClass}`}>{raid.name[locale]}</a>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
const deleteButton = () => {
|
||||
if (party.editable) {
|
||||
|
|
@ -173,36 +173,36 @@ const PartyDetails = (props: Props) => {
|
|||
<span className="icon">
|
||||
<CrossIcon />
|
||||
</span>
|
||||
<span className="text">{t("buttons.delete")}</span>
|
||||
<span className="text">{t('buttons.delete')}</span>
|
||||
</AlertDialog.Trigger>
|
||||
<AlertDialog.Portal>
|
||||
<AlertDialog.Overlay className="Overlay" />
|
||||
<AlertDialog.Content className="Dialog">
|
||||
<AlertDialog.Title className="DialogTitle">
|
||||
{t("modals.delete_team.title")}
|
||||
{t('modals.delete_team.title')}
|
||||
</AlertDialog.Title>
|
||||
<AlertDialog.Description className="DialogDescription">
|
||||
{t("modals.delete_team.description")}
|
||||
{t('modals.delete_team.description')}
|
||||
</AlertDialog.Description>
|
||||
<div className="actions">
|
||||
<AlertDialog.Cancel className="Button modal">
|
||||
{t("modals.delete_team.buttons.cancel")}
|
||||
{t('modals.delete_team.buttons.cancel')}
|
||||
</AlertDialog.Cancel>
|
||||
<AlertDialog.Action
|
||||
className="Button modal destructive"
|
||||
onClick={(e) => props.deleteCallback(e)}
|
||||
>
|
||||
{t("modals.delete_team.buttons.confirm")}
|
||||
{t('modals.delete_team.buttons.confirm')}
|
||||
</AlertDialog.Action>
|
||||
</div>
|
||||
</AlertDialog.Content>
|
||||
</AlertDialog.Portal>
|
||||
</AlertDialog.Root>
|
||||
);
|
||||
)
|
||||
} else {
|
||||
return "";
|
||||
return ''
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const editable = (
|
||||
<section className={editableClasses}>
|
||||
|
|
@ -217,13 +217,13 @@ const PartyDetails = (props: Props) => {
|
|||
/>
|
||||
<RaidDropdown
|
||||
showAllRaidsOption={false}
|
||||
currentRaid={party.raid?.slug || ""}
|
||||
currentRaid={party.raid?.slug || ''}
|
||||
ref={raidSelect}
|
||||
/>
|
||||
<TextFieldset
|
||||
fieldName="name"
|
||||
placeholder={
|
||||
"Write your notes here\n\n\nWatch out for the 50% trigger!\nMake sure to click Fediel’s 1 first\nGood luck with RNG!"
|
||||
'Write your notes here\n\n\nWatch out for the 50% trigger!\nMake sure to click Fediel’s 1 first\nGood luck with RNG!'
|
||||
}
|
||||
value={party.description}
|
||||
onChange={handleTextAreaChange}
|
||||
|
|
@ -233,29 +233,29 @@ const PartyDetails = (props: Props) => {
|
|||
|
||||
<div className="bottom">
|
||||
<div className="left">
|
||||
{router.pathname !== "/new" ? deleteButton() : ""}
|
||||
{router.pathname !== '/new' ? deleteButton() : ''}
|
||||
</div>
|
||||
<div className="right">
|
||||
<Button active={true} onClick={toggleDetails}>
|
||||
{t("buttons.cancel")}
|
||||
{t('buttons.cancel')}
|
||||
</Button>
|
||||
|
||||
<Button active={true} icon="check" onClick={updateDetails}>
|
||||
{t("buttons.save_info")}
|
||||
{t('buttons.save_info')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
)
|
||||
|
||||
const readOnly = (
|
||||
<section className={readOnlyClasses}>
|
||||
<div className="info">
|
||||
<div className="left">
|
||||
{party.name ? <h1>{party.name}</h1> : ""}
|
||||
{party.name ? <h1>{party.name}</h1> : ''}
|
||||
<div className="attribution">
|
||||
{party.user ? linkedUserBlock(party.user) : userBlock()}
|
||||
{party.raid ? linkedRaidBlock(party.raid) : ""}
|
||||
{party.raid ? linkedRaidBlock(party.raid) : ''}
|
||||
{party.created_at != undefined ? (
|
||||
<time
|
||||
className="last-updated"
|
||||
|
|
@ -264,14 +264,14 @@ const PartyDetails = (props: Props) => {
|
|||
{formatTimeAgo(new Date(party.created_at), locale)}
|
||||
</time>
|
||||
) : (
|
||||
""
|
||||
''
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="right">
|
||||
{party.editable ? (
|
||||
<Button active={true} icon="edit" onClick={toggleDetails}>
|
||||
{t("buttons.show_info")}
|
||||
{t('buttons.show_info')}
|
||||
</Button>
|
||||
) : (
|
||||
<div />
|
||||
|
|
@ -283,71 +283,52 @@ const PartyDetails = (props: Props) => {
|
|||
<Linkify>{party.description}</Linkify>
|
||||
</p>
|
||||
) : (
|
||||
""
|
||||
''
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
)
|
||||
|
||||
const emptyDetails = (
|
||||
<div className={emptyClasses}>
|
||||
{party.editable ? (
|
||||
<Button active={true} icon="edit" onClick={toggleDetails}>
|
||||
{t("buttons.show_info")}
|
||||
{t('buttons.show_info')}
|
||||
</Button>
|
||||
) : (
|
||||
<div />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
)
|
||||
|
||||
const generateTitle = () => {
|
||||
let title = party.raid ? `[${party.raid?.name[locale]}] ` : "";
|
||||
let title = party.raid ? `[${party.raid?.name[locale]}] ` : ''
|
||||
|
||||
const username =
|
||||
party.user != null ? `@${party.user?.username}` : t("header.anonymous");
|
||||
party.user != null ? `@${party.user?.username}` : t('header.anonymous')
|
||||
|
||||
if (party.name != null)
|
||||
title += t("header.byline", {
|
||||
title += t('header.byline', {
|
||||
partyName: party.name,
|
||||
username: username,
|
||||
});
|
||||
else if (party.name == null && party.editable && router.route === "/new")
|
||||
title = t("header.new_team");
|
||||
})
|
||||
else if (party.name == null && party.editable && router.route === '/new')
|
||||
title = t('header.new_team')
|
||||
else
|
||||
title += t("header.untitled_team", {
|
||||
title += t('header.untitled_team', {
|
||||
username: username,
|
||||
});
|
||||
})
|
||||
|
||||
return title;
|
||||
};
|
||||
return title
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Head>
|
||||
<title>{generateTitle()}</title>
|
||||
|
||||
<meta property="og:title" content={generateTitle()} />
|
||||
<meta
|
||||
property="og:description"
|
||||
content={party.description ? party.description : ""}
|
||||
/>
|
||||
<meta property="og:url" content="https://app.granblue.team" />
|
||||
<meta property="og:type" content="website" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:domain" content="app.granblue.team" />
|
||||
<meta name="twitter:title" content={generateTitle()} />
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content={party.description ? party.description : ""}
|
||||
/>
|
||||
</Head>
|
||||
<React.Fragment>
|
||||
{editable && (party.name || party.description || party.raid)
|
||||
? readOnly
|
||||
: emptyDetails}
|
||||
{editable}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default PartyDetails;
|
||||
export default PartyDetails
|
||||
|
|
|
|||
|
|
@ -1,68 +1,78 @@
|
|||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import api from "~utils/api";
|
||||
import { appState } from "~utils/appState";
|
||||
import { raidGroups } from "~utils/raidGroups";
|
||||
import Select from '~components/Select'
|
||||
import SelectItem from '~components/SelectItem'
|
||||
import SelectGroup from '~components/SelectGroup'
|
||||
import { SelectSeparator } from '@radix-ui/react-select'
|
||||
|
||||
import "./index.scss";
|
||||
import api from '~utils/api'
|
||||
import { appState } from '~utils/appState'
|
||||
import { raidGroups } from '~utils/raidGroups'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
// Props
|
||||
interface Props {
|
||||
showAllRaidsOption: boolean;
|
||||
currentRaid?: string;
|
||||
onChange?: (slug?: string) => void;
|
||||
onBlur?: (event: React.ChangeEvent<HTMLSelectElement>) => void;
|
||||
showAllRaidsOption: boolean
|
||||
currentRaid?: string
|
||||
onChange?: (slug?: string) => void
|
||||
onBlur?: (event: React.ChangeEvent<HTMLSelectElement>) => void
|
||||
}
|
||||
|
||||
const RaidDropdown = React.forwardRef<HTMLSelectElement, Props>(
|
||||
function useFieldSet(props, ref) {
|
||||
// Set up router for locale
|
||||
const router = useRouter();
|
||||
const locale = router.locale || "en";
|
||||
const router = useRouter()
|
||||
const locale = router.locale || 'en'
|
||||
|
||||
// Set up local states for storing raids
|
||||
const [currentRaid, setCurrentRaid] = useState<Raid>();
|
||||
const [raids, setRaids] = useState<Raid[]>();
|
||||
const [sortedRaids, setSortedRaids] = useState<Raid[][]>();
|
||||
const [open, setOpen] = useState(false)
|
||||
const [currentRaid, setCurrentRaid] = useState<Raid>()
|
||||
const [raids, setRaids] = useState<Raid[]>()
|
||||
const [sortedRaids, setSortedRaids] = useState<Raid[][]>()
|
||||
|
||||
function openRaidSelect() {
|
||||
setOpen(!open)
|
||||
}
|
||||
|
||||
// Organize raids into groups on mount
|
||||
const organizeRaids = useCallback(
|
||||
(raids: Raid[]) => {
|
||||
// Set up empty raid for "All raids"
|
||||
const all = {
|
||||
id: "0",
|
||||
id: '0',
|
||||
name: {
|
||||
en: "All raids",
|
||||
ja: "全て",
|
||||
en: 'All raids',
|
||||
ja: '全て',
|
||||
},
|
||||
slug: "all",
|
||||
slug: 'all',
|
||||
level: 0,
|
||||
group: 0,
|
||||
element: 0,
|
||||
};
|
||||
}
|
||||
|
||||
const numGroups = Math.max.apply(
|
||||
Math,
|
||||
raids.map((raid) => raid.group)
|
||||
);
|
||||
let groupedRaids = [];
|
||||
)
|
||||
let groupedRaids = []
|
||||
|
||||
for (let i = 0; i <= numGroups; i++) {
|
||||
groupedRaids[i] = raids.filter((raid) => raid.group == i);
|
||||
groupedRaids[i] = raids.filter((raid) => raid.group == i)
|
||||
}
|
||||
|
||||
if (props.showAllRaidsOption) {
|
||||
raids.unshift(all);
|
||||
groupedRaids[0].unshift(all);
|
||||
raids.unshift(all)
|
||||
groupedRaids[0].unshift(all)
|
||||
}
|
||||
|
||||
setRaids(raids);
|
||||
setSortedRaids(groupedRaids);
|
||||
appState.raids = raids;
|
||||
setRaids(raids)
|
||||
setSortedRaids(groupedRaids)
|
||||
appState.raids = raids
|
||||
},
|
||||
[props.showAllRaidsOption]
|
||||
);
|
||||
)
|
||||
|
||||
// Fetch all raids on mount
|
||||
useEffect(() => {
|
||||
|
|
@ -70,24 +80,25 @@ const RaidDropdown = React.forwardRef<HTMLSelectElement, Props>(
|
|||
.getAll()
|
||||
.then((response) =>
|
||||
organizeRaids(response.data.map((r: any) => r.raid))
|
||||
);
|
||||
}, [organizeRaids]);
|
||||
)
|
||||
}, [organizeRaids])
|
||||
|
||||
// Set current raid on mount
|
||||
useEffect(() => {
|
||||
if (raids && props.currentRaid) {
|
||||
const raid = raids.find((raid) => raid.slug === props.currentRaid);
|
||||
setCurrentRaid(raid);
|
||||
const raid = raids.find((raid) => raid.slug === props.currentRaid)
|
||||
setCurrentRaid(raid)
|
||||
}
|
||||
}, [raids, props.currentRaid]);
|
||||
}, [raids, props.currentRaid])
|
||||
|
||||
// Enable changing select value
|
||||
function handleChange(event: React.ChangeEvent<HTMLSelectElement>) {
|
||||
if (props.onChange) props.onChange(event.target.value);
|
||||
function handleChange(value: string) {
|
||||
console.log(value)
|
||||
if (props.onChange) props.onChange(value)
|
||||
|
||||
if (raids) {
|
||||
const raid = raids.find((raid) => raid.slug === event.target.value);
|
||||
setCurrentRaid(raid);
|
||||
const raid = raids.find((raid) => raid.slug === value)
|
||||
setCurrentRaid(raid)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,33 +112,36 @@ const RaidDropdown = React.forwardRef<HTMLSelectElement, Props>(
|
|||
.sort((a, b) => a.element - b.element)
|
||||
.map((item, i) => {
|
||||
return (
|
||||
<option key={i} value={item.slug}>
|
||||
<SelectItem key={i} value={item.slug}>
|
||||
{item.name[locale]}
|
||||
</option>
|
||||
);
|
||||
});
|
||||
|
||||
</SelectItem>
|
||||
)
|
||||
})
|
||||
return (
|
||||
<optgroup key={index} label={raidGroups[index].name[locale]}>
|
||||
<SelectGroup
|
||||
key={index}
|
||||
label={raidGroups[index].name[locale]}
|
||||
separator={false}
|
||||
>
|
||||
{options}
|
||||
</optgroup>
|
||||
);
|
||||
</SelectGroup>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<select
|
||||
key={currentRaid?.slug}
|
||||
value={currentRaid?.slug}
|
||||
onBlur={props.onBlur}
|
||||
<Select
|
||||
trigger={'Select a raid...'}
|
||||
placeholder={'Select a raid'}
|
||||
open={open}
|
||||
onClick={openRaidSelect}
|
||||
onChange={handleChange}
|
||||
ref={ref}
|
||||
>
|
||||
{Array.from(Array(sortedRaids?.length)).map((x, i) =>
|
||||
renderRaidGroup(i)
|
||||
)}
|
||||
</select>
|
||||
);
|
||||
</Select>
|
||||
)
|
||||
}
|
||||
);
|
||||
)
|
||||
|
||||
export default RaidDropdown;
|
||||
export default RaidDropdown
|
||||
|
|
|
|||
51
components/Select/index.scss
Normal file
51
components/Select/index.scss
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
.SelectTrigger {
|
||||
align-items: center;
|
||||
background-color: var(--input-bg);
|
||||
border-radius: $input-corner;
|
||||
border: none;
|
||||
display: flex;
|
||||
padding: $unit-2x $unit-2x;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--input-bg-hover);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&[data-placeholder] > span:not(.SelectIcon) {
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
& > span:not(.SelectIcon) {
|
||||
color: var(--text-primary);
|
||||
flex-grow: 1;
|
||||
font-size: $font-regular;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.SelectIcon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.Select {
|
||||
background: var(--card-bg);
|
||||
border-radius: $input-corner;
|
||||
border: $hover-stroke;
|
||||
box-shadow: $hover-shadow;
|
||||
padding: 0 $unit;
|
||||
// position: relative;
|
||||
// max-height: 350px !important;
|
||||
// top: -800px;
|
||||
z-index: 99999;
|
||||
|
||||
.Scroll.Up,
|
||||
.Scroll.Down {
|
||||
padding: $unit 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.Scroll.Up {
|
||||
transform: scale(1, -1);
|
||||
}
|
||||
}
|
||||
49
components/Select/index.tsx
Normal file
49
components/Select/index.tsx
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import React from 'react'
|
||||
import * as RadixSelect from '@radix-ui/react-select'
|
||||
|
||||
import ArrowIcon from '~public/icons/Arrow.svg'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
// Props
|
||||
interface Props {
|
||||
open: boolean
|
||||
placeholder?: string
|
||||
trigger?: React.ReactNode
|
||||
children?: React.ReactNode
|
||||
onClick?: () => void
|
||||
onChange?: (value: string) => void
|
||||
}
|
||||
|
||||
const Select = React.forwardRef<HTMLSelectElement, Props>(function useFieldSet(
|
||||
props,
|
||||
ref
|
||||
) {
|
||||
return (
|
||||
<RadixSelect.Root onValueChange={props.onChange}>
|
||||
<RadixSelect.Trigger
|
||||
className="SelectTrigger"
|
||||
placeholder={props.placeholder}
|
||||
>
|
||||
<RadixSelect.Value placeholder={props.placeholder} />
|
||||
<RadixSelect.Icon className="SelectIcon">
|
||||
<ArrowIcon />
|
||||
</RadixSelect.Icon>
|
||||
</RadixSelect.Trigger>
|
||||
|
||||
<RadixSelect.Portal className="Select">
|
||||
<RadixSelect.Content>
|
||||
<RadixSelect.ScrollUpButton className="Scroll Up">
|
||||
<ArrowIcon />
|
||||
</RadixSelect.ScrollUpButton>
|
||||
<RadixSelect.Viewport>{props.children}</RadixSelect.Viewport>
|
||||
<RadixSelect.ScrollDownButton className="Scroll Down">
|
||||
<ArrowIcon />
|
||||
</RadixSelect.ScrollDownButton>
|
||||
</RadixSelect.Content>
|
||||
</RadixSelect.Portal>
|
||||
</RadixSelect.Root>
|
||||
)
|
||||
})
|
||||
|
||||
export default Select
|
||||
25
components/SelectGroup/index.scss
Normal file
25
components/SelectGroup/index.scss
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
.SelectGroup {
|
||||
.Label {
|
||||
align-items: center;
|
||||
color: var(--text-tertiary);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-shrink: 0;
|
||||
font-size: $font-small;
|
||||
font-weight: $medium;
|
||||
gap: $unit;
|
||||
padding: $unit $unit-2x $unit-half;
|
||||
|
||||
&:first-child {
|
||||
padding-top: $unit-2x;
|
||||
}
|
||||
|
||||
.Separator {
|
||||
background: var(--item-bg-hover);
|
||||
border-radius: 1px;
|
||||
display: block;
|
||||
flex-grow: 1;
|
||||
height: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
components/SelectGroup/index.tsx
Normal file
33
components/SelectGroup/index.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import React from 'react'
|
||||
import * as RadixSelect from '@radix-ui/react-select'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
// Props
|
||||
interface Props {
|
||||
label?: string
|
||||
separator?: boolean
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
separator: true,
|
||||
}
|
||||
|
||||
const SelectGroup = (props: Props) => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<RadixSelect.Group className="SelectGroup">
|
||||
<RadixSelect.Label className="Label">
|
||||
{props.label}
|
||||
<RadixSelect.Separator className="Separator" />
|
||||
</RadixSelect.Label>
|
||||
{props.children}
|
||||
</RadixSelect.Group>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
SelectGroup.defaultProps = defaultProps
|
||||
|
||||
export default SelectGroup
|
||||
11
components/SelectItem/index.scss
Normal file
11
components/SelectItem/index.scss
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
.SelectItem {
|
||||
border-radius: $item-corner;
|
||||
color: var(--text-primary);
|
||||
font-size: $font-regular;
|
||||
padding: ($unit * 1.5) $unit-2x;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--item-bg-hover);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
21
components/SelectItem/index.tsx
Normal file
21
components/SelectItem/index.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import React from 'react'
|
||||
import * as Select from '@radix-ui/react-select'
|
||||
|
||||
import './index.scss'
|
||||
import classNames from 'classnames'
|
||||
|
||||
const SelectItem = React.forwardRef<HTMLDivElement>(
|
||||
({ children, className, ...props }, forwardedRef) => {
|
||||
return (
|
||||
<Select.Item
|
||||
className={classNames('SelectItem', className)}
|
||||
{...props}
|
||||
ref={forwardedRef}
|
||||
>
|
||||
<Select.ItemText>{children}</Select.ItemText>
|
||||
</Select.Item>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
export default SelectItem
|
||||
|
|
@ -78,7 +78,7 @@ h1 {
|
|||
|
||||
select {
|
||||
appearance: none;
|
||||
background-color: var(--input-bg);
|
||||
background-color: var(--input-bound-bg);
|
||||
background-image: url("/icons/Arrow.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-position-y: center;
|
||||
|
|
|
|||
|
|
@ -9,12 +9,18 @@
|
|||
|
||||
--input-bg: #{$input--bg--light};
|
||||
--input-bg-hover: #{$input--bg--light--hover};
|
||||
--input-bound-bg: #{$input--bound--bg--light};
|
||||
--input-bound-bg-hover: #{$input--bound--bg--light--hover};
|
||||
|
||||
--item-bg-hover: #{$item--bg--light--hover};
|
||||
|
||||
--text-primary: #{$text--primary--color--light};
|
||||
|
||||
--text-secondary: #{$text--secondary--color--light};
|
||||
--text-secondary-hover: #{$text--secondary--hover--light};
|
||||
|
||||
--text-tertiary: #{$text--tertiary--color--light};
|
||||
|
||||
--icon-secondary: #{$icon--secondary--color--light};
|
||||
--icon-secondary-hover: #{$icon--secondary--hover--light};
|
||||
|
||||
|
|
@ -47,12 +53,18 @@
|
|||
|
||||
--input-bg: #{$input--bg--dark};
|
||||
--input-bg-hover: #{$input--bg--dark--hover};
|
||||
--input-bound-bg: #{$input--bound--bg--dark};
|
||||
--input-bound-bg-hover: #{$input--bound--bg--dark--hover};
|
||||
|
||||
--item-bg-hover: #{$item--bg--dark--hover};
|
||||
|
||||
--text-primary: #{$text--primary--color--dark};
|
||||
|
||||
--text-secondary: #{$text--secondary--color--dark};
|
||||
--text-secondary-hover: #{$text--secondary--hover--dark};
|
||||
|
||||
--text-tertiary: #{$text--tertiary--color--dark};
|
||||
|
||||
--icon-secondary: #{$icon--secondary--color--dark};
|
||||
--icon-secondary-hover: #{$icon--secondary--hover--dark};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,16 @@ $medium-screen: 800px;
|
|||
// Sizing
|
||||
$unit: 8px;
|
||||
|
||||
$unit-fourth: calc($unit / 4);
|
||||
$unit-half: calc($unit / 2);
|
||||
$unit-2x: $unit * 2;
|
||||
$unit-4x: $unit * 4;
|
||||
$unit-6x: $unit * 6;
|
||||
$unit-8x: $unit * 8;
|
||||
$unit-10x: $unit * 10;
|
||||
$unit-12x: $unit * 12;
|
||||
$unit-20x: $unit * 20;
|
||||
|
||||
// Colors
|
||||
$grey-00: #111;
|
||||
$grey-10: #191919;
|
||||
|
|
@ -35,12 +45,20 @@ $page--hover--dark: $grey-20;
|
|||
$page--element--bg--light: $grey-70;
|
||||
$page--element--bg--dark: $grey-30;
|
||||
|
||||
$input--bg--light: $grey-90;
|
||||
$input--bg--light--hover: $grey-80;
|
||||
$input--bg--dark: $grey-10;
|
||||
$input--bg--light: $grey-100;
|
||||
$input--bg--light--hover: $grey-95;
|
||||
$input--bg--dark: $grey-20;
|
||||
$input--bg--dark--hover: $grey-15;
|
||||
|
||||
$grid--rep--hover--light: white;
|
||||
$input--bound--bg--light: $grey-90;
|
||||
$input--bound--bg--light--hover: $grey-80;
|
||||
$input--bound--bg--dark: $grey-10;
|
||||
$input--bound--bg--dark--hover: $grey-15;
|
||||
|
||||
$item--bg--light--hover: $grey-90;
|
||||
$item--bg--dark--hover: $grey-10;
|
||||
|
||||
$grid--rep--hover--light: $grey-100;
|
||||
$grid--rep--hover--dark: $grey-00;
|
||||
|
||||
$grid--border--color--light: $grey-80;
|
||||
|
|
@ -62,6 +80,9 @@ $icon--secondary--color--dark: $grey-40;
|
|||
$icon--secondary--hover--light: $grey-40;
|
||||
$icon--secondary--hover--dark: $grey-70;
|
||||
|
||||
$text--tertiary--color--light: $grey-60;
|
||||
$text--tertiary--color--dark: $grey-60;
|
||||
|
||||
$blue: #275dc5;
|
||||
$red: #ff6161;
|
||||
$error: #d13a3a;
|
||||
|
|
@ -128,6 +149,10 @@ $font-xxlarge: 28px;
|
|||
$scale-wide: scale(1.05, 1.05);
|
||||
$scale-tall: scale(1.012, 1.012);
|
||||
|
||||
// Border radius
|
||||
$input-corner: $unit;
|
||||
$item-corner: $unit-half;
|
||||
|
||||
// Shadows
|
||||
$hover-stroke: 1px solid rgba(0, 0, 0, 0.1);
|
||||
$hover-shadow: rgba(0, 0, 0, 0.08) 0px 0px 14px;
|
||||
|
|
|
|||
Loading…
Reference in a new issue