mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Admin X design system updates (#19102)
refs. https://github.com/TryGhost/Product/issues/4169 - some of the new components were not prepared for mobile sizes and dark mode - Storybook settings had to be updated to include mobile sizes that reflect the actual system
This commit is contained in:
parent
9848469568
commit
82a775086c
11 changed files with 172 additions and 53 deletions
|
@ -7,6 +7,46 @@ import type { Preview } from "@storybook/react";
|
|||
import DesignSystemProvider from '../src/providers/DesignSystemProvider';
|
||||
import adminxTheme from './adminx-theme';
|
||||
|
||||
// import { MINIMAL_VIEWPORTS } from '@storybook/addon-viewport';
|
||||
|
||||
const customViewports = {
|
||||
sm: {
|
||||
name: 'sm',
|
||||
styles: {
|
||||
width: '480px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
md: {
|
||||
name: 'md',
|
||||
styles: {
|
||||
width: '640px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
lg: {
|
||||
name: 'lg',
|
||||
styles: {
|
||||
width: '1024px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
xl: {
|
||||
name: 'xl',
|
||||
styles: {
|
||||
width: '1320px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
tablet: {
|
||||
name: 'tablet',
|
||||
styles: {
|
||||
width: '860px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const preview: Preview = {
|
||||
parameters: {
|
||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||
|
@ -25,6 +65,11 @@ const preview: Preview = {
|
|||
docs: {
|
||||
theme: adminxTheme,
|
||||
},
|
||||
viewport: {
|
||||
viewports: {
|
||||
...customViewports,
|
||||
},
|
||||
},
|
||||
},
|
||||
decorators: [
|
||||
(Story, context) => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Icon from './Icon';
|
||||
import Icon, {IconSize} from './Icon';
|
||||
import React, {HTMLProps} from 'react';
|
||||
import clsx from 'clsx';
|
||||
import {LoadingIndicator, LoadingIndicatorColor, LoadingIndicatorSize} from './LoadingIndicator';
|
||||
|
@ -11,6 +11,7 @@ export interface ButtonProps extends Omit<HTMLProps<HTMLButtonElement>, 'label'
|
|||
label?: React.ReactNode;
|
||||
hideLabel?: boolean;
|
||||
icon?: string;
|
||||
iconSize?: IconSize;
|
||||
iconColorClass?: string;
|
||||
key?: string;
|
||||
color?: ButtonColor;
|
||||
|
@ -24,6 +25,7 @@ export interface ButtonProps extends Omit<HTMLProps<HTMLButtonElement>, 'label'
|
|||
loading?: boolean;
|
||||
loadingIndicatorSize?: LoadingIndicatorSize;
|
||||
loadingIndicatorColor?: LoadingIndicatorColor;
|
||||
outlineOnMobile?: boolean;
|
||||
onClick?: (e?:React.MouseEvent<HTMLElement>) => void;
|
||||
}
|
||||
|
||||
|
@ -32,6 +34,7 @@ const Button: React.FC<ButtonProps> = ({
|
|||
label = '',
|
||||
hideLabel = false,
|
||||
icon = '',
|
||||
iconSize,
|
||||
iconColorClass,
|
||||
color = 'clear',
|
||||
fullWidth,
|
||||
|
@ -43,6 +46,7 @@ const Button: React.FC<ButtonProps> = ({
|
|||
tag = 'button',
|
||||
loading = false,
|
||||
loadingIndicatorColor,
|
||||
outlineOnMobile = false,
|
||||
onClick,
|
||||
...props
|
||||
}) => {
|
||||
|
@ -108,7 +112,8 @@ const Button: React.FC<ButtonProps> = ({
|
|||
break;
|
||||
default:
|
||||
className = clsx(
|
||||
link ? ' text-black hover:text-grey-800 dark:text-white' : ` text-black dark:text-white dark:hover:bg-grey-900 ${!disabled && 'hover:bg-grey-200'}`,
|
||||
link ? ' text-black hover:text-grey-800 dark:text-white' : `text-black dark:text-white dark:hover:bg-grey-900 ${!disabled && 'hover:bg-grey-200'}`,
|
||||
(outlineOnMobile && !link) && 'border border-grey-300 hover:border-transparent md:border-transparent',
|
||||
className
|
||||
);
|
||||
loadingIndicatorColor = 'dark';
|
||||
|
@ -128,8 +133,10 @@ const Button: React.FC<ButtonProps> = ({
|
|||
labelClasses += (label && hideLabel) ? 'sr-only' : '';
|
||||
labelClasses += loading ? 'invisible' : '';
|
||||
|
||||
iconSize = iconSize || ((size === 'sm') || (label && icon) ? 'sm' : 'md');
|
||||
|
||||
const buttonChildren = <>
|
||||
{icon && <Icon className={iconClasses} colorClass={iconColorClass} name={icon} size={size === 'sm' || (label && icon) ? 'sm' : 'md'} />}
|
||||
{icon && <Icon className={iconClasses} colorClass={iconColorClass} name={icon} size={iconSize} />}
|
||||
<span className={labelClasses}>{label}</span>
|
||||
{loading && <div className='absolute flex'><LoadingIndicator color={loadingIndicatorColor} size={size}/><span className='sr-only'>Loading...</span></div>}
|
||||
</>;
|
||||
|
|
|
@ -10,10 +10,11 @@ export interface ButtonGroupProps {
|
|||
link?: boolean;
|
||||
linkWithPadding?: boolean;
|
||||
clearBg?: boolean;
|
||||
outlineOnMobile?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const ButtonGroup: React.FC<ButtonGroupProps> = ({size = 'md', buttons, link, linkWithPadding, clearBg = true, className}) => {
|
||||
const ButtonGroup: React.FC<ButtonGroupProps> = ({size = 'md', buttons, link, linkWithPadding, clearBg = true, outlineOnMobile, className}) => {
|
||||
let groupColorClasses = clsx(
|
||||
'flex items-center justify-start rounded',
|
||||
link ? 'gap-4' : 'gap-5',
|
||||
|
@ -24,6 +25,7 @@ const ButtonGroup: React.FC<ButtonGroupProps> = ({size = 'md', buttons, link, li
|
|||
groupColorClasses = clsx(
|
||||
'transition-all hover:bg-grey-200 dark:hover:bg-grey-900',
|
||||
size === 'sm' ? 'h-7 px-3' : 'h-[34px] px-4',
|
||||
outlineOnMobile && 'border border-grey-300 hover:border-transparent md:border-transparent',
|
||||
groupColorClasses
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import Button from '../Button';
|
|||
|
||||
const PageMenu: React.FC = () => {
|
||||
return (
|
||||
<Button icon='hamburger' iconColorClass='text-black' size='sm' link onClick={() => {
|
||||
<Button icon='hamburger' iconColorClass='text-black dark:text-white' size='sm' link onClick={() => {
|
||||
alert('Clicked on hamburger');
|
||||
}} />
|
||||
);
|
||||
|
|
|
@ -3,7 +3,7 @@ import Button from '../Button';
|
|||
|
||||
const GlobalActions: React.FC = () => {
|
||||
return (
|
||||
<Button icon='magnifying-glass' iconColorClass='text-black' size='sm' link onClick={() => {}} />
|
||||
<Button icon='magnifying-glass' iconColorClass='dark:text-white text-black' size='sm' link onClick={() => {}} />
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ const currentAdminExample = <ViewContainer
|
|||
>
|
||||
<DynamicTable
|
||||
columns={testColumns}
|
||||
pageHasSidebar={false}
|
||||
rows={testRows(100)}
|
||||
/>
|
||||
</ViewContainer>;
|
||||
|
@ -127,6 +128,7 @@ const simpleList = <ViewContainer
|
|||
<DynamicTable
|
||||
columns={testColumns}
|
||||
footer={<Hint>Just a regular table footer</Hint>}
|
||||
pageHasSidebar={false}
|
||||
rows={testRows(100)}
|
||||
/>
|
||||
</ViewContainer>;
|
||||
|
@ -149,6 +151,7 @@ const stickyList = <ViewContainer
|
|||
<DynamicTable
|
||||
columns={testColumns}
|
||||
footer={<Hint>Sticky footer</Hint>}
|
||||
pageHasSidebar={false}
|
||||
rows={testRows(40)}
|
||||
stickyFooter
|
||||
stickyHeader
|
||||
|
@ -180,6 +183,7 @@ const examplePrimaryAction = <ViewContainer
|
|||
<DynamicTable
|
||||
columns={testColumns}
|
||||
footer={<Hint>Sticky footer</Hint>}
|
||||
pageHasSidebar={false}
|
||||
rows={testRows(40)}
|
||||
stickyFooter
|
||||
stickyHeader
|
||||
|
@ -213,6 +217,7 @@ const exampleActionsContent = <ViewContainer
|
|||
<DynamicTable
|
||||
columns={testColumns}
|
||||
footer={<Hint>Sticky footer</Hint>}
|
||||
pageHasSidebar={false}
|
||||
rows={testRows(40)}
|
||||
stickyFooter
|
||||
stickyHeader
|
||||
|
@ -262,7 +267,7 @@ const exampleCardViewContent = (
|
|||
title='Ideas'
|
||||
type='page'
|
||||
>
|
||||
<div className='grid grid-cols-4 gap-7 py-7'>
|
||||
<div className='grid grid-cols-2 gap-7 py-7 tablet:grid-cols-4'>
|
||||
{mockIdeaCards()}
|
||||
</div>
|
||||
</ViewContainer>
|
||||
|
@ -352,7 +357,10 @@ export const ExampleDetailScreen: Story = {
|
|||
breadCrumbs: <Breadcrumbs
|
||||
items={[
|
||||
{
|
||||
label: 'Members'
|
||||
label: 'Members',
|
||||
onClick: () => {
|
||||
alert('Clicked back');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Emerson Vaccaro'
|
||||
|
@ -379,25 +387,25 @@ export const ExampleDetailScreen: Story = {
|
|||
}
|
||||
type='page'
|
||||
>
|
||||
<div className='grid grid-cols-4 border-b border-grey-200 pb-5'>
|
||||
<div className='-ml-5 flex h-full flex-col px-5'>
|
||||
<div className='grid grid-cols-3 border-b border-grey-200 pb-5 tablet:grid-cols-4'>
|
||||
<div className='col-span-3 -ml-5 mb-5 hidden h-full gap-4 px-5 tablet:col-span-1 tablet:mb-0 tablet:!flex tablet:flex-col tablet:gap-0'>
|
||||
<span>Last seen on <strong>22 June 2023</strong></span>
|
||||
<span className='mt-2'>Created on <strong>27 Jan 2021</strong></span>
|
||||
<span className='tablet:mt-2'>Created on <strong>27 Jan 2021</strong></span>
|
||||
</div>
|
||||
<div className='flex h-full flex-col px-5'>
|
||||
<div className='flex h-full flex-col tablet:px-5'>
|
||||
<Heading level={6}>Emails received</Heading>
|
||||
<span className='mt-1 text-4xl font-bold leading-none'>181</span>
|
||||
</div>
|
||||
<div className='flex h-full flex-col px-5'>
|
||||
<div className='flex h-full flex-col tablet:px-5'>
|
||||
<Heading level={6}>Emails opened</Heading>
|
||||
<span className='mt-1 text-4xl font-bold leading-none'>104</span>
|
||||
</div>
|
||||
<div className='-mr-5 flex h-full flex-col px-5'>
|
||||
<div className='-mr-5 flex h-full flex-col tablet:px-5'>
|
||||
<Heading level={6}>Average open rate</Heading>
|
||||
<span className='mt-1 text-4xl font-bold leading-none'>57%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className='grid grid-cols-4 items-baseline py-5'>
|
||||
<div className='grid grid-cols-2 items-baseline border-b border-grey-200 py-5 tablet:grid-cols-4'>
|
||||
<div className='-ml-5 flex h-full flex-col gap-6 border-r border-grey-200 px-5'>
|
||||
<div className='flex justify-between'>
|
||||
<Heading level={5}>Member data</Heading>
|
||||
|
@ -413,10 +421,17 @@ export const ExampleDetailScreen: Story = {
|
|||
</div>
|
||||
<div>
|
||||
<Heading level={6}>Labels</Heading>
|
||||
<div className='inline-block rounded-sm bg-grey-300 px-1 text-xs font-medium'>VIP</div>
|
||||
<div className='mt-2 flex gap-1'>
|
||||
<div className='inline-block rounded-sm bg-grey-200 px-1.5 text-xs font-medium'>VIP</div>
|
||||
<div className='inline-block rounded-sm bg-grey-200 px-1.5 text-xs font-medium'>Inner Circle</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Heading level={6}>Notes</Heading>
|
||||
<div className='text-grey-500'>No notes.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex h-full flex-col gap-6 border-r border-grey-200 px-5'>
|
||||
<div className='flex h-full flex-col gap-6 border-grey-200 px-5 tablet:border-r'>
|
||||
<Heading level={5}>Newsletters</Heading>
|
||||
<div className='flex flex-col gap-3'>
|
||||
<div className='flex items-center gap-2'>
|
||||
|
@ -427,24 +442,44 @@ export const ExampleDetailScreen: Story = {
|
|||
<Toggle />
|
||||
<span>Weekly roundup</span>
|
||||
</div>
|
||||
<div className='flex items-center gap-2'>
|
||||
<Toggle checked />
|
||||
<span>The Inner Circle</span>
|
||||
</div>
|
||||
<div className='mt-5 rounded border border-red p-4 text-sm text-red'>
|
||||
This member cannot receive emails due to permanent failure (bounce).
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex h-full flex-col gap-6 border-r border-grey-200 px-5'>
|
||||
<div className='-ml-5 flex h-full flex-col gap-6 border-r border-grey-200 px-5 pt-10 tablet:ml-0 tablet:pt-0'>
|
||||
<Heading level={5}>Subscriptions</Heading>
|
||||
<div className='flex flex-col'>
|
||||
<span className='font-semibold'>Gold — $12/month</span>
|
||||
<span className='text-sm text-grey-500'>Renews 21 Jan 2024</span>
|
||||
<div className='flex items-center gap-3'>
|
||||
<div className='flex h-16 w-16 flex-col items-center justify-center rounded-md bg-grey-200'>
|
||||
<Heading level={5}>$5</Heading>
|
||||
<span className='text-xs text-grey-700'>Yearly</span>
|
||||
</div>
|
||||
<div className='flex flex-col'>
|
||||
<span className='font-semibold'>Gold</span>
|
||||
<span className='text-sm text-grey-500'>Renews 21 Jan 2024</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='-mr-5 flex h-full flex-col gap-6 px-5'>
|
||||
<Heading level={5}>Activity</Heading>
|
||||
<div className='flex flex-col'>
|
||||
<span className='font-semibold'>Logged in</span>
|
||||
<span className='text-sm text-grey-500'>Renews 21 Jan 2024</span>
|
||||
<div className='-mr-5 flex h-full flex-col gap-6 px-5 pt-10 tablet:pt-0'>
|
||||
<div className='flex justify-between'>
|
||||
<Heading level={5}>Activity</Heading>
|
||||
<Button color='green' label='View all' link />
|
||||
</div>
|
||||
<div className='flex flex-col'>
|
||||
<div className='flex flex-col text-sm'>
|
||||
<span className='font-semibold'>Logged in</span>
|
||||
<span className='text-sm text-grey-500'>13 days ago</span>
|
||||
</div>
|
||||
<div className='flex flex-col text-sm'>
|
||||
<span className='font-semibold'>Subscribed to Daily News</span>
|
||||
<span className='text-sm text-grey-500'>Renews 21 Jan 2024</span>
|
||||
<span className='text-sm text-grey-500'>17 days ago</span>
|
||||
</div>
|
||||
<div className='flex flex-col text-sm'>
|
||||
<span className='font-semibold'>Logged in</span>
|
||||
<span className='text-sm text-grey-500'>21 days ago</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -125,7 +125,7 @@ const Page: React.FC<PageProps> = ({
|
|||
<div className='sticky flex items-center gap-7'>
|
||||
{(customGlobalActions?.map((action) => {
|
||||
return (
|
||||
<Button icon={action.iconName} iconColorClass='text-black' size='sm' link onClick={action.onClick} />
|
||||
<Button icon={action.iconName} iconColorClass='text-black dark:text-white' size='sm' link onClick={action.onClick} />
|
||||
);
|
||||
}))}
|
||||
{showGlobalActions && <GlobalActions />}
|
||||
|
@ -138,7 +138,7 @@ const Page: React.FC<PageProps> = ({
|
|||
);
|
||||
|
||||
pageToolbarClassName = clsx(
|
||||
'sticky top-0 z-50 flex h-18 w-full items-center justify-between gap-5 bg-white p-6',
|
||||
'sticky top-0 z-50 flex h-18 w-full items-center justify-between gap-5 bg-white p-6 dark:bg-black',
|
||||
!fullBleedToolbar && 'mx-auto max-w-7xl',
|
||||
pageToolbarClassName
|
||||
);
|
||||
|
|
|
@ -39,7 +39,7 @@ const PageHeader: React.FC<PageHeaderProps> = ({
|
|||
const leftClasses = clsx(
|
||||
'flex flex-auto items-center',
|
||||
(right && center) && 'basis-1/3',
|
||||
((right && !center) || (!right && center)) && 'basis-1/2'
|
||||
((!right && center)) && 'basis-1/2'
|
||||
);
|
||||
left = <div className={leftClasses}>{left}</div>;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ const PageHeader: React.FC<PageHeaderProps> = ({
|
|||
const rightClasses = clsx(
|
||||
'flex flex-auto items-center justify-end',
|
||||
(left && center) && 'basis-1/3',
|
||||
((left && !center) || (!left && center)) && 'basis-1/2'
|
||||
((!left && center)) && 'basis-1/2'
|
||||
);
|
||||
right = <div className={rightClasses}>{right}</div>;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ import ButtonGroup from '../ButtonGroup';
|
|||
const meta = {
|
||||
title: 'Global / Layout / View Container',
|
||||
component: ViewContainer,
|
||||
parameters: {
|
||||
layout: 'fullscreen'
|
||||
},
|
||||
render: function Component(args) {
|
||||
const [, updateArgs] = useArgs();
|
||||
|
||||
|
@ -33,13 +36,13 @@ export default meta;
|
|||
type Story = StoryObj<typeof ViewContainer>;
|
||||
|
||||
export const exampleActions = [
|
||||
<Button label='Filter' onClick={() => {
|
||||
<Button label='Filter' outlineOnMobile onClick={() => {
|
||||
alert('Clicked filter');
|
||||
}} />,
|
||||
<Button label='Sort' onClick={() => {
|
||||
<Button label='Sort' outlineOnMobile onClick={() => {
|
||||
alert('Clicked sort');
|
||||
}} />,
|
||||
<Button icon='magnifying-glass' size='sm' onClick={() => {
|
||||
<Button icon='magnifying-glass' iconSize='sm' outlineOnMobile onClick={() => {
|
||||
alert('Clicked search');
|
||||
}} />,
|
||||
<ButtonGroup buttons={[
|
||||
|
@ -59,7 +62,7 @@ export const exampleActions = [
|
|||
alert('Clicked card view');
|
||||
}
|
||||
}
|
||||
]} clearBg={false} link />
|
||||
]} clearBg={false} link outlineOnMobile />
|
||||
];
|
||||
|
||||
const primaryAction: PrimaryActionProps = {
|
||||
|
@ -152,13 +155,37 @@ export const TabsWithPrimaryAction: Story = {
|
|||
}
|
||||
};
|
||||
|
||||
const sectionActions = [
|
||||
<Button label='Filter' size='sm' onClick={() => {
|
||||
alert('Clicked filter');
|
||||
}} />,
|
||||
<ButtonGroup buttons={[
|
||||
{
|
||||
icon: 'listview',
|
||||
size: 'sm',
|
||||
iconColorClass: 'text-black',
|
||||
onClick: () => {
|
||||
alert('Clicked list view');
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: 'cardview',
|
||||
size: 'sm',
|
||||
iconColorClass: 'text-grey-500',
|
||||
onClick: () => {
|
||||
alert('Clicked card view');
|
||||
}
|
||||
}
|
||||
]} clearBg={false} size='sm' link />
|
||||
];
|
||||
|
||||
export const TabsWithActions: Story = {
|
||||
args: {
|
||||
type: 'section',
|
||||
title: 'Section title',
|
||||
tabs: tabs,
|
||||
primaryAction: primaryAction,
|
||||
actions: exampleActions
|
||||
actions: sectionActions
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -167,7 +194,7 @@ export const HiddenActions: Story = {
|
|||
type: 'section',
|
||||
title: 'Hover to show actions',
|
||||
tabs: tabs,
|
||||
actions: exampleActions,
|
||||
actions: sectionActions,
|
||||
actionsHidden: true
|
||||
}
|
||||
};
|
|
@ -172,15 +172,16 @@ const ViewContainer: React.FC<ViewContainerProps> = ({
|
|||
|
||||
toolbarWrapperClassName = clsx(
|
||||
'z-50',
|
||||
type === 'page' && 'mx-auto w-full max-w-7xl bg-white px-12',
|
||||
type === 'page' && 'mx-auto w-full max-w-7xl bg-white px-[4vw] dark:bg-black tablet:px-12',
|
||||
(type === 'page' && stickyHeader) && (firstOnPage ? 'sticky top-0 pt-8' : 'sticky top-18 pt-[3vmin]'),
|
||||
toolbarContainerClassName
|
||||
);
|
||||
|
||||
toolbarContainerClassName = clsx(
|
||||
'flex items-end justify-between',
|
||||
(firstOnPage && type === 'page') ? 'pb-8' : (tabs?.length ? '' : 'pb-2'),
|
||||
toolbarBorder && 'border-b border-grey-200',
|
||||
'flex justify-between gap-5',
|
||||
(type === 'page' && actions?.length) ? 'flex-col md:flex-row md:items-end' : 'items-end',
|
||||
(firstOnPage && type === 'page') ? 'pb-3 tablet:pb-8' : (tabs?.length ? '' : 'pb-2'),
|
||||
toolbarBorder && 'border-b border-grey-200 dark:border-grey-900',
|
||||
toolbarContainerClassName
|
||||
);
|
||||
|
||||
|
@ -190,9 +191,9 @@ const ViewContainer: React.FC<ViewContainerProps> = ({
|
|||
);
|
||||
|
||||
actionsClassName = clsx(
|
||||
'flex items-center gap-5 transition-all',
|
||||
'flex items-center justify-between gap-3 transition-all tablet:justify-start tablet:gap-5',
|
||||
actionsHidden && 'opacity-0 group-hover/view-container:opacity-100',
|
||||
tabs?.length ? 'pb-2' : (type === 'page' ? 'pb-1' : ''),
|
||||
tabs?.length ? 'pb-1' : (type === 'page' ? 'pb-1' : ''),
|
||||
actionsClassName
|
||||
);
|
||||
|
||||
|
@ -243,7 +244,7 @@ const ViewContainer: React.FC<ViewContainerProps> = ({
|
|||
|
||||
contentWrapperClassName = clsx(
|
||||
'relative mx-auto w-full flex-auto',
|
||||
(!contentFullBleed && type === 'page') && 'max-w-7xl px-12',
|
||||
(!contentFullBleed && type === 'page') && 'max-w-7xl px-[4vw] tablet:px-12',
|
||||
contentWrapperClassName,
|
||||
(!title && !actions) && 'pt-[3vmin]'
|
||||
);
|
||||
|
|
|
@ -32,6 +32,7 @@ export interface DynamicTableProps {
|
|||
* Set this parameter if the table is the main content in a viewcontainer or on a page
|
||||
*/
|
||||
singlePageTable?: boolean;
|
||||
pageHasSidebar?: boolean;
|
||||
|
||||
border?: boolean;
|
||||
footerBorder?:boolean;
|
||||
|
@ -60,6 +61,7 @@ const DynamicTable: React.FC<DynamicTableProps> = ({
|
|||
footerBorder = true,
|
||||
stickyFooter = false,
|
||||
singlePageTable = false,
|
||||
pageHasSidebar = true,
|
||||
containerClassName,
|
||||
tableContainerClassName,
|
||||
tableClassName,
|
||||
|
@ -81,7 +83,7 @@ const DynamicTable: React.FC<DynamicTableProps> = ({
|
|||
tableContainerClassName = clsx(
|
||||
'flex-auto overflow-x-auto',
|
||||
!horizontalScrolling && 'w-full max-w-full',
|
||||
(singlePageTable && (stickyHeader || stickyFooter || absolute)) && 'px-12 xl:px-[calc((100%-1320px)/2+48px)]',
|
||||
(singlePageTable && (stickyHeader || stickyFooter || absolute)) && `px-[4vw] tablet:px-12 ${pageHasSidebar ? 'min-[1640px]:px-[calc((100%-1320px)/2+48px)]' : 'xl:px-[calc((100%-1320px)/2+48px)]'}`,
|
||||
tableContainerClassName
|
||||
);
|
||||
|
||||
|
@ -91,13 +93,13 @@ const DynamicTable: React.FC<DynamicTableProps> = ({
|
|||
);
|
||||
|
||||
thClassName = clsx(
|
||||
'last-child:pr-5 bg-white py-3 text-left [&:not(:first-child)]:pl-5',
|
||||
'last-child:pr-5 bg-white py-3 text-left dark:bg-black [&:not(:first-child)]:pl-5',
|
||||
thClassName
|
||||
);
|
||||
|
||||
tdClassName = clsx(
|
||||
'w-full border-b group-hover:border-grey-200',
|
||||
border ? 'border-grey-200' : 'border-transparent',
|
||||
'w-full border-b group-hover:border-grey-200 dark:group-hover:border-grey-900',
|
||||
border ? 'border-grey-200 dark:border-grey-900' : 'border-transparent',
|
||||
tdClassName
|
||||
);
|
||||
|
||||
|
@ -113,11 +115,11 @@ const DynamicTable: React.FC<DynamicTableProps> = ({
|
|||
);
|
||||
|
||||
footerClassName = clsx(
|
||||
'bg-white',
|
||||
(singlePageTable && stickyFooter) && 'mx-12 xl:mx-[calc((100%-1320px)/2+48px)]',
|
||||
'bg-white dark:bg-black',
|
||||
(singlePageTable && stickyFooter) && `mx-[4vw] tablet:mx-12 ${pageHasSidebar ? 'min-[1640px]:mx-[calc((100%-1320px)/2+48px)]' : 'xl:mx-[calc((100%-1320px)/2+48px)]'}`,
|
||||
footer && 'py-4',
|
||||
stickyFooter && 'sticky inset-x-0 bottom-0',
|
||||
footerBorder && 'border-t border-grey-200',
|
||||
footerBorder && 'border-t border-grey-200 dark:border-grey-900',
|
||||
footerClassName
|
||||
);
|
||||
|
||||
|
@ -150,7 +152,7 @@ const DynamicTable: React.FC<DynamicTableProps> = ({
|
|||
</tr>
|
||||
{headerBorder && (
|
||||
<tr>
|
||||
<th className='h-px bg-grey-200 p-0' colSpan={columns.length}></th>
|
||||
<th className='h-px bg-grey-200 p-0 dark:bg-grey-900' colSpan={columns.length}></th>
|
||||
</tr>
|
||||
)}
|
||||
</thead>
|
||||
|
|
Loading…
Add table
Reference in a new issue