@spothero/ui 25.1.5 → 25.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import { Modal as Modal$1, ModalOverlay, ModalContent, Box, ModalCloseButton, keyframes, theme as theme$2, Button as Button$2, Drawer as Drawer$1, DrawerOverlay, DrawerContent, DrawerHeader, DrawerCloseButton, Alert as Alert$1, Icon, VStack, AlertTitle, AlertDescription, Flex, forwardRef as forwardRef$1, Tabs as Tabs$1, FormControl as FormControl$2, FormLabel, Text as Text$1, FormHelperText, FormErrorMessage, Select as Select$2, Switch as Switch$1, Grid as Grid$1, GridItem as GridItem$1, List as List$1, Spinner as Spinner$1, Heading as Heading$1, Container as Container$1, createMultiStyleConfigHelpers, extendTheme, ChakraProvider, Img, Image as Image$1, CircularProgress, Progress as Progress$1, Checkbox as Checkbox$1, Input as Input$2, InputGroup, InputLeftElement, InputRightElement, useTheme, Radio as Radio$1, RadioGroup as RadioGroup$1, Stack, usePrefersReducedMotion, Divider as Divider$1, Textarea as Textarea$1, Popover as Popover$1, PopoverArrow as PopoverArrow$1, PopoverCloseButton as PopoverCloseButton$1, PopoverContent as PopoverContent$1, PopoverHeader, PopoverBody, ButtonGroup, Menu as Menu$1 } from '@chakra-ui/react';
3
- export { Accordion, AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, AspectRatio, Badge, Input as BasicInput, Textarea as BasicTextarea, Box, Breadcrumb, BreadcrumbItem, BreadcrumbLink, ButtonGroup, Center, CheckboxGroup, Circle, Code, Collapse, DrawerBody, DrawerCloseButton, Drawer as DrawerContainer, DrawerContent, DrawerFooter, DrawerHeader, DrawerOverlay, Fade, Flex, HStack, Icon, InputGroup, InputLeftAddon, InputLeftElement, InputRightAddon, InputRightElement, Kbd, Link, LinkBox, LinkOverlay, ListItem, MenuButton, MenuDivider, MenuGroup, MenuItem, MenuItemOption, MenuList, MenuOptionGroup, ModalBody, ModalFooter, ModalHeader, PopoverAnchor, PopoverTrigger, Portal, ScaleFade, SimpleGrid, Skeleton, SkeletonCircle, SkeletonText, Slide, SlideFade, Square, Tab, TabList, TabPanel, TabPanels, Table, TableCaption, TableContainer, Tbody, Td, Tfoot, Th, Thead, Tooltip, Tr, VStack, createIcon, keyframes, useBreakpointValue, useClipboard, useControllableProp, useControllableState, useDisclosure, useMediaQuery, usePopper, usePrefersReducedMotion, useStyleConfig, useTheme, useToast, useToken } from '@chakra-ui/react';
3
+ export { Accordion, AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, AspectRatio, Badge, Input as BasicInput, Textarea as BasicTextarea, Box, Breadcrumb, BreadcrumbItem, BreadcrumbLink, ButtonGroup, Center, CheckboxGroup, Circle, Code, Collapse, DrawerBody, DrawerCloseButton, Drawer as DrawerContainer, DrawerContent, DrawerFooter, DrawerHeader, DrawerOverlay, Fade, Flex, HStack, Icon, InputGroup, InputLeftAddon, InputLeftElement, InputRightAddon, InputRightElement, Kbd, Link, LinkBox, LinkOverlay, ListItem, MenuButton, MenuDivider, MenuGroup, MenuItem, MenuItemOption, MenuList, MenuOptionGroup, ModalBody, ModalFooter, ModalHeader, PopoverAnchor, PopoverTrigger, Portal, ScaleFade, SimpleGrid, Skeleton, SkeletonCircle, SkeletonText, Slide, SlideFade, Square, Tab, TabList, TabPanel, TabPanels, Table, TableCaption, TableContainer, Tbody, Td, Tfoot, Th, Thead, Tooltip, Tr, VStack, createIcon, extendTheme, keyframes, useBreakpointValue, useClipboard, useControllableProp, useControllableState, useDisclosure, useMediaQuery, usePopper, usePrefersReducedMotion, useStyleConfig, useTheme, useToast, useToken } from '@chakra-ui/react';
4
4
  import * as React from 'react';
5
5
  import React__default, { forwardRef, useState, useEffect, Children, cloneElement } from 'react';
6
6
  import merge from 'lodash/merge';
@@ -9,7 +9,7 @@ import { accordionAnatomy, selectAnatomy } from '@chakra-ui/anatomy';
9
9
  import template from 'lodash/template';
