@vygruppen/spor-react 2.4.3 → 2.5.1

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.3 build
2
+ > @vygruppen/spor-react@2.5.1 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-Z3I6W6PC.mjs".
14
- CJS dist/index.js 896.27 KB
15
- CJS ⚡️ Build success in 5484ms
16
- ESM dist/index.mjs 2.08 KB
17
- ESM dist/CountryCodeSelect-GFQIGSFV.mjs 351.67 KB
18
- ESM dist/chunk-Z3I6W6PC.mjs 416.47 KB
19
- ESM ⚡️ Build success in 5484ms
20
- DTS ⚡️ Build success in 22623ms
21
- DTS dist/index.d.ts 262.86 KB
13
+ "toTime" is imported from external module "@internationalized/date" but never used in "dist/chunk-QEKFPZKV.mjs".
14
+ CJS dist/index.js 895.50 KB
15
+ CJS ⚡️ Build success in 4556ms
16
+ ESM dist/index.mjs 2.06 KB
17
+ ESM dist/CountryCodeSelect-JL2OVNXX.mjs 351.67 KB
18
+ ESM dist/chunk-QEKFPZKV.mjs 415.80 KB
19
+ ESM ⚡️ Build success in 4557ms
20
+ DTS ⚡️ Build success in 17324ms
21
+ DTS dist/index.d.ts 259.33 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @vygruppen/spor-react
2
2
 
3
+ ## 2.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 28a772f4: Datepicker, Timepicker: Changed color to meet contrast minimum requriement
8
+ - f49fa9d2: TimePicker: Fixes typing bug in onChange prop
9
+ - 643afb0d: Combobox: Fix glitchy loading state
10
+
11
+ ## 2.5.0
12
+
13
+ ### Minor Changes
14
+
15
+ - 042dba35: Make accordions and cards default to the sm size
16
+
17
+ ### Patch Changes
18
+
19
+ - f9d6bd34: Combobox: Fix a bug where menuTrigger="focus" wouldn't work
20
+ - 76914a15: Remove non-working Autosuggest component
21
+
3
22
  ## 2.4.3
4
23
 
5
24
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { createTexts, useTranslation, InfoSelect, SelectItem } from './chunk-Z3I6W6PC.mjs';
1
+ import { createTexts, useTranslation, InfoSelect, SelectItem } from './chunk-QEKFPZKV.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,46 +4019,6 @@ var AttachedInputs = ({
4019
4019
  }
4020
4020
  );
4021
4021
  };
