generated from gravity-ui/package-example
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/src/components/FormRow @ogonkov |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
@use '../variables'; | ||
|
||
.#{variables.$ns}form-row { | ||
--gc-form-row-label-width: 172px; | ||
--gc-form-row-field-height: 28px; | ||
|
||
margin-bottom: 20px; | ||
align-items: flex-start; | ||
display: flex; | ||
|
||
&__left { | ||
display: flex; | ||
flex-flow: row; | ||
min-height: var(--gc-form-row-field-height); | ||
box-sizing: border-box; | ||
flex-shrink: 0; | ||
width: var(--gc-form-row-label-width); | ||
padding-right: 8px; | ||
} | ||
|
||
&__field-name { | ||
align-self: center; | ||
} | ||
|
||
&__field-name-text { | ||
word-break: break-word; | ||
} | ||
|
||
&__required-mark { | ||
line-height: 0; | ||
color: var(--yc-color-text-danger); | ||
font-size: inherit; | ||
} | ||
|
||
&__help-popover { | ||
display: inline-flex; | ||
vertical-align: middle; | ||
align-items: center; | ||
} | ||
|
||
&__right { | ||
flex: 1 1 auto; | ||
min-width: 0; | ||
} | ||
|
||
&__field-description { | ||
margin: 10px 0 0; | ||
color: var(--yc-color-text-secondary); | ||
word-break: break-word; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import React, {FC} from 'react'; | ||
import {block} from '../utils/cn'; | ||
|
||
import {FormRowFieldDescription} from './FormRowFieldDescription'; | ||
import i18n from './i18n'; | ||
import {FormRowProps} from './types'; | ||
|
||
import './FormRow.scss'; | ||
|
||
const b = block('form-row'); | ||
|
||
const FormRowComponent: FC<FormRowProps> = ({ | ||
className, | ||
label, | ||
labelHelpPopover, | ||
fieldId, | ||
required = false, | ||
children, | ||
}) => { | ||
const LabelComponent = fieldId ? 'label' : 'span'; | ||
|
||
return ( | ||
<div className={b(null, [className])}> | ||
<div className={b('left')}> | ||
<LabelComponent className={b('field-name')} htmlFor={fieldId ? fieldId : undefined}> | ||
<span className={b('field-name-text')}>{label}</span> | ||
|
||
{required ? ( | ||
<> | ||
| ||
<sup | ||
className={b('required-mark')} | ||
aria-label={i18n('label_required-field')} | ||
> | ||
* | ||
</sup> | ||
</> | ||
) : null} | ||
|
||
{labelHelpPopover ? ( | ||
<> | ||
| ||
<span className={b('help-popover')}>{labelHelpPopover}</span> | ||
</> | ||
) : null} | ||
</LabelComponent> | ||
</div> | ||
<div className={b('right')}>{children}</div> | ||
</div> | ||
); | ||
}; | ||
|
||
FormRowComponent.displayName = 'FormRow'; | ||
|
||
export const FormRow = Object.assign(FormRowComponent, {FieldDescription: FormRowFieldDescription}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React, {FC} from 'react'; | ||
import {block} from '../utils/cn'; | ||
import type {FormRowFieldDescriptionProps} from './types'; | ||
|
||
const b = block('form-row'); | ||
|
||
export const FormRowFieldDescription: FC<FormRowFieldDescriptionProps> = ({ | ||
children, | ||
className, | ||
...elementProps | ||
}) => { | ||
return ( | ||
<p {...elementProps} className={b('field-description', [className])}> | ||
{children} | ||
</p> | ||
); | ||
}; | ||
|
||
FormRowFieldDescription.displayName = 'FormRow.FieldDescription'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# FormRow | ||
|
||
Base component to place form input and label. | ||
|
||
## Usage | ||
|
||
```tsx | ||
import type {FC} from 'react'; | ||
import {TextInput} from '@gravity-ui/uikit'; | ||
import {FormRow} from '@gravity-ui/components'; | ||
|
||
const nameFieldId = 'form-field-name'; | ||
|
||
const Form: FC = () => { | ||
return ( | ||
<> | ||
<FormRow label={'Name'} fieldId={nameFieldId}> | ||
<TextInput id={nameFieldId} name={'name'} /> | ||
</FormRow> | ||
</> | ||
); | ||
}; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import React from 'react'; | ||
import {ComponentMeta, ComponentStory} from '@storybook/react'; | ||
import {HelpPopover, TextInput} from '@gravity-ui/uikit'; | ||
import {FormRow} from '../FormRow'; | ||
|
||
const fieldId = 'form-row-input-id'; | ||
const fieldDescriptionId = `${fieldId}-description`; | ||
|
||
const argTypeReactNode = { | ||
control: {type: null}, | ||
}; | ||
|
||
export default { | ||
title: 'Components/FormRow', | ||
component: FormRow, | ||
args: { | ||
label: 'Enter your name', | ||
fieldId, | ||
children: <TextInput id={fieldId} />, | ||
}, | ||
argTypes: { | ||
children: argTypeReactNode, | ||
labelHelpPopover: argTypeReactNode, | ||
}, | ||
} as ComponentMeta<typeof FormRow>; | ||
|
||
const Template: ComponentStory<typeof FormRow> = (args) => <FormRow {...args} />; | ||
|
||
export const Default = Template.bind({}); | ||
|
||
export const WithLongLabel = Template.bind({}); | ||
WithLongLabel.args = { | ||
label: 'Very long label for text field to test how it will wrap label text in real life', | ||
}; | ||
|
||
export const WithLongLabelWord = Template.bind({}); | ||
WithLongLabelWord.args = { | ||
label: 'Antidisestablishmentarianism', | ||
}; | ||
|
||
/** Story with corner case of label length and required mark. Mark should not be alone at the line */ | ||
export const WithCornerLabelLength = Template.bind({}); | ||
WithCornerLabelLength.args = { | ||
required: true, | ||
label: 'Antidisestablishmentariani', | ||
}; | ||
|
||
export const WithFieldDescription = Template.bind({}); | ||
WithFieldDescription.args = { | ||
children: ( | ||
<> | ||
<TextInput id={fieldId} controlProps={{'aria-describedby': fieldDescriptionId}} /> | ||
<FormRow.FieldDescription id={fieldDescriptionId}> | ||
Your name as it used in your foreign passport. | ||
</FormRow.FieldDescription> | ||
</> | ||
), | ||
}; | ||
|
||
export const WithFieldDescriptionAndLongLabel = Template.bind({}); | ||
WithFieldDescriptionAndLongLabel.storyName = 'With Field Description (Long Label)'; | ||
WithFieldDescriptionAndLongLabel.args = { | ||
...WithFieldDescription.args, | ||
...WithLongLabel.args, | ||
}; | ||
|
||
export const RequiredField = Template.bind({}); | ||
RequiredField.args = { | ||
required: true, | ||
}; | ||
|
||
export const WithHelpPopover = Template.bind({}); | ||
WithHelpPopover.args = { | ||
labelHelpPopover: ( | ||
<HelpPopover | ||
content={'Your name as it used in your foreign passport.'} | ||
placement={['top', 'bottom']} | ||
/> | ||
), | ||
}; | ||
|
||
export const WithHelpPopoverAndLongLabel = Template.bind({}); | ||
WithHelpPopoverAndLongLabel.storyName = 'With Help Popover (Long Label)'; | ||
WithHelpPopoverAndLongLabel.args = { | ||
...WithLongLabel.args, | ||
...WithHelpPopover.args, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"label_required-field": "(this field is mandatory)" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import {registerKeyset} from '../../utils/registerKeyset'; | ||
import en from './en.json'; | ||
import ru from './ru.json'; | ||
|
||
const COMPONENT = 'FormRow'; | ||
|
||
export default registerKeyset({en, ru}, COMPONENT); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"label_required-field": "(это поле обязательно для заполнения)" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export {FormRow} from './FormRow'; | ||
export type {FormRowProps, FormRowFieldDescriptionProps} from './types'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import type {ReactNode, HTMLAttributes, PropsWithChildren} from 'react'; | ||
|
||
export interface FormRowProps { | ||
className?: string; | ||
/** Field label */ | ||
label?: ReactNode; | ||
/** Slot for inserting `<HelpPopover/>` next to label text */ | ||
labelHelpPopover?: ReactNode; | ||
/** Id of field to correctly associate it label */ | ||
fieldId?: string; | ||
/** Display star next to required field */ | ||
required?: boolean; | ||
/** Field component itself. `<FormRow.FieldDescription/>` could be used here | ||
* next to field component itself */ | ||
children?: ReactNode; | ||
} | ||
|
||
export type FormRowFieldDescriptionProps = PropsWithChildren<{}> & | ||
Pick<HTMLAttributes<HTMLParagraphElement>, 'id' | 'className'>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
export * from './AdaptiveTabs'; | ||
export * from './FormRow'; | ||
export * from './InfiniteScroll'; | ||
|
||
export {Lang, configure} from './utils/configure'; |