initial commit
Some checks failed
CodeQL / Analyze (push) Failing after 1m32s

This commit is contained in:
Ludwig Lehnert
2026-01-11 11:08:48 +01:00
commit 0efd3d954b
58 changed files with 19390 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
import type { Component } from 'solid-js';
import { SSButton, SSCallout, SSHeader, SSSurface } from 'src';
import { IconShield } from '../../demo/content';
const NotFoundPage: Component = () => (
<div class="demo_page">
<SSHeader title="Not found" subtitle="This route is not available in the demo." />
<SSSurface class="demo_surface">
<SSCallout color="amber" icon={<IconShield />}>
The page you requested does not exist. Head back to the overview to continue exploring.
</SSCallout>
<SSButton onclick={() => (window.location.href = '#/')}>Back to overview</SSButton>
</SSSurface>
</div>
);
export default NotFoundPage;

View File

@@ -0,0 +1,73 @@
import type { Component } from 'solid-js';
import type { RouteSectionProps } from '@solidjs/router';
import { createSignal } from 'solid-js';
import {
SSButton,
SSCallout,
SSDropdown,
SSShell,
} from 'src';
import {
IconBell,
IconChart,
IconDots,
IconLink,
IconSettings,
IconShield,
IconSpark,
IconBolt,
IconCheck,
} from '../../demo/content';
const ShellLayout: Component<RouteSectionProps> = (props) => {
const [notice, setNotice] = createSignal(false);
return (
<SSShell
title="Sortsys UI"
actions={
<div class="demo_inline">
<SSButton isIconOnly ariaLabel="Notifications">
<IconBell />
</SSButton>
<SSButton class="secondary">Export</SSButton>
<SSDropdown
icon={<IconDots />}
items={[
{ label: 'Settings', icon: <IconSettings /> },
{ label: 'Share', icon: <IconLink /> },
]}
/>
</div>
}
nav={
<SSShell.Nav>
<SSShell.NavLink href="/" icon={<IconSpark />}>Overview</SSShell.NavLink>
<SSShell.NavLink href="/forms" icon={<IconBolt />}>Forms</SSShell.NavLink>
<SSShell.NavLink href="/data" icon={<IconChart />}>Data</SSShell.NavLink>
<SSShell.NavLink href="/modals" icon={<IconShield />}>Modals</SSShell.NavLink>
<SSShell.NavGroup title="Layout" icon={<IconSettings />} initiallyExpanded>
<SSShell.NavLink href="/layout" icon={<IconLink />}>Surfaces & tiles</SSShell.NavLink>
</SSShell.NavGroup>
<SSShell.NavAction onclick={() => setNotice(true)} icon={<IconBell />}>
Ping team
</SSShell.NavAction>
</SSShell.Nav>
}
>
{notice() && (
<div class="demo_notice">
<SSCallout color="green" icon={<IconCheck />}>
Team notified. The update will appear in the activity feed.
</SSCallout>
<SSButton class="tertiary" onclick={() => setNotice(false)}>
Clear
</SSButton>
</div>
)}
{props.children}
</SSShell>
);
};
export default ShellLayout;

View File

@@ -0,0 +1,43 @@
import type { Component } from 'solid-js';
import { createMemo } from 'solid-js';
import { SSDataTable, SSHeader, SSSurface } from 'src';
import { demoRows, renderStatus } from '../../demo/content';
const DataPage: Component = () => {
const columns = createMemo(() => [
{
label: 'Name',
render: (row: (typeof demoRows)[number]) => row.name,
sortKey: (row: (typeof demoRows)[number]) => row.name,
},
{
label: 'Role',
render: (row: (typeof demoRows)[number]) => row.role,
sortKey: (row: (typeof demoRows)[number]) => row.role,
},
{
label: 'Status',
render: (row: (typeof demoRows)[number]) => renderStatus(row.status),
sortKey: (row: (typeof demoRows)[number]) => row.status,
},
{
label: 'Updated',
render: (row: (typeof demoRows)[number]) => row.updated,
sortKey: (row: (typeof demoRows)[number]) => row.updated,
},
]);
return (
<div class="demo_page">
<SSHeader title="Data table" subtitle="Sorting, paging, and quick actions." />
<SSDataTable
columns={columns()}
rows={demoRows}
pageSize={3}
onRowClick={async () => {}}
/>
</div>
);
};
export default DataPage;

View File

