diff --git a/interface/app/$libraryId/Explorer/View/index.tsx b/interface/app/$libraryId/Explorer/View/index.tsx index dc9b5244f..fcb8c9d6f 100644 --- a/interface/app/$libraryId/Explorer/View/index.tsx +++ b/interface/app/$libraryId/Explorer/View/index.tsx @@ -1,14 +1,13 @@ import clsx from 'clsx'; +import { Columns, GridFour, Icon, MonitorPlay, Rows } from 'phosphor-react'; import { - Cards, - Columns, - FolderNotchOpen, - GridFour, - MonitorPlay, - Rows, - SquaresFour -} from 'phosphor-react'; -import { HTMLAttributes, PropsWithChildren, ReactNode, memo, useState } from 'react'; + HTMLAttributes, + PropsWithChildren, + ReactNode, + isValidElement, + memo, + useState +} from 'react'; import { createSearchParams, useNavigate } from 'react-router-dom'; import { useKey } from 'rooks'; import { ExplorerItem, isPath, useLibraryContext, useLibraryMutation } from '@sd/client'; @@ -81,11 +80,11 @@ export const ViewItem = ({ data, children, ...props }: ViewItemProps) => { ); }; -interface Props +export interface ExplorerViewProps extends Omit, 'multiSelect' | 'selectable'> { layout: ExplorerLayoutMode; className?: string; - emptyNotice?: ReactNode; + emptyNotice?: JSX.Element | { icon?: Icon | ReactNode; message?: ReactNode } | null; } export default memo(({ layout, className, emptyNotice, ...contextProps }) => { @@ -111,22 +110,24 @@ export default memo(({ layout, className, emptyNotice, ...contextProps }) => { } }); - const emptyNoticeIcon = () => { - let Icon; + const emptyNoticeIcon = (icon?: Icon) => { + let Icon = icon; - switch (layout) { - case 'grid': - Icon = GridFour; - break; - case 'media': - Icon = MonitorPlay; - break; - case 'columns': - Icon = Columns; - break; - case 'rows': - Icon = Rows; - break; + if (!Icon) { + switch (layout) { + case 'grid': + Icon = GridFour; + break; + case 'media': + Icon = MonitorPlay; + break; + case 'columns': + Icon = Columns; + break; + case 'rows': + Icon = Rows; + break; + } } return ; @@ -150,14 +151,23 @@ export default memo(({ layout, className, emptyNotice, ...contextProps }) => { {layout === 'rows' && } {layout === 'media' && } - ) : emptyNotice === null ? null : ( - emptyNotice || ( -
- {emptyNoticeIcon()} -

This list is empty

-
- ) + ) : emptyNotice === null ? null : isValidElement(emptyNotice) ? ( + emptyNotice + ) : ( +
+ {emptyNotice && 'icon' in emptyNotice + ? isValidElement(emptyNotice.icon) + ? emptyNotice.icon + : emptyNoticeIcon(emptyNotice.icon as Icon) + : emptyNoticeIcon()} + +

+ {emptyNotice && 'message' in emptyNotice + ? emptyNotice.message + : 'This list is empty'} +

+
)} ); -}) as (props: Props) => JSX.Element; +}) as (props: ExplorerViewProps) => JSX.Element; diff --git a/interface/app/$libraryId/Explorer/index.tsx b/interface/app/$libraryId/Explorer/index.tsx index e317c892b..6ac3582dc 100644 --- a/interface/app/$libraryId/Explorer/index.tsx +++ b/interface/app/$libraryId/Explorer/index.tsx @@ -7,12 +7,13 @@ import ExplorerContextMenu from './ContextMenu'; import DismissibleNotice from './DismissibleNotice'; import ContextMenu from './File/ContextMenu'; import { Inspector } from './Inspector'; -import View from './View'; +import View, { ExplorerViewProps } from './View'; import { useExplorerSearchParams } from './util'; interface Props { items: ExplorerItem[] | null; onLoadMore?(): void; + emptyNotice?: ExplorerViewProps['emptyNotice']; } export default function Explorer(props: Props) { @@ -74,10 +75,10 @@ export default function Explorer(props: Props) { onSelectedChange={setSelectedItemId} contextMenu={} emptyNotice={ -
- -

This folder is empty

-
+ props.emptyNotice || { + icon: FolderNotchOpen, + message: 'This folder is empty' + } } /> diff --git a/interface/app/$libraryId/tag/$id.tsx b/interface/app/$libraryId/tag/$id.tsx index d55ec785a..ed5905e03 100644 --- a/interface/app/$libraryId/tag/$id.tsx +++ b/interface/app/$libraryId/tag/$id.tsx @@ -36,7 +36,12 @@ export const Component = () => { /> } /> - {explorerData.data && } + ); };