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 1, 2023
1 parent 398a8c3 commit 10eee7e
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 0 deletions.
89 changes: 89 additions & 0 deletions src/components/InlineForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React, { useEffect, useMemo, useReducer, useRef } from 'react';
import styled from 'styled-components';

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

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;
}

const StyledForm = styled(Form)``;

const StyledWrapper = styled.div`
display: contents;
& ${StyledForm} {
background-color: transparent;
display: contents;
}
`;

const StyledFormWrapper = styled.div`
display: contents;
position: relative;
`;

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

return null;
}, [renderTrigger]);

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

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

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

return (
<StyledWrapper ref={wrapperRef} className={className} {...onESC}>
{!visible && trigger}
{visible && (
<StyledForm
onSubmit={() =>
onSubmit().then(() => {
toggleVisible();
onReset();
})
}
>
<StyledFormWrapper>{children}</StyledFormWrapper>
</StyledForm>
)}
</StyledWrapper>
);
};
1 change: 1 addition & 0 deletions src/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ export * from './Popup';
export * from './ListView';
export * from './ErrorPopup';
export * from './Spinner';
export * from './InlineForm';
100 changes: 100 additions & 0 deletions src/stories/InlineForm.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React, { useCallback } from 'react';
import { Meta, StoryObj } from '@storybook/react';
import styled from 'styled-components';
import { IconQuestionCircleOutline } from '@taskany/icons';
import { gray7 } from '@taskany/colors';

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';

const meta: Meta<typeof InlineForm> = {
title: 'InlineForm',
component: InlineForm,
};

export default meta;

type Story = StoryObj<typeof meta>;

const StyledWrapper = styled.div`
display: contents;
& form {
background-color: transparent;
display: contents;
}
`;

const StyledFormWrapper = styled.div`
display: contents;
position: relative;
`;

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

const StyledFormInput = styled(FormInput)`
font-size: 14px;
font-weight: normal;
padding: 5px 10px;
flex: 1;
border: 1px solid ${gray7};
box-sizing: border-box;
`;

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

export const InlineFormComponent: Story = () => {
const handleFormInputChange = useCallback(() => {
console.log('Change Click');

Check warning on line 59 in src/stories/InlineForm.stories.tsx

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
}, []);

return (
<StyledWrapper>
<Form onSubmit={() => console.log('Succes')}>
<StyledFormWrapper>
<StyledTableCell col={5} align="center">
<StyledFormInput
onChange={handleFormInputChange}
autoFocus
brick="center"
placeholder={'Enter criteria'}
/>
<StyledFormInput
onChange={handleFormInputChange}
autoComplete="off"
placeholder={'No more than 100'}
brick="center"
/>
<Button text={'Add'} brick="left" type="submit" view="primary" outline />
<>
<StyledQuestionIcon>
<a
onMouseOver={() => console.log('onMouseOver')}
onMouseLeave={() => console.log('onMouseLeave')}
>
<IconQuestionCircleOutline size="s" />
</a>
</StyledQuestionIcon>
<Popup tooltip placement="top-end">
Hint
</Popup>
</>
</StyledTableCell>
</StyledFormWrapper>
</Form>
</StyledWrapper>
);
};

InlineFormComponent.args = {};

0 comments on commit 10eee7e

Please sign in to comment.