@almadar/ui 5.128.0 → 5.130.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/avl/index.js CHANGED
@@ -26473,7 +26473,7 @@ var init_useQuerySingleton = __esm({
26473
26473
  queryStores = /* @__PURE__ */ new Map();
26474
26474
  }
26475
26475
  });
26476
- var resolveFilterType, lookStyles6, FilterGroup;
26476
+ var resolveFilterType, lookStyles6, FilterGroupControls, FilterGroupPopover, FilterGroup;
26477
26477
  var init_FilterGroup = __esm({
26478
26478
  "components/core/molecules/FilterGroup.tsx"() {
26479
26479
  "use client";
@@ -26491,10 +26491,10 @@ var init_FilterGroup = __esm({
26491
26491
  toolbar: "",
26492
26492
  chips: "gap-1 [&_input]:rounded-pill [&_select]:rounded-pill [&_button]:rounded-pill [&_input]:!px-3 [&_select]:!px-3 [&_input]:bg-muted [&_select]:bg-muted [&_label]:hidden",
26493
26493
  pills: "gap-2 [&_input]:rounded-pill [&_select]:rounded-pill [&_button]:rounded-pill",
26494
- "popover-trigger": "[&>*:not(:first-child)]:hidden",
26494
+ "popover-trigger": "",
26495
26495
  "inline-column-header": "hidden"
26496
26496
  };
26497
- FilterGroup = ({
26497
+ FilterGroupControls = ({
26498
26498
  entity,
26499
26499
  filters,
26500
26500
  onFilterChange,
@@ -26830,7 +26830,7 @@ var init_FilterGroup = __esm({
26830
26830
  className: "text-muted-foreground",
26831
26831
  children: [
26832
26832
  /* @__PURE__ */ jsx(Icon, { name: "filter", className: "h-4 w-4" }),
26833
- /* @__PURE__ */ jsx("span", { className: "text-sm font-bold uppercase tracking-wide", children: t("filterGroup.filters") })
26833
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-bold uppercase tracking-wide", children: t("filterGroup.filters") })
26834
26834
  ]
26835
26835
  }
26836
26836
  ),
@@ -26921,6 +26921,42 @@ var init_FilterGroup = __esm({
26921
26921
  }
26922
26922
  );
26923
26923
  };
26924
+ FilterGroupControls.displayName = "FilterGroupControls";
26925
+ FilterGroupPopover = (props) => {
26926
+ const { t } = useTranslate();
26927
+ const [open, setOpen] = useState(false);
26928
+ const queryState = useQuerySingleton(props.query);
26929
+ const activeFilterCount = queryState?.filters ? Object.values(queryState.filters).filter((v) => v !== null && v !== void 0).length : 0;
26930
+ return /* @__PURE__ */ jsxs("div", { className: cn("relative inline-block", props.className), children: [
26931
+ /* @__PURE__ */ jsx(
26932
+ Button,
26933
+ {
26934
+ variant: activeFilterCount > 0 ? "secondary" : "ghost",
26935
+ size: "sm",
26936
+ leftIcon: "filter",
26937
+ onClick: () => setOpen((o) => !o),
26938
+ "aria-expanded": open,
26939
+ "aria-haspopup": "true",
26940
+ children: /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
26941
+ /* @__PURE__ */ jsx("span", { children: t("filterGroup.filters") }),
26942
+ activeFilterCount > 0 && /* @__PURE__ */ jsx(Badge, { variant: "primary", size: "sm", children: activeFilterCount })
26943
+ ] })
26944
+ }
26945
+ ),
26946
+ open && /* @__PURE__ */ jsx("div", { className: "absolute left-0 z-50 mt-2 min-w-[16rem] rounded-lg border border-[var(--color-border)] bg-[var(--color-card)] p-card-md shadow-main", children: /* @__PURE__ */ jsx(
26947
+ FilterGroupControls,
26948
+ {
26949
+ ...props,
26950
+ className: void 0,
26951
+ look: "toolbar",
26952
+ variant: "vertical",
26953
+ showIcon: false
26954
+ }
26955
+ ) })
26956
+ ] });
26957
+ };
26958
+ FilterGroupPopover.displayName = "FilterGroupPopover";
26959
+ FilterGroup = (props) => props.look === "popover-trigger" ? /* @__PURE__ */ jsx(FilterGroupPopover, { ...props }) : /* @__PURE__ */ jsx(FilterGroupControls, { ...props });
26924
26960
  FilterGroup.displayName = "FilterGroup";
26925
26961
  }
26926
26962
  });
@@ -29578,12 +29614,12 @@ var init_MapView = __esm({
29578
29614
  shadowSize: [41, 41]
29579
29615
  });
29580
29616
  L.Marker.prototype.options.icon = defaultIcon;
29581
- const { useEffect: useEffect63, useRef: useRef61, useCallback: useCallback93, useState: useState97 } = React91__default;
29617
+ const { useEffect: useEffect63, useRef: useRef62, useCallback: useCallback93, useState: useState97 } = React91__default;
29582
29618
  const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
29583
29619
  const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
29584
29620
  function MapUpdater({ centerLat, centerLng, zoom }) {
29585
29621
  const map = useMap();
29586
- const prevRef = useRef61({ centerLat, centerLng, zoom });
29622
+ const prevRef = useRef62({ centerLat, centerLng, zoom });
29587
29623
  useEffect63(() => {
29588
29624
  const prev = prevRef.current;
29589
29625
  if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
@@ -30562,9 +30598,19 @@ function TableView({
30562
30598
  const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
30563
30599
  const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
30564
30600
  const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
30601
+ const colFloors = React91__default.useMemo(
30602
+ () => colDefs.map((col) => {
30603
+ const longest = data.reduce((widest, row) => {
30604
+ const cell = formatCell(asFieldValue(getNestedValue(row, col.field ?? col.key)), col.format);
30605
+ return Math.max(widest, cell.length);
30606
+ }, columnLabel(col).length);
30607
+ return Math.min(longest, MAX_MEASURED_COL_CH);
30608
+ }),
30609
+ [colDefs, data]
30610
+ );
30565
30611
  const gridTemplateColumns = [
30566
30612
  selectable ? "auto" : null,
30567
- ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
30613
+ ...colDefs.map((c, i) => c.width ?? `minmax(${colFloors[i]}ch, 1fr)`),
30568
30614
  actionsTrack
30569
30615
  ].filter(Boolean).join(" ");
30570
30616
  const header = /* @__PURE__ */ jsxs(
@@ -30731,7 +30777,7 @@ function TableView({
30731
30777
  }
30732
30778
  );
30733
30779
  }
30734
- var alignClass, weightClass, LOOKS;
30780
+ var MAX_MEASURED_COL_CH, alignClass, weightClass, LOOKS;
30735
30781
  var init_TableView = __esm({
30736
30782
  "components/core/molecules/TableView.tsx"() {
30737
30783
  "use client";
@@ -30749,6 +30795,7 @@ var init_TableView = __esm({
30749
30795
  init_Menu();
30750
30796
  init_useDataDnd();
30751
30797
  createLogger("almadar:ui:table-view");
30798
+ MAX_MEASURED_COL_CH = 32;
30752
30799
  alignClass = {
30753
30800
  left: "justify-start text-left",
30754
30801
  center: "justify-center text-center",
@@ -38364,6 +38411,290 @@ var init_GraphCanvas = __esm({
38364
38411
  GraphCanvas.displayName = "GraphCanvas";
38365
38412
  }
38366
38413
  });
38414
+ var ImportSourcePicker;
38415
+ var init_ImportSourcePicker = __esm({
38416
+ "components/core/molecules/import/ImportSourcePicker.tsx"() {
38417
+ "use client";
38418
+ init_Box();
38419
+ init_Icon();
38420
+ init_Typography();
38421
+ init_cn();
38422
+ ImportSourcePicker = ({
38423
+ sources,
38424
+ onSelect,
38425
+ onFilesSelected,
38426
+ title,
38427
+ moreSources,
38428
+ className
38429
+ }) => {
38430
+ const fileInputRef = useRef(null);
38431
+ const handlePick = (source) => {
38432
+ if (source.disabled) return;
38433
+ if (source.kind === "file") {
38434
+ const input = fileInputRef.current;
38435
+ if (!input) return;
38436
+ input.accept = source.accept ?? "";
38437
+ input.multiple = source.multiple ?? false;
38438
+ input.click();
38439
+ return;
38440
+ }
38441
+ onSelect?.(source.id);
38442
+ };
38443
+ const handleFiles = (event) => {
38444
+ const files = event.target.files ? Array.from(event.target.files) : [];
38445
+ event.target.value = "";
38446
+ if (files.length > 0) onFilesSelected?.(files);
38447
+ };
38448
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col gap-2", className), children: [
38449
+ title ? /* @__PURE__ */ jsx(Typography, { variant: "h4", children: title }) : null,
38450
+ sources.map((source) => /* @__PURE__ */ jsxs(
38451
+ Box,
38452
+ {
38453
+ role: "button",
38454
+ tabIndex: source.disabled ? -1 : 0,
38455
+ "aria-disabled": source.disabled,
38456
+ onClick: () => handlePick(source),
38457
+ onKeyDown: (event) => {
38458
+ if (event.key === "Enter" || event.key === " ") {
38459
+ event.preventDefault();
38460
+ handlePick(source);
38461
+ }
38462
+ },
38463
+ className: cn(
38464
+ "flex items-center gap-3 rounded-md border border-border bg-card px-4 py-3 text-left",
38465
+ source.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-accent hover:text-accent-foreground"
38466
+ ),
38467
+ children: [
38468
+ source.icon ? /* @__PURE__ */ jsx(Icon, { icon: source.icon, size: "md" }) : null,
38469
+ /* @__PURE__ */ jsxs(Box, { className: "flex flex-col", children: [
38470
+ /* @__PURE__ */ jsx(Typography, { variant: "label", children: source.label }),
38471
+ source.description ? /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: source.description }) : null
38472
+ ] })
38473
+ ]
38474
+ },
38475
+ source.id
38476
+ )),
38477
+ moreSources,
38478
+ /* @__PURE__ */ jsx(
38479
+ "input",
38480
+ {
38481
+ ref: fileInputRef,
38482
+ type: "file",
38483
+ className: "hidden",
38484
+ onChange: handleFiles,
38485
+ "data-testid": "import-source-file-input"
38486
+ }
38487
+ )
38488
+ ] });
38489
+ };
38490
+ }
38491
+ });
38492
+ function formatFieldValue(value) {
38493
+ if (value === null) return "\u2014";
38494
+ if (value instanceof Date) return value.toISOString();
38495
+ if (Array.isArray(value)) return value.map(formatFieldValue).join(", ");
38496
+ if (typeof value === "object") return JSON.stringify(value);
38497
+ return String(value);
38498
+ }
38499
+ function unitTitle(unit) {
38500
+ for (const key of TITLE_KEYS) {
38501
+ const value = unit.fields[key];
38502
+ if (typeof value === "string" && value.length > 0) return value;
38503
+ }
38504
+ return unit.ref;
38505
+ }
38506
+ function fieldSummary(unit) {
38507
+ return Object.entries(unit.fields).filter(([key]) => !TITLE_KEYS.includes(key)).map(([key, value]) => `${key}: ${formatFieldValue(value)}`).join(" \xB7 ");
38508
+ }
38509
+ var TITLE_KEYS, ImportPreviewTree;
38510
+ var init_ImportPreviewTree = __esm({
38511
+ "components/core/molecules/import/ImportPreviewTree.tsx"() {
38512
+ "use client";
38513
+ init_Box();
38514
+ init_Badge();
38515
+ init_Button();
38516
+ init_Icon();
38517
+ init_Typography();
38518
+ init_cn();
38519
+ TITLE_KEYS = ["title", "name", "label"];
38520
+ ImportPreviewTree = ({
38521
+ units,
38522
+ skipped = [],
38523
+ entityDisplay,
38524
+ onConfirm,
38525
+ onCancel,
38526
+ confirmLabel = "Confirm import",
38527
+ cancelLabel = "Cancel",
38528
+ indent = 16,
38529
+ className
38530
+ }) => {
38531
+ const groups = /* @__PURE__ */ new Map();
38532
+ for (const unit of units) {
38533
+ const group = groups.get(unit.targetEntity);
38534
+ if (group) group.push(unit);
38535
+ else groups.set(unit.targetEntity, [unit]);
38536
+ }
38537
+ const renderUnit = (unit, childrenByParent, depth) => {
38538
+ const summary = fieldSummary(unit);
38539
+ const children = childrenByParent.get(unit.ref) ?? [];
38540
+ return /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
38541
+ /* @__PURE__ */ jsxs(
38542
+ Box,
38543
+ {
38544
+ className: "flex flex-col py-1",
38545
+ style: { paddingLeft: depth * indent },
38546
+ "data-testid": `import-preview-unit-${unit.ref}`,
38547
+ children: [
38548
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
38549
+ /* @__PURE__ */ jsx(Icon, { icon: "file-text", size: "xs", className: "text-muted-foreground" }),
38550
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", children: unitTitle(unit) })
38551
+ ] }),
38552
+ summary ? /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: summary }) : null
38553
+ ]
38554
+ }
38555
+ ),
38556
+ children.map((child) => renderUnit(child, childrenByParent, depth + 1))
38557
+ ] }, unit.ref);
38558
+ };
38559
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col gap-4", className), children: [
38560
+ units.length === 0 ? /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-muted-foreground", children: "No units staged." }) : null,
38561
+ Array.from(groups.entries()).map(([entity, groupUnits]) => {
38562
+ const refs = new Set(groupUnits.map((unit) => unit.ref));
38563
+ const childrenByParent = /* @__PURE__ */ new Map();
38564
+ const roots = [];
38565
+ for (const unit of groupUnits) {
38566
+ if (unit.parentRef && refs.has(unit.parentRef)) {
38567
+ const siblings = childrenByParent.get(unit.parentRef);
38568
+ if (siblings) siblings.push(unit);
38569
+ else childrenByParent.set(unit.parentRef, [unit]);
38570
+ } else {
38571
+ roots.push(unit);
38572
+ }
38573
+ }
38574
+ const label = entityDisplay[entity]?.plural ?? entity;
38575
+ return /* @__PURE__ */ jsxs(Box, { border: true, className: "rounded-md border-border bg-card p-3", children: [
38576
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2 pb-2", children: [
38577
+ /* @__PURE__ */ jsx(Typography, { variant: "label", children: label }),
38578
+ /* @__PURE__ */ jsx(Badge, { amount: groupUnits.length })
38579
+ ] }),
38580
+ roots.map((unit) => renderUnit(unit, childrenByParent, 0))
38581
+ ] }, entity);
38582
+ }),
38583
+ skipped.length > 0 ? /* @__PURE__ */ jsxs(Box, { border: true, className: "rounded-md border-border bg-card p-3", children: [
38584
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2 pb-2", children: [
38585
+ /* @__PURE__ */ jsx(Typography, { variant: "label", children: "Skipped" }),
38586
+ /* @__PURE__ */ jsx(Badge, { amount: skipped.length })
38587
+ ] }),
38588
+ skipped.map((element) => /* @__PURE__ */ jsxs(Box, { className: "flex items-baseline gap-2 py-1", children: [
38589
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", children: element.ref }),
38590
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: element.reason })
38591
+ ] }, element.ref))
38592
+ ] }) : null,
38593
+ onConfirm || onCancel ? /* @__PURE__ */ jsxs(Box, { className: "flex items-center justify-end gap-2", children: [
38594
+ onCancel ? /* @__PURE__ */ jsx(Button, { variant: "default", label: cancelLabel, onClick: onCancel }) : null,
38595
+ onConfirm ? /* @__PURE__ */ jsx(Button, { variant: "primary", label: confirmLabel, onClick: onConfirm }) : null
38596
+ ] }) : null
38597
+ ] });
38598
+ };
38599
+ }
38600
+ });
38601
+ var PIPELINE, DEFAULT_LABELS, ImportProgress;
38602
+ var init_ImportProgress = __esm({
38603
+ "components/core/molecules/import/ImportProgress.tsx"() {
38604
+ "use client";
38605
+ init_Box();
38606
+ init_Badge();
38607
+ init_Icon();
38608
+ init_Typography();
38609
+ init_cn();
38610
+ PIPELINE = [
38611
+ "fetching",
38612
+ "mapping",
38613
+ "reviewing",
38614
+ "committing"
38615
+ ];
38616
+ DEFAULT_LABELS = {
38617
+ fetching: "Fetching",
38618
+ mapping: "Mapping",
38619
+ reviewing: "Reviewing",
38620
+ committing: "Committing",
38621
+ done: "Done",
38622
+ failed: "Failed"
38623
+ };
38624
+ ImportProgress = ({
38625
+ step,
38626
+ counts,
38627
+ labels,
38628
+ className
38629
+ }) => {
38630
+ const label = (key) => labels?.[key] ?? DEFAULT_LABELS[key];
38631
+ const currentIndex = step === "done" || step === "failed" ? PIPELINE.length : PIPELINE.indexOf(step);
38632
+ return /* @__PURE__ */ jsxs(Box, { className: cn("flex flex-col gap-3", className), children: [
38633
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
38634
+ PIPELINE.map((key, index) => {
38635
+ const isComplete = index < currentIndex;
38636
+ const isActive = index === currentIndex;
38637
+ return /* @__PURE__ */ jsxs(React91__default.Fragment, { children: [
38638
+ index > 0 ? /* @__PURE__ */ jsx(Box, { className: "h-px w-4 bg-border" }) : null,
38639
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-1", "data-testid": `import-progress-step-${key}`, children: [
38640
+ /* @__PURE__ */ jsx(
38641
+ Icon,
38642
+ {
38643
+ icon: isComplete ? "check" : isActive ? "loader" : "circle",
38644
+ size: "sm",
38645
+ className: cn(
38646
+ isComplete ? "text-success" : isActive ? "text-primary" : "text-muted-foreground"
38647
+ )
38648
+ }
38649
+ ),
38650
+ /* @__PURE__ */ jsx(
38651
+ Typography,
38652
+ {
38653
+ variant: "caption",
38654
+ className: cn(isActive ? "text-foreground" : "text-muted-foreground"),
38655
+ children: label(key)
38656
+ }
38657
+ )
38658
+ ] })
38659
+ ] }, key);
38660
+ }),
38661
+ step === "done" || step === "failed" ? /* @__PURE__ */ jsxs(Fragment, { children: [
38662
+ /* @__PURE__ */ jsx(Box, { className: "h-px w-4 bg-border" }),
38663
+ /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-1", "data-testid": `import-progress-step-${step}`, children: [
38664
+ /* @__PURE__ */ jsx(
38665
+ Icon,
38666
+ {
38667
+ icon: step === "done" ? "check" : "x",
38668
+ size: "sm",
38669
+ className: step === "done" ? "text-success" : "text-error"
38670
+ }
38671
+ ),
38672
+ /* @__PURE__ */ jsx(
38673
+ Typography,
38674
+ {
38675
+ variant: "caption",
38676
+ className: step === "done" ? "text-success" : "text-error",
38677
+ children: label(step)
38678
+ }
38679
+ )
38680
+ ] })
38681
+ ] }) : null
38682
+ ] }),
38683
+ counts ? /* @__PURE__ */ jsxs(Box, { className: "flex items-center gap-2", children: [
38684
+ counts.staged !== void 0 ? /* @__PURE__ */ jsx(Badge, { label: `Staged ${counts.staged}` }) : null,
38685
+ counts.committed !== void 0 ? /* @__PURE__ */ jsx(Badge, { variant: "success", label: `Committed ${counts.committed}` }) : null,
38686
+ counts.failed !== void 0 ? /* @__PURE__ */ jsx(Badge, { variant: "danger", label: `Failed ${counts.failed}` }) : null
38687
+ ] }) : null
38688
+ ] });
38689
+ };
38690
+ }
38691
+ });
38692
+
38693
+ // components/core/molecules/import/index.ts
38694
+ var init_import = __esm({
38695
+ "components/core/molecules/import/index.ts"() {
38696
+ }
38697
+ });
38367
38698
  var ReflectionBlock;
