From a8261f7439106e85e21dac5e9ffad6c684a41c1b Mon Sep 17 00:00:00 2001 From: Radek Podrazky Date: Mon, 17 Jul 2023 14:35:17 +0200 Subject: [PATCH 1/3] fix(Accordion): make 'openItems' act as value Closes UXD-1225 --- .../Accordion/Accordion.stories.tsx | 18 ++++++++---- src/components/Accordion/Accordion.tsx | 29 ++++++++++++------- src/components/Accordion/Accordion.types.ts | 3 +- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/components/Accordion/Accordion.stories.tsx b/src/components/Accordion/Accordion.stories.tsx index d371bc9ee..93c5ab4cc 100644 --- a/src/components/Accordion/Accordion.stories.tsx +++ b/src/components/Accordion/Accordion.stories.tsx @@ -1,5 +1,6 @@ import React, { useState } from 'react'; import { Meta, Story } from '@storybook/react/types-6-0'; +import { includes } from 'ramda'; import { Inline, Stack } from '../layout'; import { HexGrade } from '../HexGrade'; @@ -72,7 +73,7 @@ CustomTitleElement.args = { }; export const AcordionWithExternalManagement: Story = () => { - const [openItems, setOpenItems] = useState([]); + const [openItems, setOpenItems] = useState<(string | number)[]>([]); const handleOnClick = (id: string) => { if (!openItems.includes(id)) { const newItems = [id]; @@ -91,16 +92,23 @@ export const AcordionWithExternalManagement: Story = () => { - + { + setOpenItems(ids); + }} + /> ); }; diff --git a/src/components/Accordion/Accordion.tsx b/src/components/Accordion/Accordion.tsx index 5241e5de8..eb24037c5 100644 --- a/src/components/Accordion/Accordion.tsx +++ b/src/components/Accordion/Accordion.tsx @@ -30,29 +30,37 @@ function filterState( if (isCollapsedOnOpen) { return [item]; } + return [...state, item]; } const Accordion = React.forwardRef( ( - { isCollapsedOnOpen = true, items, openItems, className, ...props }, + { + isCollapsedOnOpen = true, + items, + openItems, + className, + onChange, + ...props + }, ref, ) => { const [openIds, setOpenIds] = useState(pickOpen(items)); - useEffect( - () => - openItems?.forEach((item: AccordionItemId) => - setOpenIds((state) => filterState(state, item, isCollapsedOnOpen)), - ), - [openItems, isCollapsedOnOpen], - ); + useEffect(() => { + if (openItems !== undefined) { + setOpenIds(isCollapsedOnOpen ? [openItems[0]] : openItems); + } + }, [openItems, isCollapsedOnOpen]); const handleClick = useCallback( (id: AccordionItemId) => { - setOpenIds((state) => filterState(state, id, isCollapsedOnOpen)); + const nextState = filterState(openIds, id, isCollapsedOnOpen); + setOpenIds(nextState); + onChange?.(nextState); }, - [setOpenIds, isCollapsedOnOpen], + [openIds, setOpenIds, onChange, isCollapsedOnOpen], ); return ( @@ -78,6 +86,7 @@ Accordion.propTypes = { isCollapsedOnOpen: PropTypes.bool, className: PropTypes.string, openItems: PropTypes.arrayOf(AccordionItemIdPropType), + onChange: PropTypes.func, }; export default Accordion; diff --git a/src/components/Accordion/Accordion.types.ts b/src/components/Accordion/Accordion.types.ts index 75a15f814..6748d4704 100644 --- a/src/components/Accordion/Accordion.types.ts +++ b/src/components/Accordion/Accordion.types.ts @@ -22,7 +22,8 @@ export interface AccordionProps { isCollapsedOnOpen?: boolean; items: AccordionItem[]; className?: string; - openItems: AccordionItemId[]; + openItems?: AccordionItemId[]; + onChange?: (openIds: AccordionItemId[]) => void; } export const AccordionItemIdPropType = PropTypes.oneOfType([ From 374cfe9ba3b2d31c9d90729d0489c56118e1921b Mon Sep 17 00:00:00 2001 From: Julian Barrionuevo Date: Mon, 17 Jul 2023 11:25:47 -0300 Subject: [PATCH 2/3] fix(Datatable): add onColumnVisibilityChange to proptypes --- src/components/Datatable/Datatable.tsx | 1 + src/components/Datatable/mocks/controls.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/components/Datatable/Datatable.tsx b/src/components/Datatable/Datatable.tsx index 25725f91b..67434afe3 100644 --- a/src/components/Datatable/Datatable.tsx +++ b/src/components/Datatable/Datatable.tsx @@ -197,6 +197,7 @@ Datatable.propTypes = { controlsConfig: PropTypes.exact({ onControlToggle: PropTypes.func, onCancelLoading: PropTypes.func, + onColumnVisibilityChange: PropTypes.func, hasSearch: PropTypes.bool, searchConfig: PropTypes.exact({ placeholder: PropTypes.string, diff --git a/src/components/Datatable/mocks/controls.ts b/src/components/Datatable/mocks/controls.ts index 1f3877bad..e12c115fa 100644 --- a/src/components/Datatable/mocks/controls.ts +++ b/src/components/Datatable/mocks/controls.ts @@ -15,4 +15,5 @@ export const controlsConfig = { onSearch: action('onSearch'), onClear: action('onClear'), }, + onColumnVisibilityChange: action('columnVisibilityChange'), }; From 03639a2681eff658ae5b86471e4d612a49cb82c0 Mon Sep 17 00:00:00 2001 From: Radek Podrazky Date: Wed, 19 Jul 2023 17:17:55 +0200 Subject: [PATCH 3/3] feat(MultiValueInput): add 'onPaste' callback --- .../MultiValueInput/MultiValueInput.stories.tsx | 9 +++++++++ .../forms/MultiValueInput/MultiValueInput.tsx | 16 ++++++++++------ .../MultiValueInput/MultiValueInput.types.ts | 1 + 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/components/forms/MultiValueInput/MultiValueInput.stories.tsx b/src/components/forms/MultiValueInput/MultiValueInput.stories.tsx index 1c639132f..de22946ab 100644 --- a/src/components/forms/MultiValueInput/MultiValueInput.stories.tsx +++ b/src/components/forms/MultiValueInput/MultiValueInput.stories.tsx @@ -26,6 +26,15 @@ Playground.args = { onValueRemove: action('OnValueRemove'), onValuesChange: action('OnValuesChange'), onInputChange: action('OnInputChange'), + onPaste: (e) => { + const pastedValue = (e.clipboardData || window.clipboardData).getData( + 'text', + ); + return pastedValue + .split(';') + .filter((i) => i !== '3') + .join(';'); + }, }; export const Filled = MultiValueInputTemplate.bind({}); diff --git a/src/components/forms/MultiValueInput/MultiValueInput.tsx b/src/components/forms/MultiValueInput/MultiValueInput.tsx index 00d762e07..62e9c7130 100644 --- a/src/components/forms/MultiValueInput/MultiValueInput.tsx +++ b/src/components/forms/MultiValueInput/MultiValueInput.tsx @@ -142,6 +142,7 @@ const MultiValueInput: React.FC = ({ onValueRemove = noop, onValuesChange = noop, onInputChange = noop, + onPaste = noop, placeholder, pattern, id, @@ -174,10 +175,9 @@ const MultiValueInput: React.FC = ({ split(';'), map(trim), filter(isNonEmptyString), - uniq, )(newValue); const newValues = [...values, ...parsedValues]; - setValues(newValues); + setValues(uniq(newValues)); onValueAdd(parsedValues, newValues); onValuesChange(newValues); } else { @@ -233,10 +233,13 @@ const MultiValueInput: React.FC = ({ e, ) => { e.preventDefault(); - const pastedValue = (e.clipboardData || window.clipboardData).getData( - 'text', - ); - addValue(pastedValue); + const pastedValue = onPaste(e); + + if (typeof pastedValue === 'string') { + addValue(pastedValue); + } else { + addValue((e.clipboardData || window.clipboardData).getData('text')); + } }; const handleInputOnChange: React.ChangeEventHandler = ( @@ -363,6 +366,7 @@ MultiValueInput.propTypes = { onValueRemove: PropTypes.func, onValuesChange: PropTypes.func, onInputChange: PropTypes.func, + onPaste: PropTypes.func, }; export default MultiValueInput; diff --git a/src/components/forms/MultiValueInput/MultiValueInput.types.ts b/src/components/forms/MultiValueInput/MultiValueInput.types.ts index 3ef2f0434..9ef333a61 100644 --- a/src/components/forms/MultiValueInput/MultiValueInput.types.ts +++ b/src/components/forms/MultiValueInput/MultiValueInput.types.ts @@ -36,4 +36,5 @@ export interface MultiValueInputProps onValueRemove?: (nextValues: MultiValueInputProps['value']) => void; onValuesChange?: (nextValues: MultiValueInputProps['value']) => void; onInputChange?: (event: React.ChangeEvent) => void; + onPaste?: (event: React.ClipboardEvent) => void | string; }