mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 15:36:33 +00:00
feat(settings,admin): every tab and popup in the planner's design
This commit is contained in:
@@ -1,21 +1,18 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import ToggleSwitch from '../Settings/ToggleSwitch'
|
||||
import { fs } from '../shared/DialogShell'
|
||||
|
||||
/**
|
||||
* One addon in the admin grid: a card whose fill carries the on/off state, with
|
||||
* an optional shelf at the foot holding its sub-features.
|
||||
* One addon in its type's card: a row like the bag sidebar's (#2541), with the
|
||||
* icon tile on the left, name and description beside it and the switch on the
|
||||
* right. Its sub-features sit under it in a grey inset box of hairline rows.
|
||||
*
|
||||
* The fill ladder is `--bg-secondary` (on) against `--bg-card` (the panel it
|
||||
* sits on) — that pair reads in both themes, because secondary is *darker* than
|
||||
* the card in light and *lighter* in dark. The obvious alternative, on =
|
||||
* `bg-surface-card`, inverts in dark and turns the disabled tiles into the loud
|
||||
* ones.
|
||||
* The on/off state rides on the icon tile and the switch: a switched-off addon
|
||||
* greys its tile and its description, but keeps its name at full strength. The
|
||||
* name is the tile's identity, not its state; greying it out reads as "broken"
|
||||
* rather than "not enabled".
|
||||
*
|
||||
* Hover and focus ride on border and fill rather than a shadow: `--shadow-card`
|
||||
* is only declared in `:root`, so the `.dark` palette never overrides it and a
|
||||
* shadow-based affordance would be invisible there.
|
||||
*
|
||||
* The card is not a click target — only the switches are. No lift, no pointer
|
||||
* The row is not a click target, only the switches are. No lift, no pointer
|
||||
* cursor, no `role="button"`.
|
||||
*/
|
||||
export default function AddonTile({
|
||||
@@ -35,46 +32,41 @@ export default function AddonTile({
|
||||
children?: ReactNode
|
||||
}) {
|
||||
return (
|
||||
<article
|
||||
className={`flex flex-col overflow-hidden rounded-xl border transition-[background-color,border-color] duration-150 focus-within:ring-2 focus-within:ring-accent ${
|
||||
enabled
|
||||
? 'border-edge bg-surface-secondary'
|
||||
: 'border-edge-secondary bg-surface hover:border-edge hover:bg-surface-secondary'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start gap-3 p-4">
|
||||
<article className="px-3.5 py-3 transition-colors duration-150 focus-within:bg-surface-secondary">
|
||||
<div className="flex items-start gap-3">
|
||||
<div
|
||||
// overflow-hidden so a brand mark that fills the slot keeps the slot's
|
||||
// rounded corners instead of squaring them off.
|
||||
className={`grid h-10 w-10 shrink-0 place-items-center overflow-hidden rounded-xl ${
|
||||
enabled ? 'border border-accent bg-accent-subtle text-accent-on' : 'bg-surface-tertiary text-content-faint'
|
||||
className={`grid h-9 w-9 flex-none place-items-center overflow-hidden rounded-[10px] transition-colors ${
|
||||
enabled ? 'bg-surface-card text-content shadow-sm ring-1 ring-edge-faint' : 'bg-surface-tertiary text-content-faint'
|
||||
}`}
|
||||
>
|
||||
{icon}
|
||||
</div>
|
||||
|
||||
<div className="min-w-0 flex-1">
|
||||
{/* The name stays full-strength when off: it is the tile's identity, not its
|
||||
state. Greying it out reads as "broken" rather than "not enabled". */}
|
||||
<h4 className="truncate text-body font-semibold text-content" title={name}>
|
||||
<div className="min-w-0 flex-1 pt-px">
|
||||
<h4 className="m-0 truncate font-semibold text-content" style={fs(13, 'body')} title={name}>
|
||||
{name}
|
||||
</h4>
|
||||
<p
|
||||
className={`mt-0.5 line-clamp-2 text-caption ${enabled ? 'text-content-muted' : 'text-content-faint'}`}
|
||||
className={`m-0 mt-0.5 line-clamp-2 leading-snug ${enabled ? 'text-content-muted' : 'text-content-faint'}`}
|
||||
style={fs(11.5)}
|
||||
title={description}
|
||||
>
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<ToggleSwitch on={enabled} onToggle={onToggle} label={name} />
|
||||
<div className="flex-none pt-1.5">
|
||||
<ToggleSwitch on={enabled} onToggle={onToggle} label={name} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{children && (
|
||||
<div className="border-t border-edge-secondary bg-surface-tertiary px-4 py-2.5">
|
||||
<div className="mt-3 overflow-hidden rounded-[12px] border border-edge-faint bg-surface-secondary">
|
||||
{/* Sitting inside the parent on its own fill is enough to say these belong
|
||||
to it — no rail, no indent guides. */}
|
||||
<ul className="space-y-0.5">{children}</ul>
|
||||
to it: no rail, no indent guides. */}
|
||||
<ul className="m-0 list-none divide-y divide-edge-faint p-0">{children}</ul>
|
||||
</div>
|
||||
)}
|
||||
</article>
|
||||
|
||||
Reference in New Issue
Block a user