UI/sidebar: rework tailwind theme and classes
This commit is contained in:
@@ -1,21 +1,20 @@
|
||||
import {type JSX} from 'solid-js'
|
||||
import { type JSX } from "solid-js";
|
||||
|
||||
type sizes = 'small' | 'medium' | 'large'
|
||||
type sizes = "small" | "medium" | "large";
|
||||
|
||||
const gapSizes:{[size in sizes]:string} = {
|
||||
small: 'gap-2',
|
||||
medium: 'gap-4',
|
||||
large: 'gap-6'
|
||||
}
|
||||
const gapSizes: { [size in sizes]: string } = {
|
||||
small: "gap-2",
|
||||
medium: "gap-4",
|
||||
large: "gap-6",
|
||||
};
|
||||
|
||||
interface List {
|
||||
children: JSX.Element;
|
||||
gapSize: sizes
|
||||
}
|
||||
|
||||
export const List = (props: List) =>{
|
||||
const {children, gapSize} = props
|
||||
|
||||
return <ul class={`flex flex-col ${gapSizes[gapSize]}`}> {children}
|
||||
</ul>
|
||||
children: JSX.Element;
|
||||
gapSize: sizes;
|
||||
}
|
||||
|
||||
export const List = (props: List) => {
|
||||
const { children, gapSize } = props;
|
||||
|
||||
return <ul class={`flex flex-col ${gapSizes[gapSize]}`}> {children}</ul>;
|
||||
};
|
||||
|
||||
@@ -1 +1 @@
|
||||
export {List} from './List'
|
||||
export { List } from "./List";
|
||||
|
||||
@@ -103,7 +103,7 @@ export const MachineListItem = (props: MachineListItemProps) => {
|
||||
};
|
||||
return (
|
||||
<li>
|
||||
<div class="card card-side m-2 timo">
|
||||
<div class="card card-side m-2">
|
||||
<figure class="pl-2">
|
||||
<span
|
||||
class="material-icons content-center text-5xl"
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import {List} from '@/src/components/Helpers'
|
||||
import {SidebarListItem} from '../SidebarListItem'
|
||||
import { List } from "@/src/components/Helpers";
|
||||
import { SidebarListItem } from "../SidebarListItem";
|
||||
|
||||
export const SidebarFlyout= () =>{
|
||||
return <div class="sidebar__flyout">
|
||||
<div class="sidebar__flyout__inner">
|
||||
<List gapSize='small'>
|
||||
<SidebarListItem href='/settings' title='Settings' />
|
||||
</List>
|
||||
</div>
|
||||
export const SidebarFlyout = () => {
|
||||
return (
|
||||
<div class="sidebar__flyout">
|
||||
<div class="sidebar__flyout__inner">
|
||||
<List gapSize="small">
|
||||
<SidebarListItem href="/settings" title="Settings" />
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,39 +1,60 @@
|
||||
import {createSignal, Show} from 'solid-js'
|
||||
import { createSignal, Show } from "solid-js";
|
||||
|
||||
import {Typography} from '@/src/components/Typography'
|
||||
import {SidebarFlyout} from './SidebarFlyout'
|
||||
import { Typography } from "@/src/components/Typography";
|
||||
import { SidebarFlyout } from "./SidebarFlyout";
|
||||
|
||||
interface SidebarHeader {
|
||||
clanName: string
|
||||
clanName: string;
|
||||
}
|
||||
|
||||
export const SidebarHeader = (props:SidebarHeader)=>{
|
||||
const {clanName} = props;
|
||||
export const SidebarHeader = (props: SidebarHeader) => {
|
||||
const { clanName } = props;
|
||||
|
||||
const [showFlyout, toggleFlyout] = createSignal(false)
|
||||
const [showFlyout, toggleFlyout] = createSignal(false);
|
||||
|
||||
function handleClick(){
|
||||
toggleFlyout(!showFlyout())
|
||||
}
|
||||
function handleClick() {
|
||||
toggleFlyout(!showFlyout());
|
||||
}
|
||||
|
||||
const renderClanProfile = () => <div class={`sidebar__profile ${showFlyout() ? 'sidebar__profile--flyout' : ''}`}>
|
||||
<Typography classes='sidebar__profile__character' tag='span' hierarchy='title' size='m' weight='bold' color='primary' inverted={true}>
|
||||
{clanName.slice(0,1)}
|
||||
</Typography>
|
||||
const renderClanProfile = () => (
|
||||
<div
|
||||
class={`sidebar__profile ${showFlyout() ? "sidebar__profile--flyout" : ""}`}
|
||||
>
|
||||
<Typography
|
||||
classes="sidebar__profile__character"
|
||||
tag="span"
|
||||
hierarchy="title"
|
||||
size="m"
|
||||
weight="bold"
|
||||
color="primary"
|
||||
inverted={true}
|
||||
>
|
||||
{clanName.slice(0, 1)}
|
||||
</Typography>
|
||||
</div>
|
||||
|
||||
);
|
||||
|
||||
const renderClanTitle = () =>
|
||||
<Typography classes='sidebar__title' tag='h3' hierarchy='body' size='default' weight='medium' color='primary' inverted={true}>{clanName}</Typography>
|
||||
|
||||
return <header class="sidebar__header">
|
||||
<div onClick={handleClick} class="sidebar__header__inner">
|
||||
{renderClanProfile()}
|
||||
{renderClanTitle()}
|
||||
</div>
|
||||
{ showFlyout() &&
|
||||
<SidebarFlyout/>
|
||||
}
|
||||
|
||||
const renderClanTitle = () => (
|
||||
<Typography
|
||||
classes="sidebar__title"
|
||||
tag="h3"
|
||||
hierarchy="body"
|
||||
size="default"
|
||||
weight="medium"
|
||||
color="primary"
|
||||
inverted={true}
|
||||
>
|
||||
{clanName}
|
||||
</Typography>
|
||||
);
|
||||
|
||||
return (
|
||||
<header class="sidebar__header">
|
||||
<div onClick={handleClick} class="sidebar__header__inner">
|
||||
{renderClanProfile()}
|
||||
{renderClanTitle()}
|
||||
</div>
|
||||
{showFlyout() && <SidebarFlyout />}
|
||||
</header>
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,19 +1,30 @@
|
||||
import { A } from "@solidjs/router";
|
||||
|
||||
|
||||
import {Typography} from '@/src/components/Typography'
|
||||
import { Typography } from "@/src/components/Typography";
|
||||
|
||||
interface SidebarListItem {
|
||||
title:string
|
||||
href:string
|
||||
title: string;
|
||||
href: string;
|
||||
}
|
||||
|
||||
export const SidebarListItem = (props: SidebarListItem) =>{
|
||||
const {title, href} = props;
|
||||
export const SidebarListItem = (props: SidebarListItem) => {
|
||||
const { title, href } = props;
|
||||
|
||||
return <li class="sidebar__list__item">
|
||||
<A class="sidebar__list__link" href={href}>
|
||||
<Typography classes='sidebar__list__content' tag='span' hierarchy='body' size='s' weight='normal' color="primary" inverted={true}>{title}</Typography>
|
||||
</A>
|
||||
return (
|
||||
<li class="sidebar__list__item">
|
||||
<A class="sidebar__list__link" href={href}>
|
||||
<Typography
|
||||
classes="sidebar__list__content"
|
||||
tag="span"
|
||||
hierarchy="body"
|
||||
size="s"
|
||||
weight="normal"
|
||||
color="primary"
|
||||
inverted={true}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
</A>
|
||||
</li>
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
.sidebar__flyout {
|
||||
top: 0;
|
||||
position: absolute;
|
||||
z-index: theme(zIndex.30);
|
||||
top: 0;
|
||||
position: absolute;
|
||||
z-index: theme(zIndex.30);
|
||||
|
||||
padding: theme(padding[1]);
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding: theme(padding[1]);
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.sidebar__flyout__inner {
|
||||
position: relative;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
|
||||
padding: theme(padding.12) theme(padding.3) theme(padding.3);
|
||||
background-color: rgba(var(--clr-bg-inv-4)/0.95);
|
||||
border: 1px solid rgb(var(--clr-border-inv-4));
|
||||
border-radius: theme(borderRadius.lg);
|
||||
}
|
||||
position: relative;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
|
||||
padding: theme(padding.12) theme(padding.3) theme(padding.3);
|
||||
background-color: rgba(var(--clr-bg-inv-4) / 0.95);
|
||||
border: 1px solid rgb(var(--clr-border-inv-4));
|
||||
border-radius: theme(borderRadius.lg);
|
||||
}
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
.sidebar__header {
|
||||
position: relative;
|
||||
padding: 1px 1px 0;
|
||||
cursor: pointer;
|
||||
|
||||
position: relative;
|
||||
padding: 1px 1px 0;
|
||||
cursor: pointer;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgb(var(--clr-bg-inv-3));
|
||||
|
||||
border-bottom: 1px solid var(--clr-border-inv-3);
|
||||
border-top-left-radius: theme(borderRadius.xl);
|
||||
border-top-right-radius: theme(borderRadius.xl);
|
||||
}
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgb(var(--clr-bg-inv-3));
|
||||
|
||||
border-bottom: 1px solid var(--clr-border-inv-3);
|
||||
border-top-left-radius: theme(borderRadius.xl);
|
||||
border-top-right-radius: theme(borderRadius.xl);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar__header__inner {
|
||||
position: relative;
|
||||
z-index: theme(zIndex.40);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 theme(gap.3);
|
||||
position: relative;
|
||||
z-index: theme(zIndex.40);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0 theme(gap.3);
|
||||
|
||||
padding: theme(padding.3) theme(padding.3);
|
||||
}
|
||||
padding: theme(padding.3) theme(padding.3);
|
||||
}
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
.sidebar__list__item {
|
||||
position: relative;
|
||||
cursor: theme(cursor.pointer);
|
||||
position: relative;
|
||||
cursor: theme(cursor.pointer);
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
z-index: theme(zIndex.10);
|
||||
top: 0;
|
||||
left:0;
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: theme(zIndex.10);
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: theme(borderRadius.md);
|
||||
transform: scale(0.98);
|
||||
transition: transform 0.24s ease-in-out;
|
||||
}
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: theme(borderRadius.md);
|
||||
transform: scale(0.98);
|
||||
transition: transform 0.24s ease-in-out;
|
||||
}
|
||||
|
||||
&:hover:after {
|
||||
background: rgb(var(--clr-bg-inv-acc-2));
|
||||
transform: scale(theme(scale.100));
|
||||
transition: transform 0.24s ease-in-out;
|
||||
}
|
||||
&:hover:after {
|
||||
background: rgb(var(--clr-bg-inv-acc-2));
|
||||
transform: scale(theme(scale.100));
|
||||
transition: transform 0.24s ease-in-out;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.99);
|
||||
transition: transform 0.08s ease-in-out;
|
||||
}
|
||||
&:active {
|
||||
transform: scale(0.99);
|
||||
transition: transform 0.08s ease-in-out;
|
||||
}
|
||||
|
||||
&:active:after {
|
||||
background: rgb(var(--clr-bg-inv-acc-3));
|
||||
transform: scale(theme(scale.100));
|
||||
}
|
||||
&:active:after {
|
||||
background: rgb(var(--clr-bg-inv-acc-3));
|
||||
transform: scale(theme(scale.100));
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar__list__link {
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
display: block;
|
||||
padding: theme(padding.3);
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
display: block;
|
||||
padding: theme(padding.3);
|
||||
}
|
||||
|
||||
.sidebar__list__content {
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
.sidebar__profile {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
width: theme(width.8);
|
||||
height: theme(height.8);
|
||||
width: theme(width.8);
|
||||
height: theme(height.8);
|
||||
|
||||
background: rgb(var(--clr-bg-inv-4));
|
||||
border-radius: 50%;
|
||||
background: rgb(var(--clr-bg-inv-4));
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.sidebar__profile--flyout{
|
||||
background: rgb(var(--clr-bg-def-2));
|
||||
.sidebar__profile--flyout {
|
||||
background: rgb(var(--clr-bg-def-2));
|
||||
}
|
||||
|
||||
.sidebar__profile--flyout > .sidebar__profile__character{
|
||||
color: rgb(var(--clr-fg-def-1)) !important;
|
||||
}
|
||||
.sidebar__profile--flyout > .sidebar__profile__character {
|
||||
color: rgb(var(--clr-fg-def-1)) !important;
|
||||
}
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
/* Sidebar Elements */
|
||||
|
||||
@import './sidebar-header';
|
||||
@import './sidebar-flyout';
|
||||
@import './sidebar-list-item';
|
||||
@import './sidebar-profile';
|
||||
@import "./sidebar-header";
|
||||
@import "./sidebar-flyout";
|
||||
@import "./sidebar-list-item";
|
||||
@import "./sidebar-profile";
|
||||
|
||||
/* Sidebar Structure */
|
||||
|
||||
.sidebar {
|
||||
min-width: theme(width.72);
|
||||
height: 100%;
|
||||
background-color: rgb(var(--clr-bg-inv-2));
|
||||
border: 1px solid rgb(var(--clr-border-inv-2));
|
||||
border-radius: theme(borderRadius.xl);
|
||||
min-width: theme(width.72);
|
||||
height: 100%;
|
||||
background-color: rgb(var(--clr-bg-inv-2));
|
||||
border: 1px solid rgb(var(--clr-border-inv-2));
|
||||
border-radius: theme(borderRadius.xl);
|
||||
}
|
||||
|
||||
.sidebar__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: theme(padding.2);
|
||||
padding: theme(padding.4) theme(padding.2);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: theme(padding.2);
|
||||
padding: theme(padding.4) theme(padding.2);
|
||||
}
|
||||
|
||||
.sidebar__section {
|
||||
padding: theme(padding.2);
|
||||
background-color: rgba(var(--clr-bg-inv-3)/0.9);
|
||||
border-radius: theme(borderRadius.md);
|
||||
}
|
||||
padding: theme(padding.2);
|
||||
background-color: rgba(var(--clr-bg-inv-3) / 0.9);
|
||||
border-radius: theme(borderRadius.md);
|
||||
}
|
||||
|
||||
@@ -1,72 +1,93 @@
|
||||
import {For, createEffect, Show, type JSX, children } from "solid-js"
|
||||
import { For, createEffect, Show, type JSX, children } from "solid-js";
|
||||
import { A, RouteSectionProps } from "@solidjs/router";
|
||||
import { activeURI } from "@/src/App"
|
||||
import { activeURI } from "@/src/App";
|
||||
import { createQuery } from "@tanstack/solid-query";
|
||||
import { callApi } from "@/src/api";
|
||||
import {AppRoute, routes} from '@/src/index'
|
||||
import { AppRoute, routes } from "@/src/index";
|
||||
|
||||
import {List} from '../Helpers';
|
||||
import {SidebarHeader} from "./SidebarHeader";
|
||||
import { List } from "../Helpers";
|
||||
import { SidebarHeader } from "./SidebarHeader";
|
||||
|
||||
import { SidebarListItem } from "./SidebarListItem";
|
||||
import "./css/sidebar.css";
|
||||
import { Typography } from "../Typography";
|
||||
|
||||
export const SidebarSection = (props:{title: string, children: JSX.Element}) =>{
|
||||
const {title, children} = props
|
||||
|
||||
return <details class="sidebar__section accordeon" open>
|
||||
<summary class="accordeon__header">
|
||||
<Typography classes="uppercase" tag="p" hierarchy="body" size="xs" weight="normal" color="tertiary" inverted={true}>{title}</Typography>
|
||||
</summary>
|
||||
<div class="accordeon__body">{children}</div>
|
||||
</details>
|
||||
}
|
||||
export const SidebarSection = (props: {
|
||||
title: string;
|
||||
children: JSX.Element;
|
||||
}) => {
|
||||
const { title, children } = props;
|
||||
|
||||
return (
|
||||
<details class="sidebar__section accordeon" open>
|
||||
<summary class="accordeon__header">
|
||||
<Typography
|
||||
classes="uppercase"
|
||||
tag="p"
|
||||
hierarchy="body"
|
||||
size="xs"
|
||||
weight="normal"
|
||||
color="tertiary"
|
||||
inverted={true}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
</summary>
|
||||
<div class="accordeon__body">{children}</div>
|
||||
</details>
|
||||
);
|
||||
};
|
||||
|
||||
export const Sidebar = (props: RouteSectionProps) => {
|
||||
createEffect(() => {
|
||||
console.log("machines");
|
||||
console.log(routes);
|
||||
});
|
||||
|
||||
createEffect(()=>{
|
||||
console.log('machines')
|
||||
console.log(routes)
|
||||
})
|
||||
const query = createQuery(() => ({
|
||||
queryKey: [activeURI(), "meta"],
|
||||
queryFn: async () => {
|
||||
const curr = activeURI();
|
||||
if (curr) {
|
||||
const result = await callApi("show_clan_meta", { uri: curr });
|
||||
|
||||
const query = createQuery(() => ({
|
||||
queryKey: [activeURI(), "meta"],
|
||||
queryFn: async () => {
|
||||
const curr = activeURI();
|
||||
if (curr) {
|
||||
const result = await callApi("show_clan_meta", { uri: curr });
|
||||
|
||||
if (result.status === "error") throw new Error("Failed to fetch data");
|
||||
|
||||
return result.data;
|
||||
}
|
||||
},
|
||||
}));
|
||||
if (result.status === "error") throw new Error("Failed to fetch data");
|
||||
|
||||
return (
|
||||
<div class="sidebar bg-opacity-95">
|
||||
<Show when={query.data} fallback={<SidebarHeader clanName={'Untitled'}/>}>
|
||||
{(meta) => <SidebarHeader clanName={meta().name}/>}
|
||||
return result.data;
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
return (
|
||||
<div class="sidebar bg-transparent/95">
|
||||
<Show
|
||||
when={query.data}
|
||||
fallback={<SidebarHeader clanName={"Untitled"} />}
|
||||
>
|
||||
{(meta) => <SidebarHeader clanName={meta().name} />}
|
||||
</Show>
|
||||
<div class="sidebar__body">
|
||||
<For each={routes.filter((r) => !r.hidden && r.path != "/clans")}>
|
||||
{(route: AppRoute) => (
|
||||
<Show when={route.children}>
|
||||
{(children) => (
|
||||
<SidebarSection title={route.label}>
|
||||
<ul>
|
||||
<For each={children().filter((r) => !r.hidden)}>
|
||||
{(child) => (
|
||||
<SidebarListItem
|
||||
href={`${route.path}${child.path}`}
|
||||
title={child.label}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</ul>
|
||||
</SidebarSection>
|
||||
)}
|
||||
</Show>
|
||||
<div class="sidebar__body">
|
||||
<For each={routes.filter((r) => !r.hidden && r.path !="/clans" )}>
|
||||
{(route:AppRoute)=>(
|
||||
<Show when={route.children}>
|
||||
{(children)=>
|
||||
<SidebarSection title={route.label}>
|
||||
<ul>
|
||||
<For each={children().filter((r)=>!r.hidden)}>
|
||||
{(child)=><SidebarListItem href={`${route.path}${child.path}`} title={child.label} />}
|
||||
</For>
|
||||
</ul>
|
||||
</SidebarSection>
|
||||
}
|
||||
</Show>
|
||||
)
|
||||
}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
.fnt-clr-primary {
|
||||
color:( rgb(--clr-fg-def-1));
|
||||
color: (rgb(--clr-fg-def-1));
|
||||
}
|
||||
|
||||
.fnt-clr-secondary {
|
||||
color: rgb(var(--clr-fg-def-2));
|
||||
color: rgb(var(--clr-fg-def-2));
|
||||
}
|
||||
|
||||
.fnt-clr-tertiary {
|
||||
color: rgb(var(--clr-fg-def-3));
|
||||
color: rgb(var(--clr-fg-def-3));
|
||||
}
|
||||
|
||||
.fnt-clr-primary.fnt-clr--inverted {
|
||||
color: rgb(var(--clr-fg-inv-1));
|
||||
color: rgb(var(--clr-fg-inv-1));
|
||||
}
|
||||
|
||||
.fnt-clr-secondary.fnt-clr--inverted {
|
||||
color: rgb(var(--clr-fg-inv-2));
|
||||
color: rgb(var(--clr-fg-inv-2));
|
||||
}
|
||||
|
||||
.fnt-clr-tertiary.fnt-clr--inverted {
|
||||
color: rgb(var(--clr-fg-inv-3));
|
||||
}
|
||||
color: rgb(var(--clr-fg-inv-3));
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
@import './typography-body.css';
|
||||
@import './typography-title.css';
|
||||
@import './typography-headline.css'
|
||||
@import "./typography-body.css";
|
||||
@import "./typography-title.css";
|
||||
@import "./typography-headline.css";
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
.fnt-body-default {
|
||||
font-size: 1rem;
|
||||
line-height: 132%;
|
||||
letter-spacing: 3%;
|
||||
font-size: 1rem;
|
||||
line-height: 132%;
|
||||
letter-spacing: 3%;
|
||||
}
|
||||
|
||||
.fnt-body-s {
|
||||
font-size: 0.925rem;
|
||||
line-height: 132%;
|
||||
letter-spacing: 3%;
|
||||
font-size: 0.925rem;
|
||||
line-height: 132%;
|
||||
letter-spacing: 3%;
|
||||
}
|
||||
|
||||
.fnt-body-xs {
|
||||
font-size: 0.875rem;
|
||||
line-height: 132%;
|
||||
letter-spacing: 3%;
|
||||
}
|
||||
font-size: 0.875rem;
|
||||
line-height: 132%;
|
||||
letter-spacing: 3%;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
.fnt-headline-default {
|
||||
font-size: 1.5rem;
|
||||
line-height: 116%;
|
||||
letter-spacing: 1%;
|
||||
font-size: 1.5rem;
|
||||
line-height: 116%;
|
||||
letter-spacing: 1%;
|
||||
}
|
||||
|
||||
.fnt-headline-m {
|
||||
font-size: 1.75rem;
|
||||
line-height: 116%;
|
||||
letter-spacing: 1%;
|
||||
font-size: 1.75rem;
|
||||
line-height: 116%;
|
||||
letter-spacing: 1%;
|
||||
}
|
||||
|
||||
.fnt-headline-l {
|
||||
font-size: 2rem;
|
||||
line-height: 116%;
|
||||
letter-spacing: 1%;
|
||||
}
|
||||
font-size: 2rem;
|
||||
line-height: 116%;
|
||||
letter-spacing: 1%;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
.fnt-title-default {
|
||||
font-size: 1.125rem;
|
||||
line-height: 124%;
|
||||
letter-spacing: 3%;
|
||||
font-size: 1.125rem;
|
||||
line-height: 124%;
|
||||
letter-spacing: 3%;
|
||||
}
|
||||
|
||||
|
||||
.fnt-title-m {
|
||||
font-size: 1.25rem;
|
||||
line-height: 124%;
|
||||
letter-spacing: 3%;
|
||||
font-size: 1.25rem;
|
||||
line-height: 124%;
|
||||
letter-spacing: 3%;
|
||||
}
|
||||
|
||||
.fnt-title-l {
|
||||
font-size: 1.375rem;
|
||||
line-height: 124%;
|
||||
letter-spacing: 3%;
|
||||
}
|
||||
font-size: 1.375rem;
|
||||
line-height: 124%;
|
||||
letter-spacing: 3%;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
@import './typography-hierarchy/';
|
||||
@import './typography-color.css';
|
||||
@import "./typography-hierarchy/";
|
||||
@import "./typography-color.css";
|
||||
|
||||
.fnt-weight-normal {
|
||||
font-weight: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.fnt-weight-medium {
|
||||
font-weight: medium;
|
||||
font-weight: medium;
|
||||
}
|
||||
|
||||
.fnt-weight-bold {
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
.fnt-weight-normal.fnt-clr--inverted {
|
||||
font-weight: light;
|
||||
font-weight: light;
|
||||
}
|
||||
|
||||
.fnt-weight-medium.fnt-clr--inverted {
|
||||
font-weight: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.fnt-weight-bold.fnt-clr--inverted {
|
||||
font-weight: 600;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,96 @@
|
||||
import {type JSX} from 'solid-js'
|
||||
import {Dynamic} from 'solid-js/web'
|
||||
import { type JSX } from "solid-js";
|
||||
import { Dynamic } from "solid-js/web";
|
||||
import cx from "classnames";
|
||||
import "./css/typography.css";
|
||||
|
||||
import './css/typography.css'
|
||||
type Hierarchy = "body" | "title" | "headline";
|
||||
type Color = "primary" | "secondary" | "tertiary";
|
||||
type Weight = "normal" | "medium" | "bold";
|
||||
type Tag = "span" | "p" | "h1" | "h2" | "h3" | "h4";
|
||||
|
||||
type Hierarchy = 'body' | 'title' | 'headline'
|
||||
type Size = 'default' | 'xs' | 's' | 'm' | 'l'
|
||||
type Color = 'primary' | 'secondary' | 'tertiary'
|
||||
type Weight = 'normal' | 'medium' | 'bold'
|
||||
type Tag = 'span' | 'p' | 'h1' | 'h2' |'h3'| 'h4'
|
||||
const colorMap: Record<Color, string> = {
|
||||
primary: cx("fnt-clr-primary"),
|
||||
secondary: cx("fnt-clr-secondary"),
|
||||
tertiary: cx("fnt-clr-tertiary"),
|
||||
};
|
||||
|
||||
interface Typography {
|
||||
hierarchy: Hierarchy
|
||||
weight: Weight
|
||||
color: Color
|
||||
inverted: boolean
|
||||
size: Size
|
||||
tag: Tag
|
||||
children: JSX.Element
|
||||
classes?: string
|
||||
// type Size = "default" | "xs" | "s" | "m" | "l";
|
||||
interface SizeForHierarchy {
|
||||
body: {
|
||||
default: string;
|
||||
xs: string;
|
||||
s: string;
|
||||
};
|
||||
headline: {
|
||||
default: string;
|
||||
m: string;
|
||||
l: string;
|
||||
};
|
||||
title: {
|
||||
default: string;
|
||||
m: string;
|
||||
l: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const Typography = (props: Typography) => {
|
||||
const {size, color, inverted, hierarchy, weight, tag, children, classes} = props
|
||||
|
||||
return <Dynamic component={tag} class={`${classes? classes + ' ' : ''} fnt-${hierarchy}-${size} fnt-clr-${color} fnt-clr--${inverted ? 'inverted' : 'default'} fnt-${weight}`}>{children}</Dynamic>
|
||||
}
|
||||
type AllowedSizes<H extends Hierarchy> = keyof SizeForHierarchy[H];
|
||||
|
||||
const sizeHierarchyMap: SizeForHierarchy = {
|
||||
body: {
|
||||
default: cx("fnt-body-default"),
|
||||
xs: cx("fnt-body-xs"),
|
||||
s: cx("fnt-body-s"),
|
||||
// m: cx("fnt-body-m"),
|
||||
// l: cx("fnt-body-l"),
|
||||
},
|
||||
headline: {
|
||||
default: cx("fnt-headline-default"),
|
||||
// xs: cx("fnt-headline-xs"),
|
||||
// s: cx("fnt-headline-s"),
|
||||
m: cx("fnt-headline-m"),
|
||||
l: cx("fnt-headline-l"),
|
||||
},
|
||||
title: {
|
||||
default: cx("fnt-title-default"),
|
||||
// xs: cx("fnt-title-xs"),
|
||||
// s: cx("fnt-title-s"),
|
||||
m: cx("fnt-title-m"),
|
||||
l: cx("fnt-title-l"),
|
||||
},
|
||||
};
|
||||
|
||||
const weightMap: Record<Weight, string> = {
|
||||
normal: cx("fnt-weight-normal"),
|
||||
medium: cx("fnt-weight-medium"),
|
||||
bold: cx("fnt-weight-bold"),
|
||||
};
|
||||
|
||||
interface TypographyProps<H extends Hierarchy> {
|
||||
hierarchy: H;
|
||||
weight: Weight;
|
||||
color: Color;
|
||||
inverted: boolean;
|
||||
size: AllowedSizes<H>;
|
||||
tag: Tag;
|
||||
children: JSX.Element;
|
||||
classes?: string;
|
||||
}
|
||||
export const Typography = <H extends Hierarchy>(props: TypographyProps<H>) => {
|
||||
const { size, color, inverted, hierarchy, weight, tag, children, classes } =
|
||||
props;
|
||||
|
||||
return (
|
||||
<Dynamic
|
||||
component={tag}
|
||||
class={cx(
|
||||
classes,
|
||||
colorMap[color],
|
||||
inverted && "fnt-clr--inverted",
|
||||
sizeHierarchyMap[hierarchy][size] as string,
|
||||
weightMap[weight],
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</Dynamic>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
@import "material-icons/iconfont/filled.css";
|
||||
/* List of icons: https://marella.me/material-icons/demo/ */
|
||||
/* @import url(./components/Typography/css/typography.css); */
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@@ -24,43 +24,43 @@
|
||||
|
||||
:root {
|
||||
--clr-bg-def-1: theme(colors.white);
|
||||
--clr-bg-def-2: theme(colors.clan-secondary.50);
|
||||
--clr-bg-def-3: theme(colors.clan-secondary.100);
|
||||
--clr-bg-def-4: theme(colors.clan-secondary.200);
|
||||
--clr-bg-def-5: theme(colors.clan-secondary.300);
|
||||
--clr-bg-def-2: theme(colors.secondary.50);
|
||||
--clr-bg-def-3: theme(colors.secondary.100);
|
||||
--clr-bg-def-4: theme(colors.secondary.200);
|
||||
--clr-bg-def-5: theme(colors.secondary.300);
|
||||
|
||||
--clr-border-def-1: theme(colors.clan-secondary.50);
|
||||
--clr-border-def-2: theme(colors.clan-secondary.100);
|
||||
--clr-border-def-3: theme(colors.clan-secondary.200);
|
||||
--clr-border-def-4: theme(colors.clan-secondary.300);
|
||||
--clr-border-def-5: theme(colors.clan-secondary.400);
|
||||
--clr-border-def-1: theme(colors.secondary.50);
|
||||
--clr-border-def-2: theme(colors.secondary.100);
|
||||
--clr-border-def-3: theme(colors.secondary.200);
|
||||
--clr-border-def-4: theme(colors.secondary.300);
|
||||
--clr-border-def-5: theme(colors.secondary.400);
|
||||
|
||||
--clr-bg-inv-1: theme(colors.clan-primary.600);
|
||||
--clr-bg-inv-2: theme(colors.clan-primary.700);
|
||||
--clr-bg-inv-3: theme(colors.clan-primary.800);
|
||||
--clr-bg-inv-4: theme(colors.clan-primary.900);
|
||||
--clr-bg-inv-5: theme(colors.clan-primary.950);
|
||||
--clr-bg-inv-1: theme(colors.primary.600);
|
||||
--clr-bg-inv-2: theme(colors.primary.700);
|
||||
--clr-bg-inv-3: theme(colors.primary.800);
|
||||
--clr-bg-inv-4: theme(colors.primary.900);
|
||||
--clr-bg-inv-5: theme(colors.primary.950);
|
||||
|
||||
--clr-border-inv-1: theme(colors.clan-secondary.800);
|
||||
--clr-border-inv-2: theme(colors.clan-secondary.900);
|
||||
--clr-border-inv-3: theme(colors.clan-secondary.900);
|
||||
--clr-border-inv-4: theme(colors.clan-secondary.950);
|
||||
--clr-border-inv-1: theme(colors.secondary.800);
|
||||
--clr-border-inv-2: theme(colors.secondary.900);
|
||||
--clr-border-inv-3: theme(colors.secondary.900);
|
||||
--clr-border-inv-4: theme(colors.secondary.950);
|
||||
--clr-border-inv-5: theme(colors.black);
|
||||
|
||||
--clr-bg-inv-acc-1: theme(colors.clan-secondary.500);
|
||||
--clr-bg-inv-acc-2: theme(colors.clan-secondary.600);
|
||||
--clr-bg-inv-acc-3: theme(colors.clan-secondary.700);
|
||||
--clr-bg-inv-acc-1: theme(colors.secondary.500);
|
||||
--clr-bg-inv-acc-2: theme(colors.secondary.600);
|
||||
--clr-bg-inv-acc-3: theme(colors.secondary.700);
|
||||
|
||||
--clr-fg-def-1: theme(colors.clan-secondary.950);
|
||||
--clr-fg-def-2: theme(colors.clan-secondary.900);
|
||||
--clr-fg-def-3: theme(colors.clan-secondary.700);
|
||||
--clr-fg-def-4: theme(colors.clan-secondary.500);
|
||||
--clr-fg-def-1: theme(colors.secondary.950);
|
||||
--clr-fg-def-2: theme(colors.secondary.900);
|
||||
--clr-fg-def-3: theme(colors.secondary.700);
|
||||
--clr-fg-def-4: theme(colors.secondary.500);
|
||||
|
||||
--clr-fg-inv-1: 255 255 255;
|
||||
--clr-fg-inv-2: theme(colors.clan-secondary.100);
|
||||
--clr-fg-inv-3: theme(colors.clan-secondary.300);
|
||||
--clr-fg-inv-4: theme(colors.clan-secondary.400);
|
||||
}
|
||||
--clr-fg-inv-1: theme(colors.white);
|
||||
--clr-fg-inv-2: theme(colors.secondary.100);
|
||||
--clr-fg-inv-3: theme(colors.secondary.300);
|
||||
--clr-fg-inv-4: theme(colors.secondary.400);
|
||||
}
|
||||
|
||||
html {
|
||||
@apply font-sans;
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { Component, createEffect, Show } from "solid-js";
|
||||
import { Header } from "./header";
|
||||
import { Sidebar } from "../Sidebar";
|
||||
import {Sidebar as SidebarUpdate} from "@/src/components/Sidebar"
|
||||
import { Sidebar as SidebarUpdate } from "@/src/components/Sidebar";
|
||||
import { activeURI, clanList } from "../App";
|
||||
import { redirect, RouteSectionProps, useNavigate } from "@solidjs/router";
|
||||
|
||||
export const Layout: Component<RouteSectionProps> = (props) => {
|
||||
const navigate = useNavigate();
|
||||
+
|
||||
createEffect(() => {
|
||||
+createEffect(() => {
|
||||
console.log("Layout props", props.location);
|
||||
console.log(
|
||||
"empty ClanList, redirect to welcome page",
|
||||
@@ -45,7 +44,7 @@ export const Layout: Component<RouteSectionProps> = (props) => {
|
||||
aria-label="close sidebar"
|
||||
class="drawer-overlay"
|
||||
></label>
|
||||
<SidebarUpdate />
|
||||
<SidebarUpdate {...props} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,21 @@ import core from "./tailwind/core-plugin";
|
||||
const config = {
|
||||
content: ["./src/**/*.{js,jsx,ts,tsx}"],
|
||||
theme: {
|
||||
extend: {},
|
||||
colors: {
|
||||
secondary: {
|
||||
50: "#f7f9f9",
|
||||
100: "#e7f2f4",
|
||||
200: "#d7e8ea",
|
||||
300: "#afc6ca",
|
||||
400: "#8fb2b6",
|
||||
500: "#7b9a9e",
|
||||
600: "#4f747a",
|
||||
700: "#415e63",
|
||||
800: "#445f64",
|
||||
900: "#2b4347",
|
||||
950: "#0d1415",
|
||||
},
|
||||
},
|
||||
},
|
||||
daisyui: {
|
||||
themes: [
|
||||
@@ -25,7 +39,7 @@ const config = {
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [typography, daisyui, core],
|
||||
plugins: [typography, core, daisyui],
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import plugin from "tailwindcss/plugin";
|
||||
import { typography } from "./typography";
|
||||
import theme from "tailwindcss/defaultTheme";
|
||||
// @ts-expect-error: lib of tailwind has no types
|
||||
import { parseColor } from "tailwindcss/lib/util/color";
|
||||
|
||||
/* Converts HEX color to RGB */
|
||||
const toRGB = (value: string) => parseColor(value).color.join(" ");
|
||||
|
||||
export default plugin.withOptions(
|
||||
(_options = {}) =>
|
||||
@@ -10,6 +14,64 @@ export default plugin.withOptions(
|
||||
// add configuration which is merged with the final config
|
||||
() => ({
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
white: toRGB("#ffffff"),
|
||||
black: toRGB("#000000"),
|
||||
primary: {
|
||||
50: toRGB("#f4f9f9"),
|
||||
100: toRGB("#dbeceb"),
|
||||
200: toRGB("#b6d9d6"),
|
||||
300: toRGB("#8abebc"),
|
||||
400: toRGB("#478585"),
|
||||
500: toRGB("#526f6f"),
|
||||
600: toRGB("#4b6667"),
|
||||
700: toRGB("#345253"),
|
||||
800: toRGB("#2a4647"),
|
||||
900: toRGB("#1f3536"),
|
||||
950: toRGB("#162324"),
|
||||
},
|
||||
secondary: {
|
||||
50: toRGB("#f7f9f9"),
|
||||
100: toRGB("#e7f2f4"),
|
||||
200: toRGB("#d7e8ea"),
|
||||
300: toRGB("#afc6ca"),
|
||||
400: toRGB("#8fb2b6"),
|
||||
500: toRGB("#7b9a9e"),
|
||||
600: toRGB("#4f747a"),
|
||||
700: toRGB("#415e63"),
|
||||
800: toRGB("#445f64"),
|
||||
900: toRGB("#2b4347"),
|
||||
950: toRGB("#0d1415"),
|
||||
},
|
||||
info: {
|
||||
50: toRGB("#eff9ff"),
|
||||
100: toRGB("#dff2ff"),
|
||||
200: toRGB("#b8e8ff"),
|
||||
300: toRGB("#78d6ff"),
|
||||
400: toRGB("#2cc0ff"),
|
||||
500: toRGB("#06aaf1"),
|
||||
600: toRGB("#006ca7"),
|
||||
700: toRGB("#006ca7"),
|
||||
800: toRGB("#025b8a"),
|
||||
900: toRGB("#084c72"),
|
||||
950: toRGB("#06304b"),
|
||||
},
|
||||
error: {
|
||||
50: toRGB("#fcf3f8"),
|
||||
100: toRGB("#f9eaf4"),
|
||||
200: toRGB("#f5d5e9"),
|
||||
300: toRGB("#ea9ecb"),
|
||||
400: toRGB("#e383ba"),
|
||||
500: toRGB("#d75d9f"),
|
||||
600: toRGB("#c43e81"),
|
||||
700: toRGB("#a82e67"),
|
||||
800: toRGB("#8c2855"),
|
||||
900: toRGB("#75264a"),
|
||||
950: toRGB("#461129"),
|
||||
},
|
||||
},
|
||||
},
|
||||
...typography,
|
||||
},
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user