@vygruppen/spor-react 2.4.2 → 2.5.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @vygruppen/spor-react@2.4.2 build
2
+ > @vygruppen/spor-react@2.5.0 build
3
3
  > tsup src/index.tsx --dts --treeshake --format cjs,esm
4
4
 
5
5
  CLI Building entry: src/index.tsx
@@ -10,12 +10,12 @@
10
10
  ESM Build start
11
11
  DTS Build start
12
12
  "toTime" is imported from external module "@internationalized/date" but never used in "dist/index.js".
13
- "toTime" is imported from external module "@internationalized/date" but never used in "dist/chunk-C3DS6BFF.mjs".
14
- CJS dist/index.js 895.96 KB
15
- CJS ⚡️ Build success in 4923ms
16
- ESM dist/index.mjs 2.08 KB
17
- ESM dist/CountryCodeSelect-FDAGWNSZ.mjs 351.67 KB
18
- ESM dist/chunk-C3DS6BFF.mjs 416.15 KB
19
- ESM ⚡️ Build success in 4924ms
20
- DTS ⚡️ Build success in 18562ms
21
- DTS dist/index.d.ts 261.82 KB
13
+ "toTime" is imported from external module "@internationalized/date" but never used in "dist/chunk-7GRTZA6T.mjs".
14
+ CJS dist/index.js 895.46 KB
15
+ CJS ⚡️ Build success in 5694ms
16
+ ESM dist/index.mjs 2.06 KB
17
+ ESM dist/CountryCodeSelect-ZTEYBERS.mjs 351.67 KB
18
+ ESM dist/chunk-7GRTZA6T.mjs 415.76 KB
19
+ ESM ⚡️ Build success in 5707ms
20
+ DTS ⚡️ Build success in 21517ms
21
+ DTS dist/index.d.ts 259.31 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @vygruppen/spor-react
2
2
 
3
+ ## 2.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 042dba35: Make accordions and cards default to the sm size
8
+
9
+ ### Patch Changes
10
+
11
+ - f9d6bd34: Combobox: Fix a bug where menuTrigger="focus" wouldn't work
12
+ - 76914a15: Remove non-working Autosuggest component
13
+
14
+ ## 2.4.3
15
+
16
+ ### Patch Changes
17
+
18
+ - 5640417f: Autosuggest: Fix a bug where the onSelectionChanged was called with no item on nested lists
19
+
3
20
  ## 2.4.2
4
21
 
5
22
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { createTexts, useTranslation, InfoSelect, SelectItem } from './chunk-C3DS6BFF.mjs';
1
+ import { createTexts, useTranslation, InfoSelect, SelectItem } from './chunk-7GRTZA6T.mjs';
2
2
  import React from 'react';
3
3
 
4
4
  // ../../node_modules/awesome-phonenumber/index-esm.mjs