4022
- function Autosuggest({
4023
- label,
4024
- fetcher,
4025
- onSelectionChange,
4026
- ...props
4027
- }) {
4028
- const list2 = useAsyncList({
4029
- async load({ filterText }) {
4030
- return {
4031
- items: await fetcher(filterText)
4032
- };
4033
- }
4034
- });
4035
- const handleSelectionChange = (key) => {
4036
- if (!onSelectionChange) {
4037
- return;
4038
- }
4039
- let selectedItem = list2.getItem(key);
4040
- if (!selectedItem) {
4041
- selectedItem = list2.items.flatMap(
4042
- (item) => "children" in item && Array.isArray(item.children) ? item.children : []
4043
- ).find((child) => child.key === key);
4044
- }
4045
- if (selectedItem) {
4046
- onSelectionChange(selectedItem);
4047
- }
4048
- };
4049
- return /* @__PURE__ */ React49__default.createElement(
4050
- Combobox,
4051
- {
4052
- label,
4053
- items: list2.items,
4054
- inputValue: list2.filterText,
4055
- onInputChange: list2.setFilterText,
4056
- onSelectionChange: handleSelectionChange,
4057
- isLoading: list2.isLoading,
4058
- ...props
4059
- }
4060
- );
4061
- }
4062
4022
  var Dialog = ({ title, children, ...props }) => {
4063
4023
  const ref = useRef(null);
4064
4024
  const { dialogProps, titleProps } = useDialog(props, ref);
@@ -4252,17 +4212,19 @@ function Combobox({
4252
4212
  paddingLeft,
4253
4213
  paddingX,
4254
4214
  paddingY,
4255
- onFocus,
4215
+ emptyContent,
4256
4216
  ...rest
4257
4217
  }) {
4258
4218
  const { contains: contains2 } = useFilter({ sensitivity: "base" });
4259
- const state2 = useComboBoxState({
4260
- ...rest,
4261
- defaultFilter: contains2
4262
- });
4263
4219
  const inputRef = useRef(null);
4264
4220
  const listBoxRef = useRef(null);
4265
4221
  const popoverRef = useRef(null);
4222
+ const state2 = useComboBoxState({
4223
+ ...rest,
4224
+ defaultFilter: contains2,
4225
+ allowsEmptyCollection: Boolean(emptyContent),
4226
+ shouldCloseOnBlur: true
4227
+ });
4266
4228
  const {
4267
4229
  inputProps: { size: size2, ...inputProps },
4268
4230
  listBoxProps
@@ -4281,9 +4243,8 @@ function Combobox({
4281
4243
  ...inputProps,
4282
4244
  ref: inputRef,
4283
4245
  label,
4284
- onFocus,
4285
- borderBottomLeftRadius: state2.isOpen ? 0 : borderBottomLeftRadius,
4286
- borderBottomRightRadius: state2.isOpen ? 0 : borderBottomRightRadius,
4246
+ borderBottomLeftRadius: state2.isOpen && !isLoading ? 0 : borderBottomLeftRadius,
4247
+ borderBottomRightRadius: state2.isOpen && !isLoading ? 0 : borderBottomRightRadius,
4287
4248
  borderTopLeftRadius,
4288
4249
  borderTopRightRadius,
4289
4250
  marginBottom,
@@ -4313,7 +4274,7 @@ function Combobox({
4313
4274
  }
4314
4275
  ) : rightIcon
4315
4276
  }
4316
- ), state2.isOpen && /* @__PURE__ */ React49__default.createElement(
4277
+ ), state2.isOpen && !isLoading && /* @__PURE__ */ React49__default.createElement(
4317
4278
  Popover3,
4318
4279
  {
4319
4280
  state: state2,
@@ -4327,7 +4288,7 @@ function Combobox({
4327
4288
  ...listBoxProps,
4328
4289
  state: state2,
4329
4290
  listBoxRef,
4330
- borderBottomRadius: "sm"
4291
+ emptyContent
4331
4292
  },
4332
4293
  rest.children
4333
4294
  )
@@ -4414,6 +4375,7 @@ function ListBox({
4414
4375
  sx: styles2.container,
4415
4376
  "aria-busy": isLoading
4416
4377
  },
4378
+ state2.collection.size === 0 && props.emptyContent,
4417
4379
  Array.from(state2.collection).map(
4418
4380
  (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 })
4419
4381
  )
@@ -4466,18 +4428,18 @@ function ListBoxSection({ section, state: state2 }) {
4466
4428
  heading: section.rendered,
4467
4429
  "aria-label": section["aria-label"]
4468
4430
  });
4469
- const isFirstSection = section.key !== state2.collection.getFirstKey();
4470
- const titleBackgroundColor = useColorModeValue("platinum", "dimGrey");
4431
+ const isFirstSection = section.key === state2.collection.getFirstKey();
4471
4432
  const titleColor = useColorModeValue("darkGrey", "white");
4472
4433
  return /* @__PURE__ */ React49__default.createElement(ListItem, { ...itemProps }, section.rendered && /* @__PURE__ */ React49__default.createElement(
4473
4434
  Box,
4474
4435
  {
4475
- textStyle: "xs",
4476
- backgroundColor: titleBackgroundColor,
4436
+ fontSize: "mobile.xs",
4477
4437
  color: titleColor,
4478
4438
  paddingX: 3,
4479
4439
  paddingY: 1,
4480
- marginTop: isFirstSection ? 0 : 0,
4440
+ marginTop: isFirstSection ? 0 : 3,
4441
+ textTransform: "uppercase",
4442
+ fontWeight: "bold",
4481
4443
  ...headingProps
4482
4444
  },
4483
4445
  section.rendered
@@ -4561,7 +4523,7 @@ var texts10 = createTexts({
4561
4523
  }
4562
4524
  });
4563
4525
  var Input = forwardRef(
4564
- ({ label, leftIcon, rightIcon, id, ...props }, ref) => {
4526
+ ({ label, leftIcon, rightIcon, id, size: size2, ...props }, ref) => {
4565
4527
  const formControlProps = useFormControlContext();
4566
4528
  const fallbackId = `input-${useId()}`;
4567
4529
  const inputId = id ?? (formControlProps == null ? void 0 : formControlProps.id) ?? fallbackId;
@@ -4576,7 +4538,7 @@ var Input = forwardRef(
4576
4538
  ref,
4577
4539
  placeholder: " "
4578
4540
  }
4579
- ), /* @__PURE__ */ React49__default.createElement(FormLabel, { htmlFor: inputId, pointerEvents: "none" }, label), rightIcon && /* @__PURE__ */ React49__default.createElement(InputRightElement, null, rightIcon));
4541
+ ), /* @__PURE__ */ React49__default.createElement(FormLabel, { htmlFor: inputId }, label), rightIcon && /* @__PURE__ */ React49__default.createElement(InputRightElement, null, rightIcon));
4580
4542
  }
4581
4543
  );
4582
4544
  var InputLeftElement2 = forwardRef(
@@ -4826,7 +4788,7 @@ var texts11 = createTexts({
4826
4788
  }
4827
4789
  });
4828
4790
  var PasswordInput = forwardRef(
4829
- ({ leftIcon, id, label, ...props }, ref) => {
4791
+ ({ leftIcon, id, label, size: size2, ...props }, ref) => {
4830
4792
  const { isOpen: isShowingPassword, onToggle } = useDisclosure();
4831
4793
  const { t: t2 } = useTranslation();
4832
4794
  const formControlProps = useFormControlContext();
@@ -4939,7 +4901,7 @@ var texts13 = createTexts({
4939
4901
  sv: "Telefonnummer"
4940
4902
  }
4941
4903
  });
4942
- var LazyCountryCodeSelect = React49__default.lazy(() => import('./CountryCodeSelect-GFQIGSFV.mjs'));
4904
+ var LazyCountryCodeSelect = React49__default.lazy(() => import('./CountryCodeSelect-JL2OVNXX.mjs'));
4943
4905
  var Radio = forwardRef((props, ref) => {
4944
4906
  return /* @__PURE__ */ React49__default.createElement(Radio$1, { ...props, ref });
4945
4907
  });
@@ -10986,7 +10948,7 @@ var config3 = helpers.defineMultiStyleConfig({
10986
10948
  },
10987
10949
  defaultProps: {
10988
10950
  variant: "list",
10989
- size: "md"
10951
+ size: "sm"
10990
10952
  }
10991
10953
  });
10992
10954
  var accordion_default = config3;
@@ -11922,7 +11884,7 @@ var config13 = helpers6.defineMultiStyleConfig({
11922
11884
  },
11923
11885
  dateTimeSegment: {
11924
11886
  color: mode(
11925
- props.isPlaceholder ? "dimGrey" : props.isEditable ? "darkGrey" : "osloGrey",
11887
+ props.isEditable ? "darkGrey" : "dimGrey",
11926
11888
  props.isPlaceholder ? "whiteAlpha.400" : "white"
11927
11889
  )(props)
11928
11890
  },
@@ -13050,19 +13012,27 @@ var config24 = helpers15.defineMultiStyleConfig({
13050
13012
  overflowY: "auto",
13051
13013
  maxHeight: "50vh",
13052
13014
  width: "100%",
13053
- listStyle: "none"
13015
+ listStyle: "none",
13016
+ borderBottomRadius: "sm"
13054
13017
  },
13055
13018
  item: {
13056
- paddingX: 3,
13057
- paddingY: 2,
13019
+ paddingX: 2,
13020
+ paddingY: 1,
13021
+ marginY: 1,
13022
+ marginX: 1,
13023
+ borderRadius: "sm",
13058
13024
  color: mode("darkGrey", "white")(props),
13059
13025
  _hover: {
13060
- background: mode("mint", "darkTeal")(props),
13026
+ backgroundColor: mode("seaMist", "darkTeal")(props),
13027
+ outline: "none"
13028
+ },
13029
+ _active: {
13030
+ backgroundColor: mode("mint", "darkTeal")(props),
13061
13031
  outline: "none"
13062
13032
  },
13063
13033
  _focus: {
13064
13034
  outline: "none",
13065
- backgroundColor: mode("mint", "darkTeal")(props)
13035
+ backgroundColor: mode("seaMist", "darkTeal")(props)
13066
13036
  },
13067
13037
  _selected: {
13068
13038
  backgroundColor: mode("pine", "pine")(props),
@@ -14567,4 +14537,4 @@ var getToastComponent = (opts) => {
14567
14537
  return ({ id }) => /* @__PURE__ */ React49__default.createElement(BaseToast, { id, variant: opts.variant }, opts.text);
14568
14538
  };
14569
14539
 
14570
- 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 };
14540
+ 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
  * ```
@@ -452,7 +452,7 @@ type DateRangePickerProps = AriaDateRangePickerProps<DateValue> & Pick<BoxProps,
452
452
  */
453
453
  declare function DateRangePicker({ variant, minHeight, startName, endName, ...props }: DateRangePickerProps): React__default.JSX.Element;
454
454
 
455
- type TimePickerProps = Omit<BoxProps, "defaultValue"> & {
455
+ type TimePickerProps = Omit<BoxProps, "defaultValue" | "onChange"> & {
456
456
  /** The label. Defaults to a localized version of "Time" */
457
457
  label?: string;
458
458
  /** The name of the form field, if used in a regular form */
@@ -607,109 +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" | "marginRight" | "marginLeft" | "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
- * The `fetcher` function can be any function that returns an iterable of items. This means that you can use any API library you want, as long as it returns an iterable of items.
690
- *
691
- * The items need to have a `key` property, which is used to identify the item. The `key` property can be any type, but it needs to be unique for each item.
692
- *
693
- * ```tsx
694
- * [{ key: 'some-key', ...}, { key: 'some-other-key', ... }]
695
- * ```
696
- *
697
- * You can also return a set of nested items, which will be rendered as a sub-list (or section). This is useful if you want to group your items. These items need to have a title prop (for labelling the section), as well as a `children` prop, which in turn will contain an iterable of items:
698
- *
699
- * ```tsx
700
- * [
701
- * {
702
- * title: 'The title of the section',
703
- * children: [{ key: 'some-key', ... }]
704
- * },
705
- * {...}
706
- * ]
707
- * ```
708
- *
709
- * The `onSelectionChanged` will return the correct `item` (the one with the matching `key`), even if the item is in a sub-list.
710
- */
711
- declare function Autosuggest<T extends object>({ label, fetcher, onSelectionChange, ...props }: AutosuggestProps<T>): React__default.JSX.Element;
712
-
713
610
  type CardSelectProps = BoxProps & {
714
611
  /** The design of the trigger button.
715
612
  *
@@ -845,6 +742,8 @@ type ComboboxProps<T> = AriaComboBoxProps<T> & {
845
742
  label: string;
846
743
  /** Whether or not the combobox is waiting for new suggestions */
847
744
  isLoading?: boolean;
745
+ /** Optional UI to show when there are no matching items */
746
+ emptyContent?: React__default.ReactNode;
848
747
  } & Pick<InputProps, "marginTop" | "marginBottom" | "marginRight" | "marginLeft" | "marginY" | "marginX" | "paddingTop" | "paddingBottom" | "paddingLeft" | "paddingRight" | "paddingY" | "paddingX" | "leftIcon" | "rightIcon" | "borderTopRightRadius" | "borderTopLeftRadius" | "borderBottomRightRadius" | "borderBottomLeftRadius" | "onFocus">;
849
748
  /**
850
749
  * A combobox is a combination of an input and a list of suggestions.
@@ -869,7 +768,7 @@ type ComboboxProps<T> = AriaComboBoxProps<T> & {
869
768
  * </Combobox>
870
769
  * ```
871
770
  */
872
- 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, 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;
873
772
 
874
773
  type FormControlProps = FormControlProps$1;
875
774
  declare const FormControl: _chakra_ui_system_dist_system_types.ComponentWithAs<"div", FormControlProps$1>;
@@ -1045,7 +944,7 @@ type InfoSelectProps<T extends object> = {
1045
944
  */
1046
945
  declare function InfoSelect<T extends object>({ placeholder, width, height, onChange, value, isLabelSrOnly, defaultValue, ...props }: InfoSelectProps<T>): React__default.JSX.Element;
1047
946
 
1048
- type InputProps = Exclude<InputProps$1, "variant" | "size"> & {
947
+ type InputProps = Omit<InputProps$1, "variant" | "size"> & {
1049
948
  /** The input's label */
1050
949
  label: string;
1051
950
  /** Icon that shows up to the left */
@@ -1112,6 +1011,8 @@ type ListBoxProps<T> = AriaListBoxProps<T> & Omit<BoxProps, "filter" | "autoFocu
1112
1011
  isLoading?: boolean;
1113
1012
  /** The state of the listbox, provided externally somehow. */
1114
1013
  state: ListState<T> | SelectState<T>;
1014
+ /** UI to render if the collection is empty */
1015
+ emptyContent?: React__default.ReactNode;
1115
1016
  };
1116
1017
  /**
1117
1018
  * A component that renders a list box with selectable options.
@@ -3750,13 +3651,21 @@ declare const theme: {
3750
3651
  maxHeight: string;
3751
3652
  width: string;
3752
3653
  listStyle: string;
3654
+ borderBottomRadius: string;
3753
3655
  };
3754
3656
  item: {
3755
3657
  paddingX: number;
3756
3658
  paddingY: number;
3659
+ marginY: number;
3660
+ marginX: number;
3661
+ borderRadius: string;
3757
3662
  color: string;
3758
3663
  _hover: {
3759
- background: string;
3664
+ backgroundColor: string;
3665
+ outline: string;
3666
+ };
3667
+ _active: {
3668
+ backgroundColor: string;
3760
3669
  outline: string;
3761
3670
  };
3762
3671
  _focus: {
@@ -7099,4 +7008,4 @@ type TextProps = Omit<TextProps$1, "textStyle"> & {
7099
7008
  */
7100
7009
  declare const Text: _chakra_ui_system_dist_system_types.ComponentWithAs<"p", TextProps>;
7101
7010
 
7102
- 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,51 +3750,6 @@ var init_AttachedInputs = __esm({
3750
3750
  };
3751
3751
  }
3752
3752
  });
3753
- function Autosuggest({
3754
- label,
3755
- fetcher,
3756
- onSelectionChange,
3757
- ...props
3758
- }) {
3759
- const list2 = reactStately.useAsyncList({
3760
- async load({ filterText }) {
3761
- return {
3762
- items: await fetcher(filterText)
3763
- };
3764
- }
3765
- });
3766
- const handleSelectionChange = (key) => {
3767
- if (!onSelectionChange) {
3768
- return;
3769
- }
3770
- let selectedItem = list2.getItem(key);
3771
- if (!selectedItem) {
3772
- selectedItem = list2.items.flatMap(
3773
- (item) => "children" in item && Array.isArray(item.children) ? item.children : []
3774
- ).find((child) => child.key === key);
3775
- }
3776
- if (selectedItem) {
3777
- onSelectionChange(selectedItem);
3778
- }
3779
- };
3780
- return /* @__PURE__ */ React49__namespace.default.createElement(
3781
- Combobox,
3782
- {
3783
- label,
3784
- items: list2.items,
3785
- inputValue: list2.filterText,
3786
- onInputChange: list2.setFilterText,
3787
- onSelectionChange: handleSelectionChange,
3788
- isLoading: list2.isLoading,
3789
- ...props
3790
- }
3791
- );
3792
- }
3793
- var init_Autosuggest = __esm({
3794
- "src/input/Autosuggest.tsx"() {
3795
- init_src();
3796
- }
3797
- });
3798
3753
  var Dialog;
3799
3754
  var init_Dialog = __esm({
3800
3755
  "src/input/Dialog.tsx"() {
@@ -4767,17 +4722,19 @@ function Combobox({
4767
4722
  paddingLeft,
4768
4723
  paddingX,
4769
4724
  paddingY,
4770
- onFocus,
4725
+ emptyContent,
4771
4726
  ...rest
4772
4727
  }) {
4773
4728
  const { contains: contains2 } = reactAria.useFilter({ sensitivity: "base" });
4774
- const state2 = reactStately.useComboBoxState({
4775
- ...rest,
4776
- defaultFilter: contains2
4777
- });
4778
4729
  const inputRef = React49.useRef(null);
4779
4730
  const listBoxRef = React49.useRef(null);
4780
4731
  const popoverRef = React49.useRef(null);
4732
+ const state2 = reactStately.useComboBoxState({
4733
+ ...rest,
4734
+ defaultFilter: contains2,
4735
+ allowsEmptyCollection: Boolean(emptyContent),
4736
+ shouldCloseOnBlur: true
4737
+ });
4781
4738
  const {
4782
4739
  inputProps: { size: size2, ...inputProps },
4783
4740
  listBoxProps
@@ -4796,9 +4753,8 @@ function Combobox({
4796
4753
  ...inputProps,
4797
4754
  ref: inputRef,
4798
4755
  label,
4799
- onFocus,
4800
- borderBottomLeftRadius: state2.isOpen ? 0 : borderBottomLeftRadius,
4801
- borderBottomRightRadius: state2.isOpen ? 0 : borderBottomRightRadius,
4756
+ borderBottomLeftRadius: state2.isOpen && !isLoading ? 0 : borderBottomLeftRadius,
4757
+ borderBottomRightRadius: state2.isOpen && !isLoading ? 0 : borderBottomRightRadius,
4802
4758
  borderTopLeftRadius,
4803
4759
  borderTopRightRadius,
4804
4760
  marginBottom,
@@ -4828,7 +4784,7 @@ function Combobox({
4828
4784
  }
4829
4785
  ) : rightIcon
4830
4786
  }
4831
- ), state2.isOpen && /* @__PURE__ */ React49__namespace.default.createElement(
4787
+ ), state2.isOpen && !isLoading && /* @__PURE__ */ React49__namespace.default.createElement(
4832
4788
  Popover3,
4833
4789
  {
4834
4790
  state: state2,
@@ -4842,7 +4798,7 @@ function Combobox({
4842
4798
  ...listBoxProps,
4843
4799
  state: state2,
4844
4800
  listBoxRef,
4845
- borderBottomRadius: "sm"
4801
+ emptyContent
4846
4802
  },
4847
4803
  rest.children
4848
4804
  )
@@ -4949,6 +4905,7 @@ function ListBox({
4949
4905
  sx: styles2.container,
4950
4906
  "aria-busy": isLoading
4951
4907
  },
4908
+ state2.collection.size === 0 && props.emptyContent,
4952
4909
  Array.from(state2.collection).map(
4953
4910
  (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 })
4954
4911
  )
@@ -4992,18 +4949,18 @@ function ListBoxSection({ section, state: state2 }) {
4992
4949
  heading: section.rendered,
4993
4950
  "aria-label": section["aria-label"]
4994
4951
  });
4995
- const isFirstSection = section.key !== state2.collection.getFirstKey();
4996
- const titleBackgroundColor = react.useColorModeValue("platinum", "dimGrey");
4952
+ const isFirstSection = section.key === state2.collection.getFirstKey();
4997
4953
  const titleColor = react.useColorModeValue("darkGrey", "white");
4998
4954
  return /* @__PURE__ */ React49__namespace.default.createElement(react.ListItem, { ...itemProps }, section.rendered && /* @__PURE__ */ React49__namespace.default.createElement(
4999
4955
  react.Box,
5000
4956
  {
5001
- textStyle: "xs",
5002
- backgroundColor: titleBackgroundColor,
4957
+ fontSize: "mobile.xs",
5003
4958
  color: titleColor,
5004
4959
  paddingX: 3,
5005
4960
  paddingY: 1,
5006
- marginTop: isFirstSection ? 0 : 0,
4961
+ marginTop: isFirstSection ? 0 : 3,
4962
+ textTransform: "uppercase",
4963
+ fontWeight: "bold",
5007
4964
  ...headingProps
5008
4965
  },
5009
4966
  section.rendered
@@ -5111,7 +5068,7 @@ exports.Input = void 0;
5111
5068
  var init_Input = __esm({
5112
5069
  "src/input/Input.tsx"() {
5113
5070
  exports.Input = react.forwardRef(
5114
- ({ label, leftIcon, rightIcon, id, ...props }, ref) => {
5071
+ ({ label, leftIcon, rightIcon, id, size: size2, ...props }, ref) => {
5115
5072
  const formControlProps = react.useFormControlContext();
5116
5073
  const fallbackId = `input-${React49.useId()}`;
5117
5074
  const inputId = id ?? (formControlProps == null ? void 0 : formControlProps.id) ?? fallbackId;
@@ -5126,7 +5083,7 @@ var init_Input = __esm({
5126
5083
  ref,
5127
5084
  placeholder: " "
5128
5085
  }
5129
- ), /* @__PURE__ */ React49__namespace.default.createElement(react.FormLabel, { htmlFor: inputId, pointerEvents: "none" }, label), rightIcon && /* @__PURE__ */ React49__namespace.default.createElement(react.InputRightElement, null, rightIcon));
5086
+ ), /* @__PURE__ */ React49__namespace.default.createElement(react.FormLabel, { htmlFor: inputId }, label), rightIcon && /* @__PURE__ */ React49__namespace.default.createElement(react.InputRightElement, null, rightIcon));
5130
5087
  }
5131
5088
  );
5132
5089
  }
@@ -5422,7 +5379,7 @@ var init_PasswordInput = __esm({
5422
5379
  init_input();
5423
5380
  init_src();
5424
5381
  exports.PasswordInput = react.forwardRef(
5425
- ({ leftIcon, id, label, ...props }, ref) => {
5382
+ ({ leftIcon, id, label, size: size2, ...props }, ref) => {
5426
5383
  const { isOpen: isShowingPassword, onToggle } = react.useDisclosure();
5427
5384
  const { t: t2 } = useTranslation();
5428
5385
  const formControlProps = react.useFormControlContext();
@@ -12358,7 +12315,6 @@ var init_Textarea = __esm({
12358
12315
  var init_input = __esm({
12359
12316
  "src/input/index.tsx"() {
12360
12317
  init_AttachedInputs();
12361
- init_Autosuggest();
12362
12318
  init_CardSelect();
12363
12319
  init_Checkbox();
12364
12320
  init_CheckboxGroup();
@@ -18993,7 +18949,7 @@ var init_accordion2 = __esm({
18993
18949
  },
18994
18950
  defaultProps: {
18995
18951
  variant: "list",
18996
- size: "md"
18952
+ size: "sm"
18997
18953
  }
18998
18954
  });
18999
18955
  accordion_default = config3;
@@ -19999,7 +19955,7 @@ var init_datepicker2 = __esm({
19999
19955
  },
20000
19956
  dateTimeSegment: {
20001
19957
  color: themeTools.mode(
20002
- props.isPlaceholder ? "dimGrey" : props.isEditable ? "darkGrey" : "osloGrey",
19958
+ props.isEditable ? "darkGrey" : "dimGrey",
20003
19959
  props.isPlaceholder ? "whiteAlpha.400" : "white"
20004
19960
  )(props)
20005
19961
  },
@@ -21200,19 +21156,27 @@ var init_listbox = __esm({
21200
21156
  overflowY: "auto",
21201
21157
  maxHeight: "50vh",
21202
21158
  width: "100%",
21203
- listStyle: "none"
21159
+ listStyle: "none",
21160
+ borderBottomRadius: "sm"
21204
21161
  },
21205
21162
  item: {
21206
- paddingX: 3,
21207
- paddingY: 2,
21163
+ paddingX: 2,
21164
+ paddingY: 1,
21165
+ marginY: 1,
21166
+ marginX: 1,
21167
+ borderRadius: "sm",
21208
21168
  color: themeTools.mode("darkGrey", "white")(props),
21209
21169
  _hover: {
21210
- background: themeTools.mode("mint", "darkTeal")(props),
21170
+ backgroundColor: themeTools.mode("seaMist", "darkTeal")(props),
21171
+ outline: "none"
21172
+ },
21173
+ _active: {
21174
+ backgroundColor: themeTools.mode("mint", "darkTeal")(props),
21211
21175
  outline: "none"
21212
21176
  },
21213
21177
  _focus: {
21214
21178
  outline: "none",
21215
- backgroundColor: themeTools.mode("mint", "darkTeal")(props)
21179
+ backgroundColor: themeTools.mode("seaMist", "darkTeal")(props)
21216
21180
  },
21217
21181
  _selected: {
21218
21182
  backgroundColor: themeTools.mode("pine", "pine")(props),
@@ -23271,7 +23235,6 @@ Object.defineProperty(exports, 'Section', {
23271
23235
  get: function () { return reactStately.Section; }
23272
23236
  });
23273
23237
  exports.tokens = tokens10__namespace;
23274
- exports.Autosuggest = Autosuggest;
23275
23238
  exports.Combobox = Combobox;
23276
23239
  exports.DatePicker = DatePicker;
23277
23240
  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-Z3I6W6PC.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-QEKFPZKV.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vygruppen/spor-react",
3
- "version": "2.4.3",
3
+ "version": "2.5.1",
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,
@@ -12,7 +12,7 @@ import { StyledField } from "./StyledField";
12
12
  import { TimeField } from "./TimeField";
13
13
  import { getCurrentTime, useCurrentLocale } from "./utils";
14
14
 
15
- type TimePickerProps = Omit<BoxProps, "defaultValue"> & {
15
+ type TimePickerProps = Omit<BoxProps, "defaultValue" | "onChange"> & {
16
16
  /** The label. Defaults to a localized version of "Time" */
17
17
  label?: string;
18
18
  /** The name of the form field, if used in a regular form */
@@ -9,6 +9,8 @@ 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"
@@ -75,19 +77,22 @@ export function Combobox<T extends object>({
75
77
  paddingLeft,
76
78
  paddingX,
77
79
  paddingY,
78
- onFocus,
80
+ emptyContent,
79
81
  ...rest
80
82
  }: ComboboxProps<T>) {
81
83
  const { contains } = useFilter({ sensitivity: "base" });
82
- const state = useComboBoxState({
83
- ...rest,
84
- defaultFilter: contains,
85
- });
86
84
 
87
85
  const inputRef = useRef(null);
88
86
  const listBoxRef = useRef(null);
89
87
  const popoverRef = useRef(null);
90
88
 
89
+ const state = useComboBoxState({
90
+ ...rest,
91
+ defaultFilter: contains,
92
+ allowsEmptyCollection: Boolean(emptyContent),
93
+ shouldCloseOnBlur: true,
94
+ });
95
+
91
96
  const {
92
97
  inputProps: { size, ...inputProps },
93
98
  listBoxProps,
@@ -107,9 +112,12 @@ export function Combobox<T extends object>({
107
112
  {...inputProps}
108
113
  ref={inputRef}
109
114
  label={label}
110
- onFocus={onFocus}
111
- borderBottomLeftRadius={state.isOpen ? 0 : borderBottomLeftRadius}
112
- borderBottomRightRadius={state.isOpen ? 0 : borderBottomRightRadius}
115
+ borderBottomLeftRadius={
116
+ state.isOpen && !isLoading ? 0 : borderBottomLeftRadius
117
+ }
118
+ borderBottomRightRadius={
119
+ state.isOpen && !isLoading ? 0 : borderBottomRightRadius
120
+ }
113
121
  borderTopLeftRadius={borderTopLeftRadius}
114
122
  borderTopRightRadius={borderTopRightRadius}
115
123
  marginBottom={marginBottom}
@@ -142,7 +150,7 @@ export function Combobox<T extends object>({
142
150
  )
143
151
  }
144
152
  />
145
- {state.isOpen && (
153
+ {state.isOpen && !isLoading && (
146
154
  <Popover
147
155
  state={state}
148
156
  triggerRef={inputRef}
@@ -153,7 +161,7 @@ export function Combobox<T extends object>({
153
161
  {...listBoxProps}
154
162
  state={state}
155
163
  listBoxRef={listBoxRef}
156
- borderBottomRadius="sm"
164
+ emptyContent={emptyContent}
157
165
  >
158
166
  {rest.children}
159
167
  </ListBox>
@@ -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
 
@@ -73,7 +73,7 @@ const config = helpers.defineMultiStyleConfig({
73
73
  },
74
74
  dateTimeSegment: {
75
75
  color: mode(
76
- props.isPlaceholder ? "dimGrey" : props.isEditable ? "darkGrey" : "osloGrey",
76
+ props.isEditable ? "darkGrey" : "dimGrey",
77
77
  props.isPlaceholder ? "whiteAlpha.400" : "white"
78
78
  )(props),
79
79
  },
@@ -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,172 +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
- | "marginRight"
57
- | "marginLeft"
58
- | "marginY"
59
- | "marginX"
60
- | "paddingTop"
61
- | "paddingBottom"
62
- | "paddingLeft"
63
- | "paddingRight"
64
- | "paddingY"
65
- | "paddingX"
66
- | "leftIcon"
67
- | "rightIcon"
68
- | "borderTopRightRadius"
69
- | "borderTopLeftRadius"
70
- | "borderBottomRightRadius"
71
- | "borderBottomLeftRadius"
72
- | "onFocus"
73
- >;
74
- /**
75
- * A component that provides an autocomplete search field with suggestions.
76
- *
77
- * 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.
78
- *
79
- * @example
80
- * ```tsx
81
- * const fetcher = async (query?: string) => {
82
- * const response = await fetch(`https://some.api.vy.no/filter=${query}`);
83
- * const json = await response.json();
84
- * return json;
85
- * };
86
- *
87
- * const Example = () => {
88
- * return (
89
- * <Autosuggest
90
- * label="Search for users"
91
- * fetcher={fetcher}
92
- * onSelectionChange={(item) => console.log(item)}
93
- * >
94
- * {(user) => (
95
- * <Item key={user.id} textValue={user.fullName}>
96
- * <ItemLabel>{user.fullName}</ItemLabel>
97
- * <ItemDescription>{user.asl}</ItemDescription>
98
- * </Item>
99
- * )}
100
- * </Autosuggest>
101
- * );
102
- * };
103
- * ```
104
- *
105
- * The `fetcher` function can be any function that returns an iterable of items. This means that you can use any API library you want, as long as it returns an iterable of items.
106
- *
107
- * The items need to have a `key` property, which is used to identify the item. The `key` property can be any type, but it needs to be unique for each item.
108
- *
109
- * ```tsx
110
- * [{ key: 'some-key', ...}, { key: 'some-other-key', ... }]
111
- * ```
112
- *
113
- * You can also return a set of nested items, which will be rendered as a sub-list (or section). This is useful if you want to group your items. These items need to have a title prop (for labelling the section), as well as a `children` prop, which in turn will contain an iterable of items:
114
- *
115
- * ```tsx
116
- * [
117
- * {
118
- * title: 'The title of the section',
119
- * children: [{ key: 'some-key', ... }]
120
- * },
121
- * {...}
122
- * ]
123
- * ```
124
- *
125
- * The `onSelectionChanged` will return the correct `item` (the one with the matching `key`), even if the item is in a sub-list.
126
- */
127
- export function Autosuggest<T extends object>({
128
- label,
129
- fetcher,
130
- onSelectionChange,
131
- ...props
132
- }: AutosuggestProps<T>) {
133
- const list = useAsyncList<T>({
134
- async load({ filterText }) {
135
- return {
136
- items: await fetcher(filterText),
137
- };
138
- },
139
- });
140
-
141
- const handleSelectionChange = (key: React.Key) => {
142
- if (!onSelectionChange) {
143
- return;
144
- }
145
-
146
- let selectedItem = list.getItem(key);
147
- if (!selectedItem) {
148
- // If the item is not in the list, it might be in a sub-list
149
- selectedItem = list.items
150
- .flatMap((item) =>
151
- "children" in item && Array.isArray(item.children)
152
- ? item.children
153
- : []
154
- )
155
- .find((child) => child.key === key);
156
- }
157
- if (selectedItem) {
158
- onSelectionChange(selectedItem);
159
- }
160
- };
161
- return (
162
- <Combobox
163
- label={label}
164
- items={list.items}
165
- inputValue={list.filterText}
166
- onInputChange={list.setFilterText}
167
- onSelectionChange={handleSelectionChange}
168
- isLoading={list.isLoading}
169
- {...props}
170
- />
171
- );
172
- }