10
10
  import cn from 'classnames';
11
11
  import AsyncSelect from 'react-select/async';
12
- import { motion } from 'framer-motion';
12
+ import { motion, AnimatePresence } from 'framer-motion';
13
13
  import Creatable from 'react-select/creatable';
14
14
  import { components as components$1 } from 'react-select';
15
15
 
@@ -748,6 +748,19 @@ var base = /*#__PURE__*/Object.freeze({
748
748
  zIndices: indices
749
749
  });
750
750
 
751
+ const heightProps = function () {
752
+ let height = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'md';
753
+ const heights = {
754
+ md: {},
755
+ lg: {
756
+ height: 12,
757
+ lineHeight: sizes$6['6']
758
+ }
759
+ };
760
+ return heights[height] || {
761
+ height // when a custom height is provided, pass it as is
762
+ };
763
+ };
751
764
  const baseStyle$f = {
752
765
  px: 8,
753
766
  py: 3,
@@ -757,7 +770,7 @@ const baseStyle$f = {
757
770
  fontWeight: 'semibold',
758
771
  borderWidth: '1px',
759
772
  borderStyle: 'solid',
760
- borderRadius: '1.25rem',
773
+ borderRadius: 'md',
761
774
  textTransform: 'capitalize',
762
775
  transition: 'all normal ease',
763
776
  _disabled: {
@@ -788,25 +801,78 @@ const destructiveButtonStyles = {
788
801
  color: 'red.800'
789
802
  }, disabledButtonHoverStyle)
790
803
  };
804
+
805
+ /**
806
+ * ## OKLCH Color Adjustments Reference
807
+ * | State | OKLCH Calculation | Visual Effect |
808
+ * |-------|-------------------|---------------|
809
+ * | Default | `primary.default` | Base color |
810
+ * | Hover (light bg) | `calc(l - 0.1)` | 10% darker (lightness) |
811
+ * | Active/Pressed | `calc(l - 0.15)` | 15% darker (lightness) |
812
+ * | Hover (secondary) | `calc(l - 0.3)` | 3% darker (lightness) |
813
+ * | Active/Pressed (secondary) | `calc(l - 0.6)` | 6% darker (lightness) |
814
+ * | Hover (dark bg) | `calc(l + 0.1)` | 10% lighter (lightness) |
815
+ * | Disabled | `opacity: 0.4` | 60% transparent |
816
+ */
817
+
818
+ //Helper function to make oklch color strings
819
+ const generateOklchColor = (colorVar, adjustment) => {
820
+ return "oklch(from var(--chakra-colors-".concat(colorVar, ") calc(l ").concat(adjustment, ") c h)");
821
+ };
822
+
823
+ // 10% darker (lightness)
824
+ const hoverPrimaryColor = generateOklchColor('primary-default', '- 0.1');
825
+ // 15% darker (lightness)
826
+ const activePrimaryColor = generateOklchColor('primary-default', '- 0.15');
827
+ // 3% darker (lightness)
828
+ const hoverSecondaryColor = generateOklchColor('white', '- 0.03');
829
+ // 6% darker (lightness)
830
+ const activeSecondaryColor = generateOklchColor('white', '- 0.06');
831
+ // 10% lighter (lightness)
832
+ const hoverDarkColor = generateOklchColor('yellow-default', '+ 0.1');
833
+
834
+ /**
835
+ * Button Variants - Simplified Color System Using OKLCH
836
+ *
837
+ * This implementation uses OKLCH relative color syntax for perceptually uniform color adjustments.
838
+ * Benefits:
839
+ * - White-label theming: Only need ONE brand color (primary.default)
840
+ * - No package dependencies (native CSS)
841
+ * - Text color NOT affected (unlike CSS filters)
842
+ * - Perceptually uniform adjustments (10% lighter looks consistent across all hues)
843
+ * - Can adjust lightness, chroma, or hue independently
844
+ * - Future-proof modern CSS standard
845
+ *
846
+ * OKLCH Syntax: oklch(from <color> <lightness> <chroma> <hue>)
847
+ * - Lightness adjustments: calc(l - 0.1) = 10% darker, calc(l + 0.1) = 10% lighter
848
+ * - Works with any color format (hex, rgb, etc.) - CSS converts automatically
849
+ *
850
+ * Browser Support: Chrome 111+, Safari 16.4+, Firefox 113+ (Mar-May 2023)
851
+ * Fallback: Older browsers use base color without hover effect degradation
852
+ *
853
+ * Note: Destructive variants still use semantic red for safety/UX consistency
854
+ */
791
855
  const variants$d = {
792
856
  primary: {
793
857
  bg: 'primary.default',
794
858
  borderColor: 'primary.default',
795
859
  color: 'white',
796
860
  _hover: _objectSpread2({
797
- bg: 'primary.600',
798
- borderColor: 'primary.600',
799
- color: 'white'
800
- }, disabledButtonHoverStyle)
861
+ bg: hoverPrimaryColor,
862
+ borderColor: hoverPrimaryColor
863
+ }, disabledButtonHoverStyle),
864
+ _active: {
865
+ bg: activePrimaryColor,
866
+ borderColor: activePrimaryColor
867
+ }
801
868
  },