@@ -12,7 +12,7 @@ import { usePopover, Overlay, DismissButton, useOverlayTrigger, useButton, usePr
12
12
  import { motion } from 'framer-motion';
13
13
  import { DateFormatter, parseTime, createCalendar, Time, toCalendarDate, toCalendarDateTime, toCalendar, getMinimumDayInMonth, getMinimumMonthInYear, today, startOfWeek, startOfMonth, endOfWeek, endOfMonth, isSameDay, getDayOfWeek, maxDate, minDate, isEqualDay, getWeeksInMonth, getLocalTimeZone, GregorianCalendar, now, startOfYear, isSameMonth, isToday } from '@internationalized/date';
14
14
  export { Time } from '@internationalized/date';
15
- import { useOverlayTriggerState, useTimeFieldState, useAsyncList, useComboBoxState, Item, useSelectState } from 'react-stately';
15
+ import { useOverlayTriggerState, useTimeFieldState, useComboBoxState, Item, useSelectState } from 'react-stately';
16
16
  export { Item, Section } from 'react-stately';
17
17
  import { useSwipeable } from 'react-swipeable';
18
18
  import { Global, keyframes } from '@emotion/react';
@@ -1523,7 +1523,7 @@ var Stack = forwardRef(
1523
1523
 
1524
1524
  // src/card/Card.tsx
1525
1525
  var Card = forwardRef(
1526
- ({ size: size2 = "lg", colorScheme = "white", children, ...props }, ref) => {
1526
+ ({ size: size2 = "sm", colorScheme = "white", children, ...props }, ref) => {
1527
1527
  const styles2 = useStyleConfig("Card", {
1528
1528
  colorScheme,
1529
1529
  size: size2
@@ -4019,40 +4019,6 @@ var AttachedInputs = ({
4019
4019
  }
4020
4020
  );
4021
4021
  };
4022
- function Autosuggest({
4023
- label,
4024
- fetcher,
4025
- children,
4026
- onSelectionChange,
4027
- ...props
4028
- }) {
4029
- const list2 = useAsyncList({
4030
- async load({ filterText }) {
4031
- return {
4032
- items: await fetcher(filterText)
4033
- };
4034
- }
4035
- });
4036
- const handleSelectionChange = (key) => {
4037
- if (!onSelectionChange) {
4038
- return;
4039
- }
4040
- return onSelectionChange(list2.getItem(key));
4041
- };
4042
- return /* @__PURE__ */ React49__default.createElement(
4043
- Combobox,
4044
- {
4045
- label,
4046
- items: list2.items,
4047
- inputValue: list2.filterText,
4048
- onInputChange: list2.setFilterText,
4049
- onSelectionChange: handleSelectionChange,
4050
- isLoading: list2.isLoading,
4051
- ...props
4052
- },
4053
- children
4054
- );
4055
- }
4056
4022
  var Dialog = ({ title, children, ...props }) => {
4057
4023
  const ref = useRef(null);
4058
4024
  const { dialogProps, titleProps } = useDialog(props, ref);
@@ -4238,23 +4204,26 @@ function Combobox({
4238
4204
  marginTop,
4239
4205
  marginX,
4240
4206
  marginY,
4207
+ marginRight,
4208
+ marginLeft,
4241
4209
  paddingBottom,
4242
4210
  paddingRight,
4243
4211
  paddingTop,
4244
4212
  paddingLeft,
4245
4213
  paddingX,
4246
4214
  paddingY,
4247
- onFocus,
4215
+ emptyContent,
4248
4216
  ...rest
4249
4217
  }) {
4250
4218
  const { contains: contains2 } = useFilter({ sensitivity: "base" });
4251
- const state2 = useComboBoxState({
4252
- ...rest,
4253
- defaultFilter: contains2
4254
- });
4255
4219
  const inputRef = useRef(null);
4256
4220
  const listBoxRef = useRef(null);
4257
4221
  const popoverRef = useRef(null);
4222
+ const state2 = useComboBoxState({
4223
+ ...rest,
4224
+ defaultFilter: contains2,
4225
+ allowsEmptyCollection: Boolean(emptyContent)
4226
+ });
4258
4227
  const {
4259
4228
  inputProps: { size: size2, ...inputProps },
4260
4229
  listBoxProps
@@ -4267,19 +4236,20 @@ function Combobox({
4267
4236
  },
4268
4237
  state2
4269
4238
  );
4270
- return /* @__PURE__ */ React49__default.createElement(FormControl, null, /* @__PURE__ */ React49__default.createElement(
4239
+ return /* @__PURE__ */ React49__default.createElement(React49__default.Fragment, null, /* @__PURE__ */ React49__default.createElement(
4271
4240
  Input,
4272
4241
  {
4273
4242
  ...inputProps,
4274
4243
  ref: inputRef,
4275
4244
  label,
4276
- onFocus,
4277
4245
  borderBottomLeftRadius: state2.isOpen ? 0 : borderBottomLeftRadius,
4278
4246
  borderBottomRightRadius: state2.isOpen ? 0 : borderBottomRightRadius,
4279
4247
  borderTopLeftRadius,
4280
4248
  borderTopRightRadius,
4281
4249
  marginBottom,
4282
4250
  marginTop,
4251
+ marginRight,
4252
+ marginLeft,
4283
4253
  marginX,
4284
4254
  marginY,
4285
4255
  paddingBottom,
@@ -4317,7 +4287,7 @@ function Combobox({
4317
4287
  ...listBoxProps,
4318
4288
  state: state2,
4319
4289
  listBoxRef,
4320
- borderBottomRadius: "sm"
4290
+ emptyContent
4321
4291
  },
4322
4292
  rest.children
4323
4293
  )
@@ -4404,6 +4374,7 @@ function ListBox({
4404
4374
  sx: styles2.container,
4405
4375
  "aria-busy": isLoading
4406
4376
  },
4377
+ state2.collection.size === 0 && props.emptyContent,
4407
4378
  Array.from(state2.collection).map(
4408
4379
  (item) => item.type === "section" ? /* @__PURE__ */ React49__default.createElement(ListBoxSection, { key: item.key, section: item, state: state2 }) : /* @__PURE__ */ React49__default.createElement(Option, { key: item.key, item, state: state2 })
4409
4380
  )
@@ -4456,18 +4427,18 @@ function ListBoxSection({ section, state: state2 }) {
4456
4427
  heading: section.rendered,
4457
4428
  "aria-label": section["aria-label"]
4458
4429
  });
4459
- const isFirstSection = section.key !== state2.collection.getFirstKey();
4460
- const titleBackgroundColor = useColorModeValue("platinum", "dimGrey");
4430
+ const isFirstSection = section.key === state2.collection.getFirstKey();
4461
4431
  const titleColor = useColorModeValue("darkGrey", "white");
4462
4432
  return /* @__PURE__ */ React49__default.createElement(ListItem, { ...itemProps }, section.rendered && /* @__PURE__ */ React49__default.createElement(
4463
4433
  Box,
4464
4434
  {
4465
- textStyle: "xs",
4466
- backgroundColor: titleBackgroundColor,
4435
+ fontSize: "mobile.xs",
4467
4436
  color: titleColor,
4468
4437
  paddingX: 3,
4469
4438
  paddingY: 1,
4470
- marginTop: isFirstSection ? 0 : 0,
4439
+ marginTop: isFirstSection ? 0 : 3,
4440
+ textTransform: "uppercase",
4441
+ fontWeight: "bold",
4471
4442
  ...headingProps
4472
4443
  },
4473
4444
  section.rendered
@@ -4551,7 +4522,7 @@ var texts10 = createTexts({
4551
4522
  }
4552
4523
  });
4553
4524
  var Input = forwardRef(
4554
- ({ label, leftIcon, rightIcon, id, ...props }, ref) => {
4525
+ ({ label, leftIcon, rightIcon, id, size: size2, ...props }, ref) => {
4555
4526
  const formControlProps = useFormControlContext();
4556
4527
  const fallbackId = `input-${useId()}`;
4557
4528
  const inputId = id ?? (formControlProps == null ? void 0 : formControlProps.id) ?? fallbackId;
@@ -4566,7 +4537,7 @@ var Input = forwardRef(
4566
4537
  ref,
4567
4538
  placeholder: " "
4568
4539
  }
4569
- ), /* @__PURE__ */ React49__default.createElement(FormLabel, { htmlFor: inputId, pointerEvents: "none" }, label), rightIcon && /* @__PURE__ */ React49__default.createElement(InputRightElement, null, rightIcon));
4540
+ ), /* @__PURE__ */ React49__default.createElement(FormLabel, { htmlFor: inputId }, label), rightIcon && /* @__PURE__ */ React49__default.createElement(InputRightElement, null, rightIcon));
4570
4541
  }
4571
4542
  );
4572
4543
  var InputLeftElement2 = forwardRef(
@@ -4816,7 +4787,7 @@ var texts11 = createTexts({
4816
4787
  }
4817
4788
  });
4818
4789
  var PasswordInput = forwardRef(
4819
- ({ leftIcon, id, label, ...props }, ref) => {
4790
+ ({ leftIcon, id, label, size: size2, ...props }, ref) => {
4820
4791
  const { isOpen: isShowingPassword, onToggle } = useDisclosure();
4821
4792
  const { t: t2 } = useTranslation();
4822
4793
  const formControlProps = useFormControlContext();
@@ -4929,7 +4900,7 @@ var texts13 = createTexts({
4929
4900
  sv: "Telefonnummer"
4930
4901
  }
4931
4902
  });
4932
- var LazyCountryCodeSelect = React49__default.lazy(() => import('./CountryCodeSelect-FDAGWNSZ.mjs'));
4903
+ var LazyCountryCodeSelect = React49__default.lazy(() => import('./CountryCodeSelect-ZTEYBERS.mjs'));
4933
4904
  var Radio = forwardRef((props, ref) => {
4934
4905
  return /* @__PURE__ */ React49__default.createElement(Radio$1, { ...props, ref });
4935
4906
  });
@@ -10976,7 +10947,7 @@ var config3 = helpers.defineMultiStyleConfig({
10976
10947
  },
10977
10948
  defaultProps: {
10978
10949
  variant: "list",
10979
- size: "md"
10950
+ size: "sm"
10980
10951
  }
10981
10952
  });
10982
10953
  var accordion_default = config3;
@@ -13040,19 +13011,27 @@ var config24 = helpers15.defineMultiStyleConfig({
13040
13011
  overflowY: "auto",
13041
13012
  maxHeight: "50vh",
13042
13013
  width: "100%",
13043
- listStyle: "none"
13014
+ listStyle: "none",
13015
+ borderBottomRadius: "sm"
13044
13016
  },
13045
13017
  item: {
13046
- paddingX: 3,
13047
- paddingY: 2,
13018
+ paddingX: 2,
13019
+ paddingY: 1,
13020
+ marginY: 1,
13021
+ marginX: 1,
13022
+ borderRadius: "sm",
13048
13023
  color: mode("darkGrey", "white")(props),
13049
13024
  _hover: {
13050
- background: mode("mint", "darkTeal")(props),
13025
+ backgroundColor: mode("seaMist", "darkTeal")(props),
13026
+ outline: "none"
13027
+ },
13028
+ _active: {
13029
+ backgroundColor: mode("mint", "darkTeal")(props),
13051
13030
  outline: "none"
13052
13031
  },
13053
13032
  _focus: {
13054
13033
  outline: "none",
13055
- backgroundColor: mode("mint", "darkTeal")(props)
13034
+ backgroundColor: mode("seaMist", "darkTeal")(props)
13056
13035
  },
13057
13036
  _selected: {
13058
13037
  backgroundColor: mode("pine", "pine")(props),
@@ -14557,4 +14536,4 @@ var getToastComponent = (opts) => {
14557
14536
  return ({ id }) => /* @__PURE__ */ React49__default.createElement(BaseToast, { id, variant: opts.variant }, opts.text);
14558
14537
  };
14559
14538
 
14560
- export { Accordion, AttachedInputs, Autosuggest, Badge, Button, ButtonGroup, Card, CardSelect, Checkbox, CheckboxGroup, ChoiceChip, ClosableAlert, CloseButton, Code, ColorInlineLoader, ColorSpinner, Combobox, ContentLoader, DarkFullScreenLoader, DarkInlineLoader, DarkSpinner, DatePicker, DateRangePicker, Divider, Drawer, DrawerContent, Expandable, ExpandableAlert, ExpandableItem, FloatingActionButton, FormControl, FormErrorMessage, FormLabel3 as FormLabel, Heading, IconButton, InfoSelect, InfoTag, Input, InputLeftElement2 as InputLeftElement, InputRightElement2 as InputRightElement, ItemDescription, ItemLabel, JumpButton, Language, LanguageProvider, LightFullScreenLoader, LightInlineLoader, LightSpinner, LineIcon, ListBox, ModalHeader, NativeSelect, NumericStepper, PasswordInput, PhoneNumberInput, PlayPauseButton, PopoverWizardBody, ProgressBar, ProgressLoader, Radio, RadioGroup, SearchInput, SelectItem, SelectItemDescription, SelectItemLabel, SimpleDrawer, SimplePopover, Skeleton, SkeletonCircle, SkeletonText, SkipButton, SporProvider, Stack, StaticAlert, Stepper, StepperStep, Switch, Table, Tabs, Text4 as Text, TextLink, Textarea, TimePicker, TravelTag, VyLogo, WizardPopover, createTexts, fontFaces, theme, useToast, useTranslation };
14539
+ export { Accordion, AttachedInputs, Badge, Button, ButtonGroup, Card, CardSelect, Checkbox, CheckboxGroup, ChoiceChip, ClosableAlert, CloseButton, Code, ColorInlineLoader, ColorSpinner, Combobox, ContentLoader, DarkFullScreenLoader, DarkInlineLoader, DarkSpinner, DatePicker, DateRangePicker, Divider, Drawer, DrawerContent, Expandable, ExpandableAlert, ExpandableItem, FloatingActionButton, FormControl, FormErrorMessage, FormLabel3 as FormLabel, Heading, IconButton, InfoSelect, InfoTag, Input, InputLeftElement2 as InputLeftElement, InputRightElement2 as InputRightElement, ItemDescription, ItemLabel, JumpButton, Language, LanguageProvider, LightFullScreenLoader, LightInlineLoader, LightSpinner, LineIcon, ListBox, ModalHeader, NativeSelect, NumericStepper, PasswordInput, PhoneNumberInput, PlayPauseButton, PopoverWizardBody, ProgressBar, ProgressLoader, Radio, RadioGroup, SearchInput, SelectItem, SelectItemDescription, SelectItemLabel, SimpleDrawer, SimplePopover, Skeleton, SkeletonCircle, SkeletonText, SkipButton, SporProvider, Stack, StaticAlert, Stepper, StepperStep, Switch, Table, Tabs, Text4 as Text, TextLink, Textarea, TimePicker, TravelTag, VyLogo, WizardPopover, createTexts, fontFaces, theme, useToast, useTranslation };
package/dist/index.d.ts CHANGED
@@ -397,10 +397,10 @@ type CardProps = Exclude<BoxProps, "size"> & {
397
397
  * </Card>
398
398
  * ```
399
399
  *
400
- * There are lots of color schemes available. You can also set the size as either `sm` or `lg`. The default is `lg`.
400
+ * There are lots of color schemes available. You can also set the size as either `sm` or `lg`. The default is `sm`.
401
401
  *
402
402
  * ```tsx
403
- * <Card colorScheme="orange" size="sm">
403
+ * <Card colorScheme="orange" size="lg">
404
404
  * A smaller card
405
405
  * </Card>
406
406
  * ```
@@ -607,87 +607,6 @@ type AttachedInputsProps = FlexProps;
607
607
  */
608
608
  declare const AttachedInputs: ({ flexDirection, ...rest }: AttachedInputsProps) => React__default.JSX.Element;
609
609
 
610
- type AutosuggestProps<T> = {
611
- /** The label of the search field */
612
- label: string;
613
- /**
614
- * The function responsible for fetching new suggestion items, based on the query.
615
- *
616
- * This will typically be an API call to a backend service.
617
- *
618
- * @example
619
- * ```tsx
620
- * const fetcher = async (query?: string) => {
621
- * const response = await fetch(`https://some.api.com/filter=${query}`);
622
- * const json = await response.json();
623
- * return json;
624
- * };
625
- * ```
626
- * */
627
- fetcher: (query?: string) => Promise<Iterable<T>>;
628
- /**
629
- * A render function that receives each item, and returns the UI for each item in the list.
630
- *
631
- * @example
632
- * ```tsx
633
- * <Autosuggest {...otherProps}>
634
- * {(user) => (
635
- * <Item key={user.id} textValue={user.fullName}>
636
- * <ItemLabel>{user.fullName}</ItemLabel>
637
- * <ItemDescription>{user.asl}</ItemDescription>
638
- * </Item>
639
- * )}
640
- * </Autosuggest>
641
- * ```
642
- *
643
- * You technically don't need to use the `<SelectItemLabel />` and `<SelectItemDescription />` components, but they are recommended to improve the accessibility of the search results. You can style them however you want, so there should never be a reason not to include at least the `<SelectItemLabel />` component. But who's judging?
644
- * */
645
- children: ComboboxProps<T>["children"];
646
- /**
647
- * Callback for when the selection changes. Returns the entire item.
648
- */
649
- onSelectionChange?: (item: T) => void;
650
- /** The selected item key (controlled) */
651
- selectedKey?: ComboboxProps<T>["selectedKey"];
652
- /** What should open the menu.
653
- *
654
- * Defaults to "input"
655
- */
656
- menuTrigger?: ComboboxProps<T>["menuTrigger"];
657
- } & Pick<InputProps, "marginTop" | "marginBottom" | "marginY" | "marginX" | "paddingTop" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingY" | "paddingX" | "leftIcon" | "rightIcon" | "borderTopRightRadius" | "borderTopLeftRadius" | "borderBottomRightRadius" | "borderBottomLeftRadius" | "onFocus">;
658
- /**
659
- * A component that provides an autocomplete search field with suggestions.
660
- *
661
- * This component requires a `fetcher` prop, which is a function that receives a query string, and returns a list of items that match the query.
662
- *
663
- * @example
664
- * ```tsx
665
- * const fetcher = async (query?: string) => {
666
- * const response = await fetch(`https://some.api.vy.no/filter=${query}`);
667
- * const json = await response.json();
668
- * return json;
669
- * };
670
- *
671
- * const Example = () => {
672
- * return (
673
- * <Autosuggest
674
- * label="Search for users"
675
- * fetcher={fetcher}
676
- * onSelectionChange={(item) => console.log(item)}
677
- * >
678
- * {(user) => (
679
- * <Item key={user.id} textValue={user.fullName}>
680
- * <ItemLabel>{user.fullName}</ItemLabel>
681
- * <ItemDescription>{user.asl}</ItemDescription>
682
- * </Item>
683
- * )}
684
- * </Autosuggest>
685
- * );
686
- * };
687
- * ```
688
- */
689
- declare function Autosuggest<T extends object>({ label, fetcher, children, onSelectionChange, ...props }: AutosuggestProps<T>): React__default.JSX.Element;
690
-
691
610
  type CardSelectProps = BoxProps & {
692
611
  /** The design of the trigger button.
693
612
  *
@@ -823,7 +742,9 @@ type ComboboxProps<T> = AriaComboBoxProps<T> & {
823
742
  label: string;
824
743
  /** Whether or not the combobox is waiting for new suggestions */
825
744
  isLoading?: boolean;
826
- } & Pick<InputProps, "marginTop" | "marginBottom" | "marginY" | "marginX" | "paddingTop" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingY" | "paddingX" | "leftIcon" | "rightIcon" | "borderTopRightRadius" | "borderTopLeftRadius" | "borderBottomRightRadius" | "borderBottomLeftRadius" | "onFocus">;
745
+ /** Optional UI to show when there are no matching items */
746
+ emptyContent?: React__default.ReactNode;
747
+ } & Pick<InputProps, "marginTop" | "marginBottom" | "marginRight" | "marginLeft" | "marginY" | "marginX" | "paddingTop" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingY" | "paddingX" | "leftIcon" | "rightIcon" | "borderTopRightRadius" | "borderTopLeftRadius" | "borderBottomRightRadius" | "borderBottomLeftRadius" | "onFocus">;
827
748
  /**
828
749
  * A combobox is a combination of an input and a list of suggestions.
829
750
  *
@@ -847,7 +768,7 @@ type ComboboxProps<T> = AriaComboBoxProps<T> & {
847
768
  * </Combobox>
848
769
  * ```
849
770
  */
850
- declare function Combobox<T extends object>({ label, isLoading, leftIcon, rightIcon, borderBottomLeftRadius, borderBottomRightRadius, borderTopLeftRadius, borderTopRightRadius, marginBottom, marginTop, marginX, marginY, paddingBottom, paddingRight, paddingTop, paddingLeft, paddingX, paddingY, onFocus, ...rest }: ComboboxProps<T>): React__default.JSX.Element;
771
+ declare function Combobox<T extends object>({ label, isLoading, leftIcon, rightIcon, borderBottomLeftRadius, borderBottomRightRadius, borderTopLeftRadius, borderTopRightRadius, marginBottom, marginTop, marginX, marginY, marginRight, marginLeft, paddingBottom, paddingRight, paddingTop, paddingLeft, paddingX, paddingY, emptyContent, ...rest }: ComboboxProps<T>): React__default.JSX.Element;
851
772
 
852
773
  type FormControlProps = FormControlProps$1;
853
774
  declare const FormControl: _chakra_ui_system_dist_system_types.ComponentWithAs<"div", FormControlProps$1>;
@@ -1023,7 +944,7 @@ type InfoSelectProps<T extends object> = {
1023
944
  */
1024
945
  declare function InfoSelect<T extends object>({ placeholder, width, height, onChange, value, isLabelSrOnly, defaultValue, ...props }: InfoSelectProps<T>): React__default.JSX.Element;
1025
946
 
1026
- type InputProps = Exclude<InputProps$1, "variant" | "size"> & {
947
+ type InputProps = Omit<InputProps$1, "variant" | "size"> & {
1027
948
  /** The input's label */
1028
949
  label: string;
1029
950
  /** Icon that shows up to the left */
@@ -1090,6 +1011,8 @@ type ListBoxProps<T> = AriaListBoxProps<T> & Omit<BoxProps, "filter" | "autoFocu
1090
1011
  isLoading?: boolean;
1091
1012
  /** The state of the listbox, provided externally somehow. */
1092
1013
  state: ListState<T> | SelectState<T>;
1014
+ /** UI to render if the collection is empty */
1015
+ emptyContent?: React__default.ReactNode;
1093
1016
  };
1094
1017
  /**
1095
1018
  * A component that renders a list box with selectable options.
@@ -3728,13 +3651,21 @@ declare const theme: {
3728
3651
  maxHeight: string;
3729
3652
  width: string;
3730
3653
  listStyle: string;
3654
+ borderBottomRadius: string;
3731
3655
  };
3732
3656
  item: {
3733
3657
  paddingX: number;
3734
3658
  paddingY: number;
3659
+ marginY: number;
3660
+ marginX: number;
3661
+ borderRadius: string;
3735
3662
  color: string;
3736
3663
  _hover: {
3737
- background: string;
3664
+ backgroundColor: string;
3665
+ outline: string;
3666
+ };
3667
+ _active: {
3668
+ backgroundColor: string;
3738
3669
  outline: string;
3739
3670
  };
3740
3671
  _focus: {
@@ -7077,4 +7008,4 @@ type TextProps = Omit<TextProps$1, "textStyle"> & {
7077
7008
  */
7078
7009
  declare const Text: _chakra_ui_system_dist_system_types.ComponentWithAs<"p", TextProps>;
7079
7010
 
7080
- export { Accordion, AccordionProps, AttachedInputs, Autosuggest, Badge, BadgeProps, Button, ButtonGroup, ButtonGroupProps, ButtonProps, Card, CardProps, CardSelect, Checkbox, CheckboxGroup, CheckboxGroupProps, CheckboxProps, ChoiceChip, ChoiceChipProps, ClosableAlert, CloseButton, CloseButtonProps, Code, CodeProps, ColorInlineLoader, ColorInlineLoaderProps, ColorSpinner, ColorSpinnerProps, Combobox, ComboboxProps, ContentLoader, ContentLoaderProps, DarkFullScreenLoader, DarkInlineLoader, DarkInlineLoaderProps, DarkSpinner, DarkSpinnerProps, DatePicker, DateRangePicker, Divider, DividerProps, Drawer, DrawerContent, ModalHeader as DrawerHeader, Expandable, ExpandableAlert, ExpandableItem, ExpandableItemProps, FloatingActionButton, FormControl, FormControlProps, FormErrorMessage, FormErrorMessageProps, FormLabel, FormLabelProps, Heading, HeadingProps, IconButton, IconButtonProps, InfoSelect, InfoTag, InfoTagProps, Input, InputElementProps, InputLeftElement, InputProps, InputRightElement, ItemDescription, ItemLabel, JumpButton, Language, LanguageProvider, LightFullScreenLoader, LightInlineLoader, LightInlineLoaderProps, LightSpinner, LightSpinnerProps, LineIcon, LineIconProps, ListBox, ModalHeader, ModalHeaderProps, NativeSelect, NativeSelectProps, NumericStepper, PasswordInput, PasswordInputProps, PhoneNumberInput, PlayPauseButton, PopoverWizardBody, PopoverWizardProps, ProgressBar, ProgressLoader, Radio, RadioGroup, RadioGroupProps, RadioProps, SearchInput, SearchInputProps, SelectItem, SelectItemDescription, SelectItemLabel, SimpleDrawer, SimpleDrawerProps, SimplePopover, Skeleton, SkeletonCircle, SkeletonCircleProps, SkeletonProps, SkeletonText, SkeletonTextProps, SkipButton, SpinnerProps, SporProvider, Stack, StackProps, StaticAlert, Stepper, StepperStep, Switch, SwitchProps, Table, TableProps, Tabs, TabsProps, Text, TextLink, TextProps, Textarea, TextareaProps, TimePicker, ToastOptions, Translations, TravelTag, TravelTagProps, VyLogo, VyLogoProps, WizardPopover, WizardPopoverProps, createTexts, fontFaces, theme, useToast, useTranslation };
7011
+ export { Accordion, AccordionProps, AttachedInputs, Badge, BadgeProps, Button, ButtonGroup, ButtonGroupProps, ButtonProps, Card, CardProps, CardSelect, Checkbox, CheckboxGroup, CheckboxGroupProps, CheckboxProps, ChoiceChip, ChoiceChipProps, ClosableAlert, CloseButton, CloseButtonProps, Code, CodeProps, ColorInlineLoader, ColorInlineLoaderProps, ColorSpinner, ColorSpinnerProps, Combobox, ComboboxProps, ContentLoader, ContentLoaderProps, DarkFullScreenLoader, DarkInlineLoader, DarkInlineLoaderProps, DarkSpinner, DarkSpinnerProps, DatePicker, DateRangePicker, Divider, DividerProps, Drawer, DrawerContent, ModalHeader as DrawerHeader, Expandable, ExpandableAlert, ExpandableItem, ExpandableItemProps, FloatingActionButton, FormControl, FormControlProps, FormErrorMessage, FormErrorMessageProps, FormLabel, FormLabelProps, Heading, HeadingProps, IconButton, IconButtonProps, InfoSelect, InfoTag, InfoTagProps, Input, InputElementProps, InputLeftElement, InputProps, InputRightElement, ItemDescription, ItemLabel, JumpButton, Language, LanguageProvider, LightFullScreenLoader, LightInlineLoader, LightInlineLoaderProps, LightSpinner, LightSpinnerProps, LineIcon, LineIconProps, ListBox, ModalHeader, ModalHeaderProps, NativeSelect, NativeSelectProps, NumericStepper, PasswordInput, PasswordInputProps, PhoneNumberInput, PlayPauseButton, PopoverWizardBody, PopoverWizardProps, ProgressBar, ProgressLoader, Radio, RadioGroup, RadioGroupProps, RadioProps, SearchInput, SearchInputProps, SelectItem, SelectItemDescription, SelectItemLabel, SimpleDrawer, SimpleDrawerProps, SimplePopover, Skeleton, SkeletonCircle, SkeletonCircleProps, SkeletonProps, SkeletonText, SkeletonTextProps, SkipButton, SpinnerProps, SporProvider, Stack, StackProps, StaticAlert, Stepper, StepperStep, Switch, SwitchProps, Table, TableProps, Tabs, TabsProps, Text, TextLink, TextProps, Textarea, TextareaProps, TimePicker, ToastOptions, Translations, TravelTag, TravelTagProps, VyLogo, VyLogoProps, WizardPopover, WizardPopoverProps, createTexts, fontFaces, theme, useToast, useTranslation };
package/dist/index.js CHANGED
@@ -1075,7 +1075,7 @@ var init_Card = __esm({
1075
1075
  "src/card/Card.tsx"() {
1076
1076
  init_layout();
1077
1077
  exports.Card = react.forwardRef(
1078
- ({ size: size2 = "lg", colorScheme = "white", children, ...props }, ref) => {
1078
+ ({ size: size2 = "sm", colorScheme = "white", children, ...props }, ref) => {
1079
1079
  const styles2 = react.useStyleConfig("Card", {
1080
1080
  colorScheme,
1081
1081
  size: size2
@@ -3750,45 +3750,6 @@ var init_AttachedInputs = __esm({
3750
3750
  };
3751
3751
  }
3752
3752
  });
3753
- function Autosuggest({
3754
- label,
3755
- fetcher,
3756
- children,
3757
- onSelectionChange,
3758
- ...props
3759
- }) {
3760
- const list2 = reactStately.useAsyncList({
3761
- async load({ filterText }) {
3762
- return {
3763
- items: await fetcher(filterText)
3764
- };
3765
- }
3766
- });
3767
- const handleSelectionChange = (key) => {
3768
- if (!onSelectionChange) {
3769
- return;
3770
- }
3771
- return onSelectionChange(list2.getItem(key));
3772
- };
3773
- return /* @__PURE__ */ React49__namespace.default.createElement(
3774
- Combobox,
3775
- {
3776
- label,
3777
- items: list2.items,
3778
- inputValue: list2.filterText,
3779
- onInputChange: list2.setFilterText,
3780
- onSelectionChange: handleSelectionChange,
3781
- isLoading: list2.isLoading,
3782
- ...props
3783
- },
3784
- children
3785
- );
3786
- }
3787
- var init_Autosuggest = __esm({
3788
- "src/input/Autosuggest.tsx"() {
3789
- init_src();
3790
- }
3791
- });
3792
3753
  var Dialog;
3793
3754
  var init_Dialog = __esm({
3794
3755
  "src/input/Dialog.tsx"() {
@@ -4753,23 +4714,26 @@ function Combobox({
4753
4714
  marginTop,
4754
4715
  marginX,
4755
4716
  marginY,
4717
+ marginRight,
4718
+ marginLeft,
4756
4719
  paddingBottom,
4757
4720
  paddingRight,
4758
4721
  paddingTop,
4759
4722
  paddingLeft,
4760
4723
  paddingX,
4761
4724
  paddingY,
4762
- onFocus,
4725
+ emptyContent,
4763
4726
  ...rest
4764
4727
  }) {
4765
4728
  const { contains: contains2 } = reactAria.useFilter({ sensitivity: "base" });
4766
- const state2 = reactStately.useComboBoxState({
4767
- ...rest,
4768
- defaultFilter: contains2
4769
- });
4770
4729
  const inputRef = React49.useRef(null);
4771
4730
  const listBoxRef = React49.useRef(null);
4772
4731
  const popoverRef = React49.useRef(null);
4732
+ const state2 = reactStately.useComboBoxState({
4733
+ ...rest,
4734
+ defaultFilter: contains2,
4735
+ allowsEmptyCollection: Boolean(emptyContent)
4736
+ });
4773
4737
  const {
4774
4738
  inputProps: { size: size2, ...inputProps },
4775
4739
  listBoxProps
@@ -4782,19 +4746,20 @@ function Combobox({
4782
4746
  },
4783
4747
  state2
4784
4748
  );
4785
- return /* @__PURE__ */ React49__namespace.default.createElement(exports.FormControl, null, /* @__PURE__ */ React49__namespace.default.createElement(
4749
+ return /* @__PURE__ */ React49__namespace.default.createElement(React49__namespace.default.Fragment, null, /* @__PURE__ */ React49__namespace.default.createElement(
4786
4750
  exports.Input,
4787
4751
  {
4788
4752
  ...inputProps,
4789
4753
  ref: inputRef,
4790
4754
  label,
4791
- onFocus,
4792
4755
  borderBottomLeftRadius: state2.isOpen ? 0 : borderBottomLeftRadius,
4793
4756
  borderBottomRightRadius: state2.isOpen ? 0 : borderBottomRightRadius,
4794
4757
  borderTopLeftRadius,
4795
4758
  borderTopRightRadius,
4796
4759
  marginBottom,
4797
4760
  marginTop,
4761
+ marginRight,
4762
+ marginLeft,
4798
4763
  marginX,
4799
4764
  marginY,
4800
4765
  paddingBottom,
@@ -4832,7 +4797,7 @@ function Combobox({
4832
4797
  ...listBoxProps,
4833
4798
  state: state2,
4834
4799
  listBoxRef,
4835
- borderBottomRadius: "sm"
4800
+ emptyContent
4836
4801
  },
4837
4802
  rest.children
4838
4803
  )
@@ -4939,6 +4904,7 @@ function ListBox({
4939
4904
  sx: styles2.container,
4940
4905
  "aria-busy": isLoading
4941
4906
  },
4907
+ state2.collection.size === 0 && props.emptyContent,
4942
4908
  Array.from(state2.collection).map(
4943
4909
  (item) => item.type === "section" ? /* @__PURE__ */ React49__namespace.default.createElement(ListBoxSection, { key: item.key, section: item, state: state2 }) : /* @__PURE__ */ React49__namespace.default.createElement(Option, { key: item.key, item, state: state2 })
4944
4910
  )
@@ -4982,18 +4948,18 @@ function ListBoxSection({ section, state: state2 }) {
4982
4948
  heading: section.rendered,
4983
4949
  "aria-label": section["aria-label"]
4984
4950
  });
4985
- const isFirstSection = section.key !== state2.collection.getFirstKey();
4986
- const titleBackgroundColor = react.useColorModeValue("platinum", "dimGrey");
4951
+ const isFirstSection = section.key === state2.collection.getFirstKey();
4987
4952
  const titleColor = react.useColorModeValue("darkGrey", "white");
4988
4953
  return /* @__PURE__ */ React49__namespace.default.createElement(react.ListItem, { ...itemProps }, section.rendered && /* @__PURE__ */ React49__namespace.default.createElement(
4989
4954
  react.Box,
4990
4955
  {
4991
- textStyle: "xs",
4992
- backgroundColor: titleBackgroundColor,
4956
+ fontSize: "mobile.xs",
4993
4957
  color: titleColor,
4994
4958
  paddingX: 3,
4995
4959
  paddingY: 1,
4996
- marginTop: isFirstSection ? 0 : 0,
4960
+ marginTop: isFirstSection ? 0 : 3,
4961
+ textTransform: "uppercase",
4962
+ fontWeight: "bold",
4997
4963
  ...headingProps
4998
4964
  },
4999
4965
  section.rendered
@@ -5101,7 +5067,7 @@ exports.Input = void 0;
5101
5067
  var init_Input = __esm({
5102
5068
  "src/input/Input.tsx"() {
5103
5069
  exports.Input = react.forwardRef(
5104
- ({ label, leftIcon, rightIcon, id, ...props }, ref) => {
5070
+ ({ label, leftIcon, rightIcon, id, size: size2, ...props }, ref) => {
5105
5071
  const formControlProps = react.useFormControlContext();
5106
5072
  const fallbackId = `input-${React49.useId()}`;
5107
5073
  const inputId = id ?? (formControlProps == null ? void 0 : formControlProps.id) ?? fallbackId;
@@ -5116,7 +5082,7 @@ var init_Input = __esm({
5116
5082
  ref,
5117
5083
  placeholder: " "
5118
5084
  }
5119
- ), /* @__PURE__ */ React49__namespace.default.createElement(react.FormLabel, { htmlFor: inputId, pointerEvents: "none" }, label), rightIcon && /* @__PURE__ */ React49__namespace.default.createElement(react.InputRightElement, null, rightIcon));
5085
+ ), /* @__PURE__ */ React49__namespace.default.createElement(react.FormLabel, { htmlFor: inputId }, label), rightIcon && /* @__PURE__ */ React49__namespace.default.createElement(react.InputRightElement, null, rightIcon));
5120
5086
  }
5121
5087
  );
5122
5088
  }
@@ -5412,7 +5378,7 @@ var init_PasswordInput = __esm({
5412
5378
  init_input();
5413
5379
  init_src();
5414
5380
  exports.PasswordInput = react.forwardRef(
5415
- ({ leftIcon, id, label, ...props }, ref) => {
5381
+ ({ leftIcon, id, label, size: size2, ...props }, ref) => {
5416
5382
  const { isOpen: isShowingPassword, onToggle } = react.useDisclosure();
5417
5383
  const { t: t2 } = useTranslation();
5418
5384
  const formControlProps = react.useFormControlContext();
@@ -12348,7 +12314,6 @@ var init_Textarea = __esm({
12348
12314
  var init_input = __esm({
12349
12315
  "src/input/index.tsx"() {
12350
12316
  init_AttachedInputs();
12351
- init_Autosuggest();
12352
12317
  init_CardSelect();
12353
12318
  init_Checkbox();
12354
12319
  init_CheckboxGroup();
@@ -18983,7 +18948,7 @@ var init_accordion2 = __esm({
18983
18948
  },
18984
18949
  defaultProps: {
18985
18950
  variant: "list",
18986
- size: "md"
18951
+ size: "sm"
18987
18952
  }
18988
18953
  });
18989
18954
  accordion_default = config3;
@@ -21190,19 +21155,27 @@ var init_listbox = __esm({
21190
21155
  overflowY: "auto",
21191
21156
  maxHeight: "50vh",
21192
21157
  width: "100%",
21193
- listStyle: "none"
21158
+ listStyle: "none",
21159
+ borderBottomRadius: "sm"
21194
21160
  },
21195
21161
  item: {
21196
- paddingX: 3,
21197
- paddingY: 2,
21162
+ paddingX: 2,
21163
+ paddingY: 1,
21164
+ marginY: 1,
21165
+ marginX: 1,
21166
+ borderRadius: "sm",
21198
21167
  color: themeTools.mode("darkGrey", "white")(props),
21199
21168
  _hover: {
21200
- background: themeTools.mode("mint", "darkTeal")(props),
21169
+ backgroundColor: themeTools.mode("seaMist", "darkTeal")(props),
21170
+ outline: "none"
21171
+ },
21172
+ _active: {
21173
+ backgroundColor: themeTools.mode("mint", "darkTeal")(props),
21201
21174
  outline: "none"
21202
21175
  },
21203
21176
  _focus: {
21204
21177
  outline: "none",
21205
- backgroundColor: themeTools.mode("mint", "darkTeal")(props)
21178
+ backgroundColor: themeTools.mode("seaMist", "darkTeal")(props)
21206
21179
  },
21207
21180
  _selected: {
21208
21181
  backgroundColor: themeTools.mode("pine", "pine")(props),
@@ -23261,7 +23234,6 @@ Object.defineProperty(exports, 'Section', {
23261
23234
  get: function () { return reactStately.Section; }
23262
23235
  });
23263
23236
  exports.tokens = tokens10__namespace;
23264
- exports.Autosuggest = Autosuggest;
23265
23237
  exports.Combobox = Combobox;
23266
23238
  exports.DatePicker = DatePicker;
23267
23239
  exports.DateRangePicker = DateRangePicker;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export { Accordion, AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, AttachedInputs, Autosuggest, Badge, Box, Button, ButtonGroup, Card, CardSelect, Center, Checkbox, CheckboxGroup, ChoiceChip, ClosableAlert, CloseButton, Code, Collapse, ColorInlineLoader, ColorSpinner, Combobox, Container, ContentLoader, DarkFullScreenLoader, DarkInlineLoader, DarkMode, DarkSpinner, DatePicker, DateRangePicker, Divider, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerFooter, ModalHeader as DrawerHeader, DrawerOverlay, Expandable, ExpandableAlert, ExpandableItem, Fade, Flex, FloatingActionButton, FormControl, FormErrorMessage, FormHelperText, FormLabel, Grid, GridItem, HStack, Heading, IconButton, Image, Img, InfoSelect, InfoTag, Input, InputGroup, InputLeftElement, InputRightElement, Item, ItemDescription, ItemLabel, JumpButton, Language, LanguageProvider, LightFullScreenLoader, LightInlineLoader, LightMode, LightSpinner, LineIcon, ListBox, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, NativeSelect, NumericStepper, PasswordInput, PhoneNumberInput, PlayPauseButton, Popover, PopoverAnchor, PopoverArrow, PopoverBody, PopoverCloseButton, PopoverContent, PopoverFooter, PopoverHeader, PopoverTrigger, PopoverWizardBody, ProgressBar, ProgressLoader, Radio, RadioGroup, ScaleFade, SearchInput, Section, SelectItem, SelectItemDescription, SelectItemLabel, SimpleDrawer, SimpleGrid, SimplePopover, Skeleton, SkeletonCircle, SkeletonText, SkipButton, Slide, SlideFade, Spacer, SporProvider, Stack, StaticAlert, Stepper, StepperStep, Switch, Tab, TabList, TabPanel, TabPanels, Table, TableCaption, Tabs, Tbody, Td, Text, TextLink, Textarea, Tfoot, Th, Thead, Time, TimePicker, Tr, TravelTag, VStack, VyLogo, WizardPopover, Wrap, WrapItem, createTexts, extendTheme, fontFaces, theme, tokens, useBreakpointValue, useClipboard, useColorMode, useColorModePreference, useColorModeValue, useControllableProp, useDisclosure, useMediaQuery, useMergeRefs, useOutsideClick, usePrefersReducedMotion, useTheme, useToast, useToken, useTranslation } from './chunk-C3DS6BFF.mjs';
1
+ export { Accordion, AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, AttachedInputs, Badge, Box, Button, ButtonGroup, Card, CardSelect, Center, Checkbox, CheckboxGroup, ChoiceChip, ClosableAlert, CloseButton, Code, Collapse, ColorInlineLoader, ColorSpinner, Combobox, Container, ContentLoader, DarkFullScreenLoader, DarkInlineLoader, DarkMode, DarkSpinner, DatePicker, DateRangePicker, Divider, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerFooter, ModalHeader as DrawerHeader, DrawerOverlay, Expandable, ExpandableAlert, ExpandableItem, Fade, Flex, FloatingActionButton, FormControl, FormErrorMessage, FormHelperText, FormLabel, Grid, GridItem, HStack, Heading, IconButton, Image, Img, InfoSelect, InfoTag, Input, InputGroup, InputLeftElement, InputRightElement, Item, ItemDescription, ItemLabel, JumpButton, Language, LanguageProvider, LightFullScreenLoader, LightInlineLoader, LightMode, LightSpinner, LineIcon, ListBox, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, NativeSelect, NumericStepper, PasswordInput, PhoneNumberInput, PlayPauseButton, Popover, PopoverAnchor, PopoverArrow, PopoverBody, PopoverCloseButton, PopoverContent, PopoverFooter, PopoverHeader, PopoverTrigger, PopoverWizardBody, ProgressBar, ProgressLoader, Radio, RadioGroup, ScaleFade, SearchInput, Section, SelectItem, SelectItemDescription, SelectItemLabel, SimpleDrawer, SimpleGrid, SimplePopover, Skeleton, SkeletonCircle, SkeletonText, SkipButton, Slide, SlideFade, Spacer, SporProvider, Stack, StaticAlert, Stepper, StepperStep, Switch, Tab, TabList, TabPanel, TabPanels, Table, TableCaption, Tabs, Tbody, Td, Text, TextLink, Textarea, Tfoot, Th, Thead, Time, TimePicker, Tr, TravelTag, VStack, VyLogo, WizardPopover, Wrap, WrapItem, createTexts, extendTheme, fontFaces, theme, tokens, useBreakpointValue, useClipboard, useColorMode, useColorModePreference, useColorModeValue, useControllableProp, useDisclosure, useMediaQuery, useMergeRefs, useOutsideClick, usePrefersReducedMotion, useTheme, useToast, useToken, useTranslation } from './chunk-7GRTZA6T.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vygruppen/spor-react",
3
- "version": "2.4.2",
3
+ "version": "2.5.0",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
package/src/card/Card.tsx CHANGED
@@ -25,10 +25,10 @@ export type CardProps = Exclude<BoxProps, "size"> & {
25
25
  * </Card>
26
26
  * ```
27
27
  *
28
- * There are lots of color schemes available. You can also set the size as either `sm` or `lg`. The default is `lg`.
28
+ * There are lots of color schemes available. You can also set the size as either `sm` or `lg`. The default is `sm`.
29
29
  *
30
30
  * ```tsx
31
- * <Card colorScheme="orange" size="sm">
31
+ * <Card colorScheme="orange" size="lg">
32
32
  * A smaller card
33
33
  * </Card>
34
34
  * ```
@@ -45,7 +45,7 @@ export type CardProps = Exclude<BoxProps, "size"> & {
45
45
  * ```
46
46
  */
47
47
  export const Card = forwardRef<CardProps, As>(
48
- ({ size = "lg", colorScheme = "white", children, ...props }, ref) => {
48
+ ({ size = "sm", colorScheme = "white", children, ...props }, ref) => {
49
49
  const styles = useStyleConfig("Card", {
50
50
  colorScheme,
51
51
  size,
@@ -1,7 +1,7 @@
1
1
  import React, { useRef } from "react";
2
2
  import { AriaComboBoxProps, useComboBox, useFilter } from "react-aria";
3
3
  import { useComboBoxState } from "react-stately";
4
- import { ColorSpinner, FormControl, Input, InputProps, ListBox } from "..";
4
+ import { ColorSpinner, Input, InputProps, ListBox } from "..";
5
5
  import { Popover } from "./Popover";
6
6
 
7
7
  export type ComboboxProps<T> = AriaComboBoxProps<T> & {
@@ -9,10 +9,14 @@ export type ComboboxProps<T> = AriaComboBoxProps<T> & {
9
9
  label: string;
10
10
  /** Whether or not the combobox is waiting for new suggestions */
11
11
  isLoading?: boolean;
12
+ /** Optional UI to show when there are no matching items */
13
+ emptyContent?: React.ReactNode;
12
14
  } & Pick<
13
15
  InputProps,
14
16
  | "marginTop"
15
17
  | "marginBottom"
18
+ | "marginRight"
19
+ | "marginLeft"
16
20
  | "marginY"
17
21
  | "marginX"
18
22
  | "paddingTop"
@@ -65,25 +69,29 @@ export function Combobox<T extends object>({
65
69
  marginTop,
66
70
  marginX,
67
71
  marginY,
72
+ marginRight,
73
+ marginLeft,
68
74
  paddingBottom,
69
75
  paddingRight,
70
76
  paddingTop,
71
77
  paddingLeft,
72
78
  paddingX,
73
79
  paddingY,
74
- onFocus,
80
+ emptyContent,
75
81
  ...rest
76
82
  }: ComboboxProps<T>) {
77
83
  const { contains } = useFilter({ sensitivity: "base" });
78
- const state = useComboBoxState({
79
- ...rest,
80
- defaultFilter: contains,
81
- });
82
84
 
83
85
  const inputRef = useRef(null);
84
86
  const listBoxRef = useRef(null);
85
87
  const popoverRef = useRef(null);
86
88
 
89
+ const state = useComboBoxState({
90
+ ...rest,
91
+ defaultFilter: contains,
92
+ allowsEmptyCollection: Boolean(emptyContent),
93
+ });
94
+
87
95
  const {
88
96
  inputProps: { size, ...inputProps },
89
97
  listBoxProps,
@@ -98,18 +106,19 @@ export function Combobox<T extends object>({
98
106
  );
99
107
 
100
108
  return (
101
- <FormControl>
109
+ <>
102
110
  <Input
103
111
  {...inputProps}
104
112
  ref={inputRef}
105
113
  label={label}
106
- onFocus={onFocus}
107
114
  borderBottomLeftRadius={state.isOpen ? 0 : borderBottomLeftRadius}
108
115
  borderBottomRightRadius={state.isOpen ? 0 : borderBottomRightRadius}
109
116
  borderTopLeftRadius={borderTopLeftRadius}
110
117
  borderTopRightRadius={borderTopRightRadius}
111
118
  marginBottom={marginBottom}
112
119
  marginTop={marginTop}
120
+ marginRight={marginRight}
121
+ marginLeft={marginLeft}
113
122
  marginX={marginX}
114
123
  marginY={marginY}
115
124
  paddingBottom={paddingBottom}
@@ -147,12 +156,12 @@ export function Combobox<T extends object>({
147
156
  {...listBoxProps}
148
157
  state={state}
149
158
  listBoxRef={listBoxRef}
150
- borderBottomRadius="sm"
159
+ emptyContent={emptyContent}
151
160
  >
152
161
  {rest.children}
153
162
  </ListBox>
154
163
  </Popover>
155
164
  )}
156
- </FormControl>
165
+ </>
157
166
  );
158
167
  }
@@ -10,7 +10,7 @@ import {
10
10
  } from "@chakra-ui/react";
11
11
  import React, { useId } from "react";
12
12
 
13
- export type InputProps = Exclude<ChakraInputProps, "variant" | "size"> & {
13
+ export type InputProps = Omit<ChakraInputProps, "variant" | "size"> & {
14
14
  /** The input's label */
15
15
  label: string;
16
16
  /** Icon that shows up to the left */
@@ -34,7 +34,7 @@ export type InputProps = Exclude<ChakraInputProps, "variant" | "size"> & {
34
34
  * ```
35
35
  */
36
36
  export const Input = forwardRef<InputProps, "input">(
37
- ({ label, leftIcon, rightIcon, id, ...props }, ref) => {
37
+ ({ label, leftIcon, rightIcon, id, size, ...props }, ref) => {
38
38
  const formControlProps = useFormControlContext();
39
39
  const fallbackId = `input-${useId()}`;
40
40
  const inputId = id ?? formControlProps?.id ?? fallbackId;
@@ -50,9 +50,7 @@ export const Input = forwardRef<InputProps, "input">(
50
50
  ref={ref}
51
51
  placeholder=" " // This is needed to make the label work as expected
52
52
  />
53
- <FormLabel htmlFor={inputId} pointerEvents="none">
54
- {label}
55
- </FormLabel>
53
+ <FormLabel htmlFor={inputId}>{label}</FormLabel>
56
54
  {rightIcon && <InputRightElement>{rightIcon}</InputRightElement>}
57
55
  </InputGroup>
58
56
  );
@@ -28,6 +28,8 @@ type ListBoxProps<T> = AriaListBoxProps<T> &
28
28
  isLoading?: boolean;
29
29
  /** The state of the listbox, provided externally somehow. */
30
30
  state: ListState<T> | SelectState<T>;
31
+ /** UI to render if the collection is empty */
32
+ emptyContent?: React.ReactNode;
31
33
  };
32
34
 
33
35
  /**
@@ -80,6 +82,7 @@ export function ListBox<T extends object>({
80
82
  sx={styles.container}
81
83
  aria-busy={isLoading}
82
84
  >
85
+ {state.collection.size === 0 && props.emptyContent}
83
86
  {Array.from(state.collection).map((item) =>
84
87
  item.type === "section" ? (
85
88
  <ListBoxSection key={item.key} section={item} state={state} />
@@ -184,19 +187,19 @@ function ListBoxSection({ section, state }: ListBoxSectionProps) {
184
187
  "aria-label": section["aria-label"],
185
188
  });
186
189
 
187
- const isFirstSection = section.key !== state.collection.getFirstKey();
188
- const titleBackgroundColor = useColorModeValue("platinum", "dimGrey");
190
+ const isFirstSection = section.key === state.collection.getFirstKey();
189
191
  const titleColor = useColorModeValue("darkGrey", "white");
190
192
  return (
191
193
  <ListItem {...itemProps}>
192
194
  {section.rendered && (
193
195
  <Box
194
- textStyle="xs"
195
- backgroundColor={titleBackgroundColor}
196
+ fontSize="mobile.xs"
196
197
  color={titleColor}
197
198
  paddingX={3}
198
199
  paddingY={1}
199
- marginTop={isFirstSection ? 0 : 0}
200
+ marginTop={isFirstSection ? 0 : 3}
201
+ textTransform="uppercase"
202
+ fontWeight="bold"
200
203
  {...headingProps}
201
204
  >
202
205
  {section.rendered}
@@ -17,7 +17,7 @@ import { createTexts, useTranslation } from "..";
17
17
 
18
18
  export type PasswordInputProps = InputProps;
19
19
  export const PasswordInput = forwardRef<PasswordInputProps, "input">(
20
- ({ leftIcon, id, label, ...props }, ref) => {
20
+ ({ leftIcon, id, label, size, ...props }, ref) => {
21
21
  const { isOpen: isShowingPassword, onToggle } = useDisclosure();
22
22
  const { t } = useTranslation();
23
23
  const formControlProps = useFormControlContext();
@@ -1,7 +1,6 @@
1
1
  export { FormHelperText, InputGroup } from "@chakra-ui/react";
2
2
  export type { InputGroupProps } from "@chakra-ui/react";
3
3
  export * from "./AttachedInputs";
4
- export * from "./Autosuggest";
5
4
  export * from "./CardSelect";
6
5
  export * from "./Checkbox";
7
6
  export * from "./CheckboxGroup";
@@ -136,7 +136,7 @@ const config = helpers.defineMultiStyleConfig({
136
136
  },
137
137
  defaultProps: {
138
138
  variant: "list",
139
- size: "md",
139
+ size: "sm",
140
140
  },
141
141
  });
142
142
 
@@ -20,18 +20,26 @@ const config = helpers.defineMultiStyleConfig({
20
20
  maxHeight: "50vh",
21
21
  width: "100%",
22
22
  listStyle: "none",
23
+ borderBottomRadius: "sm",
23
24
  },
24
25
  item: {
25
- paddingX: 3,
26
- paddingY: 2,
26
+ paddingX: 2,
27
+ paddingY: 1,
28
+ marginY: 1,
29
+ marginX: 1,
30
+ borderRadius: "sm",
27
31
  color: mode("darkGrey", "white")(props),
28
32
  _hover: {
29
- background: mode("mint", "darkTeal")(props),
33
+ backgroundColor: mode("seaMist", "darkTeal")(props),
34
+ outline: "none",
35
+ },
36
+ _active: {
37
+ backgroundColor: mode("mint", "darkTeal")(props),
30
38
  outline: "none",
31
39
  },
32
40
  _focus: {
33
41
  outline: "none",
34
- backgroundColor: mode("mint", "darkTeal")(props),
42
+ backgroundColor: mode("seaMist", "darkTeal")(props),
35
43
  },
36
44
  _selected: {
37
45
  backgroundColor: mode("pine", "pine")(props),
@@ -1,136 +0,0 @@
1
- import React from "react";
2
- import { useAsyncList } from "react-stately";
3
- import { Combobox, ComboboxProps, InputProps } from "../";
4
-
5
- type AutosuggestProps<T> = {
6
- /** The label of the search field */
7
- label: string;
8
- /**
9
- * The function responsible for fetching new suggestion items, based on the query.
10
- *
11
- * This will typically be an API call to a backend service.
12
- *
13
- * @example
14
- * ```tsx
15
- * const fetcher = async (query?: string) => {
16
- * const response = await fetch(`https://some.api.com/filter=${query}`);
17
- * const json = await response.json();
18
- * return json;
19
- * };
20
- * ```
21
- * */
22
- fetcher: (query?: string) => Promise<Iterable<T>>;
23
- /**
24
- * A render function that receives each item, and returns the UI for each item in the list.
25
- *
26
- * @example
27
- * ```tsx
28
- * <Autosuggest {...otherProps}>
29
- * {(user) => (
30
- * <Item key={user.id} textValue={user.fullName}>
31
- * <ItemLabel>{user.fullName}</ItemLabel>
32
- * <ItemDescription>{user.asl}</ItemDescription>
33
- * </Item>
34
- * )}
35
- * </Autosuggest>
36
- * ```
37
- *
38
- * You technically don't need to use the `<SelectItemLabel />` and `<SelectItemDescription />` components, but they are recommended to improve the accessibility of the search results. You can style them however you want, so there should never be a reason not to include at least the `<SelectItemLabel />` component. But who's judging?
39
- * */
40
- children: ComboboxProps<T>["children"];
41
- /**
42
- * Callback for when the selection changes. Returns the entire item.
43
- */
44
- onSelectionChange?: (item: T) => void;
45
- /** The selected item key (controlled) */
46
- selectedKey?: ComboboxProps<T>["selectedKey"];
47
- /** What should open the menu.
48
- *
49
- * Defaults to "input"
50
- */
51
- menuTrigger?: ComboboxProps<T>["menuTrigger"];
52
- } & Pick<
53
- InputProps,
54
- | "marginTop"
55
- | "marginBottom"
56
- | "marginY"
57
- | "marginX"
58
- | "paddingTop"
59
- | "paddingBottom"
60
- | "paddingLeft"
61
- | "paddingRight"
62
- | "paddingY"
63
- | "paddingX"
64
- | "leftIcon"
65
- | "rightIcon"
66
- | "borderTopRightRadius"
67
- | "borderTopLeftRadius"
68
- | "borderBottomRightRadius"
69
- | "borderBottomLeftRadius"
70
- | "onFocus"
71
- >;
72
- /**
73
- * A component that provides an autocomplete search field with suggestions.
74
- *
75
- * This component requires a `fetcher` prop, which is a function that receives a query string, and returns a list of items that match the query.
76
- *
77
- * @example
78
- * ```tsx
79
- * const fetcher = async (query?: string) => {
80
- * const response = await fetch(`https://some.api.vy.no/filter=${query}`);
81
- * const json = await response.json();
82
- * return json;
83
- * };
84
- *
85
- * const Example = () => {
86
- * return (
87
- * <Autosuggest
88
- * label="Search for users"
89
- * fetcher={fetcher}
90
- * onSelectionChange={(item) => console.log(item)}
91
- * >
92
- * {(user) => (
93
- * <Item key={user.id} textValue={user.fullName}>
94
- * <ItemLabel>{user.fullName}</ItemLabel>
95
- * <ItemDescription>{user.asl}</ItemDescription>
96
- * </Item>
97
- * )}
98
- * </Autosuggest>
99
- * );
100
- * };
101
- * ```
102
- */
103
- export function Autosuggest<T extends object>({
104
- label,
105
- fetcher,
106
- children,
107
- onSelectionChange,
108
- ...props
109
- }: AutosuggestProps<T>) {
110
- const list = useAsyncList<T>({
111
- async load({ filterText }) {
112
- return {
113
- items: await fetcher(filterText),
114
- };
115
- },
116
- });
117
- const handleSelectionChange = (key: React.Key) => {
118
- if (!onSelectionChange) {
119
- return;
120
- }
121
- return onSelectionChange(list.getItem(key));
122
- };
123
- return (
124
- <Combobox
125
- label={label}
126
- items={list.items}
127
- inputValue={list.filterText}
128
- onInputChange={list.setFilterText}
129
- onSelectionChange={handleSelectionChange}
130
- isLoading={list.isLoading}
131
- {...props}
132
- >
133
- {children}
134
- </Combobox>
135
- );
136
- }