From e84c5eb7141b741089df288070609f6e06b1b063 Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Wed, 30 Aug 2023 12:45:11 +0200 Subject: [PATCH 1/3] feat(OneOfTogglerCard): added new display toggler card --- docs/spec.md | 6 +- src/lib/core/types/specs.ts | 2 +- .../useOneOf/TogglerCard/TogglerCard.scss | 22 +++++++ .../useOneOf/TogglerCard/TogglerCard.tsx | 57 +++++++++++++++++++ .../kit/hooks/useOneOf/TogglerCard/index.ts | 1 + src/lib/kit/hooks/useOneOf/useOneOf.scss | 17 ++++++ src/lib/kit/hooks/useOneOf/useOneOf.tsx | 56 +++++++++++++++--- src/stories/ObjectMultiOneOf.stories.tsx | 8 ++- src/stories/ObjectMultiOneOfFlat.stories.tsx | 8 ++- .../components/InputPreview/constants.ts | 2 +- 10 files changed, 163 insertions(+), 16 deletions(-) create mode 100644 src/lib/kit/hooks/useOneOf/TogglerCard/TogglerCard.scss create mode 100644 src/lib/kit/hooks/useOneOf/TogglerCard/TogglerCard.tsx create mode 100644 src/lib/kit/hooks/useOneOf/TogglerCard/index.ts diff --git a/docs/spec.md b/docs/spec.md index cc7b9a92..6ce2d67c 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -136,9 +136,9 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec; #### OneOfParams -| Property | Type | Required | Description | -| :------- | :------------------- | :------: | :---------- | -| toggler | `'select'` `'radio'` | | Switch type | +| Property | Type | Required | Description | +| :------- | :---------------------------- | :------: | :---------- | +| toggler | `'select'` `'radio'` `'card'` | | Switch type | #### FileInput diff --git a/src/lib/core/types/specs.ts b/src/lib/core/types/specs.ts index 5a1c416b..56be3e3b 100644 --- a/src/lib/core/types/specs.ts +++ b/src/lib/core/types/specs.ts @@ -87,7 +87,7 @@ export interface ObjectSpec { order?: string[]; link?: LinkType; oneOfParams?: { - toggler?: 'select' | 'radio'; + toggler?: 'select' | 'radio' | 'card'; }; placeholder?: string; }; diff --git a/src/lib/kit/hooks/useOneOf/TogglerCard/TogglerCard.scss b/src/lib/kit/hooks/useOneOf/TogglerCard/TogglerCard.scss new file mode 100644 index 00000000..75b26422 --- /dev/null +++ b/src/lib/kit/hooks/useOneOf/TogglerCard/TogglerCard.scss @@ -0,0 +1,22 @@ +@import '../../../styles/variables.scss'; + +.#{$ns}toggler-card { + width: 254px; + padding: 10px; + height: 88px; + + &__header { + display: flex; + justify-content: space-between; + align-items: baseline; + } + + &__text { + margin-top: 12px; + display: block; + margin-right: 15px; + height: 36px; + overflow: hidden; + text-overflow: ellipsis; + } +} diff --git a/src/lib/kit/hooks/useOneOf/TogglerCard/TogglerCard.tsx b/src/lib/kit/hooks/useOneOf/TogglerCard/TogglerCard.tsx new file mode 100644 index 00000000..d77b892b --- /dev/null +++ b/src/lib/kit/hooks/useOneOf/TogglerCard/TogglerCard.tsx @@ -0,0 +1,57 @@ +import React from 'react'; + +import {HelpPopover} from '@gravity-ui/components'; +import {Card, Text} from '@gravity-ui/uikit'; + +import {block} from '../../../utils'; + +import './TogglerCard.scss'; + +const b = block('toggler-card'); + +interface TogglerCardProps { + description?: string; + title: string; + text: string; + onOneOfChange: ([newValue]: string[]) => void; + disabled?: boolean; + value: string; + oneOfValue: string; +} + +export const TogglerCard: React.FC = ({ + description, + title, + text, + onOneOfChange, + disabled, + value, + oneOfValue, +}) => { + const onClick = React.useCallback(() => { + onOneOfChange([value]); + }, [onOneOfChange, value]); + + return ( + +
+ + {title} + + {description ? ( + + ) : null} +
+ + {text} + +
+ ); +}; diff --git a/src/lib/kit/hooks/useOneOf/TogglerCard/index.ts b/src/lib/kit/hooks/useOneOf/TogglerCard/index.ts new file mode 100644 index 00000000..959ea1a0 --- /dev/null +++ b/src/lib/kit/hooks/useOneOf/TogglerCard/index.ts @@ -0,0 +1 @@ +export * from './TogglerCard'; diff --git a/src/lib/kit/hooks/useOneOf/useOneOf.scss b/src/lib/kit/hooks/useOneOf/useOneOf.scss index 6ab30f8a..3571bc9a 100644 --- a/src/lib/kit/hooks/useOneOf/useOneOf.scss +++ b/src/lib/kit/hooks/useOneOf/useOneOf.scss @@ -8,5 +8,22 @@ max-width: unset; } } + + &_card { + & + .#{$ns}group-indent { + & > .#{$ns}use-search:not(.#{$ns}group-indent) { + padding-top: 0px; + margin-top: 15px; + } + } + } + } + + &__card { + display: flex; + + & > :first-child { + margin-right: 8px; + } } } diff --git a/src/lib/kit/hooks/useOneOf/useOneOf.tsx b/src/lib/kit/hooks/useOneOf/useOneOf.tsx index 8fb20c9a..dec613b8 100644 --- a/src/lib/kit/hooks/useOneOf/useOneOf.tsx +++ b/src/lib/kit/hooks/useOneOf/useOneOf.tsx @@ -6,6 +6,8 @@ import _ from 'lodash'; import {ObjectIndependentInputProps} from '../../../core'; import {block} from '../../utils'; +import {TogglerCard} from './TogglerCard'; + import './useOneOf.scss'; const b = block('use-oneof'); @@ -68,17 +70,44 @@ export const useOneOf = ({props, onTogglerChange}: UseOneOfParams) => { [spec.description, spec.viewSpec.order, specProperties], ); - const selectToggler = React.useMemo( - () => + const togglerType = React.useMemo(() => { + if (spec.viewSpec.oneOfParams?.toggler === 'card' && options.length < 3) { + return 'card'; + } + + if ( spec.viewSpec.oneOfParams?.toggler !== 'radio' && (spec.viewSpec.oneOfParams?.toggler === 'select' || options.length > 3 || - _.some(options, ({title}) => title.length > MAX_TAB_TITLE_LENGTH)), - [options, spec.viewSpec.oneOfParams?.toggler], - ); + _.some(options, ({title}) => title.length > MAX_TAB_TITLE_LENGTH)) + ) { + return 'select'; + } + + return 'radio'; + }, [options, spec.viewSpec.oneOfParams?.toggler]); const togglerInput = React.useMemo(() => { - if (selectToggler) { + if (togglerType === 'card') { + return ( +
+ {options.map(({value}) => ( + + ))} +
+ ); + } + + if (togglerType === 'select') { return (