38368
38699
  var init_ReflectionBlock = __esm({
38369
38700
  "components/core/molecules/ReflectionBlock.tsx"() {
@@ -38438,6 +38769,7 @@ var init_molecules2 = __esm({
38438
38769
  init_EmptyState();
38439
38770
  init_Pagination();
38440
38771
  init_molecules();
38772
+ init_import();
38441
38773
  }
38442
38774
  });
38443
38775
 
@@ -38918,7 +39250,7 @@ function getBadgeVariant(fieldName, value) {
38918
39250
  function formatFieldLabel(fieldName) {
38919
39251
  return fieldName.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase());
38920
39252
  }
38921
- function formatFieldValue(value, fieldName) {
39253
+ function formatFieldValue2(value, fieldName) {
38922
39254
  if (typeof value === "number") {
38923
39255
  if (fieldName.toLowerCase().includes("progress") || fieldName.toLowerCase().includes("percent")) {
38924
39256
  return `${value}%`;
@@ -39013,7 +39345,7 @@ function renderRichFieldValue(value, fieldName, fieldType) {
39013
39345
  return str;
39014
39346
  }
39015
39347
  default:
39016
- return formatFieldValue(value, fieldName);
39348
+ return formatFieldValue2(value, fieldName);
39017
39349
  }
39018
39350
  }
39019
39351
  function normalizeFieldDefs(fields) {
@@ -39124,7 +39456,7 @@ var init_DetailPanel = __esm({
39124
39456
  const value = getNestedValue(normalizedData, field);
39125
39457
  return {
39126
39458
  label: labelFor(field),
39127
- value: formatFieldValue(value, field),
39459
+ value: formatFieldValue2(value, field),
39128
39460
  icon: getFieldIcon(field)
39129
39461
  };
39130
39462
  }
@@ -45155,6 +45487,9 @@ var init_component_registry_generated = __esm({
45155
45487
  init_HeroOrganism();
45156
45488
  init_HeroSection();
45157
45489
  init_Icon();
45490
+ init_ImportPreviewTree();
45491
+ init_ImportProgress();
45492
+ init_ImportSourcePicker();
45158
45493
  init_InfiniteScrollSentinel();
45159
45494
  init_Input();
45160
45495
  init_InputGroup();
@@ -45418,6 +45753,9 @@ var init_component_registry_generated = __esm({
45418
45753
  "HeroOrganism": HeroOrganism,
45419
45754
  "HeroSection": HeroSection,
45420
45755
  "Icon": Icon,
45756
+ "ImportPreviewTree": ImportPreviewTree,
45757
+ "ImportProgress": ImportProgress,
45758
+ "ImportSourcePicker": ImportSourcePicker,
45421
45759
  "InfiniteScrollSentinel": InfiniteScrollSentinel,
45422
45760
  "Input": Input,
45423
45761
  "InputGroup": InputGroup,