802
869
  primaryOnDark: {
803
870
  bg: 'yellow.default',
804
871
  borderColor: 'yellow.default',
805
872
  color: 'black',
806
873
  _hover: _objectSpread2({
807
- bg: 'yellow.500',
808
- borderColor: 'yellow.500',
809
- color: 'black'
874
+ bg: hoverDarkColor,
875
+ borderColor: hoverDarkColor
810
876
  }, disabledButtonHoverStyle),
811
877
  _focus: {
812
878
  boxShadow: '0 0 0 3px rgba(255, 255, 255, 0.7)'
@@ -817,18 +883,18 @@ const variants$d = {
817
883
  borderColor: 'gray.medium',
818
884
  color: 'primary.default',
819
885
  _hover: _objectSpread2({
820
- borderColor: 'primary.600',
821
- color: 'primary.600'
822
- }, disabledButtonHoverStyle)
886
+ bg: hoverSecondaryColor
887
+ }, disabledButtonHoverStyle),
888
+ _active: {
889
+ bg: activeSecondaryColor
890
+ }
823
891
  },
824
892
  secondaryOnDark: {
825
893
  bg: 'none',
826
894
  borderColor: 'white',
827
895
  color: 'white',
828
896
  _hover: _objectSpread2({
829
- bg: 'white',
830
- borderColor: 'white',
831
- color: 'black'
897
+ bg: 'white'
832
898
  }, disabledButtonHoverStyle),
833
899
  _focus: {
834
900
  boxShadow: '0 0 0 3px rgba(255, 255, 255, 0.7)'
@@ -849,13 +915,11 @@ const variants$d = {
849
915
  color: 'gray.dark'
850
916
  },
851
917
  _hover: {
852
- color: 'primary.600',
853
918
  _disabled: {
854
919
  color: 'gray.dark'
855
920
  }
856
921
  },
857
922
  _active: {
858
- color: 'primary.600',
859
923
  _disabled: {
860
924
  color: 'gray.dark'
861
925
  }
@@ -873,13 +937,13 @@ const variants$d = {
873
937
  _disabled: {
874
938
  bg: 'none',
875
939
  color: 'white',
876
- opacity: '.7'
940
+ opacity: 0.4
877
941
  },
878
942
  _hover: {
879
943
  color: 'white',
880
- opacity: '.8',
944
+ opacity: 0.8,
881
945
  _disabled: {
882
- opacity: '.7'
946
+ opacity: 0.4
883
947
  }
884
948
  }
885
949
  },
@@ -964,20 +1028,6 @@ const anchorProps = function () {
964
1028
  rel: 'noopener noreferrer'
965
1029
  });
966
1030
  };
967
- const heightProps = function () {
968
- let height = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'md';
969
- const heights = {
970
- md: {},
971
- lg: {
972
- height: 12,
973
- borderRadius: sizes$6['6'],
974
- lineHeight: sizes$6['6']
975
- }
976
- };
977
- return heights[height] || {
978
- height // when a custom height is provided, pass it as is
979
- };
980
- };
981
1031
  const Button$1 = /*#__PURE__*/forwardRef((_ref, ref) => {
982
1032
  let {
983
1033
  asAnchor,
@@ -3569,7 +3619,7 @@ const controlStyles = {
3569
3619
  color: 'gray.600'
3570
3620
  },
3571
3621
  '& + label': {
3572
- color: 'error'
3622
+ color: 'text.secondary.light'
3573
3623
  },
3574
3624
  '& + label .chakra-form__required-indicator': {
3575
3625
  //Styling for asterisk always to be red if invalid
@@ -4170,7 +4220,7 @@ RadioGroup.propTypes = {
4170
4220
  direction: PropTypes.oneOf(['row', 'column'])
4171
4221
  };
4172
4222
 
4173
- const _excluded$5 = ["isChecked", "isDisabled", "value", "helperText", "expandableChildren", "defaultChecked", "isRadio", "label", "isExpandable", "size", "expandableChildrenStyles", "topChild"];
4223
+ const _excluded$5 = ["isChecked", "isDisabled", "value", "helperText", "expandableChildren", "defaultChecked", "isRadio", "label", "isExpandable", "size", "expandableChildrenStyles", "topChild", "expandableContentKey"];
4174
4224
  const SelectionCard = /*#__PURE__*/forwardRef((_ref, ref) => {
4175
4225
  let {
4176
4226
  isChecked,
@@ -4184,15 +4234,23 @@ const SelectionCard = /*#__PURE__*/forwardRef((_ref, ref) => {
4184
4234
  isExpandable,
4185
4235
  size = 'md',
4186
4236
  expandableChildrenStyles = {},
4187
- topChild
4237
+ topChild,
4238
+ expandableContentKey = 'selection-card-content'
4188
4239
  } = _ref,
4189
4240
  props = _objectWithoutProperties(_ref, _excluded$5);
4190
4241
  const Component = isRadio ? Radio : Checkbox;
4191
4242
  const expandableTextSize = size === 'sm' || size === 'md' ? 'xs' : 'sm';
4192
4243
  const hasExpandableContent = isExpandable && isChecked && expandableChildren;
4193
4244
  const prefersReducedMotion = usePrefersReducedMotion();
4245
+
4246
+ // Create a unique key based on the content to force re-animation
4247
+ const contentKey = React__default.useMemo(() => {
4248
+ if (typeof expandableChildren === 'string') {
4249
+ return expandableChildren;
4250
+ }
4251
+ return expandableContentKey || JSON.stringify(expandableChildren === null || expandableChildren === void 0 ? void 0 : expandableChildren.props) || Math.random();
4252
+ }, [expandableChildren, expandableContentKey]);
4194
4253
  return /*#__PURE__*/React__default.createElement(Box, {
4195
- paddingBottom: hasExpandableContent ? 3 : 0,
4196
4254
  borderRadius: "lg",
4197
4255
  borderColor: isChecked ? 'primary.default' : 'gray.medium',
4198
4256
  borderWidth: "1px",
@@ -4215,21 +4273,34 @@ const SelectionCard = /*#__PURE__*/forwardRef((_ref, ref) => {
4215
4273
  width: "100%",
4216
4274
  paddingX: 4,
4217
4275
  paddingY: 3
4218
- }, props), label)), /*#__PURE__*/React__default.createElement(Box, {
4219
- overflow: "hidden",
4220
- display: "grid"
4221
- // Using this as a pseudo height transition to get around no height auto transition
4222
- ,
4223
- gridTemplateRows: hasExpandableContent ? '1fr' : '0fr',
4224
- opacity: hasExpandableContent ? '100%' : '0%',
4225
- transition: prefersReducedMotion ? '' : 'all 150ms ease-out'
4226
- }, /*#__PURE__*/React__default.createElement(Box, {
4276
+ }, props), label)), /*#__PURE__*/React__default.createElement(AnimatePresence, {
4277
+ mode: "wait"
4278
+ }, hasExpandableContent && /*#__PURE__*/React__default.createElement(Box, {
4279
+ as: motion.div,
4280
+ key: contentKey,
4281
+ initial: {
4282
+ height: 0,
4283
+ opacity: 0
4284
+ },
4285
+ animate: {
4286
+ height: 'auto',
4287
+ opacity: 1
4288
+ },
4289
+ exit: {
4290
+ height: 0,
4291
+ opacity: 0
4292
+ },
4293
+ transition: {
4294
+ duration: prefersReducedMotion ? 0 : 0.15,
4295
+ ease: 'easeOut'
4296
+ },
4227
4297
  overflow: "hidden"
4228
- }, hasExpandableContent && /*#__PURE__*/React__default.createElement(Box, _extends$6({
4298
+ }, /*#__PURE__*/React__default.createElement(Box, _extends$6({
4229
4299
  color: "gray.600",
4230
4300
  fontSize: expandableTextSize,
4231
4301
  paddingTop: 3,
4232
- paddingX: 4
4302
+ paddingX: 4,
4303
+ paddingBottom: 3
4233
4304
  }, expandableChildrenStyles), expandableChildren))));
4234
4305
  });
4235
4306
  SelectionCard.propTypes = {
@@ -4244,7 +4315,8 @@ SelectionCard.propTypes = {
4244
4315
  isExpandable: PropTypes.bool,
4245
4316
  expandableChildrenStyles: PropTypes.object,
4246
4317
  size: PropTypes.oneOf(['sm', 'md', 'lg']),
4247
- topChild: PropTypes.element
4318
+ topChild: PropTypes.element,
4319
+ expandableContentKey: PropTypes.string
4248
4320
  };
4249
4321
 
4250
4322
  const _excluded$4 = ["variant", "colorScheme"];