0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Made the tabs sticky in design and newsletter settings (#21477)

ref DES-927, DES-928
This commit is contained in:
Sodbileg Gansukh 2024-10-31 13:30:25 +08:00 committed by GitHub
parent 87e24f6403
commit e01b952ed2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 23 additions and 18 deletions

View file

@ -50,7 +50,7 @@ export const TabButton: React.FC<TabButtonProps> = ({
>
{icon && <Icon className='mb-0.5 mr-1.5 inline' name={icon} size='sm' />}
{title}
{(typeof counter === 'number') &&
{(typeof counter === 'number') &&
<span className='ml-1.5 rounded-full bg-grey-200 px-1.5 py-[2px] text-xs font-medium text-grey-800 dark:bg-grey-900 dark:text-grey-300'>
{new Intl.NumberFormat().format(counter)}
</span>
@ -66,7 +66,8 @@ export interface TabListProps<ID = string> {
border: boolean;
buttonBorder?: boolean;
selectedTab?: ID,
topRightContent?: React.ReactNode
topRightContent?: React.ReactNode,
stickyHeader?: boolean
}
export const TabList: React.FC<TabListProps> = ({
@ -75,7 +76,8 @@ export const TabList: React.FC<TabListProps> = ({
handleTabChange,
border,
buttonBorder,
topRightContent
topRightContent,
stickyHeader
}) => {
const containerClasses = clsx(
'no-scrollbar mb-px flex w-full overflow-x-auto',
@ -85,7 +87,7 @@ export const TabList: React.FC<TabListProps> = ({
border && 'border-b border-grey-300 dark:border-grey-900'
);
return (
<TabsPrimitive.List>
<TabsPrimitive.List className={`${stickyHeader ? 'sticky top-0 z-50 bg-white dark:bg-black' : ''}`}>
<div className={containerClasses} role='tablist'>
{tabs.map(tab => (
<div>
@ -117,6 +119,7 @@ export interface TabViewProps<ID = string> {
width?: TabWidth;
containerClassName?: string;
topRightContent?: React.ReactNode;
stickyHeader?: boolean;
testId?: string;
}
@ -129,7 +132,8 @@ function TabView<ID extends string = string>({
buttonBorder = border,
width = 'normal',
containerClassName,
topRightContent
topRightContent,
stickyHeader
}: TabViewProps<ID>) {
if (tabs.length !== 0 && selectedTab === undefined) {
selectedTab = tabs[0].id;
@ -151,6 +155,7 @@ function TabView<ID extends string = string>({
buttonBorder={buttonBorder}
handleTabChange={handleTabChange}
selectedTab={selectedTab}
stickyHeader={stickyHeader}
tabs={tabs}
topRightContent={topRightContent}
width={width}

View file

@ -514,8 +514,8 @@ const Sidebar: React.FC<{
return (
<div className='flex flex-col'>
<div className='px-7 pb-7 pt-5'>
<TabView selectedTab={selectedTab} tabs={tabs} onTabChange={handleTabChange} />
<div className='px-7 pb-7 pt-0'>
<TabView selectedTab={selectedTab} stickyHeader={true} tabs={tabs} onTabChange={handleTabChange} />
</div>
</div>
);

View file

@ -31,7 +31,7 @@ const Sidebar: React.FC<{
const tabs: Tab[] = [
{
id: 'global',
title: 'Global',
title: 'Brand',
contents: <GlobalSettings updateSetting={updateGlobalSetting} values={globalSettings} />
}
];
@ -39,7 +39,7 @@ const Sidebar: React.FC<{
if (themeSettingSections.length > 0) {
tabs.push({
id: 'theme-settings',
title: 'Theme settings',
title: 'Theme',
contents: <ThemeSettings sections={themeSettingSections} updateSetting={updateThemeSetting} />
});
}
@ -51,9 +51,9 @@ const Sidebar: React.FC<{
return (
<div className='flex h-full flex-col justify-between'>
<div className='grow p-7 pt-2' data-testid="design-setting-tabs">
<div className='grow p-7 pt-0' data-testid="design-setting-tabs">
{tabs.length > 1 ?
<TabView selectedTab={selectedTab} tabs={tabs} onTabChange={handleTabChange} />
<TabView selectedTab={selectedTab} stickyHeader={true} tabs={tabs} onTabChange={handleTabChange} />
:
<GlobalSettings updateSetting={updateGlobalSetting} values={globalSettings} />
}

View file

@ -89,7 +89,7 @@ test.describe('Design settings', async () => {
await section.getByRole('button', {name: 'Customize'}).click();
await modal.getByTestId('design-setting-tabs').getByRole('tab', {name: 'Theme settings'}).click();
await modal.getByTestId('design-setting-tabs').getByRole('tab', {name: 'Theme'}).click();
await modal.getByLabel('Email signup text').fill('test');
@ -182,14 +182,14 @@ test.describe('Design settings', async () => {
const modal = page.getByTestId('design-modal');
await modal.getByRole('tab', {name: 'Theme settings'}).click();
await modal.getByRole('tab', {name: 'Theme'}).click();
await chooseOptionInSelect(modal.getByTestId('setting-select-navigation_layout'), 'Logo in the middle');
const expectedSettings = {navigation_layout: 'Logo in the middle'};
const expectedEncoded = new URLSearchParams([['custom', JSON.stringify(expectedSettings)]]).toString();
const matchingHeader = previewRequests.find(header => new RegExp(`&${expectedEncoded.replace(/\+/g, '\\+')}`).test(header));
expect(matchingHeader).toBeDefined();
expect(matchingHeader).toBeDefined();
await modal.getByRole('button', {name: 'Save'}).click();
expect(lastApiRequests.editCustomThemeSettings?.body).toMatchObject({
@ -230,8 +230,8 @@ test.describe('Design settings', async () => {
const designSettingTabs = modal.getByTestId('design-setting-tabs');
await expect(designSettingTabs.getByRole('tab', {name: 'Global'})).toBeHidden();
await expect(designSettingTabs.getByRole('tab', {name: 'Theme settings'})).toBeHidden();
await expect(designSettingTabs.getByRole('tab', {name: 'Brand'})).toBeHidden();
await expect(designSettingTabs.getByRole('tab', {name: 'Theme'})).toBeHidden();
await expect(designSettingTabs.getByTestId('accent-color-picker')).toBeVisible();
});
@ -277,7 +277,7 @@ test.describe('Design settings', async () => {
const modal = page.getByTestId('design-modal');
await modal.getByRole('tab', {name: 'Theme settings'}).click();
await modal.getByRole('tab', {name: 'Theme'}).click();
const showFeaturedPostsCustomThemeSetting = modal.getByLabel('Show featured posts');