@@ -0,0 +1,118 @@
import type { Component } from 'solid-js';
import { createSignal } from 'solid-js';
import {
SSChip,
SSDivider,
SSForm,
SSHeader,
SSSurface,
} from 'src';
import { peopleOptions, stackSuggestions, teamOptions } from '../../demo/content';
const FormsPage: Component = () => {
const [result, setResult] = createSignal<string | null>(null);
return (
<div class="demo_page">
<SSHeader title="Forms" subtitle="Inputs, selections, and validation in one place." />
<SSSurface class="demo_surface">
<SSForm
onsubmit={async (context) => {
const values = await context.getValues();
setResult(JSON.stringify(values, null, 2));
}}
>
<div class="demo_form_grid">
<SSForm.Input label="Project name" name="project" required />
<SSForm.Input label="Email" name="email" type="email" required />
<SSForm.Input label="Password" name="password" type="password" required />
<SSForm.Input label="Contact phone" name="phone" type="tel" />
</div>
<SSForm.Input
label="Message"
name="message"
textArea
/>
<SSForm.Input
label="Tech stack"
name="stack"
suggestions={{
prepare: () => stackSuggestions,
getItems: ({ query, init }) =>
init.filter((item) => item.toLowerCase().includes(query)).slice(0, 5),
stringify: ({ item }) => item,
}}
/>
<div class="demo_form_grid">
<SSForm.Date label="Start date" name="startDate" editable />
<SSForm.Date label="Target date" name="targetDate" />
</div>
<div class="demo_form_grid">
<SSForm.Select
label="Team"
name="team"
getOptions={() => teamOptions}
buildOption={(item) => item.label}
/>
<SSForm.Checkbox label="Notify stakeholders" name="notify" />
</div>
<SSDivider />
<SSForm.ACSelect
label="Invite members"
name="members"
minSelectedItems={1}
getOptions={({ query }) =>
peopleOptions.filter((item) =>
item.name.toLowerCase().includes(query.toLowerCase())
)
}
renderItem={({ item }) => (
<div class="demo_ac_item">
<strong>{item.name}</strong>
<span>{item.role}</span>
</div>
)}
/>
<SSForm.ACSelect
label="Primary owner"
name="owner"
maxSelectedItems={1}
getOptions={({ query }) =>
peopleOptions.filter((item) =>
item.name.toLowerCase().includes(query.toLowerCase())
)
}
renderItem={({ item }) => (
<div class="demo_ac_item">
<strong>{item.name}</strong>
<span>{item.role}</span>
</div>
)}
renderSelection={({ item }) => (
<SSChip color="indigo">{item.name}</SSChip>
)}
/>
<SSForm.SubmitButton>Save form</SSForm.SubmitButton>
</SSForm>
</SSSurface>
{result() && (
<SSSurface class="demo_surface">
<div class="demo_section_title">Submitted values</div>
<pre class="demo_code">{result()}</pre>
</SSSurface>
)}
</div>
);
};
export default FormsPage;

View File

