ui: use css modules for Typography and SidebarBody
Extra changes: - Add missing transition to according triggers in SidebarBody - More sensible tag for each Typography hierarchy
This commit is contained in:
@@ -125,10 +125,6 @@
|
|||||||
&.loading {
|
&.loading {
|
||||||
@apply cursor-wait;
|
@apply cursor-wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .typography {
|
|
||||||
@apply max-w-full overflow-hidden whitespace-nowrap text-ellipsis;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button.in-HostFileInput-horizontal {
|
.button.in-HostFileInput-horizontal {
|
||||||
|
|||||||
@@ -90,12 +90,11 @@ export const Button = (props: ButtonProps) => {
|
|||||||
|
|
||||||
{local.children && (
|
{local.children && (
|
||||||
<Typography
|
<Typography
|
||||||
class={styles.typography}
|
|
||||||
hierarchy="label"
|
hierarchy="label"
|
||||||
size={local.size}
|
size={local.size}
|
||||||
inverted={local.hierarchy === "primary"}
|
inverted={local.hierarchy === "primary"}
|
||||||
weight="bold"
|
weight="bold"
|
||||||
tag="span"
|
in="Button"
|
||||||
>
|
>
|
||||||
{local.children}
|
{local.children}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
@@ -30,3 +30,9 @@
|
|||||||
.icon.in-ConfigureRole {
|
.icon.in-ConfigureRole {
|
||||||
@apply ml-auto;
|
@apply ml-auto;
|
||||||
}
|
}
|
||||||
|
.icon.in-SidebarBody-AccordionTrigger {
|
||||||
|
transition: transform 300ms cubic-bezier(0.87, 0, 0.13, 1);
|
||||||
|
}
|
||||||
|
[data-expanded] > .icon.in-SidebarBody-AccordionTrigger {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|||||||
@@ -131,7 +131,8 @@ type In =
|
|||||||
| "MachineTags-s"
|
| "MachineTags-s"
|
||||||
| "ConfigureRole"
|
| "ConfigureRole"
|
||||||
// TODO: better name
|
// TODO: better name
|
||||||
| "WorkflowPanelTitle";
|
| "WorkflowPanelTitle"
|
||||||
|
| "SidebarBody-AccordionTrigger";
|
||||||
export interface IconProps extends JSX.SvgSVGAttributes<SVGElement> {
|
export interface IconProps extends JSX.SvgSVGAttributes<SVGElement> {
|
||||||
icon: IconVariant;
|
icon: IconVariant;
|
||||||
size?: number | string;
|
size?: number | string;
|
||||||
@@ -153,8 +154,8 @@ const Icon: Component<IconProps> = (props) => {
|
|||||||
component={component()}
|
component={component()}
|
||||||
class={cx(
|
class={cx(
|
||||||
styles.icon,
|
styles.icon,
|
||||||
colorsStyles[local.color],
|
|
||||||
getInClasses(styles, local.in),
|
getInClasses(styles, local.in),
|
||||||
|
colorsStyles[local.color],
|
||||||
{
|
{
|
||||||
[colorsStyles.inverted]: local.inverted,
|
[colorsStyles.inverted]: local.inverted,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,10 +19,6 @@
|
|||||||
border-bottom: solid 1px theme(colors.border.def.2);
|
border-bottom: solid 1px theme(colors.border.def.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal_title {
|
|
||||||
@apply mx-auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal_body {
|
.modal_body {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@apply rounded-b-md p-4 pt-4 bg-def-1 flex-grow;
|
@apply rounded-b-md p-4 pt-4 bg-def-1 flex-grow;
|
||||||
|
|||||||
@@ -67,10 +67,10 @@ export const Modal = (props: ModalProps) => {
|
|||||||
<>
|
<>
|
||||||
<div class={styles.modal_header}>
|
<div class={styles.modal_header}>
|
||||||
<Typography
|
<Typography
|
||||||
class={styles.modal_title}
|
|
||||||
hierarchy="label"
|
hierarchy="label"
|
||||||
family="mono"
|
family="mono"
|
||||||
size="xs"
|
size="xs"
|
||||||
|
in="Modal-title"
|
||||||
>
|
>
|
||||||
{props.title}
|
{props.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ export const Default: Story = {
|
|||||||
height: "14.5rem",
|
height: "14.5rem",
|
||||||
// Test with lots of modules
|
// Test with lots of modules
|
||||||
options: generateModules(1000),
|
options: generateModules(1000),
|
||||||
|
// FIXME: replace with a component
|
||||||
renderItem: (item: Module) => {
|
renderItem: (item: Module) => {
|
||||||
return (
|
return (
|
||||||
<div class="flex items-center justify-between gap-2 rounded-md px-2 py-1 pr-4">
|
<div class="flex items-center justify-between gap-2 rounded-md px-2 py-1 pr-4">
|
||||||
@@ -93,7 +94,6 @@ export const Default: Story = {
|
|||||||
weight="normal"
|
weight="normal"
|
||||||
color="quaternary"
|
color="quaternary"
|
||||||
inverted
|
inverted
|
||||||
class="flex justify-between"
|
|
||||||
>
|
>
|
||||||
<span class="inline-block max-w-72 truncate align-middle">
|
<span class="inline-block max-w-72 truncate align-middle">
|
||||||
{item.description}
|
{item.description}
|
||||||
|
|||||||
@@ -29,10 +29,11 @@ export function TagSelect<T extends { value: unknown }>(
|
|||||||
<Typography
|
<Typography
|
||||||
hierarchy="label"
|
hierarchy="label"
|
||||||
weight="medium"
|
weight="medium"
|
||||||
class="flex gap-2 uppercase"
|
|
||||||
size="xs"
|
size="xs"
|
||||||
inverted
|
inverted
|
||||||
color="secondary"
|
color="secondary"
|
||||||
|
transform="uppercase"
|
||||||
|
in="TagSelect-label"
|
||||||
>
|
>
|
||||||
{props.label}
|
{props.label}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ export const Select = (props: SelectProps) => {
|
|||||||
size="s"
|
size="s"
|
||||||
weight="bold"
|
weight="bold"
|
||||||
family="condensed"
|
family="condensed"
|
||||||
class="flex w-full items-center"
|
in="Select-item-label"
|
||||||
>
|
>
|
||||||
{props.item.rawValue.label}
|
{props.item.rawValue.label}
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -129,8 +129,8 @@ export const Select = (props: SelectProps) => {
|
|||||||
size="s"
|
size="s"
|
||||||
weight="bold"
|
weight="bold"
|
||||||
family="condensed"
|
family="condensed"
|
||||||
class="flex w-full items-center"
|
|
||||||
color="secondary"
|
color="secondary"
|
||||||
|
in="Select-item-label"
|
||||||
>
|
>
|
||||||
Loading...
|
Loading...
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -144,8 +144,8 @@ export const Select = (props: SelectProps) => {
|
|||||||
size="s"
|
size="s"
|
||||||
weight="normal"
|
weight="normal"
|
||||||
family="condensed"
|
family="condensed"
|
||||||
class="flex w-full items-center"
|
|
||||||
color="secondary"
|
color="secondary"
|
||||||
|
in="Select-item-label"
|
||||||
>
|
>
|
||||||
{props.noOptionsText || "No options available"}
|
{props.noOptionsText || "No options available"}
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -157,7 +157,7 @@ export const Select = (props: SelectProps) => {
|
|||||||
size="s"
|
size="s"
|
||||||
weight="bold"
|
weight="bold"
|
||||||
family="condensed"
|
family="condensed"
|
||||||
class="flex w-full items-center"
|
in="Select-item-label"
|
||||||
>
|
>
|
||||||
{props.placeholder}
|
{props.placeholder}
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -186,7 +186,7 @@ export const Select = (props: SelectProps) => {
|
|||||||
size="s"
|
size="s"
|
||||||
weight="bold"
|
weight="bold"
|
||||||
family="condensed"
|
family="condensed"
|
||||||
class="flex w-full items-center"
|
in="Select-item-label"
|
||||||
>
|
>
|
||||||
{state.selectedOption().label}
|
{state.selectedOption().label}
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -219,7 +219,7 @@ export const Select = (props: SelectProps) => {
|
|||||||
hierarchy="body"
|
hierarchy="body"
|
||||||
size="xs"
|
size="xs"
|
||||||
weight="bold"
|
weight="bold"
|
||||||
class="flex w-full items-center"
|
in="Select-item-label"
|
||||||
>
|
>
|
||||||
{state.selectedOption().label}
|
{state.selectedOption().label}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
@@ -1,133 +0,0 @@
|
|||||||
div.sidebar-body {
|
|
||||||
@apply py-4 px-2;
|
|
||||||
/* full - (y padding) */
|
|
||||||
height: calc(100% - 2rem);
|
|
||||||
|
|
||||||
@apply border border-inv-3 rounded-bl-md rounded-br-md;
|
|
||||||
|
|
||||||
/* TODO: This is weird, we shouldn't disable native browser features, a11y impacts incomming */
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
background:
|
|
||||||
linear-gradient(0deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%),
|
|
||||||
linear-gradient(
|
|
||||||
180deg,
|
|
||||||
theme(colors.bg.inv.1) 0%,
|
|
||||||
theme(colors.bg.inv.3) 100%
|
|
||||||
);
|
|
||||||
|
|
||||||
@apply backdrop-blur-sm;
|
|
||||||
|
|
||||||
.accordion {
|
|
||||||
@apply w-full mb-4 h-full flex flex-col justify-start gap-4;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
@apply mb-0;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .item {
|
|
||||||
max-height: 50%;
|
|
||||||
&:last-child {
|
|
||||||
@apply mb-0;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .header {
|
|
||||||
@apply flex mb-2 px-2;
|
|
||||||
|
|
||||||
& > .trigger {
|
|
||||||
@apply inline-flex items-center justify-between w-full;
|
|
||||||
|
|
||||||
&:focus-visible {
|
|
||||||
@apply z-10;
|
|
||||||
outline: 2px solid hsl(200 98% 39%);
|
|
||||||
outline-offset: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .icon {
|
|
||||||
transition: transform 300ms cubic-bezier(0.87, 0, 0.13, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-expanded] > .icon {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-title {
|
|
||||||
@apply uppercase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .content {
|
|
||||||
@apply flex flex-col;
|
|
||||||
@apply py-3 px-1.5 bg-inv-4 rounded-md mb-4;
|
|
||||||
|
|
||||||
max-height: calc(100% - 24px);
|
|
||||||
overflow-y: auto;
|
|
||||||
scrollbar-width: none;
|
|
||||||
|
|
||||||
animation: slideAccordionUp 300ms cubic-bezier(0.87, 0, 0.13, 1);
|
|
||||||
|
|
||||||
&[data-expanded] {
|
|
||||||
animation: slideAccordionDown 300ms cubic-bezier(0.87, 0, 0.13, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
nav * {
|
|
||||||
@apply outline-none;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav > a {
|
|
||||||
@apply block w-full px-2 py-1.5 min-h-7 my-2 rounded-md;
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
@apply mt-0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
@apply mb-0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus-visible {
|
|
||||||
background: linear-gradient(
|
|
||||||
90deg,
|
|
||||||
theme(colors.secondary.900),
|
|
||||||
60%,
|
|
||||||
theme(colors.secondary.600) 100%
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
@apply bg-inv-acc-2;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
@apply bg-inv-acc-3;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
@apply bg-inv-acc-2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes slideAccordionDown {
|
|
||||||
from {
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
height: var(--kb-accordion-content-height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes slideAccordionUp {
|
|
||||||
from {
|
|
||||||
height: var(--kb-accordion-content-height);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
115
pkgs/clan-app/ui/src/components/Sidebar/SidebarBody.module.css
Normal file
115
pkgs/clan-app/ui/src/components/Sidebar/SidebarBody.module.css
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
.sidebarBody {
|
||||||
|
@apply py-4 px-2;
|
||||||
|
/* full - (y padding) */
|
||||||
|
height: calc(100% - 2rem);
|
||||||
|
|
||||||
|
@apply border border-inv-3 rounded-bl-md rounded-br-md;
|
||||||
|
|
||||||
|
/* TODO: This is weird, we shouldn't disable native browser features, a11y impacts incomming */
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
background:
|
||||||
|
linear-gradient(0deg, rgba(0, 0, 0, 0.1) 0%, rgba(0, 0, 0, 0.1) 100%),
|
||||||
|
linear-gradient(
|
||||||
|
180deg,
|
||||||
|
theme(colors.bg.inv.1) 0%,
|
||||||
|
theme(colors.bg.inv.3) 100%
|
||||||
|
);
|
||||||
|
|
||||||
|
@apply backdrop-blur-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion {
|
||||||
|
@apply w-full mb-4 h-full flex flex-col justify-start gap-4;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
@apply mb-0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.accordionItem {
|
||||||
|
max-height: 50%;
|
||||||
|
&:last-child {
|
||||||
|
@apply mb-0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.accordionHeader {
|
||||||
|
@apply flex mb-2 px-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordionTrigger {
|
||||||
|
@apply inline-flex items-center justify-between w-full;
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
@apply z-10;
|
||||||
|
outline: 2px solid hsl(200 98% 39%);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordionContent {
|
||||||
|
@apply flex flex-col;
|
||||||
|
@apply py-3 px-1.5 bg-inv-4 rounded-md mb-4;
|
||||||
|
|
||||||
|
max-height: calc(100% - 24px);
|
||||||
|
overflow-y: auto;
|
||||||
|
scrollbar-width: none;
|
||||||
|
|
||||||
|
animation: slideAccordionUp 300ms cubic-bezier(0.87, 0, 0.13, 1);
|
||||||
|
|
||||||
|
&[data-expanded] {
|
||||||
|
animation: slideAccordionDown 300ms cubic-bezier(0.87, 0, 0.13, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
nav * {
|
||||||
|
@apply outline-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav > a {
|
||||||
|
@apply block w-full px-2 py-1.5 min-h-7 my-2 rounded-md;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
@apply mt-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
@apply mb-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
theme(colors.secondary.900),
|
||||||
|
60%,
|
||||||
|
theme(colors.secondary.600) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
@apply bg-inv-acc-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
@apply bg-inv-acc-3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideAccordionDown {
|
||||||
|
from {
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
height: var(--kb-accordion-content-height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideAccordionUp {
|
||||||
|
from {
|
||||||
|
height: var(--kb-accordion-content-height);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import "./SidebarBody.css";
|
import styles from "./SidebarBody.module.css";
|
||||||
import { A } from "@solidjs/router";
|
import { A } from "@solidjs/router";
|
||||||
import { Accordion } from "@kobalte/core/accordion";
|
import { Accordion } from "@kobalte/core/accordion";
|
||||||
import Icon from "../Icon/Icon";
|
import Icon from "../Icon/Icon";
|
||||||
@@ -75,23 +75,29 @@ const Machines = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Accordion.Item class="item" value="machines">
|
<Accordion.Item class={styles.accordionItem} value="machines">
|
||||||
<Accordion.Header class="header">
|
<Accordion.Header class={styles.accordionHeader}>
|
||||||
<Accordion.Trigger class="trigger">
|
<Accordion.Trigger class={styles.accordionTrigger}>
|
||||||
<Typography
|
<Typography
|
||||||
class="section-title"
|
|
||||||
hierarchy="label"
|
hierarchy="label"
|
||||||
family="mono"
|
family="mono"
|
||||||
size="xs"
|
size="xs"
|
||||||
inverted
|
inverted
|
||||||
color="tertiary"
|
color="tertiary"
|
||||||
|
transform="uppercase"
|
||||||
>
|
>
|
||||||
Your Machines
|
Your Machines
|
||||||
</Typography>
|
</Typography>
|
||||||
<Icon icon="CaretDown" color="tertiary" inverted size="0.75rem" />
|
<Icon
|
||||||
|
icon="CaretDown"
|
||||||
|
color="tertiary"
|
||||||
|
inverted
|
||||||
|
size="0.75rem"
|
||||||
|
in="SidebarBody-AccordionTrigger"
|
||||||
|
/>
|
||||||
</Accordion.Trigger>
|
</Accordion.Trigger>
|
||||||
</Accordion.Header>
|
</Accordion.Header>
|
||||||
<Accordion.Content class="content">
|
<Accordion.Content class={styles.accordionContent}>
|
||||||
<Show
|
<Show
|
||||||
when={machines()}
|
when={machines()}
|
||||||
fallback={
|
fallback={
|
||||||
@@ -198,23 +204,29 @@ const Services = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Accordion.Item class="item" value="services">
|
<Accordion.Item class={styles.accordionItem} value="services">
|
||||||
<Accordion.Header class="header">
|
<Accordion.Header class={styles.accordionHeader}>
|
||||||
<Accordion.Trigger class="trigger">
|
<Accordion.Trigger class={styles.accordionTrigger}>
|
||||||
<Typography
|
<Typography
|
||||||
class="section-title"
|
|
||||||
hierarchy="label"
|
hierarchy="label"
|
||||||
family="mono"
|
family="mono"
|
||||||
size="xs"
|
size="xs"
|
||||||
inverted
|
inverted
|
||||||
color="tertiary"
|
color="tertiary"
|
||||||
|
transform="uppercase"
|
||||||
>
|
>
|
||||||
Services
|
Services
|
||||||
</Typography>
|
</Typography>
|
||||||
<Icon icon="CaretDown" color="tertiary" inverted size="0.75rem" />
|
<Icon
|
||||||
|
icon="CaretDown"
|
||||||
|
color="tertiary"
|
||||||
|
inverted
|
||||||
|
size="0.75rem"
|
||||||
|
in="SidebarBody-AccordionTrigger"
|
||||||
|
/>
|
||||||
</Accordion.Trigger>
|
</Accordion.Trigger>
|
||||||
</Accordion.Header>
|
</Accordion.Header>
|
||||||
<Accordion.Content class="content">
|
<Accordion.Content class={styles.accordionContent}>
|
||||||
<nav>
|
<nav>
|
||||||
<For each={serviceInstances()}>
|
<For each={serviceInstances()}>
|
||||||
{(mapped) => (
|
{(mapped) => (
|
||||||
@@ -242,9 +254,9 @@ export const SidebarBody = (props: SidebarProps) => {
|
|||||||
const defaultAccordionValues = ["machines", "services", ...sectionLabels];
|
const defaultAccordionValues = ["machines", "services", ...sectionLabels];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="sidebar-body">
|
<div class={styles.sidebarBody}>
|
||||||
<Accordion
|
<Accordion
|
||||||
class="accordion"
|
class={styles.accordion}
|
||||||
multiple
|
multiple
|
||||||
defaultValue={defaultAccordionValues}
|
defaultValue={defaultAccordionValues}
|
||||||
>
|
>
|
||||||
@@ -253,16 +265,16 @@ export const SidebarBody = (props: SidebarProps) => {
|
|||||||
|
|
||||||
<For each={props.staticSections}>
|
<For each={props.staticSections}>
|
||||||
{(section) => (
|
{(section) => (
|
||||||
<Accordion.Item class="item" value={section.title}>
|
<Accordion.Item class={styles.accordionItem} value={section.title}>
|
||||||
<Accordion.Header class="header">
|
<Accordion.Header class={styles.accordionHeader}>
|
||||||
<Accordion.Trigger class="trigger">
|
<Accordion.Trigger class={styles.accordionTrigger}>
|
||||||
<Typography
|
<Typography
|
||||||
class="section-title"
|
|
||||||
hierarchy="label"
|
hierarchy="label"
|
||||||
family="mono"
|
family="mono"
|
||||||
size="xs"
|
size="xs"
|
||||||
inverted
|
inverted
|
||||||
color="tertiary"
|
color="tertiary"
|
||||||
|
transform="uppercase"
|
||||||
>
|
>
|
||||||
{section.title}
|
{section.title}
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -271,10 +283,11 @@ export const SidebarBody = (props: SidebarProps) => {
|
|||||||
color="tertiary"
|
color="tertiary"
|
||||||
inverted
|
inverted
|
||||||
size="0.75rem"
|
size="0.75rem"
|
||||||
|
in="SidebarBody-AccordionTrigger"
|
||||||
/>
|
/>
|
||||||
</Accordion.Trigger>
|
</Accordion.Trigger>
|
||||||
</Accordion.Header>
|
</Accordion.Header>
|
||||||
<Accordion.Content class="content">
|
<Accordion.Content class={styles.accordionContent}>
|
||||||
<nav>
|
<nav>
|
||||||
<For each={section.links || []}>
|
<For each={section.links || []}>
|
||||||
{(link) => (
|
{(link) => (
|
||||||
|
|||||||
@@ -13,6 +13,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.body {
|
&.body {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.32;
|
||||||
|
letter-spacing: 0.005rem;
|
||||||
|
|
||||||
&.family-regular {
|
&.family-regular {
|
||||||
font-family: "Archivo", sans-serif;
|
font-family: "Archivo", sans-serif;
|
||||||
}
|
}
|
||||||
@@ -21,12 +25,6 @@
|
|||||||
font-family: "Archivo SemiCondensed", sans-serif;
|
font-family: "Archivo SemiCondensed", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.size-default {
|
|
||||||
font-size: 1rem;
|
|
||||||
line-height: 1.32;
|
|
||||||
letter-spacing: 0.005rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.size-s {
|
&.size-s {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
line-height: 1.32;
|
line-height: 1.32;
|
||||||
@@ -50,11 +48,9 @@
|
|||||||
&.family-condensed {
|
&.family-condensed {
|
||||||
font-family: "Archivo SemiCondensed", sans-serif;
|
font-family: "Archivo SemiCondensed", sans-serif;
|
||||||
|
|
||||||
&.size-default {
|
font-size: 1rem;
|
||||||
font-size: 1rem;
|
line-height: normal;
|
||||||
line-height: normal;
|
letter-spacing: 0.02rem;
|
||||||
letter-spacing: 0.02rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.size-s {
|
&.size-s {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
@@ -78,11 +74,9 @@
|
|||||||
&.family-mono {
|
&.family-mono {
|
||||||
font-family: "Commit Mono", monospace;
|
font-family: "Commit Mono", monospace;
|
||||||
|
|
||||||
&.size-default {
|
font-size: 1rem;
|
||||||
font-size: 1rem;
|
line-height: normal;
|
||||||
line-height: normal;
|
letter-spacing: normal;
|
||||||
letter-spacing: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.size-s {
|
&.size-s {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
@@ -104,16 +98,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.title {
|
&.title {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
line-height: 124%;
|
||||||
|
letter-spacing: 0.03375rem;
|
||||||
|
|
||||||
&.family-regular {
|
&.family-regular {
|
||||||
font-family: "Archivo", sans-serif;
|
font-family: "Archivo", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.size-default {
|
|
||||||
font-size: 1.125rem;
|
|
||||||
line-height: 124%;
|
|
||||||
letter-spacing: 0.03375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.size-m {
|
&.size-m {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
line-height: 124%;
|
line-height: 124%;
|
||||||
@@ -128,16 +120,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.headline {
|
&.headline {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
line-height: 116%;
|
||||||
|
letter-spacing: 0.015rem;
|
||||||
|
|
||||||
&.family-regular {
|
&.family-regular {
|
||||||
font-family: "Archivo", sans-serif;
|
font-family: "Archivo", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.size-default {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
line-height: 116%;
|
|
||||||
letter-spacing: 0.015rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.size-m {
|
&.size-m {
|
||||||
font-size: 1.75rem;
|
font-size: 1.75rem;
|
||||||
line-height: 116%;
|
line-height: 116%;
|
||||||
@@ -164,15 +154,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.teaser {
|
&.teaser {
|
||||||
|
font-size: 3rem;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: -0.06rem;
|
||||||
|
|
||||||
&.family-regular {
|
&.family-regular {
|
||||||
font-family: "Archivo", sans-serif;
|
font-family: "Archivo", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.size-default {
|
|
||||||
font-size: 3rem;
|
|
||||||
line-height: normal;
|
|
||||||
letter-spacing: -0.06rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.align-left {
|
&.align-left {
|
||||||
@@ -186,4 +174,31 @@
|
|||||||
&.align-right {
|
&.align-right {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.uppercase {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
&.lowercase {
|
||||||
|
text-transform: lowercase;
|
||||||
|
}
|
||||||
|
&.capitalize {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.typography.in-Button {
|
||||||
|
@apply max-w-full overflow-hidden whitespace-nowrap text-ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.typography.in-Modal-title {
|
||||||
|
@apply mx-auto;
|
||||||
|
}
|
||||||
|
.typography.in-TagSelect-label {
|
||||||
|
@apply flex gap-2;
|
||||||
|
}
|
||||||
|
.typography.in-Select-item-label {
|
||||||
|
@apply flex w-full items-center;
|
||||||
|
}
|
||||||
|
.typography.in-SelectService-item-description {
|
||||||
|
@apply flex justify-between;
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,6 @@ const TypographyExamples: Component<TypographyExamplesProps> = (props) => (
|
|||||||
<Show when={!props.colors}>
|
<Show when={!props.colors}>
|
||||||
<Typography
|
<Typography
|
||||||
hierarchy={props.hierarchy}
|
hierarchy={props.hierarchy}
|
||||||
//@ts-expect-error: difficult to generify for the story
|
|
||||||
size={size}
|
size={size}
|
||||||
weight={weight}
|
weight={weight}
|
||||||
family={props.family}
|
family={props.family}
|
||||||
@@ -51,7 +50,6 @@ const TypographyExamples: Component<TypographyExamplesProps> = (props) => (
|
|||||||
<>
|
<>
|
||||||
<Typography
|
<Typography
|
||||||
hierarchy={props.hierarchy}
|
hierarchy={props.hierarchy}
|
||||||
//@ts-expect-error: difficult to generify for the story
|
|
||||||
size={size}
|
size={size}
|
||||||
weight={weight}
|
weight={weight}
|
||||||
color={color}
|
color={color}
|
||||||
|
|||||||
@@ -1,135 +1,99 @@
|
|||||||
import { type JSX } from "solid-js";
|
import { mergeProps, type ValidComponent, type JSX } from "solid-js";
|
||||||
import { Dynamic } from "solid-js/web";
|
import { Dynamic } from "solid-js/web";
|
||||||
import cx from "classnames";
|
import cx from "classnames";
|
||||||
import "./Typography.css";
|
import styles from "./Typography.module.css";
|
||||||
import { Color, fgClass } from "@/src/components/colors";
|
import { Color } from "@/src/components/colors";
|
||||||
|
import colorsStyles from "../colors.module.css";
|
||||||
|
import { getInClasses } from "@/src/util";
|
||||||
|
|
||||||
export type Tag = "span" | "p" | "h1" | "h2" | "h3" | "h4" | "div";
|
|
||||||
export type Hierarchy = "body" | "title" | "headline" | "label" | "teaser";
|
export type Hierarchy = "body" | "title" | "headline" | "label" | "teaser";
|
||||||
export type Weight = "normal" | "medium" | "bold";
|
export type Weight = "normal" | "medium" | "bold";
|
||||||
export type Family = "regular" | "condensed" | "mono";
|
export type Family = "regular" | "condensed" | "mono";
|
||||||
export type Transform = "uppercase" | "lowercase" | "capitalize";
|
export type Transform = "uppercase" | "lowercase" | "capitalize";
|
||||||
|
export interface SizeForHierarchy {
|
||||||
// type Size = "default" | "xs" | "s" | "m" | "l";
|
body: "default" | "s" | "xs" | "xxs";
|
||||||
interface SizeForHierarchy {
|
headline: "default" | "m" | "l" | "xl" | "xxl";
|
||||||
body: {
|
title: "default" | "m" | "l";
|
||||||
default: string;
|
label: "default" | "s" | "xs" | "xxs";
|
||||||
s: string;
|
teaser: "default";
|
||||||
xs: string;
|
}
|
||||||
xxs: string;
|
export interface TagForHierarchy {
|
||||||
};
|
body: "span" | "p" | "div";
|
||||||
label: {
|
headline: "h1" | "h2" | "h3" | "h4";
|
||||||
default: string;
|
title: "h1" | "h2" | "h3" | "h4";
|
||||||
s: string;
|
label: "span" | "div";
|
||||||
xs: string;
|
teaser: "h1" | "h2" | "h3" | "h4";
|
||||||
xxs: string;
|
|
||||||
};
|
|
||||||
headline: {
|
|
||||||
default: string;
|
|
||||||
m: string;
|
|
||||||
l: string;
|
|
||||||
xl: string;
|
|
||||||
xxl: string;
|
|
||||||
};
|
|
||||||
title: {
|
|
||||||
default: string;
|
|
||||||
m: string;
|
|
||||||
l: string;
|
|
||||||
};
|
|
||||||
teaser: {
|
|
||||||
default: string;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AllowedSizes<H extends Hierarchy> = keyof SizeForHierarchy[H];
|
const defaultFamilyMap = {
|
||||||
|
|
||||||
const sizeHierarchyMap: SizeForHierarchy = {
|
|
||||||
body: {
|
|
||||||
default: cx("size-default"),
|
|
||||||
s: cx("size-s"),
|
|
||||||
xs: cx("size-xs"),
|
|
||||||
xxs: cx("size-xxs"),
|
|
||||||
},
|
|
||||||
headline: {
|
|
||||||
default: cx("size-default"),
|
|
||||||
m: cx("size-m"),
|
|
||||||
l: cx("size-l"),
|
|
||||||
xl: cx("size-xl"),
|
|
||||||
xxl: cx("size-xxl"),
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
default: cx("size-default"),
|
|
||||||
// xs: cx("size-xs"),
|
|
||||||
// s: cx("size-s"),
|
|
||||||
m: cx("size-m"),
|
|
||||||
l: cx("size-l"),
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
default: cx("size-default"),
|
|
||||||
s: cx("size-s"),
|
|
||||||
xs: cx("size-xs"),
|
|
||||||
xxs: cx("size-xxs"),
|
|
||||||
},
|
|
||||||
teaser: {
|
|
||||||
default: cx("size-default"),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultFamilyMap: Record<Hierarchy, Family> = {
|
|
||||||
body: "condensed",
|
body: "condensed",
|
||||||
label: "condensed",
|
|
||||||
title: "regular",
|
|
||||||
headline: "regular",
|
headline: "regular",
|
||||||
|
title: "regular",
|
||||||
|
label: "condensed",
|
||||||
teaser: "regular",
|
teaser: "regular",
|
||||||
};
|
} as const;
|
||||||
|
|
||||||
const weightMap: Record<Weight, string> = {
|
const defaultTagMap = {
|
||||||
normal: "weight-normal",
|
body: "p",
|
||||||
medium: "weight-medium",
|
headline: "h1",
|
||||||
bold: "weight-bold",
|
title: "h2",
|
||||||
};
|
label: "span",
|
||||||
|
teaser: "h3",
|
||||||
interface _TypographyProps<H extends Hierarchy> {
|
} as const;
|
||||||
|
export interface TypographyProps<H extends Hierarchy> {
|
||||||
hierarchy: H;
|
hierarchy: H;
|
||||||
size: AllowedSizes<H>;
|
|
||||||
color?: Color;
|
|
||||||
children: JSX.Element;
|
children: JSX.Element;
|
||||||
|
size?: SizeForHierarchy[H];
|
||||||
|
color?: Color;
|
||||||
weight?: Weight;
|
weight?: Weight;
|
||||||
family?: Family;
|
family?: Family;
|
||||||
inverted?: boolean;
|
inverted?: boolean;
|
||||||
tag?: Tag;
|
tag?: TagForHierarchy[H];
|
||||||
class?: string;
|
|
||||||
transform?: Transform;
|
transform?: Transform;
|
||||||
align?: "left" | "center" | "right";
|
align?: "left" | "center" | "right";
|
||||||
|
in?:
|
||||||
|
| "Button"
|
||||||
|
| "Modal-title"
|
||||||
|
| "TagSelect-label"
|
||||||
|
| "Select-item-label"
|
||||||
|
| "SelectService-item-description";
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Typography = <H extends Hierarchy>(props: _TypographyProps<H>) => {
|
export const Typography = <H extends Hierarchy>(props: TypographyProps<H>) => {
|
||||||
const family = () =>
|
const local = mergeProps(
|
||||||
`family-${props.family || defaultFamilyMap[props.hierarchy]}`;
|
{
|
||||||
const hierarchy = () => props.hierarchy || "body";
|
size: "default",
|
||||||
const size = () => sizeHierarchyMap[props.hierarchy][props.size] as string;
|
color: "primary",
|
||||||
const weight = () => weightMap[props.weight || "normal"];
|
weight: "normal",
|
||||||
const color = () => fgClass(props.color, props.inverted);
|
family: defaultFamilyMap[props.hierarchy],
|
||||||
const align = () => `align-${props.align || "left"}`;
|
align: "left",
|
||||||
|
tag: defaultTagMap[props.hierarchy],
|
||||||
|
} as const,
|
||||||
|
props,
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dynamic
|
<Dynamic
|
||||||
|
component={local.tag as ValidComponent}
|
||||||
class={cx(
|
class={cx(
|
||||||
"typography",
|
styles.typography,
|
||||||
hierarchy(),
|
styles[local.hierarchy],
|
||||||
family(),
|
styles[`family-${local.family}`],
|
||||||
weight(),
|
styles[`weight-${local.weight}`],
|
||||||
size(),
|
local.size != "default" &&
|
||||||
color(),
|
styles[
|
||||||
align(),
|
`size-${local.size as Exclude<SizeForHierarchy[H], "default">}`
|
||||||
props.transform,
|
],
|
||||||
props.class,
|
styles[`align-${local.align}`],
|
||||||
|
local.transform && styles[local.transform],
|
||||||
|
colorsStyles[local.color],
|
||||||
|
{
|
||||||
|
[colorsStyles.inverted]: local.inverted,
|
||||||
|
},
|
||||||
|
getInClasses(styles, local.in),
|
||||||
)}
|
)}
|
||||||
component={props.tag || "span"}
|
|
||||||
>
|
>
|
||||||
{props.children}
|
{local.children}
|
||||||
</Dynamic>
|
</Dynamic>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TypographyProps = _TypographyProps<Hierarchy>;
|
|
||||||
|
|||||||
@@ -138,22 +138,11 @@ const UpdateProgress = () => {
|
|||||||
<div class="relative flex size-full flex-col items-center justify-end bg-inv-4">
|
<div class="relative flex size-full flex-col items-center justify-end bg-inv-4">
|
||||||
<img src={usbLogo} alt="usb logo" class="absolute top-2 z-0" />
|
<img src={usbLogo} alt="usb logo" class="absolute top-2 z-0" />
|
||||||
<div class="z-10 mb-6 flex w-full max-w-md flex-col items-center gap-2 fg-inv-1">
|
<div class="z-10 mb-6 flex w-full max-w-md flex-col items-center gap-2 fg-inv-1">
|
||||||
<Typography
|
<Typography hierarchy="title" weight="bold" color="inherit">
|
||||||
hierarchy="title"
|
|
||||||
size="default"
|
|
||||||
weight="bold"
|
|
||||||
color="inherit"
|
|
||||||
>
|
|
||||||
Machine is being updated
|
Machine is being updated
|
||||||
</Typography>
|
</Typography>
|
||||||
<LoadingBar />
|
<LoadingBar />
|
||||||
<Typography
|
<Typography hierarchy="label" color="secondary" inverted>
|
||||||
hierarchy="label"
|
|
||||||
size="default"
|
|
||||||
class=""
|
|
||||||
color="secondary"
|
|
||||||
inverted
|
|
||||||
>
|
|
||||||
Update {updateState()?.topic}...
|
Update {updateState()?.topic}...
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -38,17 +38,13 @@ const Prose = () => (
|
|||||||
>
|
>
|
||||||
Local Setup
|
Local Setup
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography
|
<div class="text-balance">
|
||||||
hierarchy="headline"
|
<Typography hierarchy="headline" weight="bold" color="inherit">
|
||||||
size="default"
|
Here's what you
|
||||||
weight="bold"
|
<br />
|
||||||
color="inherit"
|
need to do
|
||||||
class="text-balance"
|
</Typography>
|
||||||
>
|
</div>
|
||||||
Here's what you
|
|
||||||
<br />
|
|
||||||
need to do
|
|
||||||
</Typography>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-4 px-4">
|
<div class="flex flex-col gap-4 px-4">
|
||||||
|
|||||||
@@ -841,13 +841,7 @@ const InstallProgress = () => {
|
|||||||
Machine is being installed
|
Machine is being installed
|
||||||
</Typography>
|
</Typography>
|
||||||
<LoadingBar />
|
<LoadingBar />
|
||||||
<Typography
|
<Typography hierarchy="label" color="secondary" inverted>
|
||||||
hierarchy="label"
|
|
||||||
size="default"
|
|
||||||
class=""
|
|
||||||
color="secondary"
|
|
||||||
inverted
|
|
||||||
>
|
|
||||||
<Switch fallback={"Waiting for preparation to start..."}>
|
<Switch fallback={"Waiting for preparation to start..."}>
|
||||||
<Match when={store.install.prepareStep === "disk"}>
|
<Match when={store.install.prepareStep === "disk"}>
|
||||||
Configuring disk schema ...
|
Configuring disk schema ...
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export const SelectService = (props: FlyoutProps) => {
|
|||||||
weight="normal"
|
weight="normal"
|
||||||
color="quaternary"
|
color="quaternary"
|
||||||
inverted
|
inverted
|
||||||
class="flex justify-between"
|
in="SelectService-item-description"
|
||||||
>
|
>
|
||||||
<span class="inline-block max-w-80 truncate align-middle">
|
<span class="inline-block max-w-80 truncate align-middle">
|
||||||
{item.raw.info.manifest.description}
|
{item.raw.info.manifest.description}
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ const ConfigureRole = () => {
|
|||||||
size="s"
|
size="s"
|
||||||
weight="medium"
|
weight="medium"
|
||||||
inverted
|
inverted
|
||||||
class="capitalize"
|
transform="capitalize"
|
||||||
>
|
>
|
||||||
Select {store.currentRole}
|
Select {store.currentRole}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|||||||
Reference in New Issue
Block a user