From 9838c859635dcfda2fb852d4d4c818186c5dcbf3 Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Fri, 17 Mar 2023 14:50:04 +0100 Subject: [PATCH 01/12] feat: search --- src/lib/core/components/Form/Controller.tsx | 4 +- src/lib/core/components/Form/DynamicField.tsx | 47 +++++++++++--- .../components/Form/hooks/defaultSearch.ts | 6 ++ src/lib/core/components/Form/hooks/index.tsx | 4 ++ .../components/Form/hooks/useSearch/index.ts | 1 + .../Form/hooks/useSearch/useSearch.scss | 14 +++++ .../Form/hooks/useSearch/useSearch.tsx | 36 +++++++++++ .../components/Form/hooks/useSearchContext.ts | 29 +++++++++ .../components/Form/hooks/useSearchStore.ts | 63 +++++++++++++++++++ .../TableArrayInput/TableArrayInput.scss | 15 +++++ .../TableArrayInput/TableArrayInput.tsx | 46 ++++++++++++-- .../components/DynamicField/DynamicField.tsx | 12 +++- 12 files changed, 259 insertions(+), 18 deletions(-) create mode 100644 src/lib/core/components/Form/hooks/defaultSearch.ts create mode 100644 src/lib/core/components/Form/hooks/useSearch/index.ts create mode 100644 src/lib/core/components/Form/hooks/useSearch/useSearch.scss create mode 100644 src/lib/core/components/Form/hooks/useSearch/useSearch.tsx create mode 100644 src/lib/core/components/Form/hooks/useSearchContext.ts create mode 100644 src/lib/core/components/Form/hooks/useSearchStore.ts diff --git a/src/lib/core/components/Form/Controller.tsx b/src/lib/core/components/Form/Controller.tsx index bdc6fb7d..b80cc6b0 100644 --- a/src/lib/core/components/Form/Controller.tsx +++ b/src/lib/core/components/Form/Controller.tsx @@ -4,6 +4,7 @@ import {isCorrectSpec} from '../../helpers'; import {Spec} from '../../types'; import {useComponents, useDynamicFormsCtx, useField, useRender, useValidate} from './hooks'; +import {useSearch} from './hooks/useSearch'; import {FieldValue, ValidateError} from './types'; export interface ControllerProps { @@ -30,9 +31,10 @@ export const Controller = ({ const render = useRender({name, spec, inputEntity, Layout}); const validate = useValidate(spec); const renderProps = useField({name, initialValue, spec, validate, tools, parentOnChange}); + const searchWrapper = useSearch(spec, renderProps.input.value, name); if (_.isString(name) && isCorrectSpec(spec)) { - return render(renderProps); + return searchWrapper(render(renderProps)); } return null; diff --git a/src/lib/core/components/Form/DynamicField.tsx b/src/lib/core/components/Form/DynamicField.tsx index f9cb7abe..9f6bffc4 100644 --- a/src/lib/core/components/Form/DynamicField.tsx +++ b/src/lib/core/components/Form/DynamicField.tsx @@ -9,19 +9,33 @@ import {Spec} from '../../types'; import {Controller} from './Controller'; import {isCorrectConfig} from './helpers'; -import {useCreateContext, useStore} from './hooks'; -import {DynamicFormConfig} from './types'; +import { + defaultSearch, + useCreateContext, + useCreateSearchContext, + useSearchStore, + useStore, +} from './hooks'; +import {DynamicFormConfig, FieldValue} from './types'; export interface DynamicFieldProps { name: string; spec: Spec; config: DynamicFormConfig; Monaco?: React.ComponentType; + search?: string | ((spec: Spec, input: FieldValue, name: string) => boolean); } -export const DynamicField: React.FC = ({name, spec, config, Monaco}) => { +export const DynamicField: React.FC = ({name, spec, config, Monaco, search}) => { const DynamicFormsCtx = useCreateContext(); + const SearchContext = useCreateSearchContext(); const {tools, watcher} = useStore(name); + const {store, onChangeStore, onDeleteField, isShowFieldByName} = useSearchStore(name); + + const searchFunction = React.useMemo( + () => (typeof search === 'string' ? defaultSearch(search) : search), + [search], + ); const context = React.useMemo( () => ({ @@ -32,6 +46,17 @@ export const DynamicField: React.FC = ({name, spec, config, M [tools, config, Monaco], ); + const searchContext = React.useMemo( + () => ({ + store, + onChangeStore, + searchFunction, + onDeleteField, + isShowFieldByName, + }), + [isShowFieldByName, onChangeStore, onDeleteField, searchFunction, store], + ); + const correctParams = React.useMemo( () => _.isString(name) && isCorrectSpec(spec) && isCorrectConfig(config), [name, spec, config], @@ -40,13 +65,15 @@ export const DynamicField: React.FC = ({name, spec, config, M if (correctParams) { return ( - - {watcher} + + + {watcher} + ); } diff --git a/src/lib/core/components/Form/hooks/defaultSearch.ts b/src/lib/core/components/Form/hooks/defaultSearch.ts new file mode 100644 index 00000000..8de94949 --- /dev/null +++ b/src/lib/core/components/Form/hooks/defaultSearch.ts @@ -0,0 +1,6 @@ +import {Spec} from '../../../types'; + +export const defaultSearch = (search: string) => (spec: Spec) => + spec?.viewSpec.layoutTitle + ? spec?.viewSpec.layoutTitle.toLowerCase().includes(search.toLowerCase()) + : false; diff --git a/src/lib/core/components/Form/hooks/index.tsx b/src/lib/core/components/Form/hooks/index.tsx index 88b4ff3e..1e1bf5a7 100644 --- a/src/lib/core/components/Form/hooks/index.tsx +++ b/src/lib/core/components/Form/hooks/index.tsx @@ -6,3 +6,7 @@ export * from './useRender'; export * from './useStore'; export * from './useValidate'; export * from './useMonaco'; +export * from './useSearchStore'; +export * from './useSearchContext'; +export * from './useSearch'; +export * from './defaultSearch'; diff --git a/src/lib/core/components/Form/hooks/useSearch/index.ts b/src/lib/core/components/Form/hooks/useSearch/index.ts new file mode 100644 index 00000000..30a83eec --- /dev/null +++ b/src/lib/core/components/Form/hooks/useSearch/index.ts @@ -0,0 +1 @@ +export * from './useSearch'; diff --git a/src/lib/core/components/Form/hooks/useSearch/useSearch.scss b/src/lib/core/components/Form/hooks/useSearch/useSearch.scss new file mode 100644 index 00000000..9f76ed09 --- /dev/null +++ b/src/lib/core/components/Form/hooks/useSearch/useSearch.scss @@ -0,0 +1,14 @@ +@import '../../../../../kit/styles/variables.scss'; + +.#{$ns}search-wrapper { + margin-bottom: 15px; + display: block; + + &_hide { + display: none; + } + + &:last-child { + margin-bottom: 0; + } +} diff --git a/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx b/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx new file mode 100644 index 00000000..c4d99945 --- /dev/null +++ b/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx @@ -0,0 +1,36 @@ +import React from 'react'; + +import {FieldValue} from '../..'; +import {block} from '../../../../../kit/utils'; +import {Spec} from '../../../../types'; +import {useSearchContext} from '../useSearchContext'; + +import './useSearch.scss'; + +const b = block('search-wrapper'); + +export const useSearch = (spec: Spec, value: FieldValue, name: string) => { + const {searchFunction, onChangeStore, onDeleteField, isShowFieldByName} = useSearchContext(); + + const searchResult = React.useMemo( + () => (searchFunction ? searchFunction(spec, value, name) : true), + [name, searchFunction, spec, value], + ); + + React.useEffect(() => { + onChangeStore(name, searchResult); + }, [searchResult]); + + React.useEffect(() => { + return () => onDeleteField(name); + }, []); + + const isShow = React.useMemo(() => isShowFieldByName(name), [isShowFieldByName, name]); + + const searchWrapper = React.useCallback( + (children: JSX.Element | null) => {children}, + [isShow], + ); + + return searchWrapper; +}; diff --git a/src/lib/core/components/Form/hooks/useSearchContext.ts b/src/lib/core/components/Form/hooks/useSearchContext.ts new file mode 100644 index 00000000..4b64cd90 --- /dev/null +++ b/src/lib/core/components/Form/hooks/useSearchContext.ts @@ -0,0 +1,29 @@ +import React from 'react'; + +import _ from 'lodash'; + +import {Spec} from '../../../types'; +import {FieldValue} from '../types'; + +export type SearchStore = { + [key: string]: boolean; +}; + +export interface SearchContext { + store?: SearchStore; + onChangeStore: (name: string, search: boolean) => void; + searchFunction?: (spec: Spec, value: FieldValue, name: string) => boolean; + onDeleteField: (name: string) => void; + isShowFieldByName: (name: string) => boolean; +} + +const createContext = _.once(() => React.createContext({} as unknown as SearchContext)); + +export const useCreateSearchContext = () => createContext(); + +export const useSearchContext = () => { + const SearchContext = useCreateSearchContext(); + const context = React.useContext(SearchContext); + + return context; +}; diff --git a/src/lib/core/components/Form/hooks/useSearchStore.ts b/src/lib/core/components/Form/hooks/useSearchStore.ts new file mode 100644 index 00000000..d3621220 --- /dev/null +++ b/src/lib/core/components/Form/hooks/useSearchStore.ts @@ -0,0 +1,63 @@ +import React from 'react'; + +import _ from 'lodash'; + +import {SearchStore} from './useSearchContext'; + +const searchParentName = (name: string) => { + const index = name.lastIndexOf('.'); + if (index !== -1) { + return name.substring(0, index); + } + return undefined; +}; + +export const useSearchStore = (name: string) => { + const [store, setStore] = React.useState({[name]: true}); + + const isShowFieldByName = React.useCallback( + (name: string) => { + const storeSearch = store[name]; + if (storeSearch) { + return storeSearch; + } + + let parentName = searchParentName(name); + + if (parentName) { + for (let i = 0; i < name.split('.').length - 1; i++) { + if (store[parentName]) { + return true; + } + + parentName = searchParentName(parentName); + + if (!parentName) { + break; + } + } + } + + for (const key of Object.keys(store)) { + if (key.includes(name)) { + if (store[key]) { + return true; + } + } + } + + return false; + }, + [name, store], + ); + + return { + store, + onChangeStore: (name: string, search: boolean) => + setStore((store) => ({...store, [name]: search})), + onDeleteField: (name: string) => { + setStore((store) => _.omit(store, name)); + }, + isShowFieldByName, + }; +}; diff --git a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss index 47e1e07d..41096f6c 100644 --- a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss +++ b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss @@ -3,6 +3,21 @@ .#{$ns}table-array { &__table { margin-bottom: 10px; + + .yc-table__cell { + border-bottom-color: transparent; + } + } + + &__row { + .yc-table__cell { + border-bottom-color: transparent; + border-top: 1px solid var(--yc-color-line-generic); + } + + &_hide { + display: none; + } } &__cell { diff --git a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx index 2642fe8c..f5652cd5 100644 --- a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx +++ b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx @@ -15,12 +15,14 @@ import { OBJECT_ARRAY_FLAG, ObjectValue, REMOVED_ITEM, + Spec, ValidateError, isArraySpec, isBooleanSpec, isObjectSpec, transformArrIn, } from '../../../../core'; +import {useSearchContext} from '../../../../core/components/Form/hooks'; import {block} from '../../../utils'; import './TableArrayInput.scss'; @@ -28,6 +30,28 @@ import './TableArrayInput.scss'; const b = block('table-array'); export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => { + const {isShowFieldByName} = useSearchContext(); + + const titleField = React.useMemo( + () => spec.viewSpec.table?.map(({label}) => label), + [spec.viewSpec.table], + ); + + const getPreparedSpec = React.useCallback( + (entitySpec: Spec, id: number) => { + const preparedEntitySpec = { + ...entitySpec, + viewSpec: { + ...entitySpec.viewSpec, + layoutTitle: titleField?.join(` ${id} `), + }, + }; + + return preparedEntitySpec; + }, + [titleField], + ); + const keys = React.useMemo( () => Object.keys(arrayInput.value || {}) @@ -106,19 +130,21 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => const columns = table.map(({property, label}) => ({ id: property, name: label, - template: (key: FieldValue) => { + template: (key: FieldValue, idx: number) => { const entitySpec = items?.properties?.[property]; if (!entitySpec) { return null; } + const preparedEntitySpec = getPreparedSpec(entitySpec, idx + 1); + return (
.${property}`} > @@ -126,7 +152,7 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => initialValue={ (input.value?.[`<${key}>`] as FieldObjectValue)?.[property] } - spec={entitySpec} + spec={preparedEntitySpec} name={`${name}.<${key}>.${property}`} parentOnChange={parentOnChange} /> @@ -138,6 +164,15 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => return [idxColumn, ...columns, removeColumn]; }, [name, spec, onItemRemove, parentOnChange, input.value]); + const rowClassNames = React.useCallback( + (item: ObjectValue) => { + const searchResult = isShowFieldByName(`${name}.<${item}>`); + + return [b('row', {hide: !searchResult})]; + }, + [isShowFieldByName, name], + ); + if (!columns) { return null; } @@ -151,6 +186,7 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => columns={columns as any} getRowId={(_, idx) => `${name}-${idx}`} verticalAlign="top" + getRowClassNames={rowClassNames} /> ) : null} {!arrayInput.value && spec.defaultValue ? ( diff --git a/src/stories/components/DynamicField/DynamicField.tsx b/src/stories/components/DynamicField/DynamicField.tsx index 3497c697..ab7f22b0 100644 --- a/src/stories/components/DynamicField/DynamicField.tsx +++ b/src/stories/components/DynamicField/DynamicField.tsx @@ -3,15 +3,22 @@ import React from 'react'; import _ from 'lodash'; import MonacoEditor from 'react-monaco-editor'; -import {DynamicField as BaseDynamicField, Spec, dynamicConfig, prepareSpec} from '../../../lib'; +import { + DynamicField as BaseDynamicField, + FieldValue, + Spec, + dynamicConfig, + prepareSpec, +} from '../../../lib'; import {SpecSelector} from '../InputPreview/SpecSelector'; export interface DynamicFieldProps { name: string; spec: Spec; + search?: string | ((spec: Spec, input: FieldValue, name: string) => boolean); } -export const DynamicField: React.FC = ({name, spec}) => { +export const DynamicField: React.FC = ({name, spec, search}) => { const config = React.useMemo(() => { const cfg = _.cloneDeep(dynamicConfig); @@ -26,6 +33,7 @@ export const DynamicField: React.FC = ({name, spec}) => { spec={prepareSpec(spec, true)} config={config} Monaco={MonacoEditor} + search={search} /> ); }; From 490224ca132227843e72b94c9a4663ba5433cac7 Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Tue, 21 Mar 2023 14:32:59 +0100 Subject: [PATCH 02/12] fix: corrected remarks --- src/lib/core/components/Form/DynamicField.tsx | 19 ++++------ src/lib/core/components/Form/hooks/index.tsx | 2 +- .../components/Form/hooks/useComponents.tsx | 2 +- .../Form/hooks/useCreateSearchContext.ts | 9 +++++ .../core/components/Form/hooks/useField.tsx | 2 +- .../Form/hooks/useSearch/useSearch.scss | 2 +- .../Form/hooks/useSearch/useSearch.tsx | 12 +++--- .../components/Form/hooks/useSearchContext.ts | 21 +---------- .../components/Form/hooks/useSearchStore.ts | 33 +++++++---------- .../core/components/Form/hooks/useStore.tsx | 2 +- .../core/components/Form/hooks/useValidate.ts | 2 +- src/lib/core/components/Form/index.ts | 2 +- src/lib/core/components/Form/types/index.ts | 1 + src/lib/core/components/Form/types/search.ts | 15 ++++++++ .../Form/{helpers.ts => utils/common.ts} | 7 ++-- src/lib/core/components/Form/utils/index.ts | 2 + .../defaultSearch.ts => utils/search.ts} | 8 ++++ .../TableArrayInput/TableArrayInput.tsx | 8 ++-- .../components/Inputs/TextArea/TextArea.scss | 7 ++++ .../components/Inputs/TextArea/TextArea.tsx | 6 +++ .../components/InputPreview/InputPreview.scss | 9 +++++ .../components/InputPreview/InputPreview.tsx | 37 ++++++++++++++++++- 22 files changed, 133 insertions(+), 75 deletions(-) create mode 100644 src/lib/core/components/Form/hooks/useCreateSearchContext.ts create mode 100644 src/lib/core/components/Form/types/search.ts rename src/lib/core/components/Form/{helpers.ts => utils/common.ts} (95%) create mode 100644 src/lib/core/components/Form/utils/index.ts rename src/lib/core/components/Form/{hooks/defaultSearch.ts => utils/search.ts} (55%) create mode 100644 src/lib/kit/components/Inputs/TextArea/TextArea.scss diff --git a/src/lib/core/components/Form/DynamicField.tsx b/src/lib/core/components/Form/DynamicField.tsx index 9f6bffc4..463d5eb0 100644 --- a/src/lib/core/components/Form/DynamicField.tsx +++ b/src/lib/core/components/Form/DynamicField.tsx @@ -8,16 +8,11 @@ import {isCorrectSpec} from '../../helpers'; import {Spec} from '../../types'; import {Controller} from './Controller'; -import {isCorrectConfig} from './helpers'; -import { - defaultSearch, - useCreateContext, - useCreateSearchContext, - useSearchStore, - useStore, -} from './hooks'; +import {useCreateContext, useCreateSearchContext, useSearchStore, useStore} from './hooks'; import {DynamicFormConfig, FieldValue} from './types'; +import {defaultSearch, isCorrectConfig} from '.'; + export interface DynamicFieldProps { name: string; spec: Spec; @@ -30,10 +25,10 @@ export const DynamicField: React.FC = ({name, spec, config, M const DynamicFormsCtx = useCreateContext(); const SearchContext = useCreateSearchContext(); const {tools, watcher} = useStore(name); - const {store, onChangeStore, onDeleteField, isShowFieldByName} = useSearchStore(name); + const {store, onChangeStore, onDeleteField, isHidden} = useSearchStore(name); const searchFunction = React.useMemo( - () => (typeof search === 'string' ? defaultSearch(search) : search), + () => (_.isString(search) ? defaultSearch(search) : search), [search], ); @@ -52,9 +47,9 @@ export const DynamicField: React.FC = ({name, spec, config, M onChangeStore, searchFunction, onDeleteField, - isShowFieldByName, + isHidden, }), - [isShowFieldByName, onChangeStore, onDeleteField, searchFunction, store], + [isHidden, onChangeStore, onDeleteField, searchFunction, store], ); const correctParams = React.useMemo( diff --git a/src/lib/core/components/Form/hooks/index.tsx b/src/lib/core/components/Form/hooks/index.tsx index 1e1bf5a7..53418765 100644 --- a/src/lib/core/components/Form/hooks/index.tsx +++ b/src/lib/core/components/Form/hooks/index.tsx @@ -9,4 +9,4 @@ export * from './useMonaco'; export * from './useSearchStore'; export * from './useSearchContext'; export * from './useSearch'; -export * from './defaultSearch'; +export * from './useCreateSearchContext'; diff --git a/src/lib/core/components/Form/hooks/useComponents.tsx b/src/lib/core/components/Form/hooks/useComponents.tsx index 2ecf1a24..1b8555a5 100644 --- a/src/lib/core/components/Form/hooks/useComponents.tsx +++ b/src/lib/core/components/Form/hooks/useComponents.tsx @@ -3,9 +3,9 @@ import React from 'react'; import _ from 'lodash'; import {isValidElementType} from 'react-is'; +import {isCorrectConfig} from '..'; import {isCorrectSpec} from '../../../helpers'; import {FormValue, Spec} from '../../../types'; -import {isCorrectConfig} from '../helpers'; import {FieldValue, IndependentInputEntity, InputEntity, LayoutType, TypeConfig} from '../types'; import {useDynamicFormsCtx} from './'; diff --git a/src/lib/core/components/Form/hooks/useCreateSearchContext.ts b/src/lib/core/components/Form/hooks/useCreateSearchContext.ts new file mode 100644 index 00000000..40181e00 --- /dev/null +++ b/src/lib/core/components/Form/hooks/useCreateSearchContext.ts @@ -0,0 +1,9 @@ +import React from 'react'; + +import _ from 'lodash'; + +import {SearchContext} from '../types'; + +const createContext = _.once(() => React.createContext({} as unknown as SearchContext)); + +export const useCreateSearchContext = () => createContext(); diff --git a/src/lib/core/components/Form/hooks/useField.tsx b/src/lib/core/components/Form/hooks/useField.tsx index fc6a88f4..c62cdd57 100644 --- a/src/lib/core/components/Form/hooks/useField.tsx +++ b/src/lib/core/components/Form/hooks/useField.tsx @@ -2,10 +2,10 @@ import React from 'react'; import _ from 'lodash'; +import {isArrayItem, transformArrIn, transformArrOut} from '..'; import {isArraySpec, isObjectSpec} from '../../../helpers'; import {Spec} from '../../../types'; import {OBJECT_ARRAY_CNT, OBJECT_ARRAY_FLAG, REMOVED_ITEM} from '../constants'; -import {isArrayItem, transformArrIn, transformArrOut} from '../helpers'; import { DynamicFormsContext, FieldArrayValue, diff --git a/src/lib/core/components/Form/hooks/useSearch/useSearch.scss b/src/lib/core/components/Form/hooks/useSearch/useSearch.scss index 9f76ed09..98f02a9a 100644 --- a/src/lib/core/components/Form/hooks/useSearch/useSearch.scss +++ b/src/lib/core/components/Form/hooks/useSearch/useSearch.scss @@ -1,6 +1,6 @@ @import '../../../../../kit/styles/variables.scss'; -.#{$ns}search-wrapper { +.#{$ns}use-search { margin-bottom: 15px; display: block; diff --git a/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx b/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx index c4d99945..2dc78720 100644 --- a/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx +++ b/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx @@ -7,13 +7,13 @@ import {useSearchContext} from '../useSearchContext'; import './useSearch.scss'; -const b = block('search-wrapper'); +const b = block('use-search'); export const useSearch = (spec: Spec, value: FieldValue, name: string) => { - const {searchFunction, onChangeStore, onDeleteField, isShowFieldByName} = useSearchContext(); + const {searchFunction, onChangeStore, onDeleteField, isHidden} = useSearchContext(); const searchResult = React.useMemo( - () => (searchFunction ? searchFunction(spec, value, name) : true), + () => (searchFunction ? !searchFunction(spec, value, name) : false), [name, searchFunction, spec, value], ); @@ -25,11 +25,11 @@ export const useSearch = (spec: Spec, value: FieldValue, name: string) => { return () => onDeleteField(name); }, []); - const isShow = React.useMemo(() => isShowFieldByName(name), [isShowFieldByName, name]); + const hide = React.useMemo(() => isHidden(name), [isHidden, name]); const searchWrapper = React.useCallback( - (children: JSX.Element | null) => {children}, - [isShow], + (children: JSX.Element | null) => {children}, + [hide], ); return searchWrapper; diff --git a/src/lib/core/components/Form/hooks/useSearchContext.ts b/src/lib/core/components/Form/hooks/useSearchContext.ts index 4b64cd90..7334b6b6 100644 --- a/src/lib/core/components/Form/hooks/useSearchContext.ts +++ b/src/lib/core/components/Form/hooks/useSearchContext.ts @@ -1,25 +1,6 @@ import React from 'react'; -import _ from 'lodash'; - -import {Spec} from '../../../types'; -import {FieldValue} from '../types'; - -export type SearchStore = { - [key: string]: boolean; -}; - -export interface SearchContext { - store?: SearchStore; - onChangeStore: (name: string, search: boolean) => void; - searchFunction?: (spec: Spec, value: FieldValue, name: string) => boolean; - onDeleteField: (name: string) => void; - isShowFieldByName: (name: string) => boolean; -} - -const createContext = _.once(() => React.createContext({} as unknown as SearchContext)); - -export const useCreateSearchContext = () => createContext(); +import {useCreateSearchContext} from '.'; export const useSearchContext = () => { const SearchContext = useCreateSearchContext(); diff --git a/src/lib/core/components/Form/hooks/useSearchStore.ts b/src/lib/core/components/Form/hooks/useSearchStore.ts index d3621220..3189199c 100644 --- a/src/lib/core/components/Form/hooks/useSearchStore.ts +++ b/src/lib/core/components/Form/hooks/useSearchStore.ts @@ -2,32 +2,25 @@ import React from 'react'; import _ from 'lodash'; -import {SearchStore} from './useSearchContext'; - -const searchParentName = (name: string) => { - const index = name.lastIndexOf('.'); - if (index !== -1) { - return name.substring(0, index); - } - return undefined; -}; +import {SearchStore, searchParentName} from '../'; export const useSearchStore = (name: string) => { const [store, setStore] = React.useState({[name]: true}); - const isShowFieldByName = React.useCallback( + const isHidden = React.useCallback( (name: string) => { const storeSearch = store[name]; - if (storeSearch) { - return storeSearch; + + if (!storeSearch && storeSearch !== undefined) { + return false; } let parentName = searchParentName(name); if (parentName) { for (let i = 0; i < name.split('.').length - 1; i++) { - if (store[parentName]) { - return true; + if (!store[parentName]) { + return false; } parentName = searchParentName(parentName); @@ -39,16 +32,16 @@ export const useSearchStore = (name: string) => { } for (const key of Object.keys(store)) { - if (key.includes(name)) { - if (store[key]) { - return true; + if (key.includes(name + '.')) { + if (!store[key]) { + return false; } } } - return false; + return true; }, - [name, store], + [store], ); return { @@ -58,6 +51,6 @@ export const useSearchStore = (name: string) => { onDeleteField: (name: string) => { setStore((store) => _.omit(store, name)); }, - isShowFieldByName, + isHidden, }; }; diff --git a/src/lib/core/components/Form/hooks/useStore.tsx b/src/lib/core/components/Form/hooks/useStore.tsx index bea8cfc6..2faedbf2 100644 --- a/src/lib/core/components/Form/hooks/useStore.tsx +++ b/src/lib/core/components/Form/hooks/useStore.tsx @@ -3,7 +3,7 @@ import React from 'react'; import _ from 'lodash'; import {Field as FinalFormField, useForm} from 'react-final-form'; -import {transformArrIn, transformArrOut} from '../helpers'; +import {transformArrIn, transformArrOut} from '..'; import { AsyncValidateError, BaseValidateError, diff --git a/src/lib/core/components/Form/hooks/useValidate.ts b/src/lib/core/components/Form/hooks/useValidate.ts index 59eeb3a6..bf9339dc 100644 --- a/src/lib/core/components/Form/hooks/useValidate.ts +++ b/src/lib/core/components/Form/hooks/useValidate.ts @@ -2,9 +2,9 @@ import React from 'react'; import _ from 'lodash'; +import {isCorrectConfig} from '..'; import {isCorrectSpec} from '../../../helpers'; import {FormValue, Spec} from '../../../types'; -import {isCorrectConfig} from '../helpers'; import {FieldValue, TypeConfig} from '../types'; import {useDynamicFormsCtx} from './'; diff --git a/src/lib/core/components/Form/index.ts b/src/lib/core/components/Form/index.ts index 75c52bb2..515d1629 100644 --- a/src/lib/core/components/Form/index.ts +++ b/src/lib/core/components/Form/index.ts @@ -1,5 +1,5 @@ export * from './constants'; export * from './Controller'; export * from './DynamicField'; -export * from './helpers'; export * from './types'; +export * from './utils'; diff --git a/src/lib/core/components/Form/types/index.ts b/src/lib/core/components/Form/types/index.ts index fd4a313b..cf90abd6 100644 --- a/src/lib/core/components/Form/types/index.ts +++ b/src/lib/core/components/Form/types/index.ts @@ -10,3 +10,4 @@ export * from './object'; export * from './string'; export * from './validators'; export * from './value'; +export * from './search'; diff --git a/src/lib/core/components/Form/types/search.ts b/src/lib/core/components/Form/types/search.ts new file mode 100644 index 00000000..c346a366 --- /dev/null +++ b/src/lib/core/components/Form/types/search.ts @@ -0,0 +1,15 @@ +import {Spec} from '../../../types'; + +import {FieldValue} from './value'; + +export type SearchStore = { + [key: string]: boolean; +}; + +export interface SearchContext { + store?: SearchStore; + onChangeStore: (name: string, search: boolean) => void; + searchFunction?: (spec: Spec, value: FieldValue, name: string) => boolean; + onDeleteField: (name: string) => void; + isHidden: (name: string) => boolean; +} diff --git a/src/lib/core/components/Form/helpers.ts b/src/lib/core/components/Form/utils/common.ts similarity index 95% rename from src/lib/core/components/Form/helpers.ts rename to src/lib/core/components/Form/utils/common.ts index 735d9166..613a073d 100644 --- a/src/lib/core/components/Form/helpers.ts +++ b/src/lib/core/components/Form/utils/common.ts @@ -1,9 +1,8 @@ import _ from 'lodash'; -import {SpecTypes} from '../../constants'; -import {FormValue, ObjectValue} from '../../types'; - -import {OBJECT_ARRAY_CNT, OBJECT_ARRAY_FLAG, REMOVED_ITEM} from './constants'; +import {SpecTypes} from '../../../constants'; +import {FormValue, ObjectValue} from '../../../types'; +import {OBJECT_ARRAY_CNT, OBJECT_ARRAY_FLAG, REMOVED_ITEM} from '../constants'; export const isCorrectConfig = (candidate: any) => Object.values(SpecTypes).every( diff --git a/src/lib/core/components/Form/utils/index.ts b/src/lib/core/components/Form/utils/index.ts new file mode 100644 index 00000000..b14538f0 --- /dev/null +++ b/src/lib/core/components/Form/utils/index.ts @@ -0,0 +1,2 @@ +export * from './common'; +export * from './search'; diff --git a/src/lib/core/components/Form/hooks/defaultSearch.ts b/src/lib/core/components/Form/utils/search.ts similarity index 55% rename from src/lib/core/components/Form/hooks/defaultSearch.ts rename to src/lib/core/components/Form/utils/search.ts index 8de94949..123a5af3 100644 --- a/src/lib/core/components/Form/hooks/defaultSearch.ts +++ b/src/lib/core/components/Form/utils/search.ts @@ -1,5 +1,13 @@ import {Spec} from '../../../types'; +export const searchParentName = (name: string) => { + const index = name.lastIndexOf('.'); + if (index !== -1) { + return name.substring(0, index); + } + return undefined; +}; + export const defaultSearch = (search: string) => (spec: Spec) => spec?.viewSpec.layoutTitle ? spec?.viewSpec.layoutTitle.toLowerCase().includes(search.toLowerCase()) diff --git a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx index f5652cd5..86337132 100644 --- a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx +++ b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx @@ -30,7 +30,7 @@ import './TableArrayInput.scss'; const b = block('table-array'); export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => { - const {isShowFieldByName} = useSearchContext(); + const {isHidden} = useSearchContext(); const titleField = React.useMemo( () => spec.viewSpec.table?.map(({label}) => label), @@ -166,11 +166,11 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => const rowClassNames = React.useCallback( (item: ObjectValue) => { - const searchResult = isShowFieldByName(`${name}.<${item}>`); + const searchResult = isHidden(`${name}.<${item}>`); - return [b('row', {hide: !searchResult})]; + return [b('row', {hide: searchResult})]; }, - [isShowFieldByName, name], + [isHidden, name], ); if (!columns) { diff --git a/src/lib/kit/components/Inputs/TextArea/TextArea.scss b/src/lib/kit/components/Inputs/TextArea/TextArea.scss new file mode 100644 index 00000000..95f52de6 --- /dev/null +++ b/src/lib/kit/components/Inputs/TextArea/TextArea.scss @@ -0,0 +1,7 @@ +@import '../../../styles/variables'; + +.#{$ns}text-area { + .yc-text-input__control { + min-height: 142px; + } +} diff --git a/src/lib/kit/components/Inputs/TextArea/TextArea.tsx b/src/lib/kit/components/Inputs/TextArea/TextArea.tsx index 4d782471..3c333685 100644 --- a/src/lib/kit/components/Inputs/TextArea/TextArea.tsx +++ b/src/lib/kit/components/Inputs/TextArea/TextArea.tsx @@ -3,6 +3,11 @@ import React from 'react'; import {TextInput as TextInputBase} from '@gravity-ui/uikit'; import {StringInput} from '../../../../core'; +import {block} from '../../../utils'; + +import './TextArea.scss'; + +const b = block('text-area'); export const TextArea: StringInput = ({input, spec}) => { const {value, onBlur, onChange, onFocus} = input; @@ -19,6 +24,7 @@ export const TextArea: StringInput = ({input, spec}) => { disabled={spec.viewSpec.disabled} multiline placeholder={spec.viewSpec.placeholder} + className={b()} /> ); }; diff --git a/src/stories/components/InputPreview/InputPreview.scss b/src/stories/components/InputPreview/InputPreview.scss index 7508fa91..8160b7c7 100644 --- a/src/stories/components/InputPreview/InputPreview.scss +++ b/src/stories/components/InputPreview/InputPreview.scss @@ -63,4 +63,13 @@ display: none; } } + + &__search { + border-bottom: 1px solid var(--yc-color-line-generic); + margin-bottom: 20px; + + &-input { + margin-bottom: 5px; + } + } } diff --git a/src/stories/components/InputPreview/InputPreview.tsx b/src/stories/components/InputPreview/InputPreview.tsx index d3578146..adbadcc8 100644 --- a/src/stories/components/InputPreview/InputPreview.tsx +++ b/src/stories/components/InputPreview/InputPreview.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {RadioButton} from '@gravity-ui/uikit'; +import {RadioButton, TextInput} from '@gravity-ui/uikit'; import block from 'bem-cn-lite'; import _ from 'lodash'; import {Form} from 'react-final-form'; @@ -29,6 +29,8 @@ export const InputPreview: React.FC = ({ excludeOptions, viewMode, }) => { + const [searchOptions, setSearchOptions] = React.useState(''); + const [searchInput, setSearchInput] = React.useState(''); const [toggler, setToggler] = React.useState<'form' | 'json'>('form'); const [togglerInput, setTogglerInput] = React.useState<'form' | 'view' | 'json'>('form'); @@ -96,6 +98,14 @@ export const InputPreview: React.FC = ({ [], ); + const searchFunction = React.useCallback( + (spec: Spec) => + spec?.viewSpec.layoutTitle + ? spec?.viewSpec.layoutTitle.toLowerCase().includes(searchOptions.toLowerCase()) + : false, + [searchOptions], + ); + return (
{(form) => ( @@ -113,7 +123,20 @@ export const InputPreview: React.FC = ({ ))}
- +
+ +
+
{toggler === 'json' ? (
@@ -136,9 +159,19 @@ export const InputPreview: React.FC = ({ ))}
+
+ +
From 2206293123c1d52bc93ea88aa5e003d107e5dc1d Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Tue, 21 Mar 2023 12:27:18 +0100 Subject: [PATCH 03/12] fix: input preview search --- .../components/InputPreview/InputPreview.scss | 5 --- .../components/InputPreview/InputPreview.tsx | 32 ++++++++----------- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/stories/components/InputPreview/InputPreview.scss b/src/stories/components/InputPreview/InputPreview.scss index 8160b7c7..8a19cfa7 100644 --- a/src/stories/components/InputPreview/InputPreview.scss +++ b/src/stories/components/InputPreview/InputPreview.scss @@ -65,11 +65,6 @@ } &__search { - border-bottom: 1px solid var(--yc-color-line-generic); margin-bottom: 20px; - - &-input { - margin-bottom: 5px; - } } } diff --git a/src/stories/components/InputPreview/InputPreview.tsx b/src/stories/components/InputPreview/InputPreview.tsx index adbadcc8..ec9f2328 100644 --- a/src/stories/components/InputPreview/InputPreview.tsx +++ b/src/stories/components/InputPreview/InputPreview.tsx @@ -123,15 +123,13 @@ export const InputPreview: React.FC = ({ ))}
-
- -
+ = ({ ))}
-
- -
+ Date: Tue, 21 Mar 2023 14:56:13 +0100 Subject: [PATCH 04/12] fix: import path --- src/lib/core/components/Form/DynamicField.tsx | 3 +-- src/lib/core/components/Form/hooks/useComponents.tsx | 2 +- src/lib/core/components/Form/hooks/useField.tsx | 2 +- src/lib/core/components/Form/hooks/useSearchContext.ts | 2 +- src/lib/core/components/Form/hooks/useStore.tsx | 2 +- src/lib/core/components/Form/hooks/useValidate.ts | 2 +- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/lib/core/components/Form/DynamicField.tsx b/src/lib/core/components/Form/DynamicField.tsx index 463d5eb0..485b501f 100644 --- a/src/lib/core/components/Form/DynamicField.tsx +++ b/src/lib/core/components/Form/DynamicField.tsx @@ -10,8 +10,7 @@ import {Spec} from '../../types'; import {Controller} from './Controller'; import {useCreateContext, useCreateSearchContext, useSearchStore, useStore} from './hooks'; import {DynamicFormConfig, FieldValue} from './types'; - -import {defaultSearch, isCorrectConfig} from '.'; +import {defaultSearch, isCorrectConfig} from './utils'; export interface DynamicFieldProps { name: string; diff --git a/src/lib/core/components/Form/hooks/useComponents.tsx b/src/lib/core/components/Form/hooks/useComponents.tsx index 1b8555a5..460fcb9a 100644 --- a/src/lib/core/components/Form/hooks/useComponents.tsx +++ b/src/lib/core/components/Form/hooks/useComponents.tsx @@ -3,10 +3,10 @@ import React from 'react'; import _ from 'lodash'; import {isValidElementType} from 'react-is'; -import {isCorrectConfig} from '..'; import {isCorrectSpec} from '../../../helpers'; import {FormValue, Spec} from '../../../types'; import {FieldValue, IndependentInputEntity, InputEntity, LayoutType, TypeConfig} from '../types'; +import {isCorrectConfig} from '../utils'; import {useDynamicFormsCtx} from './'; diff --git a/src/lib/core/components/Form/hooks/useField.tsx b/src/lib/core/components/Form/hooks/useField.tsx index c62cdd57..ca1eab83 100644 --- a/src/lib/core/components/Form/hooks/useField.tsx +++ b/src/lib/core/components/Form/hooks/useField.tsx @@ -2,7 +2,6 @@ import React from 'react'; import _ from 'lodash'; -import {isArrayItem, transformArrIn, transformArrOut} from '..'; import {isArraySpec, isObjectSpec} from '../../../helpers'; import {Spec} from '../../../types'; import {OBJECT_ARRAY_CNT, OBJECT_ARRAY_FLAG, REMOVED_ITEM} from '../constants'; @@ -13,6 +12,7 @@ import { FieldValue, ValidateError, } from '../types'; +import {isArrayItem, transformArrIn, transformArrOut} from '../utils'; export interface FieldProps { name: string; diff --git a/src/lib/core/components/Form/hooks/useSearchContext.ts b/src/lib/core/components/Form/hooks/useSearchContext.ts index 7334b6b6..27fcd56b 100644 --- a/src/lib/core/components/Form/hooks/useSearchContext.ts +++ b/src/lib/core/components/Form/hooks/useSearchContext.ts @@ -1,6 +1,6 @@ import React from 'react'; -import {useCreateSearchContext} from '.'; +import {useCreateSearchContext} from './index'; export const useSearchContext = () => { const SearchContext = useCreateSearchContext(); diff --git a/src/lib/core/components/Form/hooks/useStore.tsx b/src/lib/core/components/Form/hooks/useStore.tsx index 2faedbf2..2806acc7 100644 --- a/src/lib/core/components/Form/hooks/useStore.tsx +++ b/src/lib/core/components/Form/hooks/useStore.tsx @@ -3,7 +3,6 @@ import React from 'react'; import _ from 'lodash'; import {Field as FinalFormField, useForm} from 'react-final-form'; -import {transformArrIn, transformArrOut} from '..'; import { AsyncValidateError, BaseValidateError, @@ -11,6 +10,7 @@ import { FieldValue, ValidateError, } from '../types'; +import {transformArrIn, transformArrOut} from '../utils'; export interface DynamicFieldStore { name: string; diff --git a/src/lib/core/components/Form/hooks/useValidate.ts b/src/lib/core/components/Form/hooks/useValidate.ts index bf9339dc..f14c25d3 100644 --- a/src/lib/core/components/Form/hooks/useValidate.ts +++ b/src/lib/core/components/Form/hooks/useValidate.ts @@ -2,10 +2,10 @@ import React from 'react'; import _ from 'lodash'; -import {isCorrectConfig} from '..'; import {isCorrectSpec} from '../../../helpers'; import {FormValue, Spec} from '../../../types'; import {FieldValue, TypeConfig} from '../types'; +import {isCorrectConfig} from '../utils'; import {useDynamicFormsCtx} from './'; From 458abf84cd90b7bba0661d91960098404722c1c6 Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Wed, 22 Mar 2023 13:13:42 +0100 Subject: [PATCH 05/12] fix: corrected remarks --- src/lib/core/components/Form/Controller.tsx | 4 +- src/lib/core/components/Form/DynamicField.tsx | 19 ++---- .../Form/hooks/useSearch/useSearch.scss | 7 +- .../Form/hooks/useSearch/useSearch.tsx | 18 ++--- .../components/Form/hooks/useSearchStore.ts | 40 +++++------- src/lib/core/components/Form/types/search.ts | 11 +--- src/lib/core/components/Form/utils/search.ts | 8 +-- .../AccordeonCard/AccordeonCard.scss | 8 +-- src/lib/kit/components/Card/Card.scss | 8 +-- .../kit/components/Inputs/OneOf/OneOf.scss | 14 ---- .../Inputs/OneOfCard/OneOfCard.scss | 4 ++ .../TableArrayInput/TableArrayInput.scss | 6 +- .../TableArrayInput/TableArrayInput.tsx | 65 +++++++++---------- src/lib/kit/components/Layouts/Row/Row.scss | 4 -- src/lib/kit/components/Layouts/Row2/Row2.scss | 4 -- .../components/Layouts/Section/Section.scss | 4 -- .../Layouts/Transparent/Transparent.scss | 4 -- .../SimpleVerticalAccordeon.scss | 4 -- .../components/InputPreview/InputPreview.tsx | 10 ++- 19 files changed, 94 insertions(+), 148 deletions(-) diff --git a/src/lib/core/components/Form/Controller.tsx b/src/lib/core/components/Form/Controller.tsx index b80cc6b0..41303237 100644 --- a/src/lib/core/components/Form/Controller.tsx +++ b/src/lib/core/components/Form/Controller.tsx @@ -31,10 +31,10 @@ export const Controller = ({ const render = useRender({name, spec, inputEntity, Layout}); const validate = useValidate(spec); const renderProps = useField({name, initialValue, spec, validate, tools, parentOnChange}); - const searchWrapper = useSearch(spec, renderProps.input.value, name); + const withSearch = useSearch(spec, renderProps.input.value, name); if (_.isString(name) && isCorrectSpec(spec)) { - return searchWrapper(render(renderProps)); + return withSearch(render(renderProps)); } return null; diff --git a/src/lib/core/components/Form/DynamicField.tsx b/src/lib/core/components/Form/DynamicField.tsx index 485b501f..6b59a409 100644 --- a/src/lib/core/components/Form/DynamicField.tsx +++ b/src/lib/core/components/Form/DynamicField.tsx @@ -10,7 +10,7 @@ import {Spec} from '../../types'; import {Controller} from './Controller'; import {useCreateContext, useCreateSearchContext, useSearchStore, useStore} from './hooks'; import {DynamicFormConfig, FieldValue} from './types'; -import {defaultSearch, isCorrectConfig} from './utils'; +import {getDefaultSearchFunction, isCorrectConfig} from './utils'; export interface DynamicFieldProps { name: string; @@ -24,12 +24,8 @@ export const DynamicField: React.FC = ({name, spec, config, M const DynamicFormsCtx = useCreateContext(); const SearchContext = useCreateSearchContext(); const {tools, watcher} = useStore(name); - const {store, onChangeStore, onDeleteField, isHidden} = useSearchStore(name); - const searchFunction = React.useMemo( - () => (_.isString(search) ? defaultSearch(search) : search), - [search], - ); + const {setField, removeField, isHiddenField} = useSearchStore(name); const context = React.useMemo( () => ({ @@ -42,13 +38,12 @@ export const DynamicField: React.FC = ({name, spec, config, M const searchContext = React.useMemo( () => ({ - store, - onChangeStore, - searchFunction, - onDeleteField, - isHidden, + setField, + removeField, + isHiddenField, + searchFunction: _.isString(search) ? getDefaultSearchFunction(search) : search, }), - [isHidden, onChangeStore, onDeleteField, searchFunction, store], + [isHiddenField, removeField, search, setField], ); const correctParams = React.useMemo( diff --git a/src/lib/core/components/Form/hooks/useSearch/useSearch.scss b/src/lib/core/components/Form/hooks/useSearch/useSearch.scss index 98f02a9a..c7361966 100644 --- a/src/lib/core/components/Form/hooks/useSearch/useSearch.scss +++ b/src/lib/core/components/Form/hooks/useSearch/useSearch.scss @@ -1,14 +1,11 @@ @import '../../../../../kit/styles/variables.scss'; .#{$ns}use-search { - margin-bottom: 15px; - display: block; - - &_hide { + &_hidden { display: none; } - &:last-child { + &:last-child > * { margin-bottom: 0; } } diff --git a/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx b/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx index 2dc78720..a3bbfff5 100644 --- a/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx +++ b/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx @@ -1,8 +1,8 @@ import React from 'react'; -import {FieldValue} from '../..'; import {block} from '../../../../../kit/utils'; import {Spec} from '../../../../types'; +import {FieldValue} from '../../types'; import {useSearchContext} from '../useSearchContext'; import './useSearch.scss'; @@ -10,27 +10,27 @@ import './useSearch.scss'; const b = block('use-search'); export const useSearch = (spec: Spec, value: FieldValue, name: string) => { - const {searchFunction, onChangeStore, onDeleteField, isHidden} = useSearchContext(); + const {setField, removeField, isHiddenField, searchFunction} = useSearchContext(); const searchResult = React.useMemo( () => (searchFunction ? !searchFunction(spec, value, name) : false), [name, searchFunction, spec, value], ); + const hide = React.useMemo(() => isHiddenField(name), [isHiddenField, name]); + React.useEffect(() => { - onChangeStore(name, searchResult); + setField(name, searchResult); }, [searchResult]); React.useEffect(() => { - return () => onDeleteField(name); + return () => removeField(name); }, []); - const hide = React.useMemo(() => isHidden(name), [isHidden, name]); - - const searchWrapper = React.useCallback( - (children: JSX.Element | null) => {children}, + const withSearch = React.useCallback( + (children: JSX.Element | null) => {children}, [hide], ); - return searchWrapper; + return withSearch; }; diff --git a/src/lib/core/components/Form/hooks/useSearchStore.ts b/src/lib/core/components/Form/hooks/useSearchStore.ts index 3189199c..b8401829 100644 --- a/src/lib/core/components/Form/hooks/useSearchStore.ts +++ b/src/lib/core/components/Form/hooks/useSearchStore.ts @@ -2,40 +2,32 @@ import React from 'react'; import _ from 'lodash'; -import {SearchStore, searchParentName} from '../'; +import {getParentName} from '../'; export const useSearchStore = (name: string) => { - const [store, setStore] = React.useState({[name]: true}); + const [store, setStore] = React.useState({[name]: false}); - const isHidden = React.useCallback( + const isHiddenField = React.useCallback( (name: string) => { - const storeSearch = store[name]; + const selfFlag = store[name]; - if (!storeSearch && storeSearch !== undefined) { + if (selfFlag === false) { return false; } - let parentName = searchParentName(name); + let parentName = getParentName(name); - if (parentName) { - for (let i = 0; i < name.split('.').length - 1; i++) { - if (!store[parentName]) { - return false; - } - - parentName = searchParentName(parentName); - - if (!parentName) { - break; - } + while (parentName) { + if (store[parentName] === false) { + return false; } + + parentName = getParentName(parentName); } for (const key of Object.keys(store)) { - if (key.includes(name + '.')) { - if (!store[key]) { - return false; - } + if (key.includes(name + '.') && !store[key]) { + return false; } } @@ -46,11 +38,11 @@ export const useSearchStore = (name: string) => { return { store, - onChangeStore: (name: string, search: boolean) => + setField: (name: string, search: boolean) => setStore((store) => ({...store, [name]: search})), - onDeleteField: (name: string) => { + removeField: (name: string) => { setStore((store) => _.omit(store, name)); }, - isHidden, + isHiddenField, }; }; diff --git a/src/lib/core/components/Form/types/search.ts b/src/lib/core/components/Form/types/search.ts index c346a366..1848e279 100644 --- a/src/lib/core/components/Form/types/search.ts +++ b/src/lib/core/components/Form/types/search.ts @@ -2,14 +2,9 @@ import {Spec} from '../../../types'; import {FieldValue} from './value'; -export type SearchStore = { - [key: string]: boolean; -}; - export interface SearchContext { - store?: SearchStore; - onChangeStore: (name: string, search: boolean) => void; + setField: (name: string, search: boolean) => void; + removeField: (name: string) => void; + isHiddenField: (name: string) => boolean; searchFunction?: (spec: Spec, value: FieldValue, name: string) => boolean; - onDeleteField: (name: string) => void; - isHidden: (name: string) => boolean; } diff --git a/src/lib/core/components/Form/utils/search.ts b/src/lib/core/components/Form/utils/search.ts index 123a5af3..3db3b6e1 100644 --- a/src/lib/core/components/Form/utils/search.ts +++ b/src/lib/core/components/Form/utils/search.ts @@ -1,6 +1,6 @@ import {Spec} from '../../../types'; -export const searchParentName = (name: string) => { +export const getParentName = (name: string) => { const index = name.lastIndexOf('.'); if (index !== -1) { return name.substring(0, index); @@ -8,7 +8,5 @@ export const searchParentName = (name: string) => { return undefined; }; -export const defaultSearch = (search: string) => (spec: Spec) => - spec?.viewSpec.layoutTitle - ? spec?.viewSpec.layoutTitle.toLowerCase().includes(search.toLowerCase()) - : false; +export const getDefaultSearchFunction = (search: string) => (spec: Spec) => + Boolean((spec.viewSpec.layoutTitle || '').toLowerCase().includes(search.trim().toLowerCase())); diff --git a/src/lib/kit/components/AccordeonCard/AccordeonCard.scss b/src/lib/kit/components/AccordeonCard/AccordeonCard.scss index 4894e7da..3eaceeed 100644 --- a/src/lib/kit/components/AccordeonCard/AccordeonCard.scss +++ b/src/lib/kit/components/AccordeonCard/AccordeonCard.scss @@ -15,10 +15,6 @@ box-shadow: 0 3px 10px var(--yc-color-sfx-shadow); } - &:last-child { - margin-bottom: 0; - } - &_empty { .#{$ns}accordeon-card__body, .#{$ns}accordeon-card__header-toggle-btn { @@ -85,6 +81,10 @@ justify-content: flex-end; order: 1; } + + > * { + margin-bottom: 0px; + } } &__interal-actions { diff --git a/src/lib/kit/components/Card/Card.scss b/src/lib/kit/components/Card/Card.scss index cf307c3f..2c856605 100644 --- a/src/lib/kit/components/Card/Card.scss +++ b/src/lib/kit/components/Card/Card.scss @@ -3,10 +3,6 @@ .#{$ns}card { margin-bottom: 20px; - &:last-child { - margin-bottom: 0; - } - .#{$ns}row { width: 100%; max-width: unset; @@ -51,6 +47,10 @@ &__header-left { display: flex; align-items: center; + + > * { + margin-bottom: 0px; + } } &__header-right { diff --git a/src/lib/kit/components/Inputs/OneOf/OneOf.scss b/src/lib/kit/components/Inputs/OneOf/OneOf.scss index b283dccf..c9d3ef8b 100644 --- a/src/lib/kit/components/Inputs/OneOf/OneOf.scss +++ b/src/lib/kit/components/Inputs/OneOf/OneOf.scss @@ -3,18 +3,4 @@ .#{$ns}oneof { display: flex; flex-direction: column-reverse; - - &:last-child { - & > .#{$ns}group-indent { - margin-bottom: 0; - - &:empty + .#{$ns}oneof__toggler { - margin-bottom: 0; - } - } - } - - &__toggler { - margin-bottom: 15px; - } } diff --git a/src/lib/kit/components/Inputs/OneOfCard/OneOfCard.scss b/src/lib/kit/components/Inputs/OneOfCard/OneOfCard.scss index e7dd9931..451da2fe 100644 --- a/src/lib/kit/components/Inputs/OneOfCard/OneOfCard.scss +++ b/src/lib/kit/components/Inputs/OneOfCard/OneOfCard.scss @@ -6,4 +6,8 @@ .df-accordeon-card__header-toggle-btn { margin-left: 5px; } + + &__title { + margin-bottom: 0; + } } diff --git a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss index 41096f6c..329c8d22 100644 --- a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss +++ b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss @@ -5,17 +5,17 @@ margin-bottom: 10px; .yc-table__cell { - border-bottom-color: transparent; + border-bottom: 0px transparent; } } &__row { .yc-table__cell { - border-bottom-color: transparent; + border-bottom: 0px transparent; border-top: 1px solid var(--yc-color-line-generic); } - &_hide { + &_hidden { display: none; } } diff --git a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx index 86337132..58036015 100644 --- a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx +++ b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx @@ -13,9 +13,7 @@ import { FieldValue, OBJECT_ARRAY_CNT, OBJECT_ARRAY_FLAG, - ObjectValue, REMOVED_ITEM, - Spec, ValidateError, isArraySpec, isBooleanSpec, @@ -30,27 +28,7 @@ import './TableArrayInput.scss'; const b = block('table-array'); export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => { - const {isHidden} = useSearchContext(); - - const titleField = React.useMemo( - () => spec.viewSpec.table?.map(({label}) => label), - [spec.viewSpec.table], - ); - - const getPreparedSpec = React.useCallback( - (entitySpec: Spec, id: number) => { - const preparedEntitySpec = { - ...entitySpec, - viewSpec: { - ...entitySpec.viewSpec, - layoutTitle: titleField?.join(` ${id} `), - }, - }; - - return preparedEntitySpec; - }, - [titleField], - ); + const {isHiddenField} = useSearchContext(); const keys = React.useMemo( () => @@ -62,7 +40,10 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => arrayInput.value[k] !== REMOVED_ITEM, ) .map((k) => k.split('<').join('').split('>').join('')) - .sort((a, b) => Number(a) - Number(b)), + .sort((a, b) => Number(a) - Number(b)) + .map((key) => ({ + key, + })), [arrayInput.value], ); @@ -130,14 +111,28 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => const columns = table.map(({property, label}) => ({ id: property, name: label, - template: (key: FieldValue, idx: number) => { + template: ( + { + key, + }: { + key: string; + }, + idx: number, + ) => { const entitySpec = items?.properties?.[property]; if (!entitySpec) { return null; } - const preparedEntitySpec = getPreparedSpec(entitySpec, idx + 1); + const preparedEntitySpec = { + ...entitySpec, + viewSpec: { + ...entitySpec.viewSpec, + layoutTitle: + table.map(({label}) => label).join(` ${idx + 1} `) + ` ${idx + 1}`, + }, + }; return (
return [idxColumn, ...columns, removeColumn]; }, [name, spec, onItemRemove, parentOnChange, input.value]); - const rowClassNames = React.useCallback( - (item: ObjectValue) => { - const searchResult = isHidden(`${name}.<${item}>`); + const getRowClassNames = React.useCallback( + ({key}: {key: string}) => { + const searchResult = isHiddenField(`${name}.<${key}>`); - return [b('row', {hide: searchResult})]; + return [b('row', {hidden: searchResult})]; }, - [isHidden, name], + [isHiddenField, name], ); if (!columns) { @@ -180,13 +175,13 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => return (
{keys.length ? ( - + `${name}-${idx}`} verticalAlign="top" - getRowClassNames={rowClassNames} + getRowClassNames={getRowClassNames} /> ) : null} {!arrayInput.value && spec.defaultValue ? ( diff --git a/src/lib/kit/components/Layouts/Row/Row.scss b/src/lib/kit/components/Layouts/Row/Row.scss index ee73db06..b802d58d 100644 --- a/src/lib/kit/components/Layouts/Row/Row.scss +++ b/src/lib/kit/components/Layouts/Row/Row.scss @@ -6,10 +6,6 @@ max-width: 500px; margin-bottom: 15px; - &:last-child { - margin-bottom: 0; - } - &_extra-width { width: 533px; max-width: 533px; diff --git a/src/lib/kit/components/Layouts/Row2/Row2.scss b/src/lib/kit/components/Layouts/Row2/Row2.scss index e152c688..ba69b37a 100644 --- a/src/lib/kit/components/Layouts/Row2/Row2.scss +++ b/src/lib/kit/components/Layouts/Row2/Row2.scss @@ -5,10 +5,6 @@ display: flex; margin-bottom: 15px; - &:last-child { - margin-bottom: 0; - } - &__left { width: 180px; min-width: 180px; diff --git a/src/lib/kit/components/Layouts/Section/Section.scss b/src/lib/kit/components/Layouts/Section/Section.scss index 2f2151f6..1d9370aa 100644 --- a/src/lib/kit/components/Layouts/Section/Section.scss +++ b/src/lib/kit/components/Layouts/Section/Section.scss @@ -7,10 +7,6 @@ $block: '.#{$ns}section'; $block: &; - &:last-child { - margin-bottom: 0; - } - &__header { margin-bottom: $normalOffset; diff --git a/src/lib/kit/components/Layouts/Transparent/Transparent.scss b/src/lib/kit/components/Layouts/Transparent/Transparent.scss index e1086e6e..dae58865 100644 --- a/src/lib/kit/components/Layouts/Transparent/Transparent.scss +++ b/src/lib/kit/components/Layouts/Transparent/Transparent.scss @@ -4,10 +4,6 @@ display: flex; margin-bottom: 15px; - &:last-child { - margin-bottom: 0; - } - &_array-item { max-width: 338px; } diff --git a/src/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.scss b/src/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.scss index 50058da9..3f303518 100644 --- a/src/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.scss +++ b/src/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.scss @@ -5,10 +5,6 @@ $animationDuration: 0.3s; .#{$ns}simple-vertical-accordeon { margin-bottom: $normalOffset; - &:last-child { - margin-bottom: 0; - } - &_branch &__body { padding-left: $normalOffset; margin-left: 5px; diff --git a/src/stories/components/InputPreview/InputPreview.tsx b/src/stories/components/InputPreview/InputPreview.tsx index ec9f2328..5d20c847 100644 --- a/src/stories/components/InputPreview/InputPreview.tsx +++ b/src/stories/components/InputPreview/InputPreview.tsx @@ -100,9 +100,11 @@ export const InputPreview: React.FC = ({ const searchFunction = React.useCallback( (spec: Spec) => - spec?.viewSpec.layoutTitle - ? spec?.viewSpec.layoutTitle.toLowerCase().includes(searchOptions.toLowerCase()) - : false, + Boolean( + (spec.viewSpec.layoutTitle || '') + .toLowerCase() + .includes(searchOptions.trim().toLowerCase()), + ), [searchOptions], ); @@ -129,6 +131,7 @@ export const InputPreview: React.FC = ({ value={searchOptions} placeholder="Search by field" className={b('search')} + hasClear /> = ({ value={searchInput} placeholder="Search by field" className={b('search')} + hasClear /> Date: Wed, 22 Mar 2023 13:52:15 +0100 Subject: [PATCH 06/12] fix: fix rebase problems --- .../Inputs/TableArrayInput/TableArrayInput.tsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx index f1519856..ef39234b 100644 --- a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx +++ b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx @@ -91,7 +91,7 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => id: 'idx', name: '', sticky: 'left', - template: (key: FieldValue, idx: number) => ( + template: ({key}: {key: string}, idx: number) => (
{idx + 1}
@@ -102,12 +102,8 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => id: 'remove', name: '', sticky: 'right', - template: (key: FieldValue) => ( - ), From 6a29cf572814f04ba916288f42619e5760e540fc Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Wed, 22 Mar 2023 14:35:36 +0100 Subject: [PATCH 07/12] fix: search function --- src/lib/core/components/Form/DynamicField.tsx | 8 ++++++-- .../components/Form/hooks/useSearch/useSearch.tsx | 14 +++++++------- src/lib/core/components/Form/types/search.ts | 2 +- src/lib/core/components/Form/utils/search.ts | 4 +++- .../components/InputPreview/InputPreview.tsx | 4 ++-- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/lib/core/components/Form/DynamicField.tsx b/src/lib/core/components/Form/DynamicField.tsx index 2edbe5fb..1c822d94 100644 --- a/src/lib/core/components/Form/DynamicField.tsx +++ b/src/lib/core/components/Form/DynamicField.tsx @@ -10,7 +10,7 @@ import {Spec} from '../../types'; import {Controller} from './Controller'; import {useCreateContext, useCreateSearchContext, useSearchStore, useStore} from './hooks'; import {DynamicFormConfig, FieldValue} from './types'; -import {getDefaultSearchFunction, isCorrectConfig} from './utils'; +import {getDefaultSearchFunction, getEmptySearchFunction, isCorrectConfig} from './utils'; export interface DynamicFieldProps { name: string; @@ -41,7 +41,11 @@ export const DynamicField: React.FC = ({name, spec, config, M setField, removeField, isHiddenField, - searchFunction: _.isString(search) ? getDefaultSearchFunction(search) : search, + searchFunction: _.isString(search) + ? getDefaultSearchFunction(search) + : _.isFunction(search) + ? search + : getEmptySearchFunction, }), [isHiddenField, removeField, search, setField], ); diff --git a/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx b/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx index a3bbfff5..8b119e2b 100644 --- a/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx +++ b/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx @@ -13,11 +13,16 @@ export const useSearch = (spec: Spec, value: FieldValue, name: string) => { const {setField, removeField, isHiddenField, searchFunction} = useSearchContext(); const searchResult = React.useMemo( - () => (searchFunction ? !searchFunction(spec, value, name) : false), + () => !searchFunction(spec, value, name), [name, searchFunction, spec, value], ); - const hide = React.useMemo(() => isHiddenField(name), [isHiddenField, name]); + const hidden = React.useMemo(() => isHiddenField(name), [isHiddenField, name]); + + const withSearch = React.useCallback( + (children: JSX.Element | null) => {children}, + [hidden], + ); React.useEffect(() => { setField(name, searchResult); @@ -27,10 +32,5 @@ export const useSearch = (spec: Spec, value: FieldValue, name: string) => { return () => removeField(name); }, []); - const withSearch = React.useCallback( - (children: JSX.Element | null) => {children}, - [hide], - ); - return withSearch; }; diff --git a/src/lib/core/components/Form/types/search.ts b/src/lib/core/components/Form/types/search.ts index 1848e279..63d518ea 100644 --- a/src/lib/core/components/Form/types/search.ts +++ b/src/lib/core/components/Form/types/search.ts @@ -6,5 +6,5 @@ export interface SearchContext { setField: (name: string, search: boolean) => void; removeField: (name: string) => void; isHiddenField: (name: string) => boolean; - searchFunction?: (spec: Spec, value: FieldValue, name: string) => boolean; + searchFunction: (spec: Spec, value: FieldValue, name: string) => boolean; } diff --git a/src/lib/core/components/Form/utils/search.ts b/src/lib/core/components/Form/utils/search.ts index 3db3b6e1..fe9d0852 100644 --- a/src/lib/core/components/Form/utils/search.ts +++ b/src/lib/core/components/Form/utils/search.ts @@ -9,4 +9,6 @@ export const getParentName = (name: string) => { }; export const getDefaultSearchFunction = (search: string) => (spec: Spec) => - Boolean((spec.viewSpec.layoutTitle || '').toLowerCase().includes(search.trim().toLowerCase())); + Boolean(spec.viewSpec.layoutTitle?.toLowerCase().includes(search.trim().toLowerCase())); + +export const getEmptySearchFunction = () => true; diff --git a/src/stories/components/InputPreview/InputPreview.tsx b/src/stories/components/InputPreview/InputPreview.tsx index 5d20c847..c17d3484 100644 --- a/src/stories/components/InputPreview/InputPreview.tsx +++ b/src/stories/components/InputPreview/InputPreview.tsx @@ -101,8 +101,8 @@ export const InputPreview: React.FC = ({ const searchFunction = React.useCallback( (spec: Spec) => Boolean( - (spec.viewSpec.layoutTitle || '') - .toLowerCase() + spec.viewSpec.layoutTitle + ?.toLowerCase() .includes(searchOptions.trim().toLowerCase()), ), [searchOptions], From 705a9644d36efdbf498569bd5a837267f9414eb9 Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Wed, 22 Mar 2023 14:48:51 +0100 Subject: [PATCH 08/12] fix: changed getDefaultSearchFunction --- src/lib/core/components/Form/DynamicField.tsx | 8 ++------ src/lib/core/components/Form/utils/search.ts | 13 ++++++++++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/lib/core/components/Form/DynamicField.tsx b/src/lib/core/components/Form/DynamicField.tsx index 1c822d94..5989ec9b 100644 --- a/src/lib/core/components/Form/DynamicField.tsx +++ b/src/lib/core/components/Form/DynamicField.tsx @@ -10,7 +10,7 @@ import {Spec} from '../../types'; import {Controller} from './Controller'; import {useCreateContext, useCreateSearchContext, useSearchStore, useStore} from './hooks'; import {DynamicFormConfig, FieldValue} from './types'; -import {getDefaultSearchFunction, getEmptySearchFunction, isCorrectConfig} from './utils'; +import {getDefaultSearchFunction, isCorrectConfig} from './utils'; export interface DynamicFieldProps { name: string; @@ -41,11 +41,7 @@ export const DynamicField: React.FC = ({name, spec, config, M setField, removeField, isHiddenField, - searchFunction: _.isString(search) - ? getDefaultSearchFunction(search) - : _.isFunction(search) - ? search - : getEmptySearchFunction, + searchFunction: _.isFunction(search) ? search : getDefaultSearchFunction(search), }), [isHiddenField, removeField, search, setField], ); diff --git a/src/lib/core/components/Form/utils/search.ts b/src/lib/core/components/Form/utils/search.ts index fe9d0852..d0708fb4 100644 --- a/src/lib/core/components/Form/utils/search.ts +++ b/src/lib/core/components/Form/utils/search.ts @@ -2,13 +2,20 @@ import {Spec} from '../../../types'; export const getParentName = (name: string) => { const index = name.lastIndexOf('.'); + if (index !== -1) { return name.substring(0, index); } + return undefined; }; -export const getDefaultSearchFunction = (search: string) => (spec: Spec) => - Boolean(spec.viewSpec.layoutTitle?.toLowerCase().includes(search.trim().toLowerCase())); +export const getDefaultSearchFunction = (search?: string) => (spec: Spec) => { + if (search) { + return Boolean( + spec.viewSpec.layoutTitle?.toLowerCase().includes(search.trim().toLowerCase()), + ); + } -export const getEmptySearchFunction = () => true; + return true; +}; From 1c1adabf601382992a7bcd70b223000cf16d8286 Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Wed, 22 Mar 2023 15:00:24 +0100 Subject: [PATCH 09/12] fix: text area delete syles --- src/lib/kit/components/Inputs/TextArea/TextArea.scss | 7 ------- src/lib/kit/components/Inputs/TextArea/TextArea.tsx | 6 ------ 2 files changed, 13 deletions(-) delete mode 100644 src/lib/kit/components/Inputs/TextArea/TextArea.scss diff --git a/src/lib/kit/components/Inputs/TextArea/TextArea.scss b/src/lib/kit/components/Inputs/TextArea/TextArea.scss deleted file mode 100644 index 95f52de6..00000000 --- a/src/lib/kit/components/Inputs/TextArea/TextArea.scss +++ /dev/null @@ -1,7 +0,0 @@ -@import '../../../styles/variables'; - -.#{$ns}text-area { - .yc-text-input__control { - min-height: 142px; - } -} diff --git a/src/lib/kit/components/Inputs/TextArea/TextArea.tsx b/src/lib/kit/components/Inputs/TextArea/TextArea.tsx index 3c333685..4d782471 100644 --- a/src/lib/kit/components/Inputs/TextArea/TextArea.tsx +++ b/src/lib/kit/components/Inputs/TextArea/TextArea.tsx @@ -3,11 +3,6 @@ import React from 'react'; import {TextInput as TextInputBase} from '@gravity-ui/uikit'; import {StringInput} from '../../../../core'; -import {block} from '../../../utils'; - -import './TextArea.scss'; - -const b = block('text-area'); export const TextArea: StringInput = ({input, spec}) => { const {value, onBlur, onChange, onFocus} = input; @@ -24,7 +19,6 @@ export const TextArea: StringInput = ({input, spec}) => { disabled={spec.viewSpec.disabled} multiline placeholder={spec.viewSpec.placeholder} - className={b()} /> ); }; From 7adc9a92893ebcc1b2d483524cb18295e4d96007 Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Thu, 23 Mar 2023 10:11:38 +0100 Subject: [PATCH 10/12] fix: return styles --- .../components/Form/hooks/useSearch/useSearch.scss | 4 +++- .../components/AccordeonCard/AccordeonCard.scss | 8 ++++---- src/lib/kit/components/Card/Card.scss | 8 ++++---- src/lib/kit/components/Inputs/OneOf/OneOf.scss | 14 ++++++++++++++ .../kit/components/Inputs/OneOfCard/OneOfCard.scss | 4 ---- src/lib/kit/components/Layouts/Row/Row.scss | 4 ++++ src/lib/kit/components/Layouts/Row2/Row2.scss | 4 ++++ .../kit/components/Layouts/Section/Section.scss | 4 ++++ .../Layouts/Transparent/Transparent.scss | 4 ++++ .../SimpleVerticalAccordeon.scss | 4 ++++ 10 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/lib/core/components/Form/hooks/useSearch/useSearch.scss b/src/lib/core/components/Form/hooks/useSearch/useSearch.scss index c7361966..c9296735 100644 --- a/src/lib/core/components/Form/hooks/useSearch/useSearch.scss +++ b/src/lib/core/components/Form/hooks/useSearch/useSearch.scss @@ -1,11 +1,13 @@ @import '../../../../../kit/styles/variables.scss'; .#{$ns}use-search { + margin-bottom: 15px; + &_hidden { display: none; } - &:last-child > * { + &:last-child { margin-bottom: 0; } } diff --git a/src/lib/kit/components/AccordeonCard/AccordeonCard.scss b/src/lib/kit/components/AccordeonCard/AccordeonCard.scss index 3eaceeed..cd4a59ea 100644 --- a/src/lib/kit/components/AccordeonCard/AccordeonCard.scss +++ b/src/lib/kit/components/AccordeonCard/AccordeonCard.scss @@ -11,6 +11,10 @@ color: var(--yc-color-text-primary); background-color: var(--yc-color-base-float); + &:last-child { + margin-bottom: 0; + } + &:hover { box-shadow: 0 3px 10px var(--yc-color-sfx-shadow); } @@ -81,10 +85,6 @@ justify-content: flex-end; order: 1; } - - > * { - margin-bottom: 0px; - } } &__interal-actions { diff --git a/src/lib/kit/components/Card/Card.scss b/src/lib/kit/components/Card/Card.scss index 2c856605..cf307c3f 100644 --- a/src/lib/kit/components/Card/Card.scss +++ b/src/lib/kit/components/Card/Card.scss @@ -3,6 +3,10 @@ .#{$ns}card { margin-bottom: 20px; + &:last-child { + margin-bottom: 0; + } + .#{$ns}row { width: 100%; max-width: unset; @@ -47,10 +51,6 @@ &__header-left { display: flex; align-items: center; - - > * { - margin-bottom: 0px; - } } &__header-right { diff --git a/src/lib/kit/components/Inputs/OneOf/OneOf.scss b/src/lib/kit/components/Inputs/OneOf/OneOf.scss index c9d3ef8b..b283dccf 100644 --- a/src/lib/kit/components/Inputs/OneOf/OneOf.scss +++ b/src/lib/kit/components/Inputs/OneOf/OneOf.scss @@ -3,4 +3,18 @@ .#{$ns}oneof { display: flex; flex-direction: column-reverse; + + &:last-child { + & > .#{$ns}group-indent { + margin-bottom: 0; + + &:empty + .#{$ns}oneof__toggler { + margin-bottom: 0; + } + } + } + + &__toggler { + margin-bottom: 15px; + } } diff --git a/src/lib/kit/components/Inputs/OneOfCard/OneOfCard.scss b/src/lib/kit/components/Inputs/OneOfCard/OneOfCard.scss index 451da2fe..e7dd9931 100644 --- a/src/lib/kit/components/Inputs/OneOfCard/OneOfCard.scss +++ b/src/lib/kit/components/Inputs/OneOfCard/OneOfCard.scss @@ -6,8 +6,4 @@ .df-accordeon-card__header-toggle-btn { margin-left: 5px; } - - &__title { - margin-bottom: 0; - } } diff --git a/src/lib/kit/components/Layouts/Row/Row.scss b/src/lib/kit/components/Layouts/Row/Row.scss index b802d58d..ee73db06 100644 --- a/src/lib/kit/components/Layouts/Row/Row.scss +++ b/src/lib/kit/components/Layouts/Row/Row.scss @@ -6,6 +6,10 @@ max-width: 500px; margin-bottom: 15px; + &:last-child { + margin-bottom: 0; + } + &_extra-width { width: 533px; max-width: 533px; diff --git a/src/lib/kit/components/Layouts/Row2/Row2.scss b/src/lib/kit/components/Layouts/Row2/Row2.scss index ba69b37a..e152c688 100644 --- a/src/lib/kit/components/Layouts/Row2/Row2.scss +++ b/src/lib/kit/components/Layouts/Row2/Row2.scss @@ -5,6 +5,10 @@ display: flex; margin-bottom: 15px; + &:last-child { + margin-bottom: 0; + } + &__left { width: 180px; min-width: 180px; diff --git a/src/lib/kit/components/Layouts/Section/Section.scss b/src/lib/kit/components/Layouts/Section/Section.scss index 1d9370aa..2f2151f6 100644 --- a/src/lib/kit/components/Layouts/Section/Section.scss +++ b/src/lib/kit/components/Layouts/Section/Section.scss @@ -7,6 +7,10 @@ $block: '.#{$ns}section'; $block: &; + &:last-child { + margin-bottom: 0; + } + &__header { margin-bottom: $normalOffset; diff --git a/src/lib/kit/components/Layouts/Transparent/Transparent.scss b/src/lib/kit/components/Layouts/Transparent/Transparent.scss index dae58865..e1086e6e 100644 --- a/src/lib/kit/components/Layouts/Transparent/Transparent.scss +++ b/src/lib/kit/components/Layouts/Transparent/Transparent.scss @@ -4,6 +4,10 @@ display: flex; margin-bottom: 15px; + &:last-child { + margin-bottom: 0; + } + &_array-item { max-width: 338px; } diff --git a/src/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.scss b/src/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.scss index 3f303518..50058da9 100644 --- a/src/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.scss +++ b/src/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.scss @@ -5,6 +5,10 @@ $animationDuration: 0.3s; .#{$ns}simple-vertical-accordeon { margin-bottom: $normalOffset; + &:last-child { + margin-bottom: 0; + } + &_branch &__body { padding-left: $normalOffset; margin-left: 5px; From c3742179b7ace24cf31c97e27a4d1803ef2a1a4a Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Thu, 23 Mar 2023 10:28:01 +0100 Subject: [PATCH 11/12] fix: useSearch span to div --- src/lib/core/components/Form/hooks/useSearch/useSearch.tsx | 2 +- src/lib/kit/components/AccordeonCard/AccordeonCard.scss | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx b/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx index 8b119e2b..d946e97d 100644 --- a/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx +++ b/src/lib/core/components/Form/hooks/useSearch/useSearch.tsx @@ -20,7 +20,7 @@ export const useSearch = (spec: Spec, value: FieldValue, name: string) => { const hidden = React.useMemo(() => isHiddenField(name), [isHiddenField, name]); const withSearch = React.useCallback( - (children: JSX.Element | null) => {children}, + (children: JSX.Element | null) =>
{children}
, [hidden], ); diff --git a/src/lib/kit/components/AccordeonCard/AccordeonCard.scss b/src/lib/kit/components/AccordeonCard/AccordeonCard.scss index cd4a59ea..6af8f598 100644 --- a/src/lib/kit/components/AccordeonCard/AccordeonCard.scss +++ b/src/lib/kit/components/AccordeonCard/AccordeonCard.scss @@ -11,6 +11,10 @@ color: var(--yc-color-text-primary); background-color: var(--yc-color-base-float); + &:hover { + box-shadow: 0 3px 10px var(--yc-color-sfx-shadow); + } + &:last-child { margin-bottom: 0; } From 08ed3fc6707bb228889c1ef8cb2e56ef7464ca1b Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Thu, 23 Mar 2023 10:42:04 +0100 Subject: [PATCH 12/12] fix: accordeon card styles --- src/lib/kit/components/AccordeonCard/AccordeonCard.scss | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/lib/kit/components/AccordeonCard/AccordeonCard.scss b/src/lib/kit/components/AccordeonCard/AccordeonCard.scss index 6af8f598..4894e7da 100644 --- a/src/lib/kit/components/AccordeonCard/AccordeonCard.scss +++ b/src/lib/kit/components/AccordeonCard/AccordeonCard.scss @@ -19,10 +19,6 @@ margin-bottom: 0; } - &:hover { - box-shadow: 0 3px 10px var(--yc-color-sfx-shadow); - } - &_empty { .#{$ns}accordeon-card__body, .#{$ns}accordeon-card__header-toggle-btn {