Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve tree styling, fix compact buttons, fix textarea templates #358

Merged
merged 1 commit into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ReqoreContent, ReqoreLayoutContent, ReqoreUIProvider } from '../src';

export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
layout: 'fullscreen',
options: {
panelPosition: 'right',
Expand Down
16 changes: 0 additions & 16 deletions __tests__/tree.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,6 @@ test('<Tree /> items can be expanded and collapsed', () => {
expect(document.querySelectorAll('.reqore-tree-label').length).toBe(0);
});

test('Shows types for <Tree /> properly', () => {
render(
<ReqoreUIProvider>
<ReqoreLayoutContent>
<ReqoreContent>
<ReqoreTree data={MockObject} />
</ReqoreContent>
</ReqoreLayoutContent>
</ReqoreUIProvider>
);

fireEvent.click(document.querySelector('.reqore-tree-show-types'));

expect(document.querySelectorAll('.reqore-tree-type').length).toBe(7);
});

test('Renders <Tree /> with clickable items', () => {
const fn = jest.fn();

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qoretechnologies/reqore",
"version": "0.38.3",
"version": "0.38.4",
"description": "ReQore is a highly theme-able and modular UI library for React",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
17 changes: 12 additions & 5 deletions src/components/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,10 @@ export interface IReqoreButtonBadgeProps extends IWithReqoreSize {
content?: TReqoreBadge | TReqoreBadge[];
wrap?: boolean;
wrapGroup?: boolean;
compact?: boolean;
}

export const ButtonBadge = memo(({ wrapGroup, ...props }: IReqoreButtonBadgeProps) => {
export const ButtonBadge = memo(({ wrapGroup, compact, ...props }: IReqoreButtonBadgeProps) => {
const renderTag = useCallback(
({ size, color, theme, content, key }: IReqoreButtonBadgeProps & { key: number }) => (
<ReqoreTag
Expand All @@ -309,7 +310,7 @@ export const ButtonBadge = memo(({ wrapGroup, ...props }: IReqoreButtonBadgeProp
return (
<>
<ReqoreSpacer
width={props.wrap ? undefined : PADDING_FROM_SIZE[props.size]}
width={props.wrap ? undefined : PADDING_FROM_SIZE[props.size] / (compact ? 2 : 1)}
height={!props.wrap ? undefined : PADDING_FROM_SIZE[props.size] / 2}
/>
<ReqoreTagGroup wrap={wrapGroup}>
Expand Down Expand Up @@ -363,6 +364,7 @@ const ReqoreButton = memo(
leftIconProps,
rightIconProps,
label,
compact,
as,
...rest
}: IReqoreButtonProps,
Expand Down Expand Up @@ -418,6 +420,7 @@ const ReqoreButton = memo(
wrap={wrap}
description={description}
className={`${className || ''} reqore-control reqore-button`}
compact={compact}
>
<StyledButtonContent size={size} wrap={wrap} description={description} flat={_flat}>
{hasLeftIcon ? (
Expand All @@ -426,6 +429,7 @@ const ReqoreButton = memo(
icon={icon}
size={size}
color={leftIconColor || iconColor}
compact={compact}
{...leftIconProps}
style={
textAlign !== 'left' || iconsAlign === 'center'
Expand All @@ -440,7 +444,7 @@ const ReqoreButton = memo(
}
/>
{_children || hasRightIcon ? (
<ReqoreSpacer width={PADDING_FROM_SIZE[size]} />
<ReqoreSpacer width={PADDING_FROM_SIZE[size] / (compact ? 2 : 1)} />
) : null}
</>
) : _children ? (
Expand Down Expand Up @@ -471,7 +475,7 @@ const ReqoreButton = memo(
</StyledAnimatedTextWrapper>
)}
{(badge || badge === 0) && !wrap ? (
<ButtonBadge content={badge} size={size} theme={theme} />
<ButtonBadge content={badge} size={size} theme={theme} compact={compact} />
) : null}
{!hasRightIcon ? (
_children ? (
Expand All @@ -482,11 +486,14 @@ const ReqoreButton = memo(
) : null
) : (
<>
{_children || badge ? <ReqoreSpacer width={PADDING_FROM_SIZE[size]} /> : null}
{_children || badge ? (
<ReqoreSpacer width={PADDING_FROM_SIZE[size] / (compact ? 2 : 1)} />
) : null}
<ReqoreIcon
icon={rightIcon}
size={size}
color={rightIconColor || iconColor}
compact={compact}
{...rightIconProps}
style={
textAlign !== 'right' || iconsAlign === 'center'
Expand Down
11 changes: 8 additions & 3 deletions src/components/Dropdown/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ const ReqoreDropdownList = memo(

return _items.filter((item) => {
if (item.divider) {
return false;
return true;
}

const text: string | undefined = item.label || item.value || item.children;
Expand Down Expand Up @@ -153,7 +153,8 @@ const ReqoreDropdownList = memo(
{_onBackClick && (
<ReqoreButton
icon='ArrowLeftSLine'
fluid
fluid={!filterable}
fixed={filterable}
onClick={_onBackClick}
className='reqore-dropdown-back-button'
/>
Expand All @@ -163,7 +164,10 @@ const ReqoreDropdownList = memo(
value={onFilterChange ? filter : query}
icon='SearchLine'
onChange={handleQueryChange}
placeholder={filterPlaceholder || `Search ${size(_items)} items...`}
placeholder={
filterPlaceholder ||
`Search ${size(_items.filter((item) => !item.divider))} items...`
}
onClearClick={() => (onFilterChange ? onFilterChange('') : setQuery(''))}
{...inputProps}
/>
Expand Down Expand Up @@ -195,6 +199,7 @@ const ReqoreDropdownList = memo(
<ReqoreDropdownItem
key={item.label || item.value || index}
{...item}
disabled={'items' in item && !size(item.items) ? true : item.disabled}
onItemClick={handleItemClick}
scrollIntoView={scrollToSelected && item.selected && !multiSelect}
/>
Expand Down
13 changes: 10 additions & 3 deletions src/components/Icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export interface IReqoreIconProps
rounded?: boolean;
rotation?: number;
animation?: 'spin' | 'heartbeat';
interactive?: boolean;
compact?: boolean;
}

const SpinKeyframes = keyframes`
Expand All @@ -51,18 +53,23 @@ export const StyledIconWrapper = styled(StyledEffect)<{ margin: 'right' | 'left'

border-radius: ${({ rounded }) => (rounded ? '50%' : undefined)};
rotate: ${({ rotation }) => (rotation ? `${rotation}deg` : undefined)};
cursor: ${({ interactive }) => (interactive ? 'pointer' : undefined)};

${({ margin, size }) =>
${({ margin, size, compact }) =>
margin &&
css`
margin-left: ${margin === 'left' || margin === 'both'
? isStringSize(size)
? `${PADDING_FROM_SIZE[size]}px`
? `${PADDING_FROM_SIZE[size] / (compact ? 2 : 1)}px`
: compact
? '3px'
: '10px'
: undefined};
margin-right: ${margin === 'right' || margin === 'both'
? isStringSize(size)
? `${PADDING_FROM_SIZE[size]}px`
? `${PADDING_FROM_SIZE[size] / (compact ? 2 : 1)}px`
: compact
? '3px'
: '10px'
: undefined};
`}
Expand Down
4 changes: 3 additions & 1 deletion src/components/Paragraph/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export interface IReqoreParagraphProps
export const StyledParagraph = styled(StyledTextEffect)`
padding: 0;
margin: 0;
color: ${({ theme, intent }) => (intent ? theme.intents[intent] : 'inherit')};
color: ${({ theme, intent }) =>
intent ? theme.intents[intent] : theme.text?.color || 'inherit'};
font-size: ${({ _size }) => (isStringSize(_size) ? `${TEXT_FROM_SIZE[_size]}px` : _size)};
`;

Expand All @@ -29,6 +30,7 @@ export const ReqoreP = memo(
<StyledParagraph
as='p'
theme={theme}
color={theme.text.color}
intent={intent}
{...props}
_size={size}
Expand Down
3 changes: 3 additions & 0 deletions src/components/Textarea/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ const ReqoreInput = forwardRef<HTMLTextAreaElement, IReqoreTextareaProps>(
)}`;

setValue(value);
// Trigger the onChange event
onChange?.({ target: { value } } as any);
},
[inputRef, _value]
);
Expand Down Expand Up @@ -232,6 +234,7 @@ const ReqoreInput = forwardRef<HTMLTextAreaElement, IReqoreTextareaProps>(
component={StyledTextareaWrapper}
className={`${className || ''} reqore-control-wrapper`}
width={width}
filterable
height={height}
fluid={fluid}
fixed={fixed}
Expand Down
82 changes: 51 additions & 31 deletions src/components/Tree/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { cloneDeep, size as lodashSize } from 'lodash';
import { useMemo, useState } from 'react';
import styled from 'styled-components';
import { ReqoreMessage, ReqorePanel, useReqoreProperty } from '../..';
import { ReqoreHorizontalSpacer, ReqoreIcon, ReqoreP, ReqorePanel, useReqoreProperty } from '../..';
import { GAP_FROM_SIZE, TSizes } from '../../constants/sizes';
import { IReqoreTheme } from '../../constants/theme';
import { getTypeFromValue } from '../../helpers/utils';
import { getOneLessSize, getTypeFromValue } from '../../helpers/utils';
import { IWithReqoreSize } from '../../types/global';
import ReqoreButton from '../Button';
import ReqoreButton, { IReqoreButtonProps } from '../Button';
import ReqoreControlGroup from '../ControlGroup';
import { ReqoreExportModal } from '../ExportModal';
import { IReqorePanelAction, IReqorePanelProps } from '../Panel';
import { getExportActions, getZoomActions, sizeToZoom, zoomToSize } from '../Table/helpers';
import ReqoreTag from '../Tag';

export interface IReqoreTreeProps extends IReqorePanelProps, IWithReqoreSize {
data: Record<string, unknown> | Array<any>;
Expand All @@ -33,8 +32,10 @@ export interface ITreeStyle {
size?: TSizes;
}

export const StyledTreeLabel = styled(ReqoreMessage)`
export const StyledTreeLabel = styled(ReqoreP)`
flex-shrink: 1;

cursor: ${({ onClick }) => (onClick ? 'pointer' : 'default')};
`;

export const StyledTreeWrapper = styled.div<ITreeStyle>`
Expand Down Expand Up @@ -107,49 +108,68 @@ export const ReqoreTree = ({
isExpandable = false;
}

const badges: IReqoreButtonProps['badge'] = [`{...} ${lodashSize(data[key])} items`];

if (_showTypes) {
badges.push({
icon: 'CodeBoxFill',
label: dataType,
});
}

return (
<StyledTreeWrapper key={index} size={zoomToSize[zoom]} level={level}>
{isObject ? (
<ReqoreControlGroup size={zoomToSize[zoom]}>
{level !== 1 && <ReqoreHorizontalSpacer width={5} />}
<ReqoreButton
compact
minimal
className='reqore-tree-toggle'
icon={isExpandable ? 'ArrowDownSFill' : 'ArrowRightSFill'}
intent={isExpandable ? 'info' : undefined}
onClick={() => handleItemClick(stateKey, isExpandable)}
flat
flat={false}
badge={badges}
>
{displayKey}
</ReqoreButton>
{_showTypes ? <ReqoreTag label={dataType} className='reqore-tree-type' /> : null}
</ReqoreControlGroup>
) : (
<ReqoreControlGroup size={zoomToSize[zoom]} verticalAlign='flex-start'>
<ReqoreTag
label={displayKey}
actions={
withLabelCopy
? [
{
icon: 'FileCopy2Fill',
onClick: () => {
navigator.clipboard.writeText(JSON.stringify(data[key]));
addNotification({
content: 'Successfuly copied to clipboard',
id: Date.now().toString(),
type: 'success',
duration: 3000,
});
},
},
]
: undefined
}
/>
{_showTypes ? <ReqoreTag className='reqore-tree-type' label={dataType} /> : null}
<ReqoreControlGroup verticalAlign='flex-start'>
{level !== 1 && <ReqoreHorizontalSpacer width={5} />}
<ReqoreP
customTheme={{ text: { color: 'info:lighten' } }}
style={{ flexShrink: 0 }}
size={zoomToSize[zoom]}
>
{displayKey}:
</ReqoreP>
{withLabelCopy && (
<ReqoreIcon
interactive
icon='ClipboardLine'
size={getOneLessSize(zoomToSize[zoom])}
onClick={() => {
try {
navigator.clipboard.writeText(JSON.stringify(data[key]));
addNotification({
content: 'Successfuly copied to clipboard',
id: Date.now().toString(),
type: 'success',
duration: 3000,
});
} catch (e) {
console.error(e);
}
}}
/>
)}
<StyledTreeLabel
flat
onClick={() => onItemClick(data[key], [...path, key])}
onClick={() => onItemClick?.(data[key], [...path, key])}
className='reqore-tree-label'
size={zoomToSize[zoom]}
>
{JSON.stringify(data[key])}
</StyledTreeLabel>
Expand Down
2 changes: 1 addition & 1 deletion src/constants/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const Colors: Record<string, TReqoreHexColor> = {
DARK: '#000000',
DARK_THEME: '#333333',
LIGHT: '#ffffff',
BLUE: '#0E5A8A',
BLUE: '#0776CB',
GREEN: '#0A6640',
YELLOW: '#d1a036',
ORANGE: '#A66321',
Expand Down
7 changes: 7 additions & 0 deletions src/stories/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ const Template: StoryFn<typeof ReqoreButton> = (buttonProps) => {
</ReqoreButton>
<ReqoreButton {...buttonProps} rightIcon={undefined} compact />
<ReqoreButton {...buttonProps} compact />
<ReqoreButton
{...buttonProps}
compact
icon='AirplayLine'
rightIcon='Building3Fill'
label='Compact'
/>
<ReqoreButton {...buttonProps} readOnly onClick={alert}>
Read only
</ReqoreButton>
Expand Down
Loading
Loading