From 5aefa49d7d80ce3cd7e79a1f70cb3c5aec66dd7d Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Thu, 21 Sep 2023 20:01:00 +1000
Subject: [PATCH] fix(ui): popover ref & wrapping of children (wip)

---
 invokeai/frontend/web/public/locales/en.json  | 18 ++--
 .../components/IAIInformationalPopover.tsx    | 86 +++++++++++--------
 .../components/IAIMantineMultiSelect.tsx      | 10 ++-
 .../components/IAIMantineSearchableSelect.tsx | 10 ++-
 .../common/components/IAIMantineSelect.tsx    | 10 ++-
 .../src/common/components/IAINumberInput.tsx  |  8 +-
 .../web/src/common/components/IAISlider.tsx   |  8 +-
 .../web/src/common/components/IAISwitch.tsx   |  2 +
 .../Parameters/Core/ParamIterations.tsx       |  4 +-
 .../Core/ParamNegativeConditioning.tsx        | 47 +++++-----
 .../Core/ParamPositiveConditioning.tsx        | 23 ++---
 .../MainModel/ParamMainModelSelect.tsx        | 18 ++--
 .../web/src/theme/components/popover.ts       |  2 +-
 13 files changed, 140 insertions(+), 106 deletions(-)

diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json
index c309e4de50..f48df3368f 100644
--- a/invokeai/frontend/web/public/locales/en.json
+++ b/invokeai/frontend/web/public/locales/en.json
@@ -1213,14 +1213,14 @@
         },
         "dynamicPromptsCombinatorial": {
             "heading": "Combinatorial Generation",
-            "paragraph": "Generate an image for every possible combination of Dynamic Prompt until the Max Prompts is reached."
+            "paragraph": "Generate an image for every possible combination of Dynamic Prompts until the Max Prompts is reached."
         },
         "infillMethod": {
             "heading": "Infill Method",
             "paragraph": "Method to infill the selected area."
         },
         "lora": {
-            "heading": "LoRA",
+            "heading": "LoRA Weight",
             "paragraph": "Weight of the LoRA. Higher weight will lead to larger impacts on the final image."
         },
         "noiseEnable": {
@@ -1239,21 +1239,21 @@
             "heading": "Denoising Strength",
             "paragraph": "How much noise is added to the input image. 0 will result in an identical image, while 1 will result in a completely new image."
         },
