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:
Glen Huang
2025-09-19 19:37:29 +08:00
parent 91985504d0
commit 133f4aee53
20 changed files with 297 additions and 347 deletions

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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,
}, },

View File

@@ -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;

View File

@@ -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>

View File

@@ -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}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;
}
}

View 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;
}
}

View File

@@ -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) => (

View File

@@ -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;
} }

View File

@@ -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}

View File

@@ -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>;

View File

@@ -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

View File

@@ -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">

View File

@@ -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 ...

View File

@@ -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}

View File

@@ -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>