@mirohq/design-system-combobox 0.1.0-combobox.9 → 0.1.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.
package/dist/main.js CHANGED
@@ -6,8 +6,8 @@ var jsxRuntime = require('react/jsx-runtime');
6
6
  var React = require('react');
7
7
  var react = require('@ariakit/react');
8
8
  var designSystemBaseForm = require('@mirohq/design-system-base-form');
9
- var RadixPopover = require('@radix-ui/react-popover');
10
9
  var designSystemUtils = require('@mirohq/design-system-utils');
10
+ var RadixPopover = require('@radix-ui/react-popover');
11
11
  var designSystemStitches = require('@mirohq/design-system-stitches');
12
12
  var designSystemInput = require('@mirohq/design-system-input');
13
13
  var reactUseControllableState = require('@radix-ui/react-use-controllable-state');
@@ -44,15 +44,10 @@ function _interopNamespace(e) {
44
44
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
45
45
  var RadixPopover__namespace = /*#__PURE__*/_interopNamespace(RadixPopover);
46
46
 
47
- const StyledAnchor = designSystemStitches.styled(RadixPopover.Anchor, {
48
- position: "relative",
49
- width: "100%"
50
- });
51
47
  const StyledInput = designSystemStitches.styled(designSystemInput.Input, {
52
48
  flexWrap: "wrap",
53
49
  flexGrow: 1,
54
- gap: "0 $50",
55
- overflowY: "scroll",
50
+ gap: "$50",
56
51
  "&[data-valid], &[data-invalid]": {
57
52
  // we don't need a bigger padding here as Input component will render its own icon
58
53
  paddingRight: "$100"
@@ -120,6 +115,8 @@ const ComboboxProvider = ({
120
115
  });
121
116
  const [filteredItems, setFilteredItems] = React.useState(/* @__PURE__ */ new Set());
122
117
  const [searchValue, setSearchValue] = React.useState("");
118
+ const [size, setSize] = React.useState();
119
+ const [placeholder, setPlaceholder] = React.useState();
123
120
  const [itemValueTextMap, setItemValueTextMap] = React.useState(/* @__PURE__ */ new Map());
124
121
  const { valid: formFieldValid } = designSystemBaseForm.useFormFieldContext();
125
122
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -144,7 +141,11 @@ const ComboboxProvider = ({
144
141
  filteredItems,
145
142
  setFilteredItems,
146
143
  itemValueTextMap,
147
- setItemValueTextMap
144
+ setItemValueTextMap,
145
+ placeholder,
146
+ setPlaceholder,
147
+ size,
148
+ setSize
148
149
  },
149
150
  children
150
151
  }
@@ -228,7 +229,6 @@ const Trigger = React__default["default"].forwardRef(
228
229
  closeActionLabel,
229
230
  clearActionLabel,
230
231
  onChange,
231
- css,
232
232
  ...restProps
233
233
  }, forwardRef) => {
234
234
  const {
@@ -242,16 +242,21 @@ const Trigger = React__default["default"].forwardRef(
242
242
  onSearchValueChange,
243
243
  searchValue,
244
244
  setSearchValue,
245
- setOpenState
245
+ setOpenState,
246
+ setSize,
247
+ setPlaceholder
246
248
  } = useComboboxContext();
247
249
  const {
248
250
  formElementId,
249
251
  ariaInvalid: formFieldAriaInvalid,
250
- valid: formFieldValid,
251
- label,
252
- isFloatingLabel,
253
- focused
252
+ valid: formFieldValid
254
253
  } = designSystemBaseForm.useFormFieldContext();
254
+ React.useEffect(() => {
255
+ setSize(size);
256
+ }, [size, setSize]);
257
+ React.useEffect(() => {
258
+ setPlaceholder(placeholder);
259
+ }, [setPlaceholder, placeholder]);
255
260
  const valid = formFieldValid != null ? formFieldValid : comboboxValid;
256
261
  const inputProps = {
257
262
  ...restProps,
@@ -266,8 +271,6 @@ const Trigger = React__default["default"].forwardRef(
266
271
  id: id != null ? id : formElementId,
267
272
  placeholder: value.length === 0 ? placeholder : void 0
268
273
  };
269
- const shouldUseFloatingLabel = label !== null && isFloatingLabel;
270
- const isFloating = placeholder !== void 0 || value.length !== 0 || focused || searchValue !== "";
271
274
  const scrollIntoView = (event) => {
272
275
  var _a;
273
276
  const trigger = triggerRef == null ? void 0 : triggerRef.current;
@@ -287,47 +290,43 @@ const Trigger = React__default["default"].forwardRef(
287
290
  onSearchValueChange == null ? void 0 : onSearchValueChange(e.target.value);
288
291
  onChange == null ? void 0 : onChange(e);
289
292
  };
290
- return /* @__PURE__ */ jsxRuntime.jsxs(
291
- StyledAnchor,
293
+ return /* @__PURE__ */ jsxRuntime.jsx(
294
+ RadixPopover.Anchor,
292
295
  {
293
296
  ref: designSystemUtils.mergeRefs([triggerRef, forwardRef]),
294
- css,
295
297
  onClick: () => {
296
298
  if (!designSystemUtils.booleanify(disabled) && !designSystemUtils.booleanify(ariaDisabled) && !designSystemUtils.booleanify(readOnly)) {
297
299
  setOpenState(true);
298
300
  }
299
301
  },
300
- children: [
301
- shouldUseFloatingLabel && /* @__PURE__ */ jsxRuntime.jsx(designSystemBaseForm.FloatingLabel, { floating: isFloating, size, children: label }),
302
- /* @__PURE__ */ jsxRuntime.jsx(
303
- react.Combobox,
304
- {
305
- render: /* @__PURE__ */ jsxRuntime.jsxs(
306
- StyledInput,
307
- {
308
- ...inputProps,
309
- value: searchValue,
310
- size,
311
- ref: inputRef,
312
- onChange: onInputChange,
313
- onFocus: scrollIntoView,
314
- children: [
315
- children,
316
- /* @__PURE__ */ jsxRuntime.jsx(
317
- TriggerActionButton,
318
- {
319
- openActionLabel,
320
- closeActionLabel,
321
- clearActionLabel,
322
- size
323
- }
324
- )
325
- ]
326
- }
327
- )
328
- }
329
- )
330
- ]
302
+ children: /* @__PURE__ */ jsxRuntime.jsx(
303
+ react.Combobox,
304
+ {
305
+ render: /* @__PURE__ */ jsxRuntime.jsxs(
306
+ StyledInput,
307
+ {
308
+ ...inputProps,
309
+ value: searchValue,
310
+ size,
311
+ ref: inputRef,
312
+ onChange: onInputChange,
313
+ onFocus: scrollIntoView,
314
+ children: [
315
+ children,
316
+ /* @__PURE__ */ jsxRuntime.jsx(
317
+ TriggerActionButton,
318
+ {
319
+ openActionLabel,
320
+ closeActionLabel,
321
+ clearActionLabel,
322
+ size
323
+ }
324
+ )
325
+ ]
326
+ }
327
+ )
328
+ }
329
+ )
331
330
  }
332
331
  );
333
332
  }
@@ -398,7 +397,8 @@ const Item = React__default["default"].forwardRef(
398
397
  filteredItems,
399
398
  setItemValueTextMap,
400
399
  triggerRef,
401
- inputRef
400
+ inputRef,
401
+ value: comboboxValue = []
402
402
  } = useComboboxContext();
403
403
  designSystemUseLayoutEffect.useLayoutEffect(() => {
404
404
  const textToSet = textValue !== void 0 ? textValue : typeof children === "string" ? children : "";
@@ -424,6 +424,7 @@ const Item = React__default["default"].forwardRef(
424
424
  restProps.onClick(event);
425
425
  }
426
426
  };
427
+ const isSelected = comboboxValue.includes(value);
427
428
  return /* @__PURE__ */ jsxRuntime.jsxs(
428
429
  StyledItem,
429
430
  {
@@ -435,10 +436,12 @@ const Item = React__default["default"].forwardRef(
435
436
  ref: forwardRef,
436
437
  value,
437
438
  onClick: scrollIntoView,
439
+ "aria-selected": isSelected,
438
440
  children: [
439
441
  /* @__PURE__ */ jsxRuntime.jsx(
440
442
  react.ComboboxItemCheck,
441
443
  {
444
+ checked: isSelected,
442
445
  render: ({ style, ...props }) => (
443
446
  // AriakitComboboxItemCheck adds its owm inline styles which we want to omit here
444
447
  /* @__PURE__ */ jsxRuntime.jsx(StyledItemCheck, { ...props })
@@ -504,9 +507,16 @@ const isInsideRef = (element, ref) => {
504
507
  };
505
508
  const Content = React__default["default"].forwardRef(
506
509
  ({
510
+ side = "bottom",
507
511
  sideOffset = CONTENT_OFFSET,
512
+ align = "center",
513
+ alignOffset = 0,
514
+ collisionPadding = 0,
515
+ avoidCollisions = true,
516
+ sticky = "partial",
517
+ hideWhenDetached = true,
518
+ overflow = "visible",
508
519
  maxHeight,
509
- overflow,
510
520
  children,
511
521
  ...restProps
512
522
  }, forwardRef) => {
@@ -545,7 +555,14 @@ const Content = React__default["default"].forwardRef(
545
555
  asChild: true,
546
556
  ...restProps,
547
557
  dir: direction,
558
+ side,
548
559
  sideOffset,
560
+ align,
561
+ alignOffset,
562
+ avoidCollisions,
563
+ collisionPadding,
564
+ sticky,
565
+ hideWhenDetached,
549
566
  ref: designSystemUtils.mergeRefs([forwardRef, contentRef]),
550
567
  onOpenAutoFocus: (event) => event.preventDefault(),
551
568
  onInteractOutside: (event) => {
@@ -645,10 +662,6 @@ const Chip = React__default["default"].forwardRef(
645
662
  );
646
663
  Chip.LeftSlot = LeftSlot;
647
664
 
648
- const StyledValue = designSystemStitches.styled(Chip, {
649
- marginTop: "$50"
650
- });
651
-
652
665
  const Value = ({ unselectAriaLabel }) => {
653
666
  const {
654
667
  value = [],
@@ -671,9 +684,12 @@ const Value = ({ unselectAriaLabel }) => {
671
684
  return null;
672
685
  }
673
686
  return /* @__PURE__ */ jsxRuntime.jsx(
674
- StyledValue,
687
+ Chip,
675
688
  {
676
- onRemove: () => onItemRemove(itemValue),
689
+ onRemove: (e) => {
690
+ onItemRemove(itemValue);
691
+ e.stopPropagation();
692
+ },
677
693
  disabled: isDisabled,
678
694
  removeAriaLabel: "".concat(unselectAriaLabel, " ").concat(textValue),
679
695
  "data-testid": process.env.NODE_ENV === "test" ? "combobox-value-".concat(itemValue) : void 0,
@@ -702,53 +718,71 @@ const Separator = React__default["default"].forwardRef((props, forwardRef) => {
702
718
  return /* @__PURE__ */ jsxRuntime.jsx(StyledSeparator, { ...props, ref: forwardRef, "aria-hidden": true });
703
719
  });
704
720
 
705
- const Root = ({
706
- value: valueProp,
707
- children,
708
- ...restProps
709
- }) => {
710
- const {
711
- openState,
712
- setOpenState,
713
- defaultValue,
714
- value,
715
- setValue,
716
- required,
717
- readOnly,
718
- "aria-disabled": ariaDisabled,
719
- disabled
720
- } = useComboboxContext();
721
- const { setRequired, setDisabled, setAriaDisabled, setReadOnly } = designSystemBaseForm.useFormFieldContext();
722
- React.useEffect(() => {
723
- setRequired == null ? void 0 : setRequired(required);
724
- setDisabled == null ? void 0 : setDisabled(disabled);
725
- setAriaDisabled == null ? void 0 : setAriaDisabled(ariaDisabled);
726
- setReadOnly == null ? void 0 : setReadOnly(readOnly);
727
- }, [
728
- readOnly,
729
- disabled,
730
- ariaDisabled,
731
- required,
732
- setRequired,
733
- setDisabled,
734
- setAriaDisabled,
735
- setReadOnly
736
- ]);
737
- const onSetSelectedValue = (newValue) => {
738
- setValue(typeof newValue === "string" ? [newValue] : newValue);
739
- };
740
- const onOpenChange = (value2) => {
741
- if (!designSystemUtils.booleanify(readOnly)) {
742
- setOpenState(value2);
743
- }
744
- };
745
- return /* @__PURE__ */ jsxRuntime.jsx(
746
- RadixPopover__namespace.Root,
747
- {
748
- open: openState,
749
- onOpenChange,
750
- ...restProps,
751
- children: /* @__PURE__ */ jsxRuntime.jsx(
721
+ const StyledNativeSelect = designSystemStitches.styled(designSystemPrimitive.Primitive.select, {
722
+ // if we support autoComplete, we would have to use visually-hidden styles here
723
+ display: "none"
724
+ });
725
+ const StyledComboboxContent = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
726
+ position: "relative",
727
+ width: "100%"
728
+ });
729
+
730
+ const Root = React__default["default"].forwardRef(
731
+ ({ value: valueProp, onValueChange, name, children, ...restProps }, forwardRef) => {
732
+ var _a;
733
+ const {
734
+ openState,
735
+ setOpenState,
736
+ defaultValue,
737
+ value = [],
738
+ setValue,
739
+ required,
740
+ readOnly,
741
+ "aria-disabled": ariaDisabled,
742
+ disabled,
743
+ direction,
744
+ size,
745
+ placeholder,
746
+ triggerRef
747
+ } = useComboboxContext();
748
+ const {
749
+ setRequired,
750
+ setDisabled,
751
+ setAriaDisabled,
752
+ setReadOnly,
753
+ label,
754
+ isFloatingLabel,
755
+ focused,
756
+ formElementRef
757
+ } = designSystemBaseForm.useFormFieldContext();
758
+ React.useEffect(() => {
759
+ setRequired == null ? void 0 : setRequired(required);
760
+ setDisabled == null ? void 0 : setDisabled(disabled);
761
+ setAriaDisabled == null ? void 0 : setAriaDisabled(ariaDisabled);
762
+ setReadOnly == null ? void 0 : setReadOnly(readOnly);
763
+ }, [
764
+ readOnly,
765
+ disabled,
766
+ ariaDisabled,
767
+ required,
768
+ setRequired,
769
+ setDisabled,
770
+ setAriaDisabled,
771
+ setReadOnly
772
+ ]);
773
+ const shouldUseFloatingLabel = label !== null && isFloatingLabel;
774
+ const isFloating = placeholder !== void 0 || value.length !== 0 || focused;
775
+ const onSetSelectedValue = (newValue) => {
776
+ setValue(typeof newValue === "string" ? [newValue] : newValue);
777
+ };
778
+ const onOpenChange = (value2) => {
779
+ if (!designSystemUtils.booleanify(readOnly)) {
780
+ setOpenState(value2);
781
+ }
782
+ };
783
+ const isFormControl = Boolean((_a = triggerRef.current) == null ? void 0 : _a.closest("form"));
784
+ return /* @__PURE__ */ jsxRuntime.jsxs(RadixPopover__namespace.Root, { open: openState, onOpenChange, children: [
785
+ /* @__PURE__ */ jsxRuntime.jsx(
752
786
  react.ComboboxProvider,
753
787
  {
754
788
  open: openState,
@@ -756,51 +790,86 @@ const Root = ({
756
790
  defaultSelectedValue: defaultValue,
757
791
  selectedValue: value,
758
792
  setSelectedValue: onSetSelectedValue,
759
- children
793
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
794
+ StyledComboboxContent,
795
+ {
796
+ ref: forwardRef,
797
+ ...restProps,
798
+ dir: direction,
799
+ "data-form-element": "select",
800
+ children: [
801
+ shouldUseFloatingLabel && /* @__PURE__ */ jsxRuntime.jsx(designSystemBaseForm.FloatingLabel, { floating: isFloating, size, children: label }),
802
+ children
803
+ ]
804
+ }
805
+ )
806
+ }
807
+ ),
808
+ isFormControl && /* @__PURE__ */ jsxRuntime.jsx(
809
+ StyledNativeSelect,
810
+ {
811
+ multiple: true,
812
+ autoComplete: "off",
813
+ name,
814
+ tabIndex: -1,
815
+ "aria-hidden": "true",
816
+ ref: formElementRef,
817
+ required,
818
+ disabled,
819
+ "aria-disabled": ariaDisabled,
820
+ value,
821
+ onChange: () => {
822
+ },
823
+ children: value.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("option", { value: "" }) : (
824
+ // since we don't support autoComplete we can render here only selected values
825
+ value.map((itemValue) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: itemValue, children: itemValue }, itemValue))
826
+ )
760
827
  }
761
828
  )
762
- }
763
- );
764
- };
765
- const Combobox = ({
766
- "aria-disabled": ariaDisabled,
767
- defaultOpen = false,
768
- open,
769
- valid,
770
- disabled,
771
- readOnly,
772
- required,
773
- value,
774
- defaultValue,
775
- onOpen,
776
- onClose,
777
- onSearchValueChange,
778
- onValueChange,
779
- direction = "ltr",
780
- autoFilter = true,
781
- noResultsText,
782
- ...restProps
783
- }) => /* @__PURE__ */ jsxRuntime.jsx(
784
- ComboboxProvider,
785
- {
786
- defaultValue,
787
- value,
788
- onValueChange,
789
- onSearchValueChange,
790
- defaultOpen,
829
+ ] });
830
+ }
831
+ );
832
+ const Combobox = React__default["default"].forwardRef(
833
+ ({
834
+ "aria-disabled": ariaDisabled,
835
+ defaultOpen = false,
791
836
  open,
792
- onOpen,
793
- onClose,
794
837
  valid,
795
- required,
796
838
  disabled,
797
839
  readOnly,
798
- "aria-disabled": ariaDisabled,
799
- direction,
800
- autoFilter,
840
+ required,
841
+ value,
842
+ defaultValue,
843
+ onOpen,
844
+ onClose,
845
+ onSearchValueChange,
846
+ onValueChange,
847
+ direction = "ltr",
848
+ autoFilter = true,
801
849
  noResultsText,
802
- children: /* @__PURE__ */ jsxRuntime.jsx(Root, { ...restProps, value })
803
- }
850
+ ...restProps
851
+ }, forwardRef) => /* @__PURE__ */ jsxRuntime.jsx(
852
+ ComboboxProvider,
853
+ {
854
+ defaultValue,
855
+ value,
856
+ onValueChange,
857
+ onSearchValueChange,
858
+ defaultOpen,
859
+ open,
860
+ onOpen,
861
+ onClose,
862
+ valid,
863
+ required,
864
+ disabled,
865
+ readOnly,
866
+ "aria-disabled": ariaDisabled,
867
+ direction,
868
+ autoFilter,
869
+ noResultsText,
870
+ children: /* @__PURE__ */ jsxRuntime.jsx(Root, { ...restProps, value, ref: forwardRef })
871
+ }
872
+ )
804
873
  );
805
874
  Combobox.Portal = Portal;
806
875
  Combobox.Trigger = Trigger;