chore: run prettier

This commit is contained in:
Matthew Penner 2023-01-12 12:31:47 -07:00
parent 9cdbbc3a00
commit 155d7bb876
No known key found for this signature in database
76 changed files with 788 additions and 550 deletions

View file

@ -9,7 +9,7 @@ interface CodeProps {
export default ({ dark, className, children }: CodeProps) => (
<code
className={classNames('font-mono text-sm px-2 py-1 inline-block rounded', className, {
className={classNames('inline-block rounded px-2 py-1 font-mono text-sm', className, {
'bg-neutral-700': !dark,
'bg-neutral-900 text-slate-100': dark,
})}

View file

@ -50,8 +50,8 @@ const CopyOnClick = ({ text, showInNotification = true, children }: CopyOnClickP
{copied && (
<Portal>
<FadeTransition show duration="duration-250" key={copied ? 'visible' : 'invisible'}>
<div className="fixed z-50 bottom-0 right-0 m-4">
<div className="rounded-md py-3 px-4 text-slate-200 bg-neutral-600/95 shadow">
<div className="fixed bottom-0 right-0 z-50 m-4">
<div className="rounded-md bg-neutral-600/95 py-3 px-4 text-slate-200 shadow">
<p>
{showInNotification
? `Copied "${String(text)}" to clipboard.`

View file

@ -26,7 +26,15 @@ interface IdObj {
id: number;
}
export const Option = <T extends IdObj>({ selectId, id, item, active, isHighlighted, onClick, children }: OptionProps<T>) => {
export const Option = <T extends IdObj>({
selectId,
id,
item,
active,
isHighlighted,
onClick,
children,
}: OptionProps<T>) => {
if (isHighlighted === undefined) {
isHighlighted = false;
}
@ -39,16 +47,32 @@ export const Option = <T extends IdObj>({ selectId, id, item, active, isHighligh
if (active) {
return (
<li id={selectId + '-select-item-' + id} role="option" css={[ tw`relative py-2 pl-3 cursor-pointer select-none text-neutral-200 pr-9 hover:bg-neutral-700`, isHighlighted ? tw`bg-neutral-700` : null ]} onClick={onClick(item)}>
<li
id={selectId + '-select-item-' + id}
role="option"
css={[
tw`relative py-2 pl-3 cursor-pointer select-none text-neutral-200 pr-9 hover:bg-neutral-700`,
isHighlighted ? tw`bg-neutral-700` : null,
]}
onClick={onClick(item)}
>
<div css={tw`flex items-center`}>
<span css={tw`block font-medium truncate`}>
{children}
</span>
<span css={tw`block font-medium truncate`}>{children}</span>
</div>
<span css={tw`absolute inset-y-0 right-0 flex items-center pr-4`}>
<svg css={tw`w-5 h-5 text-primary-400`} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path clipRule="evenodd" fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"/>
<svg
css={tw`w-5 h-5 text-primary-400`}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path
clipRule="evenodd"
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
/>
</svg>
</span>
</li>
@ -56,11 +80,17 @@ export const Option = <T extends IdObj>({ selectId, id, item, active, isHighligh
}
return (
<li id={selectId + 'select-item-' + id} role="option" css={[ tw`relative py-2 pl-3 cursor-pointer select-none text-neutral-200 pr-9 hover:bg-neutral-700`, isHighlighted ? tw`bg-neutral-700` : null ]} onClick={onClick(item)}>
<li
id={selectId + 'select-item-' + id}
role="option"
css={[
tw`relative py-2 pl-3 cursor-pointer select-none text-neutral-200 pr-9 hover:bg-neutral-700`,
isHighlighted ? tw`bg-neutral-700` : null,
]}
onClick={onClick(item)}
>
<div css={tw`flex items-center`}>
<span css={tw`block font-normal truncate`}>
{children}
</span>
<span css={tw`block font-normal truncate`}>{children}</span>
</div>
</li>
);
@ -88,13 +118,27 @@ interface SearchableSelectProps<T> {
className?: string;
}
export const SearchableSelect = <T extends IdObj>({ id, name, label, placeholder, selected, setSelected, items, setItems, onSearch, onSelect, getSelectedText, children, className }: SearchableSelectProps<T>) => {
const [ loading, setLoading ] = useState(false);
const [ expanded, setExpanded ] = useState(false);
export const SearchableSelect = <T extends IdObj>({
id,
name,
label,
placeholder,
selected,
setSelected,
items,
setItems,
onSearch,
onSelect,
getSelectedText,
children,
className,
}: SearchableSelectProps<T>) => {
const [loading, setLoading] = useState(false);
const [expanded, setExpanded] = useState(false);
const [ inputText, setInputText ] = useState('');
const [inputText, setInputText] = useState('');
const [ highlighted, setHighlighted ] = useState<number | null>(null);
const [highlighted, setHighlighted] = useState<number | null>(null);
const searchInput = createRef<HTMLInputElement>();
const itemsList = createRef<HTMLDivElement>();
@ -220,7 +264,7 @@ export const SearchableSelect = <T extends IdObj>({ id, name, label, placeholder
window.removeEventListener('mousedown', clickHandler);
window.removeEventListener('contextmenu', contextmenuHandler);
};
}, [ expanded ]);
}, [expanded]);
const onClick = (item: T) => () => {
onSelect(item);
@ -235,13 +279,15 @@ export const SearchableSelect = <T extends IdObj>({ id, name, label, placeholder
}
setInputText(getSelectedText(selected) || '');
}, [ selected ]);
}, [selected]);
// This shit is really stupid but works, so is it really stupid?
const c = React.Children.map(children, child => React.cloneElement(child as ReactElement, {
isHighlighted: ((child as ReactElement).props as OptionProps<T>).id === highlighted,
onClick: onClick.bind(child),
}));
const c = React.Children.map(children, child =>
React.cloneElement(child as ReactElement, {
isHighlighted: ((child as ReactElement).props as OptionProps<T>).id === highlighted,
onClick: onClick.bind(child),
}),
);
return (
<div className={className}>
@ -269,33 +315,57 @@ export const SearchableSelect = <T extends IdObj>({ id, name, label, placeholder
/>
</InputSpinner>
<div css={[ tw`absolute inset-y-0 right-0 flex items-center pr-2 ml-3`, !expanded && tw`pointer-events-none` ]}>
{inputText !== '' && expanded &&
<svg css={tw`w-5 h-5 text-neutral-400 cursor-pointer`} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
onMouseDown={e => {
e.preventDefault();
setInputText('');
}}
<div
css={[
tw`absolute inset-y-0 right-0 flex items-center pr-2 ml-3`,
!expanded && tw`pointer-events-none`,
]}
>
{inputText !== '' && expanded && (
<svg
css={tw`w-5 h-5 text-neutral-400 cursor-pointer`}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
onMouseDown={e => {
e.preventDefault();
setInputText('');
}}
>
<path
clipRule="evenodd"
fillRule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
/>
</svg>
)}
<svg
css={tw`w-5 h-5 text-neutral-400 pointer-events-none`}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
aria-hidden="true"
>
<path clipRule="evenodd" fillRule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"/>
</svg>
}
<svg css={tw`w-5 h-5 text-neutral-400 pointer-events-none`} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path clipRule="evenodd" fillRule="evenodd" d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z"/>
<path
clipRule="evenodd"
fillRule="evenodd"
d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z"
/>
</svg>
</div>
<Dropdown ref={itemsList} expanded={expanded}>
{items === null || items.length < 1 ?
items === null || inputText.length < 2 ?
{items === null || items.length < 1 ? (
items === null || inputText.length < 2 ? (
<div css={tw`flex flex-row items-center h-10 px-3`}>
<p css={tw`text-sm`}>Please type 2 or more characters.</p>
</div>
:
) : (
<div css={tw`flex flex-row items-center h-10 px-3`}>
<p css={tw`text-sm`}>No results found.</p>
</div>
:
)
) : (
<ul
tabIndex={-1}
role={id + '-select'}
@ -305,7 +375,7 @@ export const SearchableSelect = <T extends IdObj>({ id, name, label, placeholder
>
{c}
</ul>
}
)}
</Dropdown>
</div>
</div>

View file

@ -1,7 +1,22 @@
import { CSSObject } from '@emotion/serialize';
import { Field as FormikField, FieldProps } from 'formik';
import React, { forwardRef } from 'react';
import Select, { ContainerProps, ControlProps, GroupProps, IndicatorContainerProps, IndicatorProps, InputProps, MenuListComponentProps, MenuProps, MultiValueProps, OptionProps, PlaceholderProps, SingleValueProps, StylesConfig, ValueContainerProps } from 'react-select';
import Select, {
ContainerProps,
ControlProps,
GroupProps,
IndicatorContainerProps,
IndicatorProps,
InputProps,
MenuListComponentProps,
MenuProps,
MultiValueProps,
OptionProps,
PlaceholderProps,
SingleValueProps,
StylesConfig,
ValueContainerProps,
} from 'react-select';
import Async from 'react-select/async';
import Creatable from 'react-select/creatable';
import tw, { theme } from 'twin.macro';
@ -42,10 +57,9 @@ export const SelectStyle: StylesConfig<T, any, any> = {
borderWidth: '2px',
color: theme`colors.neutral.200`,
cursor: 'pointer',
boxShadow: props.isFocused ?
'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(36, 135, 235, 0.5) 0px 0px 0px 2px, rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px'
:
undefined,
boxShadow: props.isFocused
? 'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(36, 135, 235, 0.5) 0px 0px 0px 2px, rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px'
: undefined,
':hover': {
borderColor: !props.isFocused ? theme`colors.neutral.400` : theme`colors.primary.300`,
@ -228,67 +242,74 @@ interface SelectFieldProps {
isSearchable?: boolean;
isCreatable?: boolean;
isValidNewOption?: ((
inputValue: string,
value: ValueType<any, boolean>,
options: ReadonlyArray<any>,
) => boolean) | undefined;
isValidNewOption?:
| ((inputValue: string, value: ValueType<any, boolean>, options: ReadonlyArray<any>) => boolean)
| undefined;
className?: string;
}
const SelectField = forwardRef<HTMLElement, SelectFieldProps>(
function Select2 ({ id, name, label, description, validate, className, isMulti, isCreatable, ...props }, ref) {
const { options } = props;
const SelectField = forwardRef<HTMLElement, SelectFieldProps>(function Select2(
{ id, name, label, description, validate, className, isMulti, isCreatable, ...props },
ref,
) {
const { options } = props;
const onChange = (options: Option | Option[], name: string, setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void) => {
if (isMulti) {
setFieldValue(name, (options as Option[]).map(o => o.value));
return;
}
const onChange = (
options: Option | Option[],
name: string,
setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void,
) => {
if (isMulti) {
setFieldValue(
name,
(options as Option[]).map(o => o.value),
);
return;
}
setFieldValue(name, (options as Option).value);
};
setFieldValue(name, (options as Option).value);
};
return (
<FormikField innerRef={ref} name={name} validate={validate}>
{({ field, form: { errors, touched, setFieldValue } }: FieldProps) => (
<div className={className}>
{label && <Label htmlFor={id}>{label}</Label>}
{isCreatable ?
<Creatable
{...field}
{...props}
styles={SelectStyle}
options={options}
value={(options ? options.find(o => o.value === field.value) : '') as any}
onChange={o => onChange(o, name, setFieldValue)}
isMulti={isMulti}
/>
:
<Select
{...field}
{...props}
styles={SelectStyle}
options={options}
value={(options ? options.find(o => o.value === field.value) : '') as any}
onChange={o => onChange(o, name, setFieldValue)}
isMulti={isMulti}
/>
}
{touched[field.name] && errors[field.name] ?
<p css={tw`text-red-200 text-xs mt-1`}>
{(errors[field.name] as string).charAt(0).toUpperCase() + (errors[field.name] as string).slice(1)}
</p>
:
description ? <p css={tw`text-neutral-400 text-xs mt-1`}>{description}</p> : null
}
</div>
)}
</FormikField>
);
}
);
return (
<FormikField innerRef={ref} name={name} validate={validate}>
{({ field, form: { errors, touched, setFieldValue } }: FieldProps) => (
<div className={className}>
{label && <Label htmlFor={id}>{label}</Label>}
{isCreatable ? (
<Creatable
{...field}
{...props}
styles={SelectStyle}
options={options}
value={(options ? options.find(o => o.value === field.value) : '') as any}
onChange={o => onChange(o, name, setFieldValue)}
isMulti={isMulti}
/>
) : (
<Select
{...field}
{...props}
styles={SelectStyle}
options={options}
value={(options ? options.find(o => o.value === field.value) : '') as any}
onChange={o => onChange(o, name, setFieldValue)}
isMulti={isMulti}
/>
)}
{touched[field.name] && errors[field.name] ? (
<p css={tw`text-red-200 text-xs mt-1`}>
{(errors[field.name] as string).charAt(0).toUpperCase() +
(errors[field.name] as string).slice(1)}
</p>
) : description ? (
<p css={tw`text-neutral-400 text-xs mt-1`}>{description}</p>
) : null}
</div>
)}
</FormikField>
);
});
interface AsyncSelectFieldProps {
id?: string;
@ -305,43 +326,52 @@ interface AsyncSelectFieldProps {
loadOptions(inputValue: string, callback: (options: Array<Option>) => void): void;
}
const AsyncSelectField = forwardRef<HTMLElement, AsyncSelectFieldProps>(
function AsyncSelect2 ({ id, name, label, description, validate, className, isMulti, ...props }, ref) {
const onChange = (options: Option | Option[], name: string, setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void) => {
if (isMulti) {
setFieldValue(name, (options as Option[]).map(o => Number(o.value)));
return;
}
const AsyncSelectField = forwardRef<HTMLElement, AsyncSelectFieldProps>(function AsyncSelect2(
{ id, name, label, description, validate, className, isMulti, ...props },
ref,
) {
const onChange = (
options: Option | Option[],
name: string,
setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void,
) => {
if (isMulti) {
setFieldValue(
name,
(options as Option[]).map(o => Number(o.value)),
);
return;
}
setFieldValue(name, Number((options as Option).value));
};
setFieldValue(name, Number((options as Option).value));
};
return (
<FormikField innerRef={ref} name={name} validate={validate}>
{({ field, form: { errors, touched, setFieldValue } }: FieldProps) => (
<div className={className}>
{label && <Label htmlFor={id}>{label}</Label>}
<Async
{...props}
id={id}
name={name}
styles={SelectStyle}
onChange={o => onChange(o, name, setFieldValue)}
isMulti={isMulti}
/>
{touched[field.name] && errors[field.name] ?
<p css={tw`text-red-200 text-xs mt-1`}>
{(errors[field.name] as string).charAt(0).toUpperCase() + (errors[field.name] as string).slice(1)}
</p>
:
description ? <p css={tw`text-neutral-400 text-xs mt-1`}>{description}</p> : null
}
</div>
)}
</FormikField>
);
}
);
return (
<FormikField innerRef={ref} name={name} validate={validate}>
{({ field, form: { errors, touched, setFieldValue } }: FieldProps) => (
<div className={className}>
{label && <Label htmlFor={id}>{label}</Label>}
<Async
{...props}
id={id}
name={name}
styles={SelectStyle}
onChange={o => onChange(o, name, setFieldValue)}
isMulti={isMulti}
/>
{touched[field.name] && errors[field.name] ? (
<p css={tw`text-red-200 text-xs mt-1`}>
{(errors[field.name] as string).charAt(0).toUpperCase() +
(errors[field.name] as string).slice(1)}
</p>
) : description ? (
<p css={tw`text-neutral-400 text-xs mt-1`}>{description}</p>
) : null}
</div>
)}
</FormikField>
);
});
export default SelectField;
export { AsyncSelectField };

View file

@ -44,13 +44,13 @@ export default ({ activity, children }: Props) => {
const properties = wrapProperties(activity.properties);
return (
<div className={'grid grid-cols-10 py-4 border-b-2 border-slate-800 last:rounded-b last:border-0 group'}>
<div className={'hidden sm:flex sm:col-span-1 items-center justify-center select-none'}>
<div className={'flex items-center w-10 h-10 rounded-full bg-slate-600 overflow-hidden'}>
<div className={'group grid grid-cols-10 border-b-2 border-slate-800 py-4 last:rounded-b last:border-0'}>
<div className={'hidden select-none items-center justify-center sm:col-span-1 sm:flex'}>
<div className={'flex h-10 w-10 items-center overflow-hidden rounded-full bg-slate-600'}>
<Avatar name={actor?.uuid || 'system'} />
</div>
</div>
<div className={'col-span-10 sm:col-span-9 flex'}>
<div className={'col-span-10 flex sm:col-span-9'}>
<div className={'flex-1 px-4 sm:px-0'}>
<div className={'flex items-center text-slate-50'}>
<Tooltip placement={'top'} content={actor?.email || 'System User'}>
@ -59,7 +59,7 @@ export default ({ activity, children }: Props) => {
<span className={'text-slate-400'}>&nbsp;&mdash;&nbsp;</span>
<Link
to={`#${pathTo({ event: activity.event })}`}
className={'transition-colors duration-75 active:text-cyan-400 hover:text-cyan-400'}
className={'transition-colors duration-75 hover:text-cyan-400 active:text-cyan-400'}
>
{activity.event}
</Link>

View file

@ -11,7 +11,7 @@ export default ({ meta }: { meta: Record<string, unknown> }) => {
<Dialog open={open} onClose={() => setOpen(false)} hideCloseIcon title={'Metadata'}>
<pre
className={
'bg-slate-900 rounded p-2 font-mono text-sm leading-relaxed overflow-x-scroll whitespace-pre-wrap'
'overflow-x-scroll whitespace-pre-wrap rounded bg-slate-900 p-2 font-mono text-sm leading-relaxed'
}
>
{JSON.stringify(meta, null, 2)}
@ -23,11 +23,11 @@ export default ({ meta }: { meta: Record<string, unknown> }) => {
<button
aria-describedby={'View additional event metadata'}
className={
'p-2 transition-colors duration-100 text-slate-400 group-hover:text-slate-300 group-hover:hover:text-slate-50'
'p-2 text-slate-400 transition-colors duration-100 group-hover:text-slate-300 group-hover:hover:text-slate-50'
}
onClick={() => setOpen(true)}
>
<ClipboardListIcon className={'w-5 h-5'} />
<ClipboardListIcon className={'h-5 w-5'} />
</button>
</div>
);

View file

@ -12,7 +12,7 @@ export default ({ type, className, children }: AlertProps) => {
return (
<div
className={classNames(
'flex items-center border-l-8 text-slate-50 rounded-md shadow px-4 py-3',
'flex items-center rounded-md border-l-8 px-4 py-3 text-slate-50 shadow',
{
['border-red-500 bg-red-500/25']: type === 'danger',
['border-yellow-500 bg-yellow-500/25']: type === 'warning',
@ -21,9 +21,9 @@ export default ({ type, className, children }: AlertProps) => {
)}
>
{type === 'danger' ? (
<ShieldExclamationIcon className={'w-6 h-6 text-red-400 mr-2'} />
<ShieldExclamationIcon className={'mr-2 h-6 w-6 text-red-400'} />
) : (
<ExclamationIcon className={'w-6 h-6 text-yellow-500 mr-2'} />
<ExclamationIcon className={'mr-2 h-6 w-6 text-yellow-500'} />
)}
{children}
</div>

View file

@ -73,8 +73,8 @@ export default ({
open={open}
onClose={onDialogClose}
>
<div className={'fixed inset-0 bg-slate-900/50 z-40'} />
<div className={'fixed inset-0 overflow-y-auto z-50'}>
<div className={'fixed inset-0 z-40 bg-slate-900/50'} />
<div className={'fixed inset-0 z-50 overflow-y-auto'}>
<div
ref={container}
className={styles.container}
@ -89,9 +89,9 @@ export default ({
variants={variants}
className={styles.panel}
>
<div className={'flex p-6 pb-0 overflow-y-auto'}>
<div className={'flex overflow-y-auto p-6 pb-0'}>
{iconPosition === 'container' && icon}
<div className={'flex-1 max-h-[70vh] min-w-0'}>
<div className={'max-h-[70vh] min-w-0 flex-1'}>
<div className={'flex items-center'}>
{iconPosition !== 'container' && icon}
<div>

View file

@ -8,7 +8,7 @@ export default ({ children }: { children: React.ReactNode }) => {
useDeepCompareEffect(() => {
setFooter(
<div className={'px-6 py-3 bg-slate-700 flex items-center justify-end space-x-3 rounded-b'}>
<div className={'flex items-center justify-end space-x-3 rounded-b bg-slate-700 px-6 py-3'}>
{children}
</div>,
);

View file

@ -18,7 +18,7 @@ export default ({ type, position, className }: DialogIconProps) => {
setIcon(
<div className={classNames(styles.dialog_icon, styles[type], className)}>
<Icon className={'w-6 h-6'} />
<Icon className={'h-6 w-6'} />
</div>,
);
}, [type, className]);

View file

@ -12,7 +12,7 @@ interface Props {
}
const DropdownGap = ({ invisible }: { invisible?: boolean }) => (
<div className={classNames('border m-2', { 'border-neutral-700': !invisible, 'border-transparent': invisible })} />
<div className={classNames('m-2 border', { 'border-neutral-700': !invisible, 'border-transparent': invisible })} />
);
type TypedChild = (React.ReactChild | React.ReactFragment | React.ReactPortal) & {

View file

@ -37,7 +37,7 @@ const PaginationFooter = ({ pagination, className, onPageSelect }: Props) => {
});
return (
<div className={classNames('flex items-center justify-between my-2', className)}>
<div className={classNames('my-2 flex items-center justify-between', className)}>
<p className={'text-sm text-neutral-500'}>
Showing&nbsp;
<span className={'font-semibold text-neutral-400'}>
@ -50,7 +50,7 @@ const PaginationFooter = ({ pagination, className, onPageSelect }: Props) => {
{pagination.totalPages > 1 && (
<div className={'flex space-x-1'}>
<Button.Text {...buttonProps(1)} disabled={pages.previous.length !== 2}>
<ChevronDoubleLeftIcon className={'w-3 h-3'} />
<ChevronDoubleLeftIcon className={'h-3 w-3'} />
</Button.Text>
{pages.previous.reverse().map(value => (
<Button.Text key={`previous-${value}`} {...buttonProps(value)}>
@ -66,7 +66,7 @@ const PaginationFooter = ({ pagination, className, onPageSelect }: Props) => {
</Button.Text>
))}
<Button.Text {...buttonProps(total)} disabled={pages.next.length !== 2}>
<ChevronDoubleRightIcon className={'w-3 h-3'} />
<ChevronDoubleRightIcon className={'h-3 w-3'} />
</Button.Text>
</div>
)}

View file

@ -3,14 +3,18 @@ import { PaginationDataSet } from '@/api/http';
const TFootPaginated = ({ pagination, span }: { span: number; pagination: PaginationDataSet }) => {
const start = (pagination.currentPage - 1) * pagination.perPage;
const end = ((pagination.currentPage - 1) * pagination.perPage) + pagination.count;
const end = (pagination.currentPage - 1) * pagination.perPage + pagination.count;
return (
<tfoot>
<tr className={'bg-neutral-800'}>
<td scope={'col'} colSpan={span} className={'px-4 py-2'}>
<p className={'text-sm text-neutral-500'}>
Showing <span className={'font-semibold text-neutral-400'}>{Math.max(start, Math.min(pagination.total, 1))}</span> to&nbsp;
Showing{' '}
<span className={'font-semibold text-neutral-400'}>
{Math.max(start, Math.min(pagination.total, 1))}
</span>{' '}
to&nbsp;
<span className={'font-semibold text-neutral-400'}>{end}</span> of&nbsp;
<span className={'font-semibold text-neutral-400'}>{pagination.total}</span> results.
</p>

View file

@ -108,7 +108,7 @@ export default ({ children, ...props }: Props) => {
ay || 0,
)}px) rotate(45deg)`,
}}
className={classNames('absolute bg-slate-900 w-3 h-3', side)}
className={classNames('absolute h-3 w-3 bg-slate-900', side)}
/>
)}
</motion.div>