@@ -0,0 +1,202 @@
import type { Component } from 'solid-js';
import { For, createSignal } from 'solid-js';
import {
SSAttrList,
SSButton,
SSCallout,
SSChip,
SSDivider,
SSDropdown,
SSExpandable,
SSHeader,
SSSurface,
SSTile,
} from 'src';
import {
IconBolt,
IconChart,
IconDots,
IconLink,
IconSettings,
IconShield,
IconSpark,
IconUser,
IconBell,
IconCheck,
} from '../../demo/content';
const OverviewPage: Component = () => {
const [bannerVisible, setBannerVisible] = createSignal(true);
const [chipItems, setChipItems] = createSignal([
{ id: 'launch', label: 'Launch ready', color: 'green' },
{ id: 'urgent', label: 'Urgent', color: 'red' },
{ id: 'info', label: 'Info', color: 'blue' },
]);
return (
<div class="demo_page">
<SSHeader
title="Sortsys UI"
subtitle="A crisp SolidJS component suite for operational products."
actions={
<div class="demo_inline">
<SSButton class="secondary">Preview</SSButton>
<SSButton>Publish</SSButton>
<SSDropdown
ariaLabel="Aktionen"
icon={<IconDots />}
items={[
{ label: 'Duplicate', icon: <IconSpark /> },
{ label: 'Share link', icon: <IconLink />, checked: true },
{ label: 'Archive', icon: <IconShield /> },
]}
/>
</div>
}
/>
{bannerVisible() && (
<div class="demo_notice">
<SSCallout color="blue" icon={<IconSpark />}>
A fresh demo layout that shows every component in context.
</SSCallout>
<SSButton class="tertiary" onclick={() => setBannerVisible(false)}>
Dismiss
</SSButton>
</div>
)}
<div class="demo_grid">
<SSSurface class="demo_surface">
<div class="demo_section_title">Status tiles</div>
<div class="demo_tiles">
<SSTile
title="Design review"
subtitle="Last updated 2 hours ago"
icon={<IconSpark />}
trailing="92%"
/>
<SSTile
title="Security sweep"
subtitle="Next window tomorrow"
icon={<IconShield />}
trailing="4 issues"
/>
<SSTile
title="Capacity"
subtitle="Quarterly planning"
icon={<IconChart />}
trailing="14 slots"
/>
</div>
</SSSurface>
<SSSurface class="demo_surface">
<div class="demo_section_title">Quick actions</div>
<div class="demo_buttons">
<SSButton>Primary action</SSButton>
<SSButton class="secondary">Secondary</SSButton>
<SSButton class="tertiary">Tertiary</SSButton>
<SSButton class="danger">Danger</SSButton>
<SSButton isIconOnly ariaLabel="Notifications">
<IconBell />
</SSButton>
</div>
<SSDivider />
<div class="demo_section_title">Chips</div>
<div class="demo_chips">
<For each={chipItems()}>
{(item) => (
<SSChip
color={item.color as any}
ondismiss={() =>
setChipItems((prev) => prev.filter((chip) => chip.id !== item.id))
}
>
{item.label}
</SSChip>
)}
</For>
<SSChip color="purple" onclick={() => {}}>
Clickable
</SSChip>
<SSChip color="amber">Display only</SSChip>
</div>
</SSSurface>
</div>
<SSSurface class="demo_surface">
<div class="demo_section_title">Attribute list</div>
<SSAttrList>
<SSAttrList.Attr
name="Lifecycle"
value="Production"
third={
<SSButton isIconOnly class="tertiary" ariaLabel="Edit">
<IconSettings />
</SSButton>
}
/>
<SSAttrList.Attr
name="Owner"
value="Customer Ops"
third="2 teams, 6 contributors"
/>
<SSAttrList.Attr name="Uptime" value="99.98%" third="Rolling 30 days" />
<SSAttrList.Attr name="Latency" value="142ms avg" third="p95 down 12%" />
<SSAttrList.Attr
name="Alerts"
value="2 open"
third="1 critical"
/>
<SSAttrList.Attr
name="Risk"
value="Low"
third="Review passed"
/>
</SSAttrList>
</SSSurface>
<div class="demo_grid">
<SSSurface class="demo_surface">
<div class="demo_section_title">Callouts</div>
<div class="demo_stack">
<SSCallout color="green" icon={<IconCheck />}>
All services are green. Next audit is scheduled for Friday.
</SSCallout>
<SSCallout color="amber" icon={<IconBolt />}>
2 alerts are pending review in the on-call queue.
</SSCallout>
<SSCallout color="red" icon={<IconShield />}>
Credentials rotation required within 14 days.
</SSCallout>
</div>
</SSSurface>
<SSSurface class="demo_surface">
<div class="demo_section_title">Expandable</div>
<SSExpandable title="Deployment checklist" initiallyExpanded>
<div class="demo_stack">
<div class="demo_inline">
<IconCheck />
<span>Review release notes and merge outstanding fixes.</span>
</div>
<div class="demo_inline">
<IconCheck />
<span>Warm up cache nodes and verify rollout.</span>
</div>
<div class="demo_inline">
<IconCheck />
<span>Post update to #ops and notify stakeholders.</span>
</div>
</div>
</SSExpandable>
</SSSurface>
</div>
</div>
);
};
export default OverviewPage;

View File

