From 78aa31973c6b5adccdd79771e8dbb7ae611cf6dd Mon Sep 17 00:00:00 2001 From: Peter Zimon Date: Fri, 16 Jun 2023 15:44:02 +0200 Subject: [PATCH] Updated installed theme list refs. https://github.com/TryGhost/Team/issues/3432 --- .../src/admin-x-ds/assets/icons/ellipsis.svg | 5 ++ .../assets/icons/menu-horizontal.svg | 1 - .../src/admin-x-ds/global/Button.stories.tsx | 4 +- .../src/admin-x-ds/global/Button.tsx | 4 +- .../src/admin-x-ds/global/ButtonGroup.tsx | 4 +- .../src/admin-x-ds/global/List.stories.tsx | 12 ++- .../src/admin-x-ds/global/List.tsx | 52 ++++++++---- .../src/admin-x-ds/global/ListItem.tsx | 20 +++-- .../src/admin-x-ds/global/Menu.tsx | 38 +++++---- .../src/admin-x-ds/global/Separator.tsx | 6 +- .../src/admin-x-ds/global/form/Checkbox.tsx | 2 +- .../src/admin-x-ds/global/form/FileUpload.tsx | 5 +- .../admin-x-ds/global/form/ImageUpload.tsx | 2 +- .../src/admin-x-ds/global/form/Radio.tsx | 2 +- .../src/admin-x-ds/global/form/Toggle.tsx | 2 +- .../src/admin-x-ds/global/modal/Modal.tsx | 4 +- .../admin-x-ds/global/modal/PreviewModal.tsx | 4 +- .../src/admin-x-ds/settings/SettingGroup.tsx | 4 +- .../settings/general/UserDetailModal.tsx | 2 +- .../src/components/settings/general/Users.tsx | 4 + .../site/theme/AdvancedThemeSettings.tsx | 80 ++++++++++--------- 21 files changed, 151 insertions(+), 106 deletions(-) create mode 100644 ghost/admin-x-settings/src/admin-x-ds/assets/icons/ellipsis.svg delete mode 100644 ghost/admin-x-settings/src/admin-x-ds/assets/icons/menu-horizontal.svg diff --git a/ghost/admin-x-settings/src/admin-x-ds/assets/icons/ellipsis.svg b/ghost/admin-x-settings/src/admin-x-ds/assets/icons/ellipsis.svg new file mode 100644 index 0000000000..bdb73aadc4 --- /dev/null +++ b/ghost/admin-x-settings/src/admin-x-ds/assets/icons/ellipsis.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/ghost/admin-x-settings/src/admin-x-ds/assets/icons/menu-horizontal.svg b/ghost/admin-x-settings/src/admin-x-ds/assets/icons/menu-horizontal.svg deleted file mode 100644 index 41751a3c9e..0000000000 --- a/ghost/admin-x-settings/src/admin-x-ds/assets/icons/menu-horizontal.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/Button.stories.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/Button.stories.tsx index 251e734e18..8fd6b69e70 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/Button.stories.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/Button.stories.tsx @@ -61,7 +61,7 @@ export const LinkButton: Story = { export const Icon: Story = { args: { - icon: 'menu-horizontal', + icon: 'ellipsis', color: 'green', iconColorClass: 'text-white' } @@ -70,7 +70,7 @@ export const Icon: Story = { export const IconSmall: Story = { args: { size: 'sm', - icon: 'menu-horizontal', + icon: 'ellipsis', color: 'green', iconColorClass: 'text-white' } diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/Button.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/Button.tsx index 4d2e24e6f7..b9ffc37658 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/Button.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/Button.tsx @@ -4,7 +4,7 @@ import React from 'react'; export type ButtonColor = 'clear' | 'grey' | 'black' | 'green' | 'red' | 'white'; export type ButtonSize = 'sm' | 'md'; -export interface IButton { +export interface ButtonProps { size?: ButtonSize; label?: React.ReactNode; icon?: string; @@ -18,7 +18,7 @@ export interface IButton { onClick?: () => void; } -const Button: React.FC = ({ +const Button: React.FC = ({ size = 'md', label = '', icon = '', diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/ButtonGroup.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/ButtonGroup.tsx index a0f3bd9950..5b068ea8d6 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/ButtonGroup.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/ButtonGroup.tsx @@ -1,10 +1,10 @@ import Button from './Button'; import React from 'react'; -import {IButton} from './Button'; +import {ButtonProps} from './Button'; interface ButtonGroupProps { - buttons: Array; + buttons: Array; link?: boolean; className?: string; } diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/List.stories.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/List.stories.tsx index 9c52edf122..d753e0e7b4 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/List.stories.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/List.stories.tsx @@ -7,8 +7,7 @@ import ListItem from './ListItem'; const meta = { title: 'Global / List', component: List, - tags: ['autodocs'], - decorators: [(_story: any) => (
{_story()}
)] + tags: ['autodocs'] } satisfies Meta; export default meta; @@ -29,5 +28,14 @@ export const Default: Story = { title: 'This is a list', children: listItems, hint: 'And here is a hint for the whole list' + }, + decorators: [(_story: any) => (
{_story()}
)] +}; + +export const PageLevel: Story = { + args: { + pageTitle: 'A page with a list', + children: listItems, + hint: 'And here is a hint for the whole list' } }; diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/List.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/List.tsx index 0e4d1e63ee..2870bb42ab 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/List.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/List.tsx @@ -2,37 +2,55 @@ import Heading from './Heading'; import Hint from './Hint'; import React from 'react'; import Separator from './Separator'; +import clsx from 'clsx'; interface ListProps { + /** + * If the list is the primary content on a page (e.g. Members list) then you can set a pagetitle to be consistent + */ + pageTitle?: string; + + /** + * When you use the list in a block and it's not the primary content of the page then you can set a title to the list + */ title?: React.ReactNode; titleSeparator?: boolean; children?: React.ReactNode; hint?: React.ReactNode; hintSeparator?: boolean; + borderTop?: boolean; } -const List: React.FC = ({title, titleSeparator, children, hint, hintSeparator}) => { +const List: React.FC = ({title, titleSeparator, children, hint, hintSeparator, borderTop, pageTitle}) => { titleSeparator = (titleSeparator === undefined) ? true : titleSeparator; hintSeparator = (hintSeparator === undefined) ? true : hintSeparator; + const listClasses = clsx( + (borderTop || pageTitle) && 'border-t border-grey-300', + pageTitle && 'mt-14' + ); + return ( -
- {title && -
- {title} - {titleSeparator && } + <> + {pageTitle && {pageTitle}} +
+ {(!pageTitle && title) && +
+ {title} + {titleSeparator && } +
+ } +
+ {children}
- } -
- {children} -
- {hint && - <> - {hintSeparator && } - {hint} - - } -
+ {hint && + <> + {hintSeparator && } + {hint} + + } +
+ ); }; diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/ListItem.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/ListItem.tsx index 07bd3e3fc7..5cf74cea72 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/ListItem.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/ListItem.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import clsx from 'clsx'; interface ListItemProps { id: string; @@ -7,32 +8,41 @@ interface ListItemProps { action?: React.ReactNode; hideActions?: boolean; avatar?: React.ReactNode; + className?: string; /** * Hidden for the last item in the list */ separator?: boolean; + + bgOnHover?: boolean; onClick?: (e: React.MouseEvent) => void; } -const ListItem: React.FC = ({id, title, detail, action, hideActions, avatar, separator, onClick}) => { +const ListItem: React.FC = ({id, title, detail, action, hideActions, avatar, className, separator, bgOnHover = true, onClick}) => { const handleClick = (e: React.MouseEvent) => { onClick?.(e); }; separator = (separator === undefined) ? true : separator; + const listItemClasses = clsx( + 'group flex items-center justify-between', + bgOnHover && 'hover:bg-gradient-to-r hover:from-white hover:to-grey-50', + separator ? 'border-b border-grey-100 last-of-type:border-none hover:border-grey-200' : 'border-b border-transparent hover:border-grey-200', + className + ); return ( -
+
{avatar && avatar} -
+
{title} {detail && {detail}}
- {action && -
+ {action && +
{action}
} diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/Menu.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/Menu.tsx index db0f6754b2..0671156145 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/Menu.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/Menu.tsx @@ -1,4 +1,6 @@ +import Button, {ButtonProps, ButtonSize} from './Button'; import React, {useState} from 'react'; +import clsx from 'clsx'; export type MenuItem = { id: string, @@ -10,53 +12,49 @@ type MenuPosition = 'left' | 'right'; interface MenuProps { trigger?: React.ReactNode; + triggerButtonProps?: ButtonProps; + triggerSize?: ButtonSize; items: MenuItem[]; position?: MenuPosition; className?: string; } -const Menu: React.FC = ({trigger, items, position, className}) => { +const Menu: React.FC = ({trigger, triggerButtonProps, items, position, className}) => { const [menuOpen, setMenuOpen] = useState(false); - let menuListStyles = 'absolute z-40 mt-2 min-w-[160px] w-max origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black/5 focus:outline-none'; - const toggleMenu = () => { setMenuOpen(!menuOpen); }; - const handleBackdropClick = (e: React.MouseEvent) => { + const handleBackdropClick = (e: React.MouseEvent) => { if (e.target === e.currentTarget) { setMenuOpen(false); } }; - switch (position) { - case 'left': - menuListStyles += ' right-0 '; - break; - case 'right': - menuListStyles += ' left-0 '; - break; - - default: - menuListStyles += ' left-0 '; - break; + if (!trigger) { + trigger = + ))}
diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/Separator.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/Separator.tsx index f85d02404e..0353392c7e 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/Separator.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/Separator.tsx @@ -1,11 +1,11 @@ import React from 'react'; interface SeparatorProps { - color?: string; + className?: string; } -const Separator: React.FC = ({color}) => { - return
; +const Separator: React.FC = ({className = 'border-grey-300'}) => { + return
; }; export default Separator; \ No newline at end of file diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/form/Checkbox.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/form/Checkbox.tsx index bdc6beefdc..aca50ab476 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/form/Checkbox.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/form/Checkbox.tsx @@ -47,7 +47,7 @@ const Checkbox: React.FC = ({id, title, label, value, onChange, e
- {(separator || error) && } + {(separator || error) && } ); }; diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/form/FileUpload.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/form/FileUpload.tsx index 95987b98c7..ee1700ebad 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/form/FileUpload.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/form/FileUpload.tsx @@ -12,9 +12,10 @@ export interface FileUploadProps { className?: string; onUpload: (file: File) => void; style?: {} + unstyled?: boolean; } -const FileUpload: React.FC = ({id, onUpload, children, style, ...props}) => { +const FileUpload: React.FC = ({id, onUpload, children, style, unstyled = false, ...props}) => { const [fileKey, setFileKey] = useState(Date.now()); const handleFileChange = (event: ChangeEvent) => { @@ -29,7 +30,7 @@ const FileUpload: React.FC = ({id, onUpload, children, style, . } - {(separator || error) && } + {(separator || error) && } ); }; diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/modal/Modal.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/modal/Modal.tsx index 3a55e7e9af..de754c6d96 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/modal/Modal.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/modal/Modal.tsx @@ -1,4 +1,4 @@ -import Button, {IButton} from '../Button'; +import Button, {ButtonProps} from '../Button'; import ButtonGroup from '../ButtonGroup'; import ConfirmationModal from './ConfirmationModal'; import Heading from '../Heading'; @@ -66,7 +66,7 @@ const Modal: React.FC = ({ }) => { const modal = useModal(); - let buttons: IButton[] = []; + let buttons: ButtonProps[] = []; const removeModal = () => { if (!dirty) { diff --git a/ghost/admin-x-settings/src/admin-x-ds/global/modal/PreviewModal.tsx b/ghost/admin-x-settings/src/admin-x-ds/global/modal/PreviewModal.tsx index 84114cb511..c99c19645e 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/global/modal/PreviewModal.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/global/modal/PreviewModal.tsx @@ -7,7 +7,7 @@ import NiceModal, {useModal} from '@ebay/nice-modal-react'; import React, {useState} from 'react'; import Select, {SelectOption} from '../form/Select'; import TabView, {Tab} from '../TabView'; -import {IButton} from '../Button'; +import {ButtonProps} from '../Button'; export interface PreviewModalProps { testId?: string; @@ -61,7 +61,7 @@ export const PreviewModalContent: React.FC = ({ onSelectMobileView }) => { const modal = useModal(); - let buttons: IButton[] = []; + let buttons: ButtonProps[] = []; const [view, setView] = useState('desktop'); diff --git a/ghost/admin-x-settings/src/admin-x-ds/settings/SettingGroup.tsx b/ghost/admin-x-settings/src/admin-x-ds/settings/SettingGroup.tsx index 29bbb92c6f..693684a8e7 100644 --- a/ghost/admin-x-settings/src/admin-x-ds/settings/SettingGroup.tsx +++ b/ghost/admin-x-settings/src/admin-x-ds/settings/SettingGroup.tsx @@ -1,7 +1,7 @@ import ButtonGroup from '../global/ButtonGroup'; import React from 'react'; import SettingGroupHeader from './SettingGroupHeader'; -import {IButton} from '../global/Button'; +import {ButtonProps} from '../global/Button'; import {SaveState} from '../../hooks/useForm'; interface SettingGroupProps { @@ -96,7 +96,7 @@ const SettingGroup: React.FC = ({ ); } - let editButtons: IButton[] = [ + let editButtons: ButtonProps[] = [ { label: 'Cancel', key: 'cancel', diff --git a/ghost/admin-x-settings/src/components/settings/general/UserDetailModal.tsx b/ghost/admin-x-settings/src/components/settings/general/UserDetailModal.tsx index 0dfdb89126..b891ac1571 100644 --- a/ghost/admin-x-settings/src/components/settings/general/UserDetailModal.tsx +++ b/ghost/admin-x-settings/src/components/settings/general/UserDetailModal.tsx @@ -401,7 +401,7 @@ interface UserDetailModalProps { const UserMenuTrigger = () => (
- +
); diff --git a/ghost/admin-x-settings/src/components/settings/general/Users.tsx b/ghost/admin-x-settings/src/components/settings/general/Users.tsx index 86c717b214..da86837b05 100644 --- a/ghost/admin-x-settings/src/components/settings/general/Users.tsx +++ b/ghost/admin-x-settings/src/components/settings/general/Users.tsx @@ -76,9 +76,11 @@ const UsersList: React.FC = ({users, updateUser}) => { key={user.id} action={