From 67ea21b55a281d6feb00820f1fec94da50165678 Mon Sep 17 00:00:00 2001 From: OpeOginni <107570612+OpeOginni@users.noreply.github.com> Date: Sat, 24 Jan 2026 19:03:36 +0100 Subject: feat(web): implement new server management for web and desktop (#8513) --- packages/ui/src/components/list.css | 36 ++++++++++ packages/ui/src/components/list.tsx | 128 +++++++++++++++++++++++------------- 2 files changed, 118 insertions(+), 46 deletions(-) (limited to 'packages/ui') diff --git a/packages/ui/src/components/list.css b/packages/ui/src/components/list.css index 95641bb20..b2b8a2262 100644 --- a/packages/ui/src/components/list.css +++ b/packages/ui/src/components/list.css @@ -214,6 +214,7 @@ [data-slot="list-item"] { display: flex; + position: relative; width: 100%; padding: 6px 8px 6px 8px; align-items: center; @@ -254,6 +255,20 @@ margin-left: -4px; } + [data-slot="list-item-divider"] { + position: absolute; + bottom: 0; + left: var(--list-divider-inset, 16px); + right: var(--list-divider-inset, 16px); + height: 1px; + background: var(--border-weak-base); + pointer-events: none; + } + + [data-slot="list-item"]:last-child [data-slot="list-item-divider"] { + display: none; + } + &[data-active="true"] { border-radius: var(--radius-md); background: var(--surface-raised-base-hover); @@ -272,6 +287,27 @@ outline: none; } } + + [data-slot="list-item-add"] { + display: flex; + position: relative; + width: 100%; + padding: 6px 8px 6px 8px; + align-items: center; + color: var(--text-strong); + + /* text-14-medium */ + font-family: var(--font-family-sans); + font-size: 14px; + font-style: normal; + font-weight: var(--font-weight-medium); + line-height: var(--line-height-large); /* 142.857% */ + letter-spacing: var(--letter-spacing-normal); + + [data-component="input"] { + width: 100%; + } + } } } } diff --git a/packages/ui/src/components/list.tsx b/packages/ui/src/components/list.tsx index 6a7f3a029..5f585f90c 100644 --- a/packages/ui/src/components/list.tsx +++ b/packages/ui/src/components/list.tsx @@ -21,6 +21,16 @@ export interface ListSearchProps { action?: JSX.Element } +export interface ListAddProps { + class?: string + render: () => JSX.Element +} + +export interface ListAddProps { + class?: string + render: () => JSX.Element +} + export interface ListProps extends FilteredListProps { class?: string children: (item: T) => JSX.Element @@ -32,6 +42,8 @@ export interface ListProps extends FilteredListProps { filter?: string search?: ListSearchProps | boolean itemWrapper?: (item: T, node: JSX.Element) => JSX.Element + divider?: boolean + add?: ListAddProps } export interface ListRef { @@ -70,6 +82,8 @@ export function List(props: ListProps & { ref?: (ref: ListRef) => void }) const searchProps = () => (typeof props.search === "object" ? props.search : {}) const searchAction = () => searchProps().action + const addProps = () => props.add + const showAdd = () => !!addProps() const moved = (event: MouseEvent) => event.movementX !== 0 || event.movementY !== 0 @@ -159,6 +173,16 @@ export function List(props: ListProps & { ref?: (ref: ListRef) => void }) setScrollRef, }) + const renderAdd = () => { + const add = addProps() + if (!add) return null + return ( +
+ {add.render()} +
+ ) + } + function GroupHeader(groupProps: { category: string }): JSX.Element { const [stuck, setStuck] = createSignal(false) const [header, setHeader] = createSignal(undefined) @@ -243,7 +267,7 @@ export function List(props: ListProps & { ref?: (ref: ListRef) => void })
0} + when={flat().length > 0 || showAdd()} fallback={
{emptyMessage()}
@@ -251,55 +275,67 @@ export function List(props: ListProps & { ref?: (ref: ListRef) => void }) } > - {(group) => ( -
- - - -
- - {(item, i) => { - const node = ( - - ) - if (props.itemWrapper) return props.itemWrapper(item, node) - return node - }} - + + ) + if (props.itemWrapper) return props.itemWrapper(item, node) + return node + }} + + {renderAdd()} +
-
- )} + ) + }} + +
+
{renderAdd()}
+
+
-- cgit v1.2.3