Files
catalog/ts_web/elements/idp-inbox-preview.ts
T

193 lines
6.0 KiB
TypeScript

import { DeesElement, html, property, customElement, css, type TemplateResult } from '@design.estate/dees-element';
import { idpElementStyles } from './tokens.js';
import './idp-approval-card.js';
import './idp-badge.js';
import './idp-button.js';
import './idp-icon.js';
import './idp-mobile-frame.js';
declare global {
interface HTMLElementTagNameMap {
'idp-inbox-preview': IdpInboxPreview;
}
}
@customElement('idp-inbox-preview')
export class IdpInboxPreview extends DeesElement {
public static demo = () => html`<idp-inbox-preview></idp-inbox-preview>`;
public static demoGroups = ['idp.global v3 approval surfaces'];
@property({ type: Boolean, reflect: true })
public accessor dark = false;
public static styles = [
...idpElementStyles,
css`
:host {
display: block;
}
idp-mobile-frame {
--idp-bg: #ffffff;
}
:host([dark]) idp-mobile-frame {
--idp-bg: #09090b;
--idp-fg: #fafafa;
}
.screen {
height: 100%;
background: var(--idp-bg);
color: var(--idp-fg);
box-sizing: border-box;
padding-top: 58px;
display: flex;
flex-direction: column;
}
.header {
padding: 0 20px 14px;
border-bottom: 1px solid var(--idp-border);
}
.brandline {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.brand {
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
font-weight: 650;
}
.brandmark {
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
background: var(--idp-primary);
color: var(--idp-primary-fg);
}
h2 {
margin: 0;
font-size: 24px;
font-weight: 760;
letter-spacing: -0.04em;
}
.summary {
display: flex;
align-items: center;
gap: 8px;
margin-top: 6px;
color: var(--idp-muted-fg);
font-size: 13px;
}
.list {
display: grid;
gap: 10px;
padding: 14px 16px 120px;
overflow: auto;
}
.earlier {
margin: 10px 0 2px;
color: var(--idp-muted-fg);
font-size: 11px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.row {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
border: 1px solid var(--idp-border);
border-radius: 10px;
font-size: 13px;
}
.row-icon {
width: 26px;
height: 26px;
border-radius: 7px;
background: var(--idp-muted);
color: var(--idp-ok);
display: flex;
align-items: center;
justify-content: center;
}
.row-sub {
color: var(--idp-muted-fg);
font-size: 12px;
margin-top: 1px;
}
.tabbar {
position: absolute;
left: 12px;
right: 12px;
bottom: 24px;
z-index: 80;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 4px;
padding: 8px;
border: 1px solid color-mix(in srgb, var(--idp-border), transparent 20%);
border-radius: 22px;
background: color-mix(in srgb, var(--idp-card), transparent 8%);
box-shadow: 0 16px 36px rgb(0 0 0 / 0.16);
backdrop-filter: blur(24px) saturate(170%);
}
.tab {
display: grid;
place-items: center;
gap: 3px;
min-height: 44px;
color: var(--idp-muted-fg);
font-size: 10px;
font-weight: 600;
}
.tab.active {
color: var(--idp-accent);
}
`,
];
public render(): TemplateResult {
return html`
<idp-mobile-frame ?dark=${this.dark}>
<div class="screen">
<header class="header">
<div class="brandline">
<div class="brand"><span class="brandmark"><idp-icon name="shield" size="14"></idp-icon></span>idp.global</div>
<idp-button variant="ghost" size="sm" icon="search" aria-label="Search"></idp-button>
</div>
<h2>Inbox</h2>
<div class="summary"><idp-badge variant="ok">3 pending</idp-badge><span>oldest 8 min ago</span></div>
</header>
<div class="list">
<idp-approval-card primary app-name="GitHub" app-initials="GH" app-color="#24292F" request-text="Sign in to github.com" location="Berlin · DE" device="Safari · MBP" time-label="now"></idp-approval-card>
<idp-approval-card app-name="Lufthansa.com" app-initials="LH" app-color="#05164D" request-text="Verify identity" location="Berlin · DE" device="iPhone 15 Pro" time-label="2m"></idp-approval-card>
<idp-approval-card app-name="Hetzner Cloud" app-initials="HZ" app-color="#D50C2D" request-text="Sign in to console" location="Falkenstein · DE" device="Firefox · Windows" risk="warning" time-label="8m"></idp-approval-card>
<div class="earlier">Earlier today</div>
${['Notion · Approved 11:42', 'Apple ID · Approved 09:18', 'reddit.com · Denied 08:57'].map((itemArg) => html`
<div class="row">
<div class="row-icon"><idp-icon name="check" size="15"></idp-icon></div>
<div>
<div>${itemArg.split(' · ')[0]}</div>
<div class="row-sub">${itemArg.split(' · ')[1]}</div>
</div>
</div>
`)}
</div>
<nav class="tabbar">
<div class="tab active"><idp-icon name="bell" size="18"></idp-icon>Inbox</div>
<div class="tab"><idp-icon name="clock" size="18"></idp-icon>History</div>
<div class="tab"><idp-icon name="device" size="18"></idp-icon>Devices</div>
<div class="tab"><idp-icon name="user" size="18"></idp-icon>Identity</div>
</nav>
</div>
</idp-mobile-frame>
`;
}
}