Skip to content

Commit

Permalink
feat: inlineForm component
Browse files Browse the repository at this point in the history
  • Loading branch information
Katrin-kudryash committed Sep 7, 2023
1 parent 30ccd24 commit 9809b8d
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 0 deletions.
74 changes: 74 additions & 0 deletions src/components/InlineForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useCallback, useEffect, useReducer, useRef } from 'react';
import styled from 'styled-components';

import { KeyCode, useKeyboard } from '../hooks/useKeyboard';
import { useClickOutside } from '../hooks/useClickOutside';
import { nullable } from '../utils';

import { Form } from './Form';

interface RenderTriggerProps {
onClick: () => void;
}

interface InlineFormProps {
renderTrigger: (props: RenderTriggerProps) => React.ReactNode;
onSubmit: () => Promise<void>;
children: React.ReactNode;
onReset: () => void;
className?: string;
text?: string;
}

const StyledForm = styled(Form)`
background-color: transparent;
`;

const StyledWrapper = styled.div`
display: contents;
}
`;

export const InlineForm: React.FC<InlineFormProps> = ({ renderTrigger, onSubmit, onReset, children, className }) => {
const wrapperRef = useRef<HTMLDivElement>(null);
const [visible, toggleVisible] = useReducer((state) => !state, !renderTrigger);

const [onESC] = useKeyboard(
[KeyCode.Escape],
() => {
if (visible) {
toggleVisible();
}
},
{
capture: true,
},
);

useClickOutside(wrapperRef, () => {
if (visible) {
toggleVisible();
}
});

const handleSubmit = useCallback(async () => {
await onSubmit();
toggleVisible();
onReset();
}, [onSubmit, onReset]);

useEffect(() => {
if (!visible) {
onReset();
}
}, [visible, onReset]);

return (
<StyledWrapper ref={wrapperRef} className={className} {...onESC}>
{nullable(!visible, () => renderTrigger({ onClick: toggleVisible }))}
{nullable(visible, () => (
<StyledForm onSubmit={handleSubmit}>{children}</StyledForm>
))}
</StyledWrapper>
);
};
1 change: 1 addition & 0 deletions src/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ export * from './Spinner';
export * from './Tabs';
export * from './Checkbox';
export * from './AutoComplete';
export * from './InlineForm';
1 change: 1 addition & 0 deletions src/stories/Button.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Button } from '../components/Button';
const meta: Meta<typeof Button> = {
title: 'Button',
component: Button,
argTypes: { onClick: { action: 'clicked' } },
};

export default meta;
Expand Down
71 changes: 71 additions & 0 deletions src/stories/InlineForm.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react';
import { action } from '@storybook/addon-actions';
import { Meta, StoryFn } from '@storybook/react';
import styled from 'styled-components';
import { IconQuestionCircleOutline } from '@taskany/icons';

import { InlineForm } from '../components/InlineForm';
import { Button } from '../components/Button';
import { TableCell } from '../components/Table';
import { Form } from '../components/Form';
import { Popup } from '../components/Popup';
import { FormInput } from '../components/FormInput';

export default {
title: 'InlineForm',
component: InlineForm,
argTypes: {
onSubmit: { action: 'form submitted' },
onClick: { action: 'clecked' },
onMouseOver: { action: 'onMouseOver' },
onMouseLeave: { action: 'onMouseLeave' },
onChange: { action: 'onChange' },
},
} as Meta<typeof InlineForm>;

const StyledWrapper = styled.div`
display: contents;
`;

const StyledForm = styled(Form)`
background-color: transparent;
`;

const StyledTableCell = styled(TableCell)`
flex-wrap: nowrap;
display: flex;
align-items: center;
`;

const StyledQuestionIcon = styled.div`
margin: 5px 0 0 4px;
`;

export const InlineFormStories: StoryFn = () => {
return (
<StyledWrapper>
<StyledForm onSubmit={action('form submitted')}>
<StyledTableCell col={5} align="center">
<FormInput autoFocus brick="right" placeholder={'Enter criteria'} onChange={action('onChange')} />
<FormInput
autoComplete="off"
placeholder={'No more than 100'}
brick="center"
onChange={action('onChange')}
/>
<Button text={'Add'} brick="left" type="submit" view="primary" size="l" outline />
<>
<StyledQuestionIcon>
<a onMouseOver={action('onMouseOver')} onMouseLeave={action('onMouseLeave')}>
<IconQuestionCircleOutline size="s" />
</a>
</StyledQuestionIcon>
<Popup tooltip placement="top-end">
Hint
</Popup>
</>
</StyledTableCell>
</StyledForm>
</StyledWrapper>
);
};

0 comments on commit 9809b8d

Please sign in to comment.