Skip to content
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: 1 addition & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const config: StorybookConfig = {
actions: false,
backgrounds: false,
controls: false,
measure: false,
measure: true,
outline: false,
toolbars: true,
viewport: false,
Expand Down
21 changes: 11 additions & 10 deletions docs/input-props-map.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
## Supported input props map

| Config type | Config name | Storybook | Type | Original component |
| :---------- | :----------- | :--------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- |
| `array` | `select` | [Select](https://preview.gravity-ui.com/dynamic-forms/?path=/story/array-select--select) | [MultiSelectProps](../src/lib/kit/components/Inputs/MultiSelect/MultiSelect.tsx#L10) | https://github.com/gravity-ui/uikit/tree/main/src/components/Select |
| `boolean` | `base` | [Base](https://preview.gravity-ui.com/dynamic-forms/?path=/story/boolean-base--base) | [CheckboxProps](../src/lib/kit/components/Inputs/Checkbox/Checkbox.tsx#L12) | https://github.com/gravity-ui/uikit/tree/main/src/components/Checkbox |
| `number` | `base` | [Base](https://preview.gravity-ui.com/dynamic-forms/?path=/story/number-base--base) | [TextProps](../src/lib/kit/components/Inputs/Text/Text.tsx#L9) | https://github.com/gravity-ui/uikit/tree/main/src/components/Text |
| `string` | `base` | [Base](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-base--base) | [TextProps](../src/lib/kit/components/Inputs/Text/Text.tsx#L9) | https://github.com/gravity-ui/uikit/tree/main/src/components/Text |
| `string` | `password` | [Password](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-password--password) | [TextProps](../src/lib/kit/components/Inputs/Text/Text.tsx#L9) | https://github.com/gravity-ui/uikit/tree/main/src/components/Text |
| `string` | `select` | [Select](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-select--select) | [SelectProps](../src/lib/kit/components/Inputs/Select/Select.tsx#L12) | https://github.com/gravity-ui/uikit/tree/main/src/components/Select |
| `string` | `textarea` | [TextArea](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-textarea--text-area) | [TextAreaProps](../src/lib/kit/components/Inputs/TextArea/TextArea.tsx#L7) | https://github.com/gravity-ui/uikit/tree/main/src/components/controls/TextArea |
| `string` | `date_input` | [DatePicker](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-dateinput--date-input) | [DatePickerProps](https://preview.gravity-ui.com/date-components/?path=/docs/components-datepicker--docs) | https://github.com/gravity-ui/date-components/tree/main/src/components/DatePicker |
| Config type | Config name | Storybook | Type | Original component |
| :---------- | :------------ | :----------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- |
| `array` | `select` | [Select](https://preview.gravity-ui.com/dynamic-forms/?path=/story/array-select--select) | [MultiSelectProps](../src/lib/kit/components/Inputs/MultiSelect/MultiSelect.tsx#L10) | https://github.com/gravity-ui/uikit/tree/main/src/components/Select |
| `boolean` | `base` | [Base](https://preview.gravity-ui.com/dynamic-forms/?path=/story/boolean-base--base) | [CheckboxProps](../src/lib/kit/components/Inputs/Checkbox/Checkbox.tsx#L12) | https://github.com/gravity-ui/uikit/tree/main/src/components/Checkbox |
| `number` | `base` | [Base](https://preview.gravity-ui.com/dynamic-forms/?path=/story/number-base--base) | [TextProps](../src/lib/kit/components/Inputs/Text/Text.tsx#L9) | https://github.com/gravity-ui/uikit/tree/main/src/components/Text |
| `string` | `base` | [Base](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-base--base) | [TextProps](../src/lib/kit/components/Inputs/Text/Text.tsx#L9) | https://github.com/gravity-ui/uikit/tree/main/src/components/Text |
| `string` | `password` | [Password](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-password--password) | [TextProps](../src/lib/kit/components/Inputs/Text/Text.tsx#L9) | https://github.com/gravity-ui/uikit/tree/main/src/components/Text |
| `string` | `select` | [Select](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-select--select) | [SelectProps](../src/lib/kit/components/Inputs/Select/Select.tsx#L12) | https://github.com/gravity-ui/uikit/tree/main/src/components/Select |
| `string` | `textarea` | [TextArea](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-textarea--text-area) | [TextAreaProps](../src/lib/kit/components/Inputs/TextArea/TextArea.tsx#L7) | https://github.com/gravity-ui/uikit/tree/main/src/components/controls/TextArea |
| `string` | `date_input` | [DatePicker](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-dateinput--date-input) | [DatePickerProps](https://preview.gravity-ui.com/date-components/?path=/docs/components-datepicker--docs) | https://github.com/gravity-ui/date-components/tree/main/src/components/DatePicker |
| `string` | `radio_group` | [RadioGroup](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-radiogroup--radio-group) | [RadioGroupProps](https://preview.gravity-ui.com/uikit/?path=/docs/components-inputs-radiogroup--docs) | https://github.com/gravity-ui/uikit/tree/main/src/components/RadioGroup |
8 changes: 8 additions & 0 deletions docs/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec;
| viewSpec.generateRandomValueButton | `boolean` | | Shows a button that allows you to generate a random value depending on the passed [function generateRandomValue](./lib.md#dynamicfield) |
| viewSpec.inputProps | `object` | | [InputProps](./input-props-map.md) Additional properties for internal input components |
| viewSpec.dateInput | `object` | | [Parameters](#dateinput) additional options for the date picker |
| viewSpec.radioGroupParams | `object` | | [Parameters](#radiogroupparams) additional options for the radio group |

#### SizeParams

Expand Down Expand Up @@ -200,6 +201,13 @@ You can provide all props of [original component](https://preview.gravity-ui.com
| placement | `'horizontal'` `'vertical'` | | Placement checkbox, default `'horizontal'` |
| disabled | `Record<string, boolean>` | | Disabled checkbox for enum values |

#### RadioGroupParams

| Property | Type | Required | Description |
| :-------- | :-------------------------- | :------: | :-------------------------------------------- |
| direction | `'horizontal'` `'vertical'` | | Direction radio group, default `'horizontal'` |
| disabled | `Record<string, boolean>` | | Disabled radio group for enum values |

#### Link

A component that serves as a wrapper for the value, if necessary, rendering the value as a link.
Expand Down
9 changes: 9 additions & 0 deletions docs/styles.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,15 @@ Variables for the Text Content component:
| `--df-text-content-icon-margin-right` | `4px` | Right margin of the icon |
| `--df-text-content-separator-margin` | `0px 4px` | Margin of the separator (top, right, bottom, left) |

### Radio Group

Variables for the Text Content component:

| Variable | Default Value | Description |
| :------------------------------------- | :-----------: | :------------------------------- |
| `--df-radio-group-height` | `28px` | Height of the radio group |
| `--df-radio-group-vertical-margin-top` | `8px` | Top margin in vertical direction |

---

## Views
Expand Down
4 changes: 4 additions & 0 deletions src/lib/core/types/specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ export interface StringSpec<
filterPlaceholder?: string;
meta?: Record<string, string>;
};
radioGroupParams?: {
direction?: 'horizontal' | 'vertical';
disabled?: Record<string, boolean>;
};
inputProps?: InputComponentProps;
layoutProps?: LayoutComponentProps;
generateRandomValueButton?: boolean;
Expand Down
12 changes: 12 additions & 0 deletions src/lib/kit/components/Inputs/RadioGroup/RadioGroup.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@import '../../../styles/variables.scss';

.#{$ns}radio-group {
align-items: center;
height: var(--df-radio-group-height, 28px);

&_vertical {
align-items: flex-start;
margin-top: var(--df-radio-group-vertical-margin-top, var(--g-spacing-2));
height: auto;
}
}
68 changes: 68 additions & 0 deletions src/lib/kit/components/Inputs/RadioGroup/RadioGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';

import {
Flex,
RadioGroup as RadioGroupBase,
type RadioGroupProps as RadioGroupBaseProps,
type RadioGroupOption,
} from '@gravity-ui/uikit';

import type {StringInput} from '../../../../core';
import {block} from '../../../utils';

import './RadioGroup.scss';

const b = block('radio-group');

export interface RadioGroupProps
extends Omit<
RadioGroupBaseProps,
'direction' | 'onChange' | 'onBlur' | 'onFocus' | 'disabled' | 'qa' | 'content'
> {
withCustomOptions?: boolean;
}

export const RadioGroup: StringInput<RadioGroupProps> = ({name, input, spec, inputProps}) => {
const {value, onBlur, onChange, onFocus} = input;

const {withCustomOptions, options: externalOptions} = inputProps || {};

const options: RadioGroupOption[] = React.useMemo(
() =>
withCustomOptions
? externalOptions || []
: spec.enum?.map((id) => ({
value: id,
content: spec.description?.[id] || id,
disabled: spec.viewSpec.radioGroupParams?.disabled?.[id] || false,
})) || [],
[
withCustomOptions,
externalOptions,
spec.enum,
spec.description,
spec.viewSpec.radioGroupParams?.disabled,
],
);

if (options.length === 0) {
return null;
}

return (
<Flex className={b({vertical: spec.viewSpec.radioGroupParams?.direction === 'vertical'})}>
<RadioGroupBase
{...inputProps}
name={name}
qa={name}
disabled={spec.viewSpec.disabled}
onUpdate={onChange}
onBlur={onBlur}
onFocus={onFocus}
value={value}
options={options}
direction={spec.viewSpec.radioGroupParams?.direction || 'horizontal'}
/>
</Flex>
);
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';

import {test} from '~playwright/core';
import {DynamicForm} from '~playwright/core/DynamicForm';
import {DynamicView} from '~playwright/core/DynamicView';

import {RADIO_GROUP, VALUE} from './helpers';

test.describe('Radio group', () => {
test('default', async ({mount, expectScreenshot}) => {
await mount(<DynamicForm spec={RADIO_GROUP.default} />);

await expectScreenshot();
});

test('default value', async ({mount, expectScreenshot}) => {
await mount(<DynamicForm spec={RADIO_GROUP.defaultValue} />);

await expectScreenshot();
});

test('required', async ({mount, expectScreenshot}) => {
await mount(<DynamicForm spec={RADIO_GROUP.required} />);

await expectScreenshot();
});

test('description', async ({mount, expectScreenshot}) => {
await mount(<DynamicForm spec={RADIO_GROUP.description} />);

await expectScreenshot();
});

test('disabled', async ({mount, expectScreenshot}) => {
await mount(<DynamicForm spec={RADIO_GROUP.disabled} />);

await expectScreenshot();
});

test('disabledOptions', async ({mount, expectScreenshot}) => {
await mount(<DynamicForm spec={RADIO_GROUP.disabledOptions} />);

await expectScreenshot();
});

test('directionVertical', async ({mount, expectScreenshot}) => {
await mount(<DynamicForm spec={RADIO_GROUP.directionVertical} />);

await expectScreenshot();
});
});

test('Radio group View', async ({mount, expectScreenshot}) => {
await mount(<DynamicView spec={RADIO_GROUP.default} value={VALUE} />);

await expectScreenshot();
});
120 changes: 120 additions & 0 deletions src/lib/kit/components/Inputs/RadioGroup/__tests__/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import type {StringSpec} from '../../../../../core';
import {SpecTypes} from '../../../../../core';

export const RADIO_GROUP: Record<string, StringSpec> = {
default: {
type: SpecTypes.String,
enum: ['foo', 'bar', 'rab'],
description: {
foo: 'Option 1',
bar: 'Option 2',
rab: 'Option 3',
},
viewSpec: {
type: 'radio_group',
layout: 'row',
layoutTitle: 'RadioGroup',
},
},
defaultValue: {
defaultValue: 'foo',
type: SpecTypes.String,
enum: ['foo', 'bar', 'rab'],
description: {
foo: 'Option 1',
bar: 'Option 2',
rab: 'Option 3',
},
viewSpec: {
type: 'radio_group',
layout: 'row',
layoutTitle: 'RadioGroup',
},
},
required: {
required: true,
type: SpecTypes.String,
enum: ['foo', 'bar', 'rab'],
description: {
foo: 'Option 1',
bar: 'Option 2',
rab: 'Option 3',
},
viewSpec: {
type: 'radio_group',
layout: 'row',
layoutTitle: 'RadioGroup',
},
},
description: {
type: SpecTypes.String,
enum: ['foo', 'bar', 'rab'],
description: {
foo: 'Option 1',
bar: 'Option 2',
rab: 'Option 3',
},
viewSpec: {
type: 'radio_group',
layout: 'row',
layoutTitle: 'RadioGroup',
layoutDescription: 'Description',
},
},
disabled: {
type: SpecTypes.String,
enum: ['foo', 'bar', 'rab'],
description: {
foo: 'Option 1',
bar: 'Option 2',
rab: 'Option 3',
},
viewSpec: {
type: 'radio_group',
layout: 'row',
layoutTitle: 'RadioGroup',
layoutDescription: 'Description',
disabled: true,
},
},
disabledOptions: {
type: SpecTypes.String,
enum: ['foo', 'bar', 'rab'],
description: {
foo: 'Option 1',
bar: 'Option 2',
rab: 'Option 3',
},
viewSpec: {
type: 'radio_group',
layout: 'row',
layoutTitle: 'RadioGroup',
layoutDescription: 'Description',
radioGroupParams: {
disabled: {
foo: true,
},
},
},
},
directionVertical: {
type: SpecTypes.String,
enum: ['foo', 'bar', 'rab'],
description: {
foo: 'Option 1',
bar: 'Option 2',
rab: 'Option 3',
},
viewSpec: {
type: 'radio_group',
layout: 'row',
layoutTitle: 'RadioGroup',
layoutDescription: 'Description',
radioGroupParams: {
direction: 'vertical',
},
},
},
};

export const VALUE = 'foo';
1 change: 1 addition & 0 deletions src/lib/kit/components/Inputs/RadioGroup/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './RadioGroup';
1 change: 1 addition & 0 deletions src/lib/kit/components/Inputs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export * from './NumberWithScale';
export * from './ObjectBase';
export * from './ObjectValueInput';
export * from './OneOf';
export * from './RadioGroup';
export * from './Secret';
export * from './Select';
export * from './Switch';
Expand Down
3 changes: 3 additions & 0 deletions src/lib/kit/constants/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
OneOfFlat,
OneOfFlatView,
OneOfView,
RadioGroup,
Row,
RowVerbose,
Secret,
Expand Down Expand Up @@ -181,6 +182,7 @@ export const dynamicConfig: DynamicFormConfig = {
number_with_scale: {Component: NumberWithScale},
monaco_input: {Component: MonacoInput},
text_content: {Component: TextContent, independent: true},
radio_group: {Component: RadioGroup},
},
layouts: {
row: Row,
Expand Down Expand Up @@ -290,6 +292,7 @@ export const dynamicViewConfig: DynamicViewConfig = {
number_with_scale: {Component: NumberWithScaleView},
monaco_input: {Component: MonacoView},
text_content: {Component: TextContentView, independent: true},
radio_group: {Component: BaseView},
},
layouts: {
row: ViewRow,
Expand Down
14 changes: 14 additions & 0 deletions src/stories/Editor.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,20 @@ const spec: ObjectSpec = {
},
},
},
operating_system: {
type: SpecTypes.String,
enum: ['windows', 'linux', 'macOs'],
description: {
windows: 'Windows',
linux: 'Linux',
macOs: 'MacOs',
},
viewSpec: {
type: 'radio_group',
layout: 'row',
layoutTitle: 'Operating System',
},
},
license: {
type: SpecTypes.Boolean,
viewSpec: {type: 'base', layout: 'row', layoutTitle: 'License'},
Expand Down
Loading