From fea20b8780755f9bc7e8f2b621c1c5febf3743d7 Mon Sep 17 00:00:00 2001 From: Joris Mancini Date: Tue, 9 Dec 2025 14:18:30 +0100 Subject: [PATCH] poc: design system RTE Signed-off-by: Joris Mancini --- demo/src/InputsTab.jsx | 5 +- package.json | 1 + src/components/authentication/Login.tsx | 17 +- src/components/authentication/Logout.tsx | 19 +- .../customMuiDialog/CustomMuiDialog.tsx | 48 +++-- .../elementSaveDialog/ElementSaveDialog.tsx | 77 +++++--- .../ModifyElementSelection.tsx | 14 +- .../PopupConfirmationDialog.tsx | 38 ++-- src/components/dnd-table/dnd-table.tsx | 2 +- .../flatParameters/FlatParameters.tsx | 11 +- .../agGridTable/csvUploader/CsvUploader.tsx | 41 ++-- .../reactHookForm/booleans/CheckboxInput.tsx | 35 +++- .../reactHookForm/booleans/SwitchInput.tsx | 26 ++- .../reactHookForm/numbers/FloatInput.tsx | 44 +++-- .../InputWithPopupConfirmation.tsx | 2 +- .../reactHookForm/utils/CancelButton.tsx | 21 +- .../reactHookForm/utils/SubmitButton.tsx | 20 -- .../reactHookForm/utils/ValidateButton.tsx | 29 +++ .../inputs/reactHookForm/utils/index.ts | 2 +- .../reactQueryBuilder/CombinatorSelector.tsx | 2 +- .../inputs/reactQueryBuilder/RemoveButton.tsx | 11 +- .../loadflow/load-flow-parameters-header.tsx | 2 +- .../loadflow/load-flow-parameters-inline.tsx | 12 +- ...twork-visualizations-parameters-inline.tsx | 11 +- .../pcc-min/pcc-min-parameters-inline.tsx | 11 +- .../security-analysis-parameters-inline.tsx | 16 +- ...sensitivity-analysis-parameters-inline.tsx | 12 +- .../short-circuit/short-circuit-fields.tsx | 14 +- .../short-circuit-parameters-inline.tsx | 12 +- .../voltage-init-parameters-inline.tsx | 13 +- .../topBar/UserInformationDialog.tsx | 2 +- .../treeViewFinder/TreeViewFinder.tsx | 183 ++++++------------ 32 files changed, 388 insertions(+), 365 deletions(-) delete mode 100644 src/components/inputs/reactHookForm/utils/SubmitButton.tsx create mode 100644 src/components/inputs/reactHookForm/utils/ValidateButton.tsx diff --git a/demo/src/InputsTab.jsx b/demo/src/InputsTab.jsx index 7553eaa69..c85244e53 100644 --- a/demo/src/InputsTab.jsx +++ b/demo/src/InputsTab.jsx @@ -20,10 +20,9 @@ import { SelectInput, CheckboxInput, SwitchInput, - SubmitButton, ExpandingTextField, CustomFormProvider, - SelectClearable, + SelectClearable, ValidateButton, } from '../../src'; const AUTOCOMPLETE_INPUT = 'autocomplete'; @@ -174,7 +173,7 @@ function InputsTab() { backgroundColor: 'pink', }} > - + diff --git a/package.json b/package.json index 41daa5740..3f2b523ec 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ }, "dependencies": { "@ag-grid-community/locale": "^33.3.2", + "@design-system-rte/react": "^1.0.0", "@hello-pangea/dnd": "^18.0.1", "@material-symbols/svg-400": "^0.31.9", "@react-querybuilder/dnd": "^8.11.0", diff --git a/src/components/authentication/Login.tsx b/src/components/authentication/Login.tsx index 5287e7dfc..39cfd2a64 100644 --- a/src/components/authentication/Login.tsx +++ b/src/components/authentication/Login.tsx @@ -4,10 +4,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { Avatar, Box, Button, Container, Link, Typography } from '@mui/material'; +import { Avatar, Box, Container, Link, Typography } from '@mui/material'; import { LockOutlined as LockOutlinedIcon } from '@mui/icons-material'; -import { FormattedMessage } from 'react-intl'; +import { Button } from '@design-system-rte/react'; +import { FormattedMessage, useIntl } from 'react-intl'; import type { MuiStyles } from '../../utils/styles'; +import {useIntlRef} from "../../hooks"; const styles = { paper: (theme) => ({ @@ -36,6 +38,8 @@ export interface LoginProps { } export function Login({ onLoginClick, disabled }: LoginProps) { + const intl = useIntl(); + return ( @@ -49,13 +53,10 @@ export function Login({ onLoginClick, disabled }: LoginProps) { + label={intl.formatMessage({ id: 'login/connection' })} + /> diff --git a/src/components/authentication/Logout.tsx b/src/components/authentication/Logout.tsx index aeac97c50..cacfe9fef 100644 --- a/src/components/authentication/Logout.tsx +++ b/src/components/authentication/Logout.tsx @@ -5,9 +5,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { Avatar, Box, Button, Container, Link, Typography } from '@mui/material'; +import { Avatar, Box, Container, Link, Typography } from '@mui/material'; import { LogoutOutlined as LogoutOutlinedIcon } from '@mui/icons-material'; -import { FormattedMessage } from 'react-intl'; +import { Button } from '@design-system-rte/react'; +import { FormattedMessage, useIntl } from 'react-intl'; import type { MuiStyles } from '../../utils/styles'; const styles = { @@ -21,10 +22,6 @@ const styles = { margin: theme.spacing(1), backgroundColor: theme.palette.error.main, }), - submit: (theme) => ({ - margin: theme.spacing(3, 0, 2), - borderRadius: '30px', - }), } as const satisfies MuiStyles; export interface LogoutProps { @@ -46,6 +43,7 @@ function Copyright() { } export function Logout({ onLogoutClick, disabled }: LogoutProps) { + const intl = useIntl(); return ( @@ -56,9 +54,12 @@ export function Logout({ onLogoutClick, disabled }: LogoutProps) { ? - + + + + - - + } + secondaryButton={ setOpenConfirmationPopup(false)} />} + description={descriptionMessage ?? intl.formatMessage({id: descriptionKey})} + onClose={() => setOpenConfirmationPopup(false)} + /> ); } diff --git a/src/components/dnd-table/dnd-table.tsx b/src/components/dnd-table/dnd-table.tsx index 4cd273333..5b5cc8f9e 100644 --- a/src/components/dnd-table/dnd-table.tsx +++ b/src/components/dnd-table/dnd-table.tsx @@ -423,7 +423,7 @@ export function DndTable(props: Readonly) { {columnsDefinition.map((column) => renderTableCell(row.id, index, column))} diff --git a/src/components/flatParameters/FlatParameters.tsx b/src/components/flatParameters/FlatParameters.tsx index a0dd092e2..ae632591a 100644 --- a/src/components/flatParameters/FlatParameters.tsx +++ b/src/components/flatParameters/FlatParameters.tsx @@ -15,13 +15,13 @@ import { ListItem, MenuItem, Select, - Switch, TextField, TextFieldProps, Tooltip, Typography, } from '@mui/material'; import { Tune as TuneIcon } from '@mui/icons-material'; +import { Switch } from '@design-system-rte/react'; import { FormattedMessage, useIntl } from 'react-intl'; import { MultipleSelectionDialog } from '../multipleSelectionDialog/MultipleSelectionDialog'; import type { MuiStyles } from '../../utils/styles'; @@ -265,7 +265,14 @@ export function FlatParameters({ // eslint-disable-next-line default-case switch (param.type) { case 'BOOLEAN': - return onFieldChange(e.target.checked, param)} />; + return ( + onFieldChange(e.target.checked, param)} + /> + ); case 'DOUBLE': { const err = Number.isNaN(fieldValue) || diff --git a/src/components/inputs/reactHookForm/agGridTable/csvUploader/CsvUploader.tsx b/src/components/inputs/reactHookForm/agGridTable/csvUploader/CsvUploader.tsx index 8b43e7af2..b4ec6535f 100644 --- a/src/components/inputs/reactHookForm/agGridTable/csvUploader/CsvUploader.tsx +++ b/src/components/inputs/reactHookForm/agGridTable/csvUploader/CsvUploader.tsx @@ -5,23 +5,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { - Alert, - Button, - Dialog, - DialogActions, - DialogContent, - DialogContentText, - DialogTitle, - Grid, -} from '@mui/material'; +import { Alert, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Grid } from '@mui/material'; import { RECORD_SEP, UNIT_SEP, useCSVReader } from 'react-papaparse'; import React, { useMemo, useState } from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; import CsvDownloader from 'react-csv-downloader'; import { useWatch } from 'react-hook-form'; +import { Button } from '@design-system-rte/react'; import { FieldConstants, GsLang, LANG_FRENCH } from '../../../../../utils'; -import { CancelButton } from '../../utils'; +import { CancelButton, ValidateButton } from '../../utils'; export interface CsvUploaderProps { name: string; @@ -160,12 +152,16 @@ export function CsvUploader({ - - + + + /> {renderConfirmationCsvData()} diff --git a/src/components/inputs/reactHookForm/booleans/CheckboxInput.tsx b/src/components/inputs/reactHookForm/booleans/CheckboxInput.tsx index 3cd281673..2c23ddc86 100644 --- a/src/components/inputs/reactHookForm/booleans/CheckboxInput.tsx +++ b/src/components/inputs/reactHookForm/booleans/CheckboxInput.tsx @@ -4,16 +4,39 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -import { Checkbox, CheckboxProps } from '@mui/material'; -import { BooleanInput } from './BooleanInput'; +import { Checkbox } from '@design-system-rte/react'; +import { type ChangeEvent, useCallback } from 'react'; +import { useController } from 'react-hook-form'; +import { useIntl } from 'react-intl'; export interface CheckboxInputProps { name: string; label?: string; - formProps?: CheckboxProps; + disabled?: boolean } -export function CheckboxInput({ name, label, formProps }: CheckboxInputProps) { - return ; +export function CheckboxInput({ name, label, disabled = false }: Readonly) { + const { + field: { onChange, value }, + } = useController>({ name }); + + const intl = useIntl(); + + const handleChangeValue = useCallback( + (event: ChangeEvent) => { + onChange(event.target.checked); + }, + [onChange] + ); + + return ( + + ); } diff --git a/src/components/inputs/reactHookForm/booleans/SwitchInput.tsx b/src/components/inputs/reactHookForm/booleans/SwitchInput.tsx index 2d1a03ab6..f6033fc4f 100644 --- a/src/components/inputs/reactHookForm/booleans/SwitchInput.tsx +++ b/src/components/inputs/reactHookForm/booleans/SwitchInput.tsx @@ -5,15 +5,31 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { Switch, SwitchProps } from '@mui/material'; -import { BooleanInput } from './BooleanInput'; +import { type ChangeEvent, useCallback } from 'react'; +import { Switch } from '@design-system-rte/react'; +import { useController } from 'react-hook-form'; export interface SwitchInputProps { name: string; label?: string; - formProps?: SwitchProps; } -export function SwitchInput({ name, label, formProps, ...props }: SwitchInputProps) { - return ; +export function SwitchInput({ name }: Readonly) { + const { + field: { onChange, value }, + } = useController>({ name }); + + const handleChangeValue = useCallback( + (event: ChangeEvent) => { + onChange(event.target.checked); + }, + [onChange] + ); + + return ( + + ); } diff --git a/src/components/inputs/reactHookForm/numbers/FloatInput.tsx b/src/components/inputs/reactHookForm/numbers/FloatInput.tsx index 693bb6eb6..2d996b7c9 100644 --- a/src/components/inputs/reactHookForm/numbers/FloatInput.tsx +++ b/src/components/inputs/reactHookForm/numbers/FloatInput.tsx @@ -5,14 +5,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { TextInput, TextInputProps } from '../text/TextInput'; import { isFloatNumber } from './utils'; import { Input } from '../../../../utils/types/types'; -export type FloatInputProps = Omit< +import { TextInput } from '@design-system-rte/react'; +import { TextInputProps } from '../text'; +import { useIntl } from 'react-intl'; + +/*export type FloatInputProps = Omit< TextInputProps, 'outputTransform' | 'inputTransform' | 'acceptValue' // already defined in FloatInput ->; +>;*/ // toLocaleString never uses exponential notation unlike toString. Avoiding // exponential notation makes in place normalizing of numbers after each @@ -37,7 +40,12 @@ const normalizeFixed = (number: number) => { }); }; -export function FloatInput(props: FloatInputProps) { +interface FloatInputProps { + label: string; + previousValue: string | number; +} + +export function FloatInput({ label, previousValue }: FloatInputProps) { const inputTransform = (value: Input) => { if (typeof value === 'number' && !Number.isNaN(value)) { // if we have a parsed real number, normalize like we do after each @@ -67,12 +75,16 @@ export function FloatInput(props: FloatInputProps) { return ''; }; - const outputTransform = (value: string): Input | null => { + const outputTransform = (value: string | number): string => { + if (typeof value === 'number') { + return Number.isNaN(value) ? '' : normalizeFixed(value); + } + if (value === '-') { return value; } if (value === '') { - return null; + return ''; } const tmp = value?.replace(',', '.') || ''; @@ -106,15 +118,25 @@ export function FloatInput(props: FloatInputProps) { // restrict what the user can type with "acceptValue" but if we // have a bug just clear the data instead of sending "NaN" const parsed = parseFloat(tmp); - return Number.isNaN(parsed) ? null : normalizeFixed(parsed); + return Number.isNaN(parsed) ? '' : normalizeFixed(parsed); }; + const intl = useIntl(); + return ( ); } diff --git a/src/components/inputs/reactHookForm/selectInputs/InputWithPopupConfirmation.tsx b/src/components/inputs/reactHookForm/selectInputs/InputWithPopupConfirmation.tsx index 77ee9ee7c..c9dba49b5 100644 --- a/src/components/inputs/reactHookForm/selectInputs/InputWithPopupConfirmation.tsx +++ b/src/components/inputs/reactHookForm/selectInputs/InputWithPopupConfirmation.tsx @@ -50,7 +50,7 @@ export function InputWithPopupConfirmation({ }} /> >) { - const props = useThemeProps({ props: inProps, name: 'CancelButton' }); +interface CancelButtonProps { + onClick: (e: React.MouseEvent) => void; +} + +export function CancelButton({ onClick }: Readonly) { + const intl = useIntl(); return ( - + - ); -} diff --git a/src/components/inputs/reactHookForm/utils/ValidateButton.tsx b/src/components/inputs/reactHookForm/utils/ValidateButton.tsx new file mode 100644 index 000000000..e02f6a87f --- /dev/null +++ b/src/components/inputs/reactHookForm/utils/ValidateButton.tsx @@ -0,0 +1,29 @@ +/** + * Copyright (c) 2022, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +import { Button } from '@design-system-rte/react'; +import { PrimitiveType, useIntl } from 'react-intl'; + +interface SubmitButtonProps { + onClick: (e: React.MouseEvent) => void; + label?: string; + labelValues?: Record; + disabled?: boolean; +} + +export function ValidateButton({ onClick, label, labelValues, disabled }: Readonly) { + const intl = useIntl(); + + return ( + - - - + /> {openCreateParameterDialog && ( @@ -176,7 +174,7 @@ export function SensitivityAnalysisParametersInline({ {/* Reset Confirmation Dialog */} {openResetConfirmation && ( {statusToShow} - - - {loads} - {shuntCompensators} - - - {vsc} - {neutralPosition} - + + {loads} + {vsc} + {shuntCompensators} + {neutralPosition} diff --git a/src/components/parameters/short-circuit/short-circuit-parameters-inline.tsx b/src/components/parameters/short-circuit/short-circuit-parameters-inline.tsx index afb3a9f3a..1d823c946 100644 --- a/src/components/parameters/short-circuit/short-circuit-parameters-inline.tsx +++ b/src/components/parameters/short-circuit/short-circuit-parameters-inline.tsx @@ -7,11 +7,11 @@ import { useCallback, useEffect, useState } from 'react'; import { Box, Grid } from '@mui/material'; -import { FormattedMessage, useIntl } from 'react-intl'; +import { useIntl } from 'react-intl'; import type { UUID } from 'node:crypto'; import { TreeViewFinderNodeProps } from '../../treeViewFinder'; import { useSnackMessage } from '../../../hooks'; -import { SubmitButton } from '../../inputs'; +import { ValidateButton } from '../../inputs'; import { ElementType, UseParametersBackendReturnProps } from '../../../utils'; import { ComputingType, LabelledButton } from '../common'; import { DirectoryItemSelector } from '../../directoryItemSelector'; @@ -86,15 +86,13 @@ export function ShortCircuitParametersInLine({ label="settings.button.chooseSettings" /> setOpenCreateParameterDialog(true)} label="save" /> - - - + disabled={!formState.isDirty} + /> {openCreateParameterDialog && ( - - - + {openCreateParameterDialog && ( - + ); diff --git a/src/components/treeViewFinder/TreeViewFinder.tsx b/src/components/treeViewFinder/TreeViewFinder.tsx index c48bb7ef6..c21f6fc83 100644 --- a/src/components/treeViewFinder/TreeViewFinder.tsx +++ b/src/components/treeViewFinder/TreeViewFinder.tsx @@ -5,23 +5,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import React, { ReactElement, useCallback, useEffect, useRef, useState } from 'react'; +import React, { ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useIntl } from 'react-intl'; import { - Button, - type ButtonProps, - Dialog, - DialogActions, - DialogContent, - DialogContentText, - DialogTitle, + Grid, type ModalProps, - styled, Typography, } from '@mui/material'; -import { TreeItem, SimpleTreeView, SimpleTreeViewClasses } from '@mui/x-tree-view'; +import { SimpleTreeView, SimpleTreeViewClasses, TreeItem } from '@mui/x-tree-view'; import { - Check as CheckIcon, ChevronRight as ChevronRightIcon, ExpandMore as ExpandMoreIcon, } from '@mui/icons-material'; @@ -29,38 +21,11 @@ import type { UUID } from 'node:crypto'; import { makeComposeClasses, type MuiStyles, toNestedGlobalSelectors } from '../../utils/styles'; import { CancelButton } from '../inputs/reactHookForm/utils/CancelButton'; import { ElementType } from '../../utils'; +import { ValidateButton } from '../inputs'; +import { Icon, Modal } from '@design-system-rte/react'; // As a bunch of individual variables to try to make it easier // to track that they are all used. Not sure, maybe group them in an object ? -const cssDialogPaper = 'dialogPaper'; -const cssLabelRoot = 'labelRoot'; -const cssLabelText = 'labelText'; -const cssLabelIcon = 'labelIcon'; -const cssIcon = 'icon'; - -// converted to nested rules -const defaultStyles = { - [cssDialogPaper]: { - minWidth: '50%', - }, - [cssLabelRoot]: { - display: 'flex', - alignContent: 'center', - alignItems: 'center', - }, - [cssLabelText]: { - fontWeight: 'inherit', - flexGrow: 1, - }, - [cssLabelIcon]: { - display: 'flex', - alignContent: 'center', - alignItems: 'center', - - marginRight: '4px', - }, - [cssIcon]: {}, -} as const satisfies MuiStyles; export const generateTreeViewFinderClass = (className: string) => `GsiTreeViewFinder-${className}`; const composeClasses = makeComposeClasses(generateTreeViewFinderClass); @@ -106,7 +71,6 @@ export interface TreeViewFinderProps { open: ModalProps['open']; onClose: (nodes: TreeViewFinderNodeProps[]) => void; validationButtonText?: string; - cancelButtonProps?: ButtonProps; title?: string; // data management props @@ -140,14 +104,12 @@ export interface TreeViewFinderProps { * @param {String} [validationButtonText=default text] - Customized Validation Button text (default: Add N Elements) * @param {Boolean} [onlyLeaves=true] - Allow/Forbid selection only on leaves * @param {Boolean} [multiSelect=false] - Allow/Forbid multiselection on Tree - * @param {Object} [cancelButtonProps] - The cancel button props * @param {Object} [selected] - ids of selected items * @param {Array} [expanded] - ids of the expanded items */ -function TreeViewFinderComponant(props: Readonly) { +export function TreeViewFinder(props: Readonly) { const intl = useIntl(); const { - classes = {}, title, contentText, open, @@ -160,8 +122,6 @@ function TreeViewFinderComponant(props: Readonly) { onlyLeaves = true, multiSelect = false, sortMethod, - className, - cancelButtonProps, selected: selectedProp, expanded: expandedProp, } = props; @@ -337,9 +297,9 @@ function TreeViewFinderComponant(props: Readonly) { }; /* Render utilities */ - const getValidationButtonText = () => { + const validationLabel = useMemo(() => { if (validationButtonText) { - return validationButtonText; + return { label: validationButtonText }; } let buttonLabelId = ''; if (Array.isArray(selectedProp)) { @@ -353,13 +313,13 @@ function TreeViewFinderComponant(props: Readonly) { : 'treeview_finder/addElementsValidation'; } - return intl.formatMessage( - { id: buttonLabelId }, - { + return { + label: buttonLabelId, + values: { nbElements: selected?.length, - } - ); - }; + }, + }; + }, [validationButtonText, selectedProp, selected]); const getNodeIcon = (node: TreeViewFinderNodeProps) => { if (!node) { @@ -367,20 +327,24 @@ function TreeViewFinderComponant(props: Readonly) { } if (isSelectable(node) && selected?.find((itemId) => itemId === node.id)) { - return ; + return ; } if (node.icon) { - return
{node.icon}
; + return
{node.icon}
; } return null; }; const renderTreeItemLabel = (node: TreeViewFinderNodeProps) => { return ( -
- {getNodeIcon(node)} - {node.name} -
+ + + {getNodeIcon(node)} + + + {node.name} + + ); }; @@ -408,14 +372,6 @@ function TreeViewFinderComponant(props: Readonly) { expandIcon: CustomExpandIcon, collapseIcon: CustomCollapseIcon, }} - slotProps={{ - expandIcon: { - className: composeClasses(classes, cssIcon), - }, - collapseIcon: { - className: composeClasses(classes, cssIcon), - }, - }} ref={(element) => { // Add to scroll ref if it's a selected element, or if no selected elements and it's an expanded element const shouldAddToScrollRef = @@ -447,68 +403,43 @@ function TreeViewFinderComponant(props: Readonly) { }; return ( - { - if (r === 'backdropClick') { - return; - } - if (r === 'escapeKeyDown') { + onClose([])} + primaryButton={ { + onClose?.(computeSelectedNodes()); + setSelected([]); + setAutoScrollAllowed(true); + }} + disabled={isValidationDisabled()} + />} + secondaryButton={ { onClose?.([]); setSelected([]); - } - }} + setAutoScrollAllowed(true); + }} + />} aria-labelledby="TreeViewFindertitle" - className={className} - classes={{ paper: composeClasses(classes, cssDialogPaper) }} data-testid="Dialog" + closeOnOverlayClick={false} > - - {title ?? intl.formatMessage({ id: 'treeview_finder/finderTitle' }, { multiSelect })} - - - - {contentText ?? intl.formatMessage({ id: 'treeview_finder/contentText' }, { multiSelect })} - - - - {data && Array.isArray(data) ? data.sort(sortMethod).map((child) => renderTree(child)) : null} - - - - { - onClose?.([]); - setSelected([]); - setAutoScrollAllowed(true); - }} - {...cancelButtonProps} - /> - - - + + {data && Array.isArray(data) ? data.sort(sortMethod).map((child) => renderTree(child)) : null} + +
); } - -const nestedGlobalSelectorsStyles = toNestedGlobalSelectors(defaultStyles, generateTreeViewFinderClass); - -export const TreeViewFinder = styled(TreeViewFinderComponant)(nestedGlobalSelectorsStyles);