-        "paramImages": {
-            "heading": "Images",
-            "paragraph": "Number of images that will be generated."
+        "paramIterations": {
+            "heading": "Iterations",
+            "paragraph": "The number of images to generate. If Dynamic Prompts is enabled, each of the prompts will be generated this many times."
         },
         "paramModel": {
             "heading": "Model",
             "paragraph": "Model used for the denoising steps. Different models are trained to specialize in producing different aesthetic results and content."
         },
         "paramNegativeConditioning": {
-            "heading": "Negative Prompts",
-            "paragraph": "This is where you enter your negative prompts."
+            "heading": "Negative Prompt",
+            "paragraph": "The generation process avoids the concepts in the negative prompt. Use this to exclude qualities or objects from the output. Supports Compel syntax and embeddings."
         },
         "paramPositiveConditioning": {
-            "heading": "Positive Prompts",
-            "paragraph": "This is where you enter your positive prompts."
+            "heading": "Positive Prompt",
+            "paragraph": "Guides the generation process. You may use any words or phrases. Supports Compel and Dynamic Prompts syntaxes and embeddings."
         },
         "paramRatio": {
             "heading": "Ratio",
diff --git a/invokeai/frontend/web/src/common/components/IAIInformationalPopover.tsx b/invokeai/frontend/web/src/common/components/IAIInformationalPopover.tsx
index 876ce6488a..4a9dd82665 100644
--- a/invokeai/frontend/web/src/common/components/IAIInformationalPopover.tsx
+++ b/invokeai/frontend/web/src/common/components/IAIInformationalPopover.tsx
@@ -1,37 +1,43 @@
 import {
+  Box,
   Button,
-  Popover,
-  PopoverTrigger,
-  PopoverContent,
-  PopoverArrow,
-  PopoverCloseButton,
-  PopoverHeader,
-  PopoverBody,
-  PopoverProps,
+  Divider,
   Flex,
-  Text,
+  Heading,
   Image,
+  Popover,
+  PopoverArrow,
+  PopoverBody,
+  PopoverCloseButton,
+  PopoverContent,
+  PopoverProps,
+  PopoverTrigger,
+  Portal,
+  Text,
 } from '@chakra-ui/react';
-import { useAppSelector } from '../../app/store/storeHooks';
+import { ReactNode, memo } from 'react';
 import { useTranslation } from 'react-i18next';
+import { useAppSelector } from '../../app/store/storeHooks';
 
-interface Props extends PopoverProps {
+const OPEN_DELAY = 1500;
+
+type Props = Omit<PopoverProps, 'children'> & {
   details: string;
-  children: JSX.Element;
+  children: ReactNode;
   image?: string;
   buttonLabel?: string;
   buttonHref?: string;
   placement?: PopoverProps['placement'];
-}
+};
 
-function IAIInformationalPopover({
+const IAIInformationalPopover = ({
   details,
   image,
   buttonLabel,
   buttonHref,
   children,
   placement,
-}: Props): JSX.Element {
+}: Props) => {
   const shouldEnableInformationalPopovers = useAppSelector(
     (state) => state.system.shouldEnableInformationalPopovers
   );
@@ -41,18 +47,21 @@ function IAIInformationalPopover({
   const paragraph = t(`popovers.${details}.paragraph`);
 
   if (!shouldEnableInformationalPopovers) {
-    return children;
-  } else {
-    return (
-      <Popover
-        placement={placement || 'top'}
-        closeOnBlur={false}
-        trigger="hover"
-        variant="informational"
-      >
-        <PopoverTrigger>
-          <div>{children}</div>
-        </PopoverTrigger>
+    return <>{children}</>;
+  }
+
+  return (
+    <Popover
+      placement={placement || 'top'}
+      closeOnBlur={false}
+      trigger="hover"
+      variant="informational"
+      openDelay={OPEN_DELAY}
+    >
+      <PopoverTrigger>
+        <Box w="full">{children}</Box>
+      </PopoverTrigger>
+      <Portal>
         <PopoverContent>
           <PopoverArrow />
           <PopoverCloseButton />
@@ -83,14 +92,17 @@ function IAIInformationalPopover({
                   gap: 3,
                   flexDirection: 'column',
                   width: '100%',
-                  p: 3,
-                  pt: heading ? 0 : 3,
                 }}
               >
-                {heading && <PopoverHeader>{heading}</PopoverHeader>}
-                <Text sx={{ px: 3 }}>{paragraph}</Text>
+                {heading && (
+                  <>
+                    <Heading size="sm">{heading}</Heading>
+                    <Divider />
+                  </>
+                )}
+                <Text>{paragraph}</Text>
                 {buttonLabel && (
-                  <Flex sx={{ px: 3 }} justifyContent="flex-end">
+                  <Flex justifyContent="flex-end">
                     <Button
                       onClick={() => window.open(buttonHref)}
                       size="sm"
@@ -104,9 +116,9 @@ function IAIInformationalPopover({
             </Flex>
           </PopoverBody>
         </PopoverContent>
-      </Popover>
-    );
-  }
-}
+      </Portal>
+    </Popover>
+  );
+};
 
-export default IAIInformationalPopover;
+export default memo(IAIInformationalPopover);
diff --git a/invokeai/frontend/web/src/common/components/IAIMantineMultiSelect.tsx b/invokeai/frontend/web/src/common/components/IAIMantineMultiSelect.tsx
index 28c680b824..07a7ada88d 100644
--- a/invokeai/frontend/web/src/common/components/IAIMantineMultiSelect.tsx
+++ b/invokeai/frontend/web/src/common/components/IAIMantineMultiSelect.tsx
@@ -1,4 +1,4 @@
-import { FormControl, FormLabel, Tooltip } from '@chakra-ui/react';
+import { FormControl, FormLabel, Tooltip, forwardRef } from '@chakra-ui/react';
 import { MultiSelect, MultiSelectProps } from '@mantine/core';
 import { useAppDispatch } from 'app/store/storeHooks';
 import { shiftKeyPressed } from 'features/ui/store/hotkeysSlice';
@@ -11,7 +11,7 @@ type IAIMultiSelectProps = Omit<MultiSelectProps, 'label'> & {
   label?: string;
 };
 
-const IAIMantineMultiSelect = (props: IAIMultiSelectProps) => {
+const IAIMantineMultiSelect = forwardRef((props: IAIMultiSelectProps, ref) => {
   const {
     searchable = true,
     tooltip,
@@ -47,7 +47,7 @@ const IAIMantineMultiSelect = (props: IAIMultiSelectProps) => {
       <MultiSelect
         label={
           label ? (
-            <FormControl isDisabled={disabled}>
+            <FormControl ref={ref} isDisabled={disabled}>
               <FormLabel>{label}</FormLabel>
             </FormControl>
           ) : undefined
@@ -63,6 +63,8 @@ const IAIMantineMultiSelect = (props: IAIMultiSelectProps) => {
       />
     </Tooltip>
   );
-};
+});
+
+IAIMantineMultiSelect.displayName = 'IAIMantineMultiSelect';
 
 export default memo(IAIMantineMultiSelect);
diff --git a/invokeai/frontend/web/src/common/components/IAIMantineSearchableSelect.tsx b/invokeai/frontend/web/src/common/components/IAIMantineSearchableSelect.tsx
index 079421d4e5..1ed8490848 100644
--- a/invokeai/frontend/web/src/common/components/IAIMantineSearchableSelect.tsx
+++ b/invokeai/frontend/web/src/common/components/IAIMantineSearchableSelect.tsx
@@ -1,4 +1,4 @@
-import { FormControl, FormLabel, Tooltip } from '@chakra-ui/react';
+import { FormControl, FormLabel, Tooltip, forwardRef } from '@chakra-ui/react';
 import { Select, SelectProps } from '@mantine/core';
 import { useAppDispatch } from 'app/store/storeHooks';
 import { shiftKeyPressed } from 'features/ui/store/hotkeysSlice';
@@ -17,7 +17,7 @@ type IAISelectProps = Omit<SelectProps, 'label'> & {
   inputRef?: RefObject<HTMLInputElement>;
 };
 
-const IAIMantineSearchableSelect = (props: IAISelectProps) => {
+const IAIMantineSearchableSelect = forwardRef((props: IAISelectProps, ref) => {
   const {
     searchable = true,
     tooltip,
@@ -74,7 +74,7 @@ const IAIMantineSearchableSelect = (props: IAISelectProps) => {
         ref={inputRef}
         label={
           label ? (
-            <FormControl isDisabled={disabled}>
+            <FormControl ref={ref} isDisabled={disabled}>
               <FormLabel>{label}</FormLabel>
             </FormControl>
           ) : undefined
@@ -92,6 +92,8 @@ const IAIMantineSearchableSelect = (props: IAISelectProps) => {
       />
     </Tooltip>
   );
-};
+});
+
+IAIMantineSearchableSelect.displayName = 'IAIMantineSearchableSelect';
 
 export default memo(IAIMantineSearchableSelect);
diff --git a/invokeai/frontend/web/src/common/components/IAIMantineSelect.tsx b/invokeai/frontend/web/src/common/components/IAIMantineSelect.tsx
index 46b5fc95f6..19c116bfd5 100644
--- a/invokeai/frontend/web/src/common/components/IAIMantineSelect.tsx
+++ b/invokeai/frontend/web/src/common/components/IAIMantineSelect.tsx
@@ -1,4 +1,4 @@
-import { FormControl, FormLabel, Tooltip } from '@chakra-ui/react';
+import { FormControl, FormLabel, Tooltip, forwardRef } from '@chakra-ui/react';
 import { Select, SelectProps } from '@mantine/core';
 import { useMantineSelectStyles } from 'mantine-theme/hooks/useMantineSelectStyles';
 import { RefObject, memo } from 'react';
@@ -15,7 +15,7 @@ export type IAISelectProps = Omit<SelectProps, 'label'> & {
   label?: string;
 };
 
-const IAIMantineSelect = (props: IAISelectProps) => {
+const IAIMantineSelect = forwardRef((props: IAISelectProps, ref) => {
   const { tooltip, inputRef, label, disabled, required, ...rest } = props;
 
   const styles = useMantineSelectStyles();
@@ -25,7 +25,7 @@ const IAIMantineSelect = (props: IAISelectProps) => {
       <Select
         label={
           label ? (
-            <FormControl isRequired={required} isDisabled={disabled}>
+            <FormControl ref={ref} isRequired={required} isDisabled={disabled}>
               <FormLabel>{label}</FormLabel>
             </FormControl>
           ) : undefined
@@ -37,6 +37,8 @@ const IAIMantineSelect = (props: IAISelectProps) => {
       />
     </Tooltip>
   );
-};
+});
+
+IAIMantineSelect.displayName = 'IAIMantineSelect';
 
 export default memo(IAIMantineSelect);
diff --git a/invokeai/frontend/web/src/common/components/IAINumberInput.tsx b/invokeai/frontend/web/src/common/components/IAINumberInput.tsx
index de3b44564a..243dac9d63 100644
--- a/invokeai/frontend/web/src/common/components/IAINumberInput.tsx
+++ b/invokeai/frontend/web/src/common/components/IAINumberInput.tsx
@@ -13,6 +13,7 @@ import {
   NumberInputStepperProps,
   Tooltip,
   TooltipProps,
+  forwardRef,
 } from '@chakra-ui/react';
 import { useAppDispatch } from 'app/store/storeHooks';
 import { stopPastePropagation } from 'common/util/stopPastePropagation';
@@ -50,7 +51,7 @@ interface Props extends Omit<NumberInputProps, 'onChange'> {
 /**
  * Customized Chakra FormControl + NumberInput multi-part component.
  */
-const IAINumberInput = (props: Props) => {
+const IAINumberInput = forwardRef((props: Props, ref) => {
   const {
     label,
     isDisabled = false,
@@ -141,6 +142,7 @@ const IAINumberInput = (props: Props) => {
   return (
     <Tooltip {...tooltipProps}>
       <FormControl
+        ref={ref}
         isDisabled={isDisabled}
         isInvalid={isInvalid}
         {...formControlProps}
@@ -172,6 +174,8 @@ const IAINumberInput = (props: Props) => {
       </FormControl>
     </Tooltip>
   );
-};
+});
+
+IAINumberInput.displayName = 'IAINumberInput';
 
 export default memo(IAINumberInput);
diff --git a/invokeai/frontend/web/src/common/components/IAISlider.tsx b/invokeai/frontend/web/src/common/components/IAISlider.tsx
index fd3eed754f..e879c00977 100644
--- a/invokeai/frontend/web/src/common/components/IAISlider.tsx
+++ b/invokeai/frontend/web/src/common/components/IAISlider.tsx
@@ -22,6 +22,7 @@ import {
   SliderTrackProps,
   Tooltip,
   TooltipProps,
+  forwardRef,
 } from '@chakra-ui/react';
 import { useAppDispatch } from 'app/store/storeHooks';
 import { roundDownToMultiple } from 'common/util/roundDownToMultiple';
@@ -71,7 +72,7 @@ export type IAIFullSliderProps = {
   sliderIAIIconButtonProps?: IAIIconButtonProps;
 };
 
-const IAISlider = (props: IAIFullSliderProps) => {
+const IAISlider = forwardRef((props: IAIFullSliderProps, ref) => {
   const [showTooltip, setShowTooltip] = useState(false);
   const {
     label,
@@ -187,6 +188,7 @@ const IAISlider = (props: IAIFullSliderProps) => {
 
   return (
     <FormControl
+      ref={ref}
       onClick={forceInputBlur}
       sx={
         isCompact
@@ -354,6 +356,8 @@ const IAISlider = (props: IAIFullSliderProps) => {
       </HStack>
     </FormControl>
   );
-};
+});
+
+IAISlider.displayName = 'IAISlider';
 
 export default memo(IAISlider);
diff --git a/invokeai/frontend/web/src/common/components/IAISwitch.tsx b/invokeai/frontend/web/src/common/components/IAISwitch.tsx
index da0883d77e..8773be49e5 100644
--- a/invokeai/frontend/web/src/common/components/IAISwitch.tsx
+++ b/invokeai/frontend/web/src/common/components/IAISwitch.tsx
@@ -72,4 +72,6 @@ const IAISwitch = (props: IAISwitchProps) => {
   );
 };
 
+IAISwitch.displayName = 'IAISwitch';
+
 export default memo(IAISwitch);
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamIterations.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamIterations.tsx
index f9df43d7ca..429291190b 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamIterations.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamIterations.tsx
@@ -61,7 +61,7 @@ const ParamIterations = ({ asSlider }: Props) => {
   }, [dispatch, initial]);
 
   return asSlider || shouldUseSliders ? (
-    <IAIInformationalPopover details="paramImages">
+    <IAIInformationalPopover details="paramIterations">
       <IAISlider
         label={t('parameters.iterations')}
         step={step}
@@ -77,7 +77,7 @@ const ParamIterations = ({ asSlider }: Props) => {
       />
     </IAIInformationalPopover>
   ) : (
-    <IAIInformationalPopover details="paramImages">
+    <IAIInformationalPopover details="paramIterations">
       <IAINumberInput
         label={t('parameters.iterations')}
         step={step}
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamNegativeConditioning.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamNegativeConditioning.tsx
index 1154187eaf..a54b1489e3 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamNegativeConditioning.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamNegativeConditioning.tsx
@@ -1,6 +1,7 @@
 import { Box, FormControl, useDisclosure } from '@chakra-ui/react';
 import type { RootState } from 'app/store/store';
 import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
+import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
 import IAITextarea from 'common/components/IAITextarea';
 import AddEmbeddingButton from 'features/embedding/components/AddEmbeddingButton';
 import ParamEmbeddingPopover from 'features/embedding/components/ParamEmbeddingPopover';
@@ -9,7 +10,6 @@ import { ChangeEvent, KeyboardEvent, memo, useCallback, useRef } from 'react';
 import { flushSync } from 'react-dom';
 import { useTranslation } from 'react-i18next';
 import { useFeatureStatus } from '../../../../system/hooks/useFeatureStatus';
-import IAIInformationalPopover from 'common/components/IAIInformationalPopover';
 
 const ParamNegativeConditioning = () => {
   const negativePrompt = useAppSelector(
@@ -76,13 +76,16 @@ const ParamNegativeConditioning = () => {
   const isEmbeddingEnabled = useFeatureStatus('embedding').isFeatureEnabled;
 
   return (
-    <FormControl>
-      <ParamEmbeddingPopover
-        isOpen={isOpen}
-        onClose={onClose}
-        onSelect={handleSelectEmbedding}
-      >
-        <IAIInformationalPopover details="paramNegativeConditioning">
+    <IAIInformationalPopover
+      placement="right"
+      details="paramNegativeConditioning"
+    >
+      <FormControl>
+        <ParamEmbeddingPopover
+          isOpen={isOpen}
+          onClose={onClose}
+          onSelect={handleSelectEmbedding}
+        >
           <IAITextarea
             id="negativePrompt"
             name="negativePrompt"
@@ -95,20 +98,20 @@ const ParamNegativeConditioning = () => {
             minH={16}
             {...(isEmbeddingEnabled && { onKeyDown: handleKeyDown })}
           />
-        </IAIInformationalPopover>
-      </ParamEmbeddingPopover>
-      {!isOpen && isEmbeddingEnabled && (
-        <Box
-          sx={{
-            position: 'absolute',
-            top: 0,
-            insetInlineEnd: 0,
-          }}
-        >
-          <AddEmbeddingButton onClick={onOpen} />
-        </Box>
-      )}
-    </FormControl>
+        </ParamEmbeddingPopover>
+        {!isOpen && isEmbeddingEnabled && (
+          <Box
+            sx={{
+              position: 'absolute',
+              top: 0,
+              insetInlineEnd: 0,
+            }}
+          >
+            <AddEmbeddingButton onClick={onOpen} />
+          </Box>
+        )}
+      </FormControl>
+    </IAIInformationalPopover>
   );
 };
 
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamPositiveConditioning.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamPositiveConditioning.tsx
index 8a78621463..9ff616084d 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamPositiveConditioning.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamPositiveConditioning.tsx
@@ -104,13 +104,16 @@ const ParamPositiveConditioning = () => {
 
   return (
     <Box position="relative">
-      <FormControl>
-        <ParamEmbeddingPopover
-          isOpen={isOpen}
-          onClose={onClose}
-          onSelect={handleSelectEmbedding}
-        >
-          <IAIInformationalPopover details="paramPositiveConditioning">
+      <IAIInformationalPopover
+        placement="right"
+        details="paramPositiveConditioning"
+      >
+        <FormControl>
+          <ParamEmbeddingPopover
+            isOpen={isOpen}
+            onClose={onClose}
+            onSelect={handleSelectEmbedding}
+          >
             <IAITextarea
               id="prompt"
               name="prompt"
@@ -122,9 +125,9 @@ const ParamPositiveConditioning = () => {
               resize="vertical"
               minH={32}
             />
-          </IAIInformationalPopover>
-        </ParamEmbeddingPopover>
-      </FormControl>
+          </ParamEmbeddingPopover>
+        </FormControl>
+      </IAIInformationalPopover>
       {!isOpen && isEmbeddingEnabled && (
         <Box
           sx={{
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/MainModel/ParamMainModelSelect.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/MainModel/ParamMainModelSelect.tsx
index 9c957523bc..4252310fc0 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/MainModel/ParamMainModelSelect.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/MainModel/ParamMainModelSelect.tsx
@@ -119,8 +119,8 @@ const ParamMainModelSelect = () => {
       data={[]}
     />
   ) : (
-    <IAIInformationalPopover details="paramModel" placement="bottom">
-      <Flex w="100%" alignItems="center" gap={3}>
+    <Flex w="100%" alignItems="center" gap={3}>
+      <IAIInformationalPopover details="paramModel" placement="bottom">
         <IAIMantineSearchableSelect
           tooltip={selectedModel?.description}
           label={t('modelManager.model')}
@@ -134,13 +134,13 @@ const ParamMainModelSelect = () => {
           onChange={handleChangeModel}
           w="100%"
         />
-        {isSyncModelEnabled && (
-          <Box mt={7}>
-            <SyncModelsButton iconMode />
-          </Box>
-        )}
-      </Flex>
-    </IAIInformationalPopover>
+      </IAIInformationalPopover>
+      {isSyncModelEnabled && (
+        <Box mt={7}>
+          <SyncModelsButton iconMode />
+        </Box>
+      )}
+    </Flex>
   );
 };
 
diff --git a/invokeai/frontend/web/src/theme/components/popover.ts b/invokeai/frontend/web/src/theme/components/popover.ts
index 55f69e9036..0facb25849 100644
--- a/invokeai/frontend/web/src/theme/components/popover.ts
+++ b/invokeai/frontend/web/src/theme/components/popover.ts
@@ -37,7 +37,7 @@ const informationalContent = defineStyle((props) => {
       'colors.base.400',
       'colors.base.400'
     )(props),
-    p: 0,
+    p: 4,
     bg: mode('base.100', 'base.600')(props),
     border: 'none',
     shadow: 'dark-lg',