@mirohq/design-system-combobox 0.1.0-combobox.5 → 0.1.0-combobox.7

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
@@ -10,7 +10,9 @@ var RadixPopover = require('@radix-ui/react-popover');
10
10
  var designSystemUtils = require('@mirohq/design-system-utils');
11
11
  var designSystemStitches = require('@mirohq/design-system-stitches');
12
12
  var designSystemInput = require('@mirohq/design-system-input');
13
+ var reactUseControllableState = require('@radix-ui/react-use-controllable-state');
13
14
  var designSystemIcons = require('@mirohq/design-system-icons');
15
+ var designSystemScrollArea = require('@mirohq/design-system-scroll-area');
14
16
  var utils = require('@react-aria/utils');
15
17
  var designSystemUseAriaDisabled = require('@mirohq/design-system-use-aria-disabled');
16
18
  var designSystemStyles = require('@mirohq/design-system-styles');
@@ -40,6 +42,10 @@ function _interopNamespace(e) {
40
42
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
41
43
  var RadixPopover__namespace = /*#__PURE__*/_interopNamespace(RadixPopover);
42
44
 
45
+ const StyledAnchor = designSystemStitches.styled(RadixPopover.Anchor, {
46
+ position: "relative",
47
+ width: "100%"
48
+ });
43
49
  const StyledInput = designSystemStitches.styled(designSystemInput.Input, {
44
50
  flexWrap: "wrap",
45
51
  flexGrow: 1,
@@ -78,10 +84,14 @@ const StyledInput = designSystemStitches.styled(designSystemInput.Input, {
78
84
  const ComboboxContext = React.createContext({});
79
85
  const ComboboxProvider = ({
80
86
  children,
87
+ open: openProp,
81
88
  defaultOpen,
89
+ onOpen,
90
+ onClose,
82
91
  valid,
83
92
  value: valueProp,
84
93
  defaultValue: defaultValueProp,
94
+ onValueChange,
85
95
  onSearchValueChange,
86
96
  autoFilter = true,
87
97
  ...restProps
@@ -89,9 +99,23 @@ const ComboboxProvider = ({
89
99
  const triggerRef = React.useRef(null);
90
100
  const inputRef = React.useRef(null);
91
101
  const contentRef = React.useRef(null);
92
- const [openState, setOpenState] = React.useState(defaultOpen != null ? defaultOpen : false);
93
- const [value, setValue] = React.useState(valueProp != null ? valueProp : []);
94
102
  const [defaultValue, setDefaultValue] = React.useState(defaultValueProp);
103
+ const [openState = false, setOpenState] = reactUseControllableState.useControllableState({
104
+ prop: openProp,
105
+ defaultProp: defaultOpen,
106
+ onChange: (state) => {
107
+ if (state) {
108
+ onOpen == null ? void 0 : onOpen();
109
+ } else {
110
+ onClose == null ? void 0 : onClose();
111
+ }
112
+ }
113
+ });
114
+ const [value, setValue] = reactUseControllableState.useControllableState({
115
+ prop: valueProp,
116
+ defaultProp: defaultValueProp,
117
+ onChange: onValueChange
118
+ });
95
119
  const [filteredItems, setFilteredItems] = React.useState(/* @__PURE__ */ new Set());
96
120
  const [searchValue, setSearchValue] = React.useState("");
97
121
  const { valid: formFieldValid } = designSystemBaseForm.useFormFieldContext();
@@ -146,7 +170,7 @@ const TriggerActionButton = ({
146
170
  clearActionLabel,
147
171
  size
148
172
  }) => {
149
- const { setOpenState, value, setValue } = useComboboxContext();
173
+ const { setOpenState, value = [], setValue } = useComboboxContext();
150
174
  const isEmpty = value.length === 0;
151
175
  const ActionButtonIcon = isEmpty ? designSystemIcons.IconChevronDown : designSystemIcons.IconCross;
152
176
  const label = isEmpty ? openActionLabel : clearActionLabel;
@@ -155,7 +179,7 @@ const TriggerActionButton = ({
155
179
  if (!isEmpty) {
156
180
  setValue([]);
157
181
  } else {
158
- setOpenState((prevOpen) => !prevOpen);
182
+ setOpenState((prevOpen = false) => !prevOpen);
159
183
  }
160
184
  event.stopPropagation();
161
185
  },
@@ -175,18 +199,21 @@ const Trigger = React__default["default"].forwardRef(
175
199
  openActionLabel,
176
200
  clearActionLabel,
177
201
  onChange,
202
+ css,
178
203
  ...restProps
179
204
  }, forwardRef) => {
180
205
  const {
181
206
  "aria-disabled": ariaDisabled,
182
207
  valid: comboboxValid,
183
208
  disabled,
184
- value,
209
+ value = [],
210
+ readOnly,
185
211
  triggerRef,
186
212
  inputRef,
187
213
  onSearchValueChange,
188
214
  searchValue,
189
- setSearchValue
215
+ setSearchValue,
216
+ setOpenState
190
217
  } = useComboboxContext();
191
218
  const {
192
219
  formElementId,
@@ -208,12 +235,13 @@ const Trigger = React__default["default"].forwardRef(
208
235
  ),
209
236
  valid,
210
237
  disabled,
238
+ readOnly,
211
239
  invalid: designSystemUtils.booleanishAttrValue(valid),
212
240
  id: id != null ? id : formElementId,
213
241
  placeholder: value.length === 0 ? placeholder : void 0
214
242
  };
215
243
  const shouldUseFloatingLabel = label !== null && isFloatingLabel;
216
- const isFloating = placeholder !== void 0 || value.length !== 0 || focused;
244
+ const isFloating = placeholder !== void 0 || value.length !== 0 || focused || searchValue !== "";
217
245
  const scrollIntoView = (event) => {
218
246
  var _a;
219
247
  const trigger = triggerRef == null ? void 0 : triggerRef.current;
@@ -233,36 +261,48 @@ const Trigger = React__default["default"].forwardRef(
233
261
  onSearchValueChange == null ? void 0 : onSearchValueChange(e.target.value);
234
262
  onChange == null ? void 0 : onChange(e);
235
263
  };
236
- return /* @__PURE__ */ jsxRuntime.jsxs(RadixPopover__namespace.Anchor, { ref: designSystemUtils.mergeRefs([triggerRef, forwardRef]), children: [
237
- shouldUseFloatingLabel && /* @__PURE__ */ jsxRuntime.jsx(designSystemBaseForm.FloatingLabel, { floating: isFloating, size, children: label }),
238
- /* @__PURE__ */ jsxRuntime.jsx(
239
- react.Combobox,
240
- {
241
- render: /* @__PURE__ */ jsxRuntime.jsxs(
242
- StyledInput,
264
+ return /* @__PURE__ */ jsxRuntime.jsxs(
265
+ StyledAnchor,
266
+ {
267
+ ref: designSystemUtils.mergeRefs([triggerRef, forwardRef]),
268
+ css,
269
+ onClick: () => {
270
+ if (!designSystemUtils.booleanify(disabled) && !designSystemUtils.booleanify(ariaDisabled) && !designSystemUtils.booleanify(readOnly)) {
271
+ setOpenState(true);
272
+ }
273
+ },
274
+ children: [
275
+ shouldUseFloatingLabel && /* @__PURE__ */ jsxRuntime.jsx(designSystemBaseForm.FloatingLabel, { floating: isFloating, size, children: label }),
276
+ /* @__PURE__ */ jsxRuntime.jsx(
277
+ react.Combobox,
243
278
  {
244
- ...inputProps,
245
- value: searchValue,
246
- size,
247
- ref: inputRef,
248
- onChange: onInputChange,
249
- onFocus: scrollIntoView,
250
- children: [
251
- children,
252
- /* @__PURE__ */ jsxRuntime.jsx(
253
- TriggerActionButton,
254
- {
255
- openActionLabel,
256
- clearActionLabel,
257
- size
258
- }
259
- )
260
- ]
279
+ render: /* @__PURE__ */ jsxRuntime.jsxs(
280
+ StyledInput,
281
+ {
282
+ ...inputProps,
283
+ value: searchValue,
284
+ size,
285
+ ref: inputRef,
286
+ onChange: onInputChange,
287
+ onFocus: scrollIntoView,
288
+ children: [
289
+ children,
290
+ /* @__PURE__ */ jsxRuntime.jsx(
291
+ TriggerActionButton,
292
+ {
293
+ openActionLabel,
294
+ clearActionLabel,
295
+ size
296
+ }
297
+ )
298
+ ]
299
+ }
300
+ )
261
301
  }
262
302
  )
263
- }
264
- )
265
- ] });
303
+ ]
304
+ }
305
+ );
266
306
  }
267
307
  );
268
308
 
@@ -272,35 +312,30 @@ const StyledContent = designSystemStitches.styled(RadixPopover__namespace.Conten
272
312
  boxShadow: "$50",
273
313
  fontSize: "$175",
274
314
  fontWeight: "normal",
275
- lineHeight: "1.5",
315
+ lineHeight: "20px",
276
316
  width: "var(--radix-popover-trigger-width)",
277
317
  zIndex: "$select",
278
318
  overflowY: "auto",
279
- marginTop: "$200",
280
- padding: "$150",
319
+ padding: "$50",
281
320
  boxSizing: "border-box",
282
321
  outline: "1px solid transparent"
283
322
  });
284
323
 
285
324
  const StyledItemCheck = designSystemStitches.styled(designSystemPrimitive.Primitive.span, {
286
- color: "$icon-primary",
287
- paddingX: "$100"
325
+ color: "$icon-primary"
288
326
  });
289
327
  const StyledItem = designSystemStitches.styled(react.ComboboxItem, {
290
- display: "flex",
291
- alignItems: "center",
292
- justifyContent: "space-between",
293
- gap: "$200",
328
+ display: "grid",
329
+ gridTemplateColumns: "20px 1fr",
294
330
  borderRadius: "$50",
295
331
  boxSizing: "border-box",
296
332
  color: "$text-neutrals",
297
333
  cursor: "pointer",
298
334
  fontSize: "$175",
299
- lineHeight: 1.5,
335
+ lineHeight: "20px",
300
336
  position: "relative",
301
337
  userSelect: "none",
302
- paddingX: "$100",
303
- paddingY: "10px",
338
+ padding: "6px $100 6px $150",
304
339
  ...designSystemStyles.focus.css({
305
340
  boxShadow: "$focus-small"
306
341
  }),
@@ -315,7 +350,13 @@ const StyledItem = designSystemStitches.styled(react.ComboboxItem, {
315
350
  },
316
351
  "&:disabled, &[aria-disabled=true], &[data-disabled]": {
317
352
  cursor: "default",
318
- color: "$text-neutrals-disabled"
353
+ color: "$text-neutrals-disabled",
354
+ ["".concat(StyledItemCheck)]: {
355
+ color: "$icon-neutrals-disabled"
356
+ }
357
+ },
358
+ '&[aria-selected="true"]:not(:disabled,[aria-disabled=true],[data-disabled])': {
359
+ color: "$text-primary-selected"
319
360
  }
320
361
  });
321
362
 
@@ -342,13 +383,13 @@ const Item = React__default["default"].forwardRef(
342
383
  {
343
384
  ...utils.mergeProps(restProps, restAriaDisabledProps),
344
385
  focusable: true,
345
- accessibleWhenDisabled: ariaDisabled === true,
346
- disabled: ariaDisabled === true || disabled,
386
+ hideOnClick: false,
387
+ accessibleWhenDisabled: designSystemUtils.booleanify(ariaDisabled),
388
+ disabled: designSystemUtils.booleanify(ariaDisabled) || disabled,
347
389
  ref: forwardRef,
348
390
  value,
349
391
  onClick: scrollIntoView,
350
392
  children: [
351
- children,
352
393
  /* @__PURE__ */ jsxRuntime.jsx(
353
394
  react.ComboboxItemCheck,
354
395
  {
@@ -356,9 +397,16 @@ const Item = React__default["default"].forwardRef(
356
397
  // AriakitComboboxItemCheck adds its owm inline styles which we want to omit here
357
398
  /* @__PURE__ */ jsxRuntime.jsx(StyledItemCheck, { ...props })
358
399
  ),
359
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystemIcons.IconCheckMark, { size: "small" })
400
+ children: /* @__PURE__ */ jsxRuntime.jsx(
401
+ designSystemIcons.IconCheckMark,
402
+ {
403
+ size: "small",
404
+ "data-testid": process.env.NODE_ENV === "test" ? "combobox-item-check" : void 0
405
+ }
406
+ )
360
407
  }
361
- )
408
+ ),
409
+ children
362
410
  ]
363
411
  }
364
412
  );
@@ -387,48 +435,65 @@ const getChildrenItemValues = (componentChildren) => {
387
435
  return values;
388
436
  };
389
437
 
438
+ const CONTENT_OFFSET = parseInt(designSystemStitches.theme.space[50]);
390
439
  const isInsideRef = (element, ref) => {
391
440
  var _a, _b;
392
441
  return (_b = element != null && ((_a = ref.current) == null ? void 0 : _a.contains(element))) != null ? _b : false;
393
442
  };
394
- const Content = React__default["default"].forwardRef(({ children, ...restProps }, forwardRef) => {
395
- const {
396
- triggerRef,
397
- contentRef,
398
- autoFilter,
399
- filteredItems,
400
- setFilteredItems,
401
- searchValue,
402
- noResultsText
403
- } = useComboboxContext();
404
- React.useEffect(() => {
405
- const childrenItemValues = getChildrenItemValues(children);
406
- setFilteredItems(
407
- new Set(
408
- autoFilter === false ? childrenItemValues : childrenItemValues.filter(
409
- (child) => child.toLowerCase().includes(searchValue.toLowerCase())
443
+ const Content = React__default["default"].forwardRef(
444
+ ({ sideOffset = CONTENT_OFFSET, maxHeight, children, ...restProps }, forwardRef) => {
445
+ const {
446
+ triggerRef,
447
+ contentRef,
448
+ autoFilter,
449
+ filteredItems,
450
+ setFilteredItems,
451
+ searchValue,
452
+ noResultsText,
453
+ direction
454
+ } = useComboboxContext();
455
+ React.useEffect(() => {
456
+ const childrenItemValues = getChildrenItemValues(children);
457
+ setFilteredItems(
458
+ new Set(
459
+ autoFilter === false ? childrenItemValues : childrenItemValues.filter(
460
+ (child) => child.toLowerCase().includes(searchValue.toLowerCase())
461
+ )
410
462
  )
411
- )
463
+ );
464
+ }, [children, autoFilter, setFilteredItems, searchValue]);
465
+ const content = filteredItems.size === 0 ? noResultsText : children;
466
+ return /* @__PURE__ */ jsxRuntime.jsx(
467
+ StyledContent,
468
+ {
469
+ ...restProps,
470
+ sideOffset,
471
+ ref: designSystemUtils.mergeRefs([forwardRef, contentRef]),
472
+ onOpenAutoFocus: (event) => event.preventDefault(),
473
+ onInteractOutside: (event) => {
474
+ const target = event.target;
475
+ const isTrigger = isInsideRef(target, triggerRef);
476
+ const isContent = isInsideRef(target, contentRef);
477
+ if (isTrigger || isContent) {
478
+ event.preventDefault();
479
+ }
480
+ },
481
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystemScrollArea.ScrollArea, { type: "always", dir: direction, children: [
482
+ /* @__PURE__ */ jsxRuntime.jsx(
483
+ designSystemScrollArea.ScrollArea.Viewport,
484
+ {
485
+ availableHeight: "var(--radix-popover-content-available-height)",
486
+ verticalGap: "var(--space-50) * 2",
487
+ maxHeight,
488
+ children: content
489
+ }
490
+ ),
491
+ /* @__PURE__ */ jsxRuntime.jsx(designSystemScrollArea.ScrollArea.Scrollbar, { orientation: "vertical", children: /* @__PURE__ */ jsxRuntime.jsx(designSystemScrollArea.ScrollArea.Thumb, {}) })
492
+ ] })
493
+ }
412
494
  );
413
- }, [children, autoFilter, setFilteredItems, searchValue]);
414
- return /* @__PURE__ */ jsxRuntime.jsx(
415
- StyledContent,
416
- {
417
- ...restProps,
418
- ref: designSystemUtils.mergeRefs([forwardRef, contentRef]),
419
- onOpenAutoFocus: (event) => event.preventDefault(),
420
- onInteractOutside: (event) => {
421
- const target = event.target;
422
- const isTrigger = isInsideRef(target, triggerRef);
423
- const isContent = isInsideRef(target, contentRef);
424
- if (isTrigger || isContent) {
425
- event.preventDefault();
426
- }
427
- },
428
- children: filteredItems.size === 0 ? noResultsText : children
429
- }
430
- );
431
- });
495
+ }
496
+ );
432
497
 
433
498
  const Portal = (props) => /* @__PURE__ */ jsxRuntime.jsx(RadixPopover.Portal, { ...props });
434
499
 
@@ -453,11 +518,8 @@ const Group = React__default["default"].forwardRef(({ children, ...rest }, forwa
453
518
  });
454
519
 
455
520
  const StyledGroupLabel = designSystemStitches.styled(react.GroupLabel, {
456
- padding: "$100",
457
- color: "$text-neutrals-subtle",
458
- fontSize: "$150",
459
- textTransform: "uppercase",
460
- fontWeight: 650
521
+ padding: "6px $100",
522
+ color: "$text-neutrals-subtle"
461
523
  });
462
524
 
463
525
  const GroupLabel = React__default["default"].forwardRef((props, forwardRef) => /* @__PURE__ */ jsxRuntime.jsx(StyledGroupLabel, { ...props, ref: forwardRef }));
@@ -508,14 +570,14 @@ const StyledValue = designSystemStitches.styled(Chip, {
508
570
 
509
571
  const Value = ({ removeChipAriaLabel }) => {
510
572
  const {
511
- value,
573
+ value = [],
512
574
  setValue,
513
575
  disabled,
514
576
  "aria-disabled": ariaDisabled
515
577
  } = useComboboxContext();
516
578
  const isDisabled = ariaDisabled === true || disabled;
517
579
  const onItemRemove = (item) => {
518
- setValue((prevValue) => prevValue.filter((value2) => value2 !== item));
580
+ setValue((prevValue) => prevValue == null ? void 0 : prevValue.filter((value2) => value2 !== item));
519
581
  };
520
582
  if (value.length === 0) {
521
583
  return null;
@@ -526,6 +588,7 @@ const Value = ({ removeChipAriaLabel }) => {
526
588
  onRemove: () => onItemRemove(item),
527
589
  disabled: isDisabled,
528
590
  removeChipAriaLabel,
591
+ "data-testid": process.env.NODE_ENV === "test" ? "combobox-value-".concat(item) : void 0,
529
592
  children: item
530
593
  },
531
594
  item
@@ -539,13 +602,19 @@ const StyledSeparator = designSystemStitches.styled(designSystemPrimitive.Primit
539
602
  margin: "$100 0"
540
603
  });
541
604
 
542
- const Separator = React__default["default"].forwardRef((props, forwardRef) => /* @__PURE__ */ jsxRuntime.jsx(StyledSeparator, { ...props, ref: forwardRef, "aria-hidden": true }));
543
-
544
- const StyledComboboxContent = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
545
- position: "relative"
605
+ const Separator = React__default["default"].forwardRef((props, forwardRef) => {
606
+ const { autoFilter, searchValue } = useComboboxContext();
607
+ if (autoFilter === true && searchValue.length > 0) {
608
+ return null;
609
+ }
610
+ return /* @__PURE__ */ jsxRuntime.jsx(StyledSeparator, { ...props, ref: forwardRef, "aria-hidden": true });
546
611
  });
547
612
 
548
- const Root = React__default["default"].forwardRef(({ value: valueProp, onValueChange, children, ...restProps }, forwardRef) => {
613
+ const Root = ({
614
+ value: valueProp,
615
+ children,
616
+ ...restProps
617
+ }) => {
549
618
  const {
550
619
  openState,
551
620
  setOpenState,
@@ -555,8 +624,7 @@ const Root = React__default["default"].forwardRef(({ value: valueProp, onValueCh
555
624
  required,
556
625
  readOnly,
557
626
  "aria-disabled": ariaDisabled,
558
- disabled,
559
- direction
627
+ disabled
560
628
  } = useComboboxContext();
561
629
  const { setRequired, setDisabled, setAriaDisabled, setReadOnly } = designSystemBaseForm.useFormFieldContext();
562
630
  React.useEffect(() => {
@@ -575,66 +643,72 @@ const Root = React__default["default"].forwardRef(({ value: valueProp, onValueCh
575
643
  setReadOnly
576
644
  ]);
577
645
  const onSetSelectedValue = (newValue) => {
578
- onValueChange == null ? void 0 : onValueChange(newValue);
579
- setValue(newValue);
646
+ setValue(typeof newValue === "string" ? [newValue] : newValue);
580
647
  };
581
- return /* @__PURE__ */ jsxRuntime.jsx(RadixPopover__namespace.Root, { open: openState, onOpenChange: setOpenState, children: /* @__PURE__ */ jsxRuntime.jsx(
582
- react.ComboboxProvider,
648
+ const onOpenChange = (value2) => {
649
+ if (!designSystemUtils.booleanify(readOnly)) {
650
+ setOpenState(value2);
651
+ }
652
+ };
653
+ return /* @__PURE__ */ jsxRuntime.jsx(
654
+ RadixPopover__namespace.Root,
583
655
  {
584
656
  open: openState,
585
- setOpen: setOpenState,
586
- defaultSelectedValue: defaultValue,
587
- selectedValue: value,
588
- setSelectedValue: onSetSelectedValue,
589
- children: /* @__PURE__ */ jsxRuntime.jsx(StyledComboboxContent, { ...restProps, ref: forwardRef, dir: direction, children })
657
+ onOpenChange,
658
+ ...restProps,
659
+ children: /* @__PURE__ */ jsxRuntime.jsx(
660
+ react.ComboboxProvider,
661
+ {
662
+ open: openState,
663
+ setOpen: onOpenChange,
664
+ defaultSelectedValue: defaultValue,
665
+ selectedValue: value,
666
+ setSelectedValue: onSetSelectedValue,
667
+ children
668
+ }
669
+ )
590
670
  }
591
- ) });
592
- });
593
- const Combobox = React__default["default"].forwardRef(
594
- ({
595
- "aria-disabled": ariaDisabled,
596
- defaultOpen = false,
671
+ );
672
+ };
673
+ const Combobox = ({
674
+ "aria-disabled": ariaDisabled,
675
+ defaultOpen = false,
676
+ open,
677
+ valid,
678
+ disabled,
679
+ readOnly,
680
+ required,
681
+ value,
682
+ defaultValue,
683
+ onOpen,
684
+ onClose,
685
+ onSearchValueChange,
686
+ onValueChange,
687
+ direction = "ltr",
688
+ autoFilter = true,
689
+ noResultsText,
690
+ ...restProps
691
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
692
+ ComboboxProvider,
693
+ {
694
+ defaultValue,
695
+ value,
696
+ onValueChange,
697
+ onSearchValueChange,
698
+ defaultOpen,
597
699
  open,
700
+ onOpen,
701
+ onClose,
598
702
  valid,
703
+ required,
599
704
  disabled,
600
705
  readOnly,
601
- required,
602
- value,
603
- defaultValue,
604
- onSearchValueChange,
605
- onOpen,
606
- onValueChange,
607
- direction = "ltr",
608
- autoFilter = true,
706
+ "aria-disabled": ariaDisabled,
707
+ direction,
708
+ autoFilter,
609
709
  noResultsText,
610
- ...restProps
611
- }, forwardRef) => /* @__PURE__ */ jsxRuntime.jsx(
612
- ComboboxProvider,
613
- {
614
- defaultValue,
615
- value,
616
- onSearchValueChange,
617
- defaultOpen,
618
- open,
619
- valid,
620
- required,
621
- disabled,
622
- readOnly,
623
- "aria-disabled": ariaDisabled,
624
- direction,
625
- autoFilter,
626
- noResultsText,
627
- children: /* @__PURE__ */ jsxRuntime.jsx(
628
- Root,
629
- {
630
- ...restProps,
631
- noResultsText,
632
- value,
633
- ref: forwardRef
634
- }
635
- )
636
- }
637
- )
710
+ children: /* @__PURE__ */ jsxRuntime.jsx(Root, { ...restProps, value })
711
+ }
638
712
  );
639
713
  Combobox.Portal = Portal;
640
714
  Combobox.Trigger = Trigger;