@@ -0,0 +1,61 @@
import type { Component } from 'solid-js';
import {
SSDivider,
SSExpandable,
SSHeader,
SSSurface,
SSTile,
} from 'src';
import { IconBolt, IconCheck, IconLink, IconShield } from '../../demo/content';
const LayoutPage: Component = () => (
<div class="demo_page">
<SSHeader title="Layout" subtitle="Surfaces, tiles, and dividers." />
<SSSurface class="demo_surface">
<div class="demo_section_title">Surface stacks</div>
<div class="demo_grid">
<SSSurface class="demo_surface demo_surface--nested">
<div class="demo_section_title">Sub-surface</div>
<p class="demo_text">Perfect for grouped content, metrics, or compact forms.</p>
</SSSurface>
<SSSurface class="demo_surface demo_surface--nested">
<div class="demo_section_title">Another surface</div>
<p class="demo_text">Use consistent radii and subtle shadows for hierarchy.</p>
</SSSurface>
</div>
</SSSurface>
<SSSurface class="demo_surface">
<div class="demo_section_title">Tile list</div>
<div class="demo_tiles">
<SSTile
title="Integrations"
subtitle="24 connected services"
icon={<IconLink />}
trailing={<IconCheck />}
/>
<SSTile
title="Automation"
subtitle="5 workflows running"
icon={<IconBolt />}
trailing="Live"
/>
<SSTile
title="Security"
subtitle="Next scan Friday"
icon={<IconShield />}
trailing="Low risk"
/>
</div>
<SSDivider />
<SSExpandable title="Notes">
<div class="demo_text">
Combine tiles with expandables to progressively reveal details.
</div>
</SSExpandable>
</SSSurface>
</div>
);
export default LayoutPage;

View File

@@ -0,0 +1,103 @@
import type { Component } from 'solid-js';
import { createSignal } from 'solid-js';
import {
SSAttrList,
SSButton,
SSCallout,
SSForm,
SSHeader,
SSModal,
SSSurface,
useSSModals,
} from 'src';
import { IconSpark } from '../../demo/content';
const ModalsPage: Component = () => {
const modals = useSSModals();
const [open, setOpen] = createSignal(false);
return (
<div class="demo_page">
<SSHeader title="Modals" subtitle="Inline and managed modal flows." />
<SSSurface class="demo_surface">
<div class="demo_inline">
<SSButton onclick={() => setOpen(true)}>Open modal</SSButton>
<SSButton
class="secondary"
onclick={() =>
modals.showDefault({
content: () => (
<div class="demo_stack">
<strong>Delete pipeline?</strong>
<span>This action will remove the pipeline and its history.</span>
</div>
),
modalProps: () => ({
title: 'Delete confirmation',
danger: true,
primaryButtonText: 'Delete',
}),
})
}
>
Default modal
</SSButton>
<SSButton
class="tertiary"
onclick={() =>
modals.showForm({
content: ({ context }) => (
<div class="demo_stack">
<SSForm.Input label="Change label" name="label" required />
<SSForm.Input label="Summary" name="summary" textArea />
<SSForm.Checkbox label="Notify watchers" name="notify" />
{context.hasError() && (
<span class="demo_hint">Please fix the highlighted fields.</span>
)}
</div>
),
modalProps: () => ({
title: 'Edit release',
primaryButtonText: 'Save',
}),
onSubmit: async ({ hide }) => {
hide();
},
})
}
>
Form modal
</SSButton>
</div>
</SSSurface>
<SSModal
open={open()}
title="Launch overview"
onClose={() => setOpen(false)}
footer={
<>
<SSButton class="secondary" onclick={() => setOpen(false)}>
Cancel
</SSButton>
<SSButton onclick={() => setOpen(false)}>Confirm</SSButton>
</>
}
>
<div class="demo_stack">
<SSCallout color="blue" icon={<IconSpark />}>
Everything is ready to go. Confirm to publish.
</SSCallout>
<SSAttrList>
<SSAttrList.Attr name="Version" value="v1.18.0" />
<SSAttrList.Attr name="Owner" value="Release team" />
<SSAttrList.Attr name="Window" value="Tomorrow 09:00 CET" />
</SSAttrList>
</div>
</SSModal>
</div>
);
};
export default ModalsPage;

25
dev/routes/auth/login.tsx Normal file
View File

@@ -0,0 +1,25 @@
import type { Component } from 'solid-js';
import { SSButton, SSCallout, SSForm, SSHeader, SSSurface } from 'src';
import { IconSpark } from '../../demo/content';
const LoginPage: Component = () => (
<div class="demo_page">
<SSHeader title="Sign in" subtitle="Access the demo workspace." />
<SSSurface class="demo_surface">
<SSCallout color="blue" icon={<IconSpark />}>
Use any email and password to explore the UI kit.
</SSCallout>
<SSForm onsubmit={() => {}}>
<SSForm.Input label="Email" name="email" type="email" required />
<SSForm.Input label="Password" name="password" type="password" required />
<SSForm.Checkbox label="Remember me" name="remember" />
<div class="demo_inline">
<SSButton>Sign in</SSButton>
<SSButton class="secondary">Request access</SSButton>
</div>
</SSForm>
</SSSurface>
</div>
);
export